Graphics Reference
In-Depth Information
must consider light arriving at P from all other sources, that is, light from some
point Q that arrives at P having been reflected at Q rather than emitted . Such light
is reflected at P to contribute to the outgoing radiance from P back toward the eye.
Once again, we estimate this incoming indirect radiance with a single sample. To
do so, we use our path-tracing code recursively. We build a ray starting at (or very
near) P , going in some random direction
into the scene; we use our path tracer
to tell us the indirect radiance back along this ray, and reflect this, via the BRDF,
into radiance transported from P toward the eye. Of course, in this case, we must
not include in the computed radiance the light emitted directly toward P —we've
already accounted for that. We therefore set includeEmissive to false at line 24.
Listing 32.7 show this.
v
Listing 32.7: Estimating the indirect light scattered back along a ray.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Radiance3 App::estimateIndirectLight(
const SurfaceElement& surfel, const Ray& ray, bool isEyeRay){
Radiance3 L_o(0.0f);
// Use recursion to estimate light running back along ray
// from surfel, but ONLY light that arrives from
// INDIRECT sources, by making a single-sample estimate
// of the arriving light.
Vector3 w_o = -ray.direction();
Vector3 w_i;
Color3 coeff;
float eta_o(0.0f);
Color3 extinction_o(0.0f);
float
ignore(0.0f);
if (!(isEyeRay) || m_indirect) {
if (surfel.scatter(w_i, w_o, coeff, eta_o, extinction_o, rnd, ignore)) {
float eta_i = surfel.material.etaReflect;
float refractiveScale = (eta_i / eta_o) * (eta_i / eta_o);
L_o += refractiveScale * coeff *
pathTrace(Ray(surfel.geometric.location, w_o).bumpedRay(0.0001f *
sign(surfel.geometric.normal.dot( w_o)),
surfel.geometric.normal), false);
}
}
return L_o;
}
The great bulk of the work is done in surfel.scatter() , which takes a ray
r arriving at a point and either absorbs it or determines an outgoing direction r
for it, and a coefficient by which the radiance arriving along r (i.e., the radiance
L ( P ,
r ) ) should be multiplied to generate a single-sample estimate of the scat-
tered radiance at P in direction
−
r .
Before examining the scatter() code, let's review that description more
closely. First, scatter() can be used either in ray/path tracing or in photon trac-
ing. The second use is perhaps more intuitive: We have a bit of light energy arriv-
ing at a surface, and it is either absorbed or scattered in one or more directions.
The scatter() procedure is used to simulate this process. If the absorption at the
surface is, say, 0.3, then 30% of the time scatter() will return false . The other
70% of the time it will return true and set the value of
−
v o . Given the direction
v i
toward the source of the light, the probability of picking a particular direction
v o
 
Search WWH ::




Custom Search