Fix nans for iridescent material

This commit is contained in:
hal8174 2025-05-24 22:45:46 +02:00
parent c26a4bece0
commit e3009563ba
Signed by: hal8174
SSH key fingerprint: SHA256:JwuqS+eVfISfKr+DkDQ6NWAbGd1jFAHkPpCM1yCnlTs
3 changed files with 42 additions and 10 deletions

View file

@ -49,6 +49,13 @@ impl Iridescent {
let imag = (num_imag * denom_real - num_real * denom_imag) let imag = (num_imag * denom_real - num_real * denom_imag)
/ (denom_real * denom_real + denom_imag * 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 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); 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!(( dbg!((
l, l,
theta1, theta1,
@ -103,17 +112,19 @@ impl Iridescent {
local_c_squred, local_c_squred,
s_polaized, s_polaized,
k_delta, k_delta,
u,
)); ));
} }
let u = f32::sin(k_delta) / f32::sin(self.n * k_delta);
local_c_squred / (local_c_squred + u * u) 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( let imk_delta = -f32::ln(f32::abs(
local_cos_k_delta - f32::sqrt(local_cos_k_delta * local_cos_k_delta - 1.0), 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!(( dbg!((
l, l,
theta1, theta1,
@ -122,9 +133,25 @@ impl Iridescent {
local_c_squred, local_c_squred,
s_polaized, s_polaized,
imk_delta, 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) local_c_squred / (local_c_squred + u * u)
} }
@ -194,7 +221,12 @@ impl<R: Rng> Material<R> for Iridescent {
fn sample(&self, w_in: Dir3, rng: &mut R) -> ray_tracing_core::material::SampleResult { 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 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) ray_tracing_core::material::SampleResult::new(w_out, color, true)
} }

View file

@ -28,7 +28,7 @@ pub fn example_scenes<R: Rng + Debug + 'static>() -> HashMap<&'static str, Box<d
"stanford_dragon_microfacet", "stanford_dragon_microfacet",
Box::new(stanford_dragon::StanfordDragon::new(material)), Box::new(stanford_dragon::StanfordDragon::new(material)),
); );
let material = Iridescent::new(300.0, 300.0, 1.0, 1.5, 10); let material = Iridescent::new(100.0, 900.0, 1.0, 1.5, 20);
map.insert( map.insert(
"stanford_dragon_iridescent", "stanford_dragon_iridescent",
Box::new(stanford_dragon::StanfordDragon::new(material)), Box::new(stanford_dragon::StanfordDragon::new(material)),

View file

@ -40,8 +40,8 @@ impl<R: Rng + 'static, M: Material<R> + 'static> ExampleScene<R> for StanfordDra
let materials = vec![ let materials = vec![
BVHMaterial::new_material(self.material.take().unwrap()), 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.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.9, 0.2, 0.2))),
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.2, 0.9, 0.2))),
BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)), BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)),
]; ];