Game Development Reference
In-Depth Information
if (edge_x)
{
float k0 = dx1 - dx0; // Left slope
float k1 = dx3 - dx2; // Right slope
float m0=dx1+k0; // Left offset
float m1 = dx2 - k1; // Right offset
offset.x = (m1 - m0) / (k0 - k1); // Intersection point
is_silhouette = (abs(offset.x) > 1.0f);
offset.x = (abs(offset.x) < 0.5f)? offset.x : 0.5f;
}
Listing 3.2. Computing horizontal crease intersection point.
In Listing 3.2 we are computing the intersection point horizontally. The math
is relatively straightforward, and the resulting value is the coordinate relative to
the center sample location. If the intersection point lands somewhere within a
pixel in either direction, we have successfully resolved this as a crease. Otherwise,
there is no valid intersection point here, indicating that we are dealing with a
silhouette edge. If we have a valid crease, we only use it if the intersection point
lands within half a pixel. This is because if the intersection point is further away,
it is actually within the neighboring pixel's area, and it is that pixel that should
do the blending.
Silhouette edges. So far we have only required a standard depth buffer. Unfor-
tunately, when we have a silhouette edge, we do not have an adjacent primitive
whose depth values can be used to derive the geometric edge. The background
primitive has nothing in particular in common with the foreground primitive that
we can take advantage of. In Figure 3.4, from the red dots alone, the only thing
we can know is that there is a gap between the second and third sample, so the
Figure 3.4. Finding the original geometric edge in the silhouette case.