Usage
Occlusion
Determining what should be displayed on the screen and what should be omitted is a multi-step process utilising various techniques. Using a z-buffer is the final step in this process. Each time an object is rendered into the framebuffer the z-buffer is used to compare the z-values of the fragments with the z-value already in the z-buffer (i.e., check what is closer), if the new z-value is closer than the old value, the fragment is written into the framebuffer and this new closer value is written into the z-buffer. If the z-value is further away than the value in the z-buffer, the fragment is discarded. This is repeated for all objects and surfaces in the scene (often in parallel). In the end, the z-buffer will allow correct reproduction of the usualShadow mapping
Z-buffer data obtained from rendering a surface from a light's point-of-view permits the creation of shadows by the shadow mapping technique.History
Z-buffering was first described in 1974 by Wolfgang Straßer in his PhD thesis on fast algorithms for rendering occluded objects. A similar solution to determining overlapping polygons is the painter's algorithm, which is capable of handling non-opaque scene elements, though at the cost of efficiency and incorrect results. Z-buffers are often implemented in hardware within consumer graphics cards. Z-buffering is also used (implemented as software as opposed to hardware) for producing computer-generated special effects for films.Developments
Even with small enough granularity, quality problems may arise when precision in the z-buffer's distance values are not spread evenly over distance. Nearer values are much more precise (and hence can display closer objects better) than values that are farther away. Generally, this is desirable, but sometimes it will cause artifacts to appear as objects become more distant. A variation on z-buffering which results in more evenly distributed precision is called w-buffering (see below). At the start of a new scene, the z-buffer must be cleared to a defined value, usually 1.0, because this value is the upper limit (on a scale of 0 to 1) of depth, meaning that no object is present at this point through the viewing frustum. The invention of the z-buffer concept is most often attributed to Edwin Catmull, although Wolfgang Straßer described this idea in his 1974 Ph.D. thesis months before Catmull's invention. On more recent PC graphics cards (1999–2005), z-buffer management uses a significant chunk of the available memory bandwidth. Various methods have been employed to reduce the performance cost of z-buffering, such as lossless compression (computer resources to compress/decompress are cheaper than bandwidth) and ultra-fast hardware z-clear that makes obsolete the "one frame positive, one frame negative" trick (skipping inter-frame clear altogether using signed numbers to cleverly check depths). Some games, notably several games later in the Nintendo 64's life cycle, decided to either minimize z-buffering (for example, rendering the background first without z-buffering and only using z-buffering for the foreground objects) or to omit it entirely, to reduce memory bandwidth requirements and memory requirements respectively. Super Smash Bros. and F-Zero X are two Nintendo 64 games that minimized z-buffering to increase framerates. SeveralZ-culling
In rendering, z-culling is early pixel elimination based on depth, a method that provides an increase in performance when rendering of hidden surfaces is costly. It is a direct consequence of z-buffering, where the depth of each pixel candidate is compared to the depth of the existing geometry behind which it might be hidden. When using a z-buffer, a pixel can be culled (discarded) as soon as its depth is known, which makes it possible to skip the entire process of lighting and texturing a pixel that would not be visible anyway. Also, time-consumingMathematics
The range of depth values in camera space to be rendered is often defined between a and value of . After a perspective transformation, the new value of , or , is defined by: : After anFixed-point representation
Typically, these values are stored in the z-buffer of the hardware graphics accelerator in fixed point format. First they are normalized to a more common range which is by substituting the appropriate conversion into the previous formula: : Simplifying: : Second, the above formula is multiplied by where d is the depth of the z-buffer (usually 16, 24 or 32 bits) and rounding the result to an integer: : This formula can be inverted and derived in order to calculate the z-buffer resolution (the 'granularity' mentioned earlier). The inverse of the above : : where The z-buffer resolution in terms of camera space would be the incremental value resulted from the smallest change in the integer stored in the z-buffer, which is +1 or -1. Therefore, this resolution can be calculated from the derivative of as a function of : : Expressing it back in camera space terms, by substituting by the above : : This shows that the values of are grouped much more densely near the plane, and much more sparsely farther away, resulting in better precision closer to the camera. The smaller is, the less precision there is far away—having the plane set too closely is a common cause of undesirable rendering artifacts in more distant objects. To implement a z-buffer, the values of are linearly interpolated across screen space between the vertices of the current polygon, and these intermediate values are generally stored in the z-buffer in fixed point format.W-buffer
To implement a w-buffer, the old values of in camera space, or , are stored in the buffer, generally in floating point format. However, these values cannot be linearly interpolated across screen space from the vertices—they usually have to be inverted, interpolated, and then inverted again. The resulting values of , as opposed to , are spaced evenly between and . There are implementations of the w-buffer that avoid the inversions altogether. Whether a z-buffer or w-buffer results in a better image depends on the application.Algorithmics
The following pseudocode demonstrates the process of z-buffering:// First of all, initialize the depth of each pixel. d(i, j) = infinite // Max length // Initialize the color value for each pixel to the background color c(i, j) = background color // For each polygon, do the following steps : for (each pixel in polygon's projection)
See also
* Z-fighting * Irregular z-buffer * Z-order * A-buffer * Depth map * HyperZ *References
External links
Notes
{{DEFAULTSORT:Z-Buffering 3D rendering