Graphics Reference
In-Depth Information
The direct-lighting computation is essentially identical to that in the path
tracer, except that we estimate the direct light from each area light with several
( m_diffuseDirectSamples ) samples rather than relying on multiple primary rays
to ensure adequate sampling. (The alternative is quite viable, however.) The simi-
larity is so great that we omit the code. This leaves only the impulse-scattered and
diffusely reflected indirect light to consider. The first is easy, and it closely resem-
bles the corresponding path-tracing code: We simply compute the total arriving
radiance for each impulse recursively, and sum (see Listing 32.17).
This leaves only the computation of diffusely reflected indirect light, which is
where the photon map finally comes into play (see Listing 32.18). Central to this
code is the photon map's kernel, the function that says how much weight to give
each nearby photon's contribution.
Listing 32.18: The photon map used to compute diffusely reflected indirect light.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Radiance3 App::estimateDiffuselyReflectedIndirectLight(const Ray& r,
const SurfaceElement& surfel){
Radiance3 L_o(0.0f);
Array<IPhoton> photonArray;
// find nearby photons
m_photonMap.getIntersectingMembers(
Sphere(surfel.geometric.location, m_photonMap.gatherRadius()), photonArray);
foreach photon p in the array
const float cos_theta_i =
L_o += p.power() * m_photonMap.kernel(p.position(), surfel.shading.location) *
surfel.evaluateBSDF(p.directionToSource(), -r.direction(), finf());
return L_o;
}
We sum up the contributions of all sufficiently nearby photons, weighting them
by our kernel and pushing each one through the BSDF to determine the light it
contributes traveling toward the source of the ray r .
Note that what is being multiplied by the BRDF term is an area-weighted
radiance, which is what we called biradiance in Chapter 14.
32.6.1 Results and Discussion
Naturally, as we discussed in Chapter 31, there's an interaction between the gather
radius, the number of photons stored in the photon map, and the quality of the
estimated radiance. When we're estimating the reflected indirect radiance at P ,
if we use a cylinder kernel (a photon is counted if it's within some distance of
P , and ignored otherwise) and there are no photons within the gather radius of
P , the radiance estimate for that ray will be zero. This can happen if the gather
radius is too small or if there are too few photons. How many photons are enough?
Well, we'd generally like nearby pixel rays hitting the same surface to get similar
radiance estimates. But one ray might be within the radius of 20 photons, while the
nearby ray might be within the radius of 21 photons. Even if all the photons share
the same incoming power, the second ray will get a radiance that's 5 % greater.
To reduce the noise in areas of constant radiance, it appears that we might need
hundreds of photons within the gather radius of P .
There are several ways to improve the results without needing that many pho-
tons. One is to alter the photon map's kernel —the weighting function, centered
 
 
 
Search WWH ::




Custom Search