Graphics Reference
In-Depth Information
(because a solid angle on one side becomes a different solid angle on the other),
while for photons, which represent power transport through the scene, there is no
such change. Thus, there's no
η i o factor in the photon-tracing code.
Having built the photon map, we must render a picture based on it. Our first
version will closely resemble the path-tracing code, in the sense that we'll break
up the computation into direct and indirect light, and handle diffuse and impulse
scattering individually. We'll use a ray-tracing approach (i.e., recursively trace
rays until some fixed depth); making the corresponding path-tracing approach is
left as an exercise for the reader. The photon map is used only to estimate the
diffusely reflected indirect light arriving at a point.
Computing the light arriving at pixel ( x , y ) of the image, using a ray-tracing
and photon-mapping hybrid, is the job of the photonRender procedure, shown in
Listing 32.15, along with some of the methods it calls.
Listing 32.15: Generating an image sample for pixel ( x , y ) from the photon map.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void App::photonRender(int x, int y) {
Radiance3 L_o(0.0f);
for (int i = 0; i < m_primaryRaysPerPixel; i++) {
const Ray r = defaultCamera.worldRay(x + rnd.uniform(),
y + rnd.uniform(), m_currentImage->rect2DBounds());
L_o += estimateTotalRadiance(r, 0);
}
m_currentImage->set(x, y, L_o / m_primaryRaysPerPixel);
}
Radiance3 App::estimateTotalRadiance(const Ray& r, int depth) {
Radiance3 L_o(0.0f);
if (m_emit) L_o += estimateEmittedLight(r);
L_o += estimateTotalScatteredRadiance(r, depth);
return L_o;
}
Radiance3 App::estimateEmittedLight(Ray r){
...declarations...
if (m_world->intersect(r, dist, surfel))
L_o += surfel.material.emit;
return L_o;
}
To generate a measurement at pixel ( x , y ) we shoot m_primaryRaysPerPixel
into the scene, and estimate the radiance returning along each ray. It's possible
that a ray hits a light source; if so, the source's radiance ( EmittedLight )mustbe
counted in the total radiance returning along the ray, along with any light reflected
from the luminaire.
We've ignored the case where the ray hits a point luminaire (point sources have
no geometry in our scene descriptions, so such an intersection is never reported).
There are two reasons for this. The first is that the intersection of the ray and the
point light is an event with (mathematical) probability zero, so in an ideal pro-
gram with perfect precision, it should never occur. This is a frequently used but
somewhat specious argument: First, the discrete nature of floating-point numbers
makes probability-zero events occur with very small, but nonzero, frequency. Sec-
ond, models like point-lighting are usually taken as a kind of “limit” of nonzero-
probability things (like small, disk-shaped lights); if the limit is to make any sense,
 
 
Search WWH ::




Custom Search