Graphics Reference
In-Depth Information
to the radiance
L_o
passing through its center from the closest triangle. Radiance
from farther triangles is not interesting because it will (conceptually) be blocked
by the back of the closest triangle and never reach the image. The implementation
of
sampleRayTriangle
appears in Listing 15.15.
To render the entire image, we must invoke
sampleRayTriangle
once for
each pixel center and for each triangle. Listing 15.13 defines
rayTrace
, which
performs this iteration. It takes as arguments a box within which to cast rays (see
Section 15.4.4). We use
L_o
to denote the radiance from the triangle; the subscript
“o” is for “outgoing”.
Listing 15.13: Code to trace one ray for every pixel between
(
x0
,
y0
)
and
(
x1-1
,
y1-1
)
, inclusive.
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
/
**
Trace eye rays with origins in the box from [x0, y0] to (x1, y1).
*
/
void
rayTrace(
Image
& image,
const
Scene
& scene,
const
Camera
& camera,
int
x0,
int
x1,
int
y0,
int
y1) {
// For each pixel
for (
int
y = y0; y < y1; ++y) {
for (
int
x = y0; x < x1; ++x) {
// Ray through the pixel
const
Ray
& R = computeEyeRay(x + 0.5f, y + 0.5f, image.width(),
image.height(), camera);
// Distance to closest known intersection
float
distance = INFINITY;
Radiance3
L_o;
// For each triangle
for
(
unsigned int
t = 0; t < scene.triangleArray.size(); ++t){
const
Triangle
& T = scene.triangleArray[t];
if
(sampleRayTriangle(scene, x, y, R, T, L_o, distance)) {
image.set(x, y, L_o);
}
}
}
}
}
To invoke
rayTrace
on the entire image, we will use the call:
rayTrace(image, scene, camera, 0, image.width(), 0, image.height());
Assume the camera's center of projection is at the origin,
(
0, 0, 0
)
, and that, in
the camera's frame of reference, the
y
-axis points upward, the
x
-axis points to the
right, and the
z
-axis points out of the screen. Thus, the camera is facing along its
own
−
z
-axis, in a right-handed coordinate system. We can transform any scene to
this coordinate system using the transformations from Chapter 11.
We require a utility function,
computeEyeRay,
to find the ray through the
center of a pixel, which in screen space is given by
(
x
+
0.5,
y
+
0.5
)
for integers
x
and
y
. Listing 15.14 gives an implementation. The key geometry is depicted in