OpenGL Depth Sorting Resolution
by James W. Walker
Depth sorting is the process by which OpenGL decides whether one triangle is in front of another. If the triangles are too close together, the process may fail. Whether depth sorting succeeds or fails depends on a number of variables: The distances of the triangles from the camera, the distances of the near and far clipping planes from the camera, and the size of the depth buffer. This article explores the relationship between these variables and depth sorting. See http://www.opengl.org/resources/faq/technical/depthbuffer.htm#dept0045 for a similar discussion.
Review of Coordinate Systems in OpenGL
The viewing transformation transforms object coordinates into eye coordinates, also known as view coordinates. The eye coordinate system has its origin at the camera location (the "eye"), x axis to the right, y axis up, and (to make the coordinate system right-handed) -z axis in the direction that the camera is looking.
The volume visible to a perspective camera is a frustum of a pyramid, bounded by 4 planes on the left, right, top, and bottom, and by the near and far clipping planes. The projection matrix maps this volume to a box in clip coordinates, also called frustum coordinates, in which x, y, and z each range from -w to w. Division of x, y, and z by w, called perspective division, brings us to normalized device coordinates, where x, y, and z range from -1 to 1.
The viewport transformation maps normalized device coordinates to window coordinates. In particular, the z coordinate maps into the range 0 to 1. These z values are then stored in the depth buffer for depth sorting. Notice that the range 0 to 1 means that the depth buffer does not need to store a sign bit or an exponent, unlike the usual case with floating-point numbers.
Window Depth as a Function of Eye Depth
The projection matrix defined by gluPerspective is:
| |
|
|
0 |
0 |
0 |
| 0 |
f |
0 |
0 |
| 0 |
0 |
| zFar + zNear |
| zNear - zFar |
|
| 2 zFar zNear |
| zNear - zFar |
|
| 0 |
0 |
-1 |
0 |
|
|
Therefore a point with eye coordinates ( ·, ·, -d, 1 )T is transformed to the point in clip coordinates
| ( ·, ·, |
| - d (zFar + zNear) + 2 zFar zNear |
| zNear - zFar |
|
, d )T. |
The perspective division brings us to normalized device coordinates
| ( ·, ·, |
| zFar + zNear |
| zFar - zNear |
|
- |
| 2 zFar zNear |
| d (zFar - zNear) |
|
, 1 )T. |
When we transform normalized device coordinates to window coordinates, the depth coordinate is transformed by the linear function x → x/2 + 1/2, producing
| ( ·, ·, |
| zFar + zNear |
| 2 (zFar - zNear) |
|
- |
| zFar zNear |
| d (zFar - zNear) |
|
+ 0.5, 1 )T. |
Therefore, window depth as a function of eye depth is given by the formula
| f( d ) = |
| zFar + zNear |
| 2 (zFar - zNear) |
|
- |
| zFar zNear |
| d (zFar - zNear) |
|
+ 0.5 . |
You can easily check that f( zNear ) = 0 and f( zFar ) = 1.
Estimating Depth Resolution
Consider two triangles at eye coordinate depths d1 and d2, differing by Δd. I want to estimate how large Δd can be in a situation where the two triangles cannot be reliably sorted by the depth buffer.
If the depth buffer is k bits deep, then the minimum significant difference in window depth is Δf = 2-k. To relate Δd to Δf,
we can use the approximation for the derivative,
or
The exact formula for the derivative is
| f'( d ) = |
| zFar zNear |
| d2 (zFar - zNear) |
|
, |
hence we obtain
| Δd ≈ 2-k |
| d2 (zFar - zNear) |
| zFar zNear |
|
, |
Clearly, the worst case is near the far plane, where this reduces to
| Δd ≈ 2-k |
| zFar (zFar - zNear) |
| zNear |
|
. |
Typically, the ratio of zFar to zNear is large, so we do not lose much by using the cruder estimate
Exact Calculation of Depth Resolution
We want to find the largest value of Δd such that
| |
f( d ) - f( d - Δd ) = Δf |
(2) |
and such that d and d - Δd are restricted to the interval from zNear to zFar.
We can express the function as
where
Now let us solve equation (1) for Δd.
Cancel the a.
Divide through by b.
Solve for d - Δd.
And finally we can obtain Δd.
| Δd = d - |
|
= |
| d b + d2 Δf - b d |
| b + d Δf |
|
= |
|
If we write this as
then it is clear that the numerator is an increasing function of d and the denominator is a decreasing function of d, so the maximum occurs at the right hand end of the interval, d = zFar. If we substitute in d = zFar, Δf = 2-k, and the defined value of b, we have:
or equivalently
| |
| Δd = |
| zFar (zFar - zNear) 2-k |
| zNear + (zFar - zNear) 2-k
|
|
. |
|
(3) |
If we assume that the ratio zFar/zNear is much larger than 1 but much smaller than 2k, then we can see that the approximation (1) is a reasonable approximation to equation (3).
Copyright ©2006, James W. Walker