Graphics Reference
In-Depth Information
Because for each screen raster (i.e., row of pixels) we hold P and Q constant
and vary
α
linearly, we can simplify the expression above to define a directly
parameterized function u (
α
) :
)= α·
z Q ·
u ( P )+( 1
−α
) z P ·
u ( Q )
u (
α
.
(15.8)
α·
z Q +( 1
−α
) z P
This is often more casually, but memorably, phrased as “In screen space, the
perspective-correct interpolation of u is the quotient of the linear interpolation
of u
/
z by the linear interpolation of 1
/
z .”
We can apply the perspective-correct interpolation strategy to any number of
per-vertex attributes, including the vertex normals and texture coordinates. That
leaves us with input data for our shade function, which remains unchanged from
its implementation in the ray tracer.
15.6.4.3 2D Barycentric Weights
To implement the perspective-correct interpolation strategy, we need only find an
expression for the 2D barycentric weights at the center of each pixel. Consider
the barycentric weight corresponding to vertex A of a point Q within a triangle
ABC . Recall from Section 7.9 that this weight is the ratio of the distance from Q
to the line containing BC to the distance from A to the line containing BC , that is,
it is the relative distance across the triangle from the opposite edge. Listing 15.25
gives code for computing a barycentric weight in 2D.
Listing 15.25: Computing one barycentric weight in 2D.
1
2
3
4
5
6
7
8
9
10
11
12
/ ** Returns the distance from Q to the line containing B and A. * /
float lineDistance2D( const Point2& A, const Point2& B, const Point2& Q) {
// Construct the line align:
const Vector2 n(A.y - B.y, B.x - A.x);
const float d = A.x * B.y - B.x * A.y;
return (n.dot(Q) + d) / n.length();
}
/ ** Returns the barycentric weight corresponding to vertex A of Q in triangle ABC * /
float bary2D( const Point2& A, const Point2& B, const Point2& C, const Point2& Q) {
return lineDistance2D(B, C, Q) / lineDistance2D(B, C, A);
}
Inline Exercise 15.10: Under what condition could lineDistance2D return 0 ,
or n.length() be 0 , leading to a division by zero? Change your rasterizer
to ensure that this condition never occurs. Why does this not affect the final
rendering? What situation does this correspond to in a ray caster? How did we
resolve that case when ray casting?
The rasterizer structure now requires a few changes from our previous version.
It will need the post-projection vertices of the triangle after computing the bound-
ing box in order to perform interpolation. We could either retain them from the
bounding-box computation or just compute them again when needed later. We'll
recompute the values when needed because it trades a small amount of efficiency
 
 
Search WWH ::




Custom Search