Graphics Reference
In-Depth Information
at P ; and the third all other light. Thus, the term L ( P ,
v i ) in the rendering equa-
tion has been split into a sum of three terms.
The first of these terms is computed (see Listing 29.2) by converting the inte-
gral over all possible incoming directions into a sum over the point luminaire
sources. This change of domain in the integral means we have to alter the inte-
grand as well, using the change of variable from Section 26.6.5.
Listing 29.2: Reflecting illumination from point lights.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Radiance3 App::estimateDirectLightFromPointLights(surfel, ray){
Radiance3 radiance(0.0f);
for (int L = 0; L < m_world->lightArray.size(); ++L) {
const GLight& light = m_world->lightArray[L];
// Shadow rays
boolean visible = m_world->lineOfSight(surfel.geometric.location +
surfel.geometric.normal * 0.0001f,
light.position.xyz())
if (visible){
Vector3 w_i = light.position.xyz() - surfel.shading.location;
const float distance2 = w_i.squaredLength();
w_i /= sqrt(distance2);
// Attenuated radiance
const Irradiance3& E_i = light.color / (4.0f * pif() * distance2);
radiance += (surfel.evaluateBRDF(w_i, -ray.direction()) *
E_i * max(0.0f, w_i.dot(surfel.shading.normal)));
}
}
return radiance;
}
As you can see, the procedure loops through all the point luminaire sources,
and for each one, it checks whether the source is visible from P ,using
m_world->lineOfSight() , the implementation of the visibility function for the
world we're rendering. The reflected radiance is computed as a product of the
BRDF, the dot product
v i · n P , and a term E i , which is the incoming radiance
adjusted by the change-of-variable factor mentioned above.
The second term is similar, involving estimates of how area luminaires are
reflected. The third term is the most interesting, however. Before we look at
it, we need one more bit of mathematics (which we'll develop extensively in
Chapter 30).
The idea is this: The integral of any function h over any domain D is the
product of the average value of h on that domain with the size of the domain.
When the domain is the interval [ a , b ] , the size is b
a ; when the domain is a unit
hemisphere, the size is 2
, etc. The “average value” can be estimated by evaluating
h at n points of the domain and averaging. As n gets large, the estimate gets better
and better. But even n = 1 works! That is to say, we can estimate the integral of
h over the domain D by evaluating h ( x ) for a randomly chosen point x
π
D and
multiplying by the size of D . The estimate won't generally be very good, but if we
repeat the estimation procedure multiple times, the average will be quite a good
estimate.
We'll apply this to the situation where h is the integrand in the reflectance
equation, and D is the upper hemisphere. Let's look at the code (see Listing 29.3).
 
 
Search WWH ::




Custom Search