From e3009563ba9f9018200d8b8cc20f3b3f41ff0dba Mon Sep 17 00:00:00 2001 From: hal8174 Date: Sat, 24 May 2025 22:45:46 +0200 Subject: [PATCH] Fix nans for iridescent material --- ray-tracing-material/src/iridescent.rs | 46 ++++++++++++++++--- ray-tracing-scene/src/examples/mod.rs | 2 +- .../src/examples/stanford_dragon.rs | 4 +- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ray-tracing-material/src/iridescent.rs b/ray-tracing-material/src/iridescent.rs index df667cd..a29f2cb 100644 --- a/ray-tracing-material/src/iridescent.rs +++ b/ray-tracing-material/src/iridescent.rs @@ -49,6 +49,13 @@ impl Iridescent { let imag = (num_imag * denom_real - num_real * denom_imag) / (denom_real * denom_real + denom_imag * denom_imag); + if !real.is_normal() || !imag.is_normal() { + dbg!( + l, theta1, theta2, s_polaized, r12, phi, num_real, num_imag, denom_real, + denom_imag, real, imag + ); + } + real * real + imag * imag } @@ -91,10 +98,12 @@ impl Iridescent { )); } - if local_cos_k_delta.abs() <= 1.0 { + if local_cos_k_delta.abs() < 1.0 { let k_delta = f32::acos(local_cos_k_delta); - if !k_delta.is_normal() { + let u = f32::sin(k_delta) / f32::sin(self.n * k_delta); + + if !k_delta.is_normal() || !u.is_normal() { dbg!(( l, theta1, @@ -103,17 +112,19 @@ impl Iridescent { local_c_squred, s_polaized, k_delta, + u, )); } - let u = f32::sin(k_delta) / f32::sin(self.n * k_delta); local_c_squred / (local_c_squred + u * u) - } else { + } else if local_cos_k_delta.abs() > 1.0 { let imk_delta = -f32::ln(f32::abs( local_cos_k_delta - f32::sqrt(local_cos_k_delta * local_cos_k_delta - 1.0), )); - if !imk_delta.is_normal() { + let u = f32::sinh(imk_delta) / f32::sinh(self.n * imk_delta); + + if !imk_delta.is_normal() || !u.is_normal() { dbg!(( l, theta1, @@ -122,9 +133,25 @@ impl Iridescent { local_c_squred, s_polaized, imk_delta, + u + )); + } + + local_c_squred / (local_c_squred + u * u) + } else { + let u = 1.0 / self.n; + + if !u.is_normal() { + dbg!(( + l, + theta1, + theta2, + local_cos_k_delta, + local_c_squred, + s_polaized, + u )); } - let u = f32::sinh(imk_delta) / f32::sinh(self.n * imk_delta); local_c_squred / (local_c_squred + u * u) } @@ -194,7 +221,12 @@ impl Material for Iridescent { fn sample(&self, w_in: Dir3, rng: &mut R) -> ray_tracing_core::material::SampleResult { let w_out = (2.0 * Dir3::up() * w_in.y()) - w_in; - let color = self.monte_carlo_reflectance(f32::acos(w_out.z()), rng); + let color = if w_out.y() > 0.0 && w_out.y() <= 1.0 { + self.monte_carlo_reflectance(f32::acos(w_out.y()), rng) + } else { + // dbg!(w_out); + Color::black() + }; ray_tracing_core::material::SampleResult::new(w_out, color, true) } diff --git a/ray-tracing-scene/src/examples/mod.rs b/ray-tracing-scene/src/examples/mod.rs index 327d832..3c4fea3 100644 --- a/ray-tracing-scene/src/examples/mod.rs +++ b/ray-tracing-scene/src/examples/mod.rs @@ -28,7 +28,7 @@ pub fn example_scenes() -> HashMap<&'static str, Box + 'static> ExampleScene for StanfordDra let materials = vec![ BVHMaterial::new_material(self.material.take().unwrap()), BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.8, 0.8, 0.8))), - BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.0, 0.0))), - BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.0, 0.9, 0.0))), + BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.2, 0.2))), + BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.2, 0.9, 0.2))), BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)), ];