Changed LightTree traversal to be a bit better in its choices.

After some experimentation, it's pretty clear that the LightTree
performs a lot better with a model of spherical _volume_ light
sources.  This makes sense considering that generally they
represent a distribution of other lights in space.

This is a quick hack to make it behave a bit more like that.  But
the long-term solution will be to adjust how
estimate_eval_over_solid_angle() of surface closures is implemented.
This commit is contained in:
Nathan Vegdahl 2016-08-21 15:27:15 -07:00
parent 7f1ab59c5e
commit 0d189f763d

View File

@ -141,19 +141,30 @@ impl LightAccel for LightTree {
let d = bbox.center() - pos; let d = bbox.center() - pos;
let dist2 = d.length2(); let dist2 = d.length2();
let r = bbox.diagonal() * 0.5; let r = bbox.diagonal() * 0.5;
let r2 = r * r; let inv_surface_area = 1.0 / (r * r);
let inv_surface_area = 1.0 / r2;
// Get the approximate amount of light contribution from the
// composite light source.
let approx_contrib = {
let mut approx_contrib = 0.0;
let steps = 2;
let fstep = 1.0 / (steps as f32);
for i in 0..steps {
let r2 = {
let step = fstep * (i + 1) as f32;
let r = r * step;
r * r
};
let cos_theta_max = if dist2 <= r2 { let cos_theta_max = if dist2 <= r2 {
-1.0 -1.0
} else { } else {
let sin_theta_max2 = (r2 / dist2).min(1.0); let sin_theta_max2 = (r2 / dist2).min(1.0);
(1.0 - sin_theta_max2).sqrt() (1.0 - sin_theta_max2).sqrt()
}; };
approx_contrib += sc.estimate_eval_over_solid_angle(inc, d, nor, cos_theta_max);
// Get the approximate amount of light contribution from the }
// composite light source. approx_contrib * fstep
let approx_contrib = sc.estimate_eval_over_solid_angle(inc, d, nor, cos_theta_max); };
node_ref.energy * inv_surface_area * approx_contrib node_ref.energy * inv_surface_area * approx_contrib
}; };