Fixed bug that was causing spurious NaN pixels.

It was because sometimes the PDF's for a sample could be zero,
leading to a divide by zero.  PDF = 0.0 is now checked for.
This commit is contained in:
Nathan Vegdahl 2017-05-14 12:45:43 -07:00
parent 567b658b6c
commit 993ba719d7

View File

@ -392,31 +392,36 @@ impl LightPath {
self.wavelength, self.wavelength,
self.time, self.time,
isect) { isect) {
// Calculate and store the light that will be contributed // Check if pdf is zero, to avoid NaN's.
// to the film plane if the light is not in shadow. if light_pdf > 0.0 {
self.pending_color_addition = { // Calculate and store the light that will be contributed
let material = closure.as_surface_closure(); // to the film plane if the light is not in shadow.
let la = self.pending_color_addition = {
material.evaluate(ray.dir, shadow_vec, idata.nor, self.wavelength); let material = closure.as_surface_closure();
light_color.e * la.e * self.light_attenuation / let la =
(light_pdf * light_sel_pdf) material.evaluate(ray.dir, shadow_vec, idata.nor, self.wavelength);
}; light_color.e * la.e * self.light_attenuation /
(light_pdf * light_sel_pdf)
};
// Calculate the shadow ray for testing if the light is // Calculate the shadow ray for testing if the light is
// in shadow or not. // in shadow or not.
// TODO: use proper ray offsets for avoiding self-shadowing // TODO: use proper ray offsets for avoiding self-shadowing
// rather than this hacky stupid stuff. // rather than this hacky stupid stuff.
*ray = Ray::new(idata.pos + shadow_vec.normalized() * 0.001, *ray = Ray::new(idata.pos + shadow_vec.normalized() * 0.001,
shadow_vec, shadow_vec,
self.time, self.time,
true); true);
// For distant lights // For distant lights
if is_infinite { if is_infinite {
ray.max_t = std::f32::INFINITY; ray.max_t = std::f32::INFINITY;
}
true
} else {
false
} }
true
} else { } else {
false false
}; };
@ -433,18 +438,23 @@ impl LightPath {
material.sample(idata.incoming, idata.nor, (u, v), self.wavelength) material.sample(idata.incoming, idata.nor, (u, v), self.wavelength)
}; };
// Account for the additional light attenuation from // Check if pdf is zero, to avoid NaN's.
// this bounce if pdf > 0.0 {
self.next_attentuation_fac = filter.e / pdf; // Account for the additional light attenuation from
// this bounce
self.next_attentuation_fac = filter.e / pdf;
// Calculate the ray for this bounce // Calculate the ray for this bounce
self.next_bounce_ray = Some(Ray::new(idata.pos + self.next_bounce_ray = Some(Ray::new(idata.pos +
dir.normalized() * 0.0001, dir.normalized() * 0.0001,
dir, dir,
self.time, self.time,
false)); false));
true true
} else {
false
}
} else { } else {
self.next_bounce_ray = None; self.next_bounce_ray = None;
false false