Graphics Reference
In-Depth Information
Inline Exercise 32.7: The areaLightEmit code uses cosHemiRandom to gener-
ate a photon in direction ( x , y , z ) with probability cos(
θ
) , where
θ
is the angle
between ( x , y , z ) and the surface normal. Why?
Listing 32.13: Photon emission in the LightList class.
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
29
// emit a EPhoton; argument is total number of photons to emit
EPhoton LightList::emitPhoton(int nEmitted)
{
u= uniform random variable between 0 and 1
find the light i with p 0 + ... + p i 1 u < p 0 + ... + p i .
if (i < m_nPointLights)
return pointLightEmit(( * m_pointLightArray)[i], nEmitted, m_probability[i]);
else
return areaLightEmit(( * m_areaLightArray)[i - m_nPointLights], nEmitted,
m_probability[i]);
}
EPhoton LightList::pointLightEmit(GLight light, int nEmitted, float prob){
// uniformly randomly select a point (x,y,z) on the unit sphere
Vector3 direction(x, y, z);
Power3 power = light.power() / (nEmitted * prob);
Vector3 location = location of the light
return EPhoton(location, direction, power);
}
EPhoton LightList::areaLightEmit(AreaLight::Ref light, int nEmitted, float prob){
SurfaceElement surfel = light->samplePoint(m_rnd);
Power3 power = light->power() / (nEmitted * prob);
// select a direction with cosine-weighted distribution around
// surface normal. m_rnd is a random number generator.
Vector3 direction = Vector3::cosHemiRandom(surfel.geometric.normal, m_rnd);
return EPhoton(surfel.geometric.location, direction, power);
}
What remains is the photon tracing itself (see Listing 32.14). We use a G3D
helper class, the Array<IPhoton> , to accumulate incident photons. This class has a
fastClear method that simply sets the number of stored values to zero rather than
actually deallocating the array; this saves substantial allocation/deallocation over-
head. The photonTraceHelper procedure keeps track of the number of bounces
that the photon has undergone so far so that the bounce process can be terminated
when this reaches the user-specified maximum. Note that in contrast to Jensen's
original algorithm, we store a photon at every bounce, whether it's diffuse or spec-
ular. For estimating radiance at surface points with purely impulsive scattering
models (e.g., mirrors), these photons will never be used, however, so there's no
impact on the results.
Once again, there are no real surprises in the program. The scatter method
does all the work. We've hidden one detail here: The scatter method should be
different from the one used in path tracing. If we're only studying reflection, and
only using symmetric BRDFs (i.e., all materials satisfy Helmholtz reciprocity),
then the two scattering methods are the same. But in the case of asymmetric scat-
tering (such as Fresnel-weighted transmission), it's possible that the probability
that a photon arriving at P in direction
v i scatters in direction
v o is completely
 
Search WWH ::




Custom Search