Game Development Reference
bool edge_x = (abs(dx1 + dx2 - 2 * dc) > 0.00001f * dc);
bool edge_y = (abs(dy1 + dy2 - 2 * dc) > 0.00001f * dc);
Listing 3.1. Horizontal and vertical edge detection.
some sort of background there. The algorithm will first detect whether there is
a discontinuity in the depth buffer. If not, we are in the middle of a primitive
and no antialiasing is necessary. If a discontinuity is present, it will first attempt
to resolve it as a crease. If that fails, it assumes it is dealing with a silhouette
instead and resolves it as such.
Edge detection. Detecting a discontinuity in the depth buffer is fairly straightfor-
ward. For pixels from the same primitive we expect the delta to the left and to
the right to be equal, or left + right
center = 0. Of course, due to limited
precision and such, we need some sort of epsilon there. An epsilon relative to the
center sample works quite well. Listing 3.1 has the edge detection part of the
shader. Note that we are detecting both horizontal and vertical discontinuities
here. To simplify understanding, for the rest of this article only the horizontal
case will be covered, but the same operations are done in both directions. In the
case that we detect a valid edge in both directions, we will decide with which
direction to go depending on in which direction the edge is closer.
Creases. Once it has been established that wehaveanedge,wetrytoresolve
it as a crease. If we have a crease, the original geometry would have the two
primitives meet at some point. In Figure 3.3, the blue and green primitives meet
at the purple dot. The red dots represent our depth buffer samples. Provided
the constant gradients in the screen space, finding this edge point is simply about
computing the intersection between the lines passing through the samples.
Figure 3.3. Finding the original geometric edge in the crease case.