DirectX SDK

What Are Depth Buffers?

A depth buffer, often called a z-buffer or a w-buffer, is a DirectDraw surface that stores depth information to be used by Direct3D. When Direct3D renders a 3-D scene to a target surface, it can use the memory in an attached depth buffer surface as a workspace to determine how the pixels of rasterized polygons occlude one another. Direct3D uses an off-screen DirectDraw surface as the target to which final color values are written. The depth buffer surface that is attached to the render-target surface is used to store depth information which tells Direct3D how "deep" each visible pixel is in the scene.

When a 3-D scene is rasterized with depth buffering enabled, each point on the rendering surface is tested. The values in the depth buffer can be a point's z-coordinate or its homogeneous w-coordinate—from the point's (x,y,z,w) location in projection space. A depth buffer that uses z values is often called a "z-buffer," and one that uses w values called a "w-buffer." Each type of depth buffer has its advantages and disadvantages, which are discussed later.

At the beginning of the test, the depth value in the depth buffer is set to the largest possible value for the scene. The color value on the rendering surface is set to either the background color value, or the color value of the background texture at that point. Each polygon in the scene is tested to see if it intersects with the current coordinate (x,y) on the rendering surface. If it does, the depth value (which will be the z coordinate in a z-buffer, and the w coordinate in a w-buffer) at the current point is tested to see if it is smaller than the depth value already stored in the depth buffer. If the depth of the polygon value is smaller, it is stored in the depth buffer and the color value from the polygon is written to the current point on the rendering surface. If the depth value of the polygon at that point is larger, the next polygon in the list is tested. This process is shown in the following illustration.

[C++]

Note  Although most applications don't use this feature, you can change the comparison Direct3D uses to determine which values will be placed in the depth buffer and subsequently the render-target surface. To do so, change the value for the D3DRENDERSTATE_ZFUNC render state.

[Visual Basic]

Note  Although most applications don't use this feature, you can change the comparison Direct3D uses to determine which values will be placed in the depth buffer and subsequently the render-target surface. To do so, change the value for the D3DRENDERSTATE_ZFUNC render state.

Nearly all 3-D accelerators on the market support z-buffering, making z-buffers the most common type of depth buffer today. However ubiquitous, z-buffers do have their drawbacks. Due to the mathematics involved, the generated z values in a z-buffer tend not to be distributed evenly across the z-buffer range (typically 0.0 to 1.0, inclusive). Specifically, the ratio between the far and near clipping planes strongly affects how unevenly z values are distributed. Using a far-plane distance to near-plane distance ratio of 100, 90% of the depth buffer range is spent on the first 10% of the scene depth range. Typical applications for entertainment or visual simulations with exterior scenes often require far plane/near plane ratios of anywhere between 1000 to 10000. At a ratio of 1000, 98% of the range is spent on the 1st 2% of the depth range, and the distribution gets worse with higher ratios. This can cause hidden surface artifacts in distant objects, especially when using 16-bit depth buffers (the most commonly supported bit-depth).

A w-based depth buffer, on the other hand, is often more evenly distributed between the near and far clip planes than z-buffer. The key benefit is that the ratio of distances for the far and near clipping planes is no longer an issue. This allows applications to support large maximum ranges, while still getting relatively accurate depth buffering close to the eye point. A w-based depth buffer isn't perfect, and can sometimes exhibit hidden surface artifacts for near objects. Another drawback to the w-buffered approach is related to hardware support: w-buffering isn't supported as widely in hardware as z-buffering.

[C++]

The DirectDraw HEL can create depth buffers for use by Direct3D or other 3-D–rendering software. The HEL supports 16-bit depth buffers. The DirectDraw device driver for a 3-D accelerator can permit the creation of depth buffers in display memory by exposing the DDSCAPS_ZBUFFER flag. You can query for the supported depth buffer bit-depths by calling the IDirect3D7::EnumZBufferFormats method.

Whenever a z-buffer surface is created, your application should maintain a pointer to the z-buffer until it shuts the Direct3D system down. Your program should release the z-buffer surface just before it releases the rendering surface.

[Visual Basic]

The DirectDraw HEL can create depth buffers for use by Direct3D or other 3-D–rendering software. The HEL supports 16-bit depth buffers. The DirectDraw device driver for a 3-D accelerator can permit the creation of depth buffers in display memory by exposing the DDSCAPS_ZBUFFER flag. You can query for the supported depth buffer bit-depths by using the Direct3D7.GetEnumZBufferFormats method. The GetEnumZBufferFormats method returns a reference to a Direct3DEnumPixelFormats class object that contains the supported pixel formats for depth buffers.

Z-buffering requires overhead during rendering. Various techniques can be used to optimized rendering when using z-buffers. For details, see Z-Buffer Performance.

Note  The actual interpretation of a depth value is specific to the 3-D renderer.