Graphics Reference
In-Depth Information
for a simpler interface to the bounding function, which makes the code easier to
write and debug. Listing 15.26 shows the bounding box-function. The rasterizer
must compute versions of the vertex attributes, which in our case are just the ver-
tex normals, that are scaled by the
z
value (which we call
w
) for the corresponding
post-projective vertex. Both of those are per-triangle changes to the code. Finally,
the inner loop must compute visibility from the 2D barycentric coordinates instead
of from a ray cast. The actual shading computation remains unchanged from the
original ray tracer, which is good—we're only looking at strategies for visibility,
not shading, so we'd like each to be as modular as possible. Listing 15.27 shows
the loop setup of the original rasterizer updated with the bounding-box and 2D
barycentric approach. Listing 15.28 shows how the inner loops change.
Listing 15.26: Bounding box for the projection of a triangle, invoked by
rasterize3
to establish the pixel iteration bounds.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void
computeBoundingBox(
const
Triangle
&T,
const
Camera
& camera,
const
Image
& image,
Point2 V[3],
int
& x0,
int
& y0,
int
& x1,
int
& y1) {
Vector2
high(image.width(), image.height());
Vector2
low(0, 0);
for
(
int
v=0;v<3;++v) {
const
Point2& X = perspectiveProject(T.vertex(v), image.width(),
image.height(), camera);
V[v] = X;
high = high.max(X);
low = low.min(X);
}
x0=(
int
)floor(low.x);
x1=(
int
)ceil(high.x);
y0=(
int
)floor(low.y);
y1=(
int
)ceil(high.y);
}
Listing 15.27: Iteration setup for a barycentric (edge align) rasterizer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/
**
2D barycentric evaluation w. perspective-correct attributes
*
/
void
rasterize3(
Image
& image,
const
Scene
& scene,
const
Camera
& camera){
DepthBuffer depthBuffer(image.width(), image.height(), INFINITY);
// For each triangle
for
(
unsigned int
t = 0; t < scene.triangleArray.size(); ++t) {
const
Triangle
& T = scene.triangleArray[t];
// Projected vertices
Vector2
V[3];
int
x0, y0, x1, y1;
computeBoundingBox(T, camera, image, V, x0, y0, x1, y1);
// Vertex attributes, divided by -z
float
vertexW[3];
Vector3
vertexNw[3];
Point3
vertexPw[3];
for
(
int
v=0;v<3;++v) {