Graphics Reference
In-Depth Information
(at least for surfaces with no mirror terms or transmissive terms) for the scat-
tered light is roughly proportional to f s (
v o ) . In an ideal world, it would be
exactly proportional. In ours, it's generally not, but the returned coefficient con-
tains a f s (
v i ,
v o )
/
p (
v o ) factor, where p (
v o ) is the probability of sampling
v i ,
v o ,
which compensates appropriately.
What happens if there is a mirror reflection? Let's say that 30% of the time the
incoming light is absorbed, 50% of the time it's mirror-reflected, and the remain-
ing 20% of the time it's scattered according to a Lambertian scattering model.
In this situation, scatter() will return false 30% of the time. Fifty percent of
the time it will return true and set
v o to be the mirror-reflection direction, and
the remaining 20% of the time
v o will be distributed on the hemisphere with a
cosine-weighted distribution (i.e., with high probability of being emitted in the
normal direction and low probability of being emitted in a tangent direction).
Let's see this in practice, and look at the start of G3D's scatter method in
Listing 32.8.
Listing 32.8: The start of the scatter method.
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
30
31
32
bool SurfaceElement::scatter
(const Vector3& w_i,
Vector3&
w_o,
Color3&
weight_o, // coeff by which to multiply sample in path-tracing
float&
eta_o,
Color3&
extinction_o,
Random&
random,
float&
density) const {
const Vector3& n = shading.normal;
// Choose a random number on [0, 1], then reduce it by each kind of
// scattering's probability until it becomes negative (i.e., scatters).
float r = random.uniform();
if (material.lambertianReflect.nonZero()) {
float p_LambertianAvg = material.lambertianReflect.average();
r -= p_LambertianAvg;
if (r < 0.0f) {
// Lambertian scatter
weight_o = material.lambertianReflect / p_LambertianAvg;
w_o = Vector3::cosHemiRandom(n, random);
density = ...
eta_o = material.etaReflect;
extinction_o = material.extinctionReflect;
debugAssert(power_o.r >= 0.0f);
return true;
}
}
...
As you can see, the material has a lambertianReflect member, which indi-
cates reflectance in each of three color bands; 2
the average of these gives a
2. We'll call these “red,” “green,” and “blue” in keeping with convention, but with no
important change in the implementation, we could record five or seven or 20 spectral
samples.
 
Search WWH ::




Custom Search