Graphics Reference
In-Depth Information
Listing 15.23: Projecting vertices and computing the screen-space bounding box.
1
2
3
4
5
Vector2 low(image.width(), image.height());
Vector2 high(0, 0);
for ( int v = 0; v < 3; ++v) {
const Vector2 & X = perspectiveProject(T.vertex(v), image.width
(), image.height(), camera);
high = high.max(X);
low = low.min(X);
6
7
8
9
10
11
12
13
14
}
const int x0=( int )(low.x + 0.5f);
const int x1=( int )(high.x + 0.5f);
const int y0=( int )(low.y + 0.5f);
const int y1=( int )(high.y + 0.5f);
Listing 15.24: Perspective projection.
1
2
Vector2 perspectiveProject( const Vector3 &P, int width, int height,
const Camera & camera) {
// Project ontoz=-1
Vector2 Q(-P.x / P.z, -P.y / P.z);
3
4
5
6
7
8
9
10
11
12
13
14
15
const float aspect = float(height) / width;
// Compute the side of a square at z = -1 based on our
// horizontal left-edge-to-right-edge field of view
const float s = -2.0f * tan(camera.fieldOfViewX * 0.5f);
Q.x = width * (-Q.x / s + 0.5f);
Q.y = height * (Q.y / (s * aspect) + 0.5f);
return Q;
}
Integrate the listings from this section into your rasterizer and run it. The
results should exactly match the ray tracer and simpler rasterizer. Furthermore,
it should be measurably faster than the simple rasterizer (although both are likely
so fast for simple scenes that rendering seems instantaneous).
Simply verifying that the output matches is insufficient testing for this opti-
mization. We're computing bounds, and we could easily have computed bounds
that were way too conservative but still happened to cover the triangles for the test
scene.
A good follow-up test and debugging tool is to plot the 2D locations to which
the 3D vertices projected. To do this, iterate over all triangles again, after the scene
has been rasterized. For each triangle, compute the projected vertices as before.
But this time, instead of computing the bounding box, directly render the projected
vertices by setting the corresponding pixels to white (of course, if there were bright
white objects in the scene, another color, such as red, would be a better choice!).
Our single-triangle test scene was chosen to be asymmetric. So this test should
reveal common errors such as inverting an axis, or a half-pixel shift between the
ray intersection and the projection routine.
 
 
Search WWH ::




Custom Search