Windows Phone

Windows Phone 7 Game Development : The World of 3D Graphics - The Depth Buffer

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
7/10/2011 3:50:03 PM
Something you might have observed in both the Perspective and ColoredCubes examples is that the objects nearer the camera all appear in front of the objects farther away. When we displayed our graphics using sprites, we had to put in some effort to provide a LayerDepth value for each sprite in order to facilitate depth sorting like this. There is no equivalent functionality in these 3D projects, though, and yet the objects still all appear in the right places. Why does this happen?

The answer is that XNA has a built-in mechanism for ensuring that objects in the front of the scene automatically hide any objects that fall behind them. This happens regardless of the order in which objects are drawn: objects drawn behind existing objects can still be partially (or totally) obscured even though they might be rendered after the object in front.

XNA achieves this effect by using a feature known as the depth buffer. It can be enabled or disabled, and is enabled by default. When rendering simple 2D graphics, the depth buffer might be unnecessary, but in 3D scenes it is almost certain to be required.

Just as the color of each rendered pixel is written into a graphical buffer for display on the screen, so the distance into the screen of each rendered pixel is written into a corresponding depth buffer when the buffer is enabled. For each individual pixel that it is about to render, XNA checks the depth of the pixel against the depth already stored in the buffer. If it finds that the new pixel is farther away than the pixel already in the buffer, the new pixel is not rendered to the screen; otherwise, the pixel is rendered and the depth buffer updated to remember the new depth of the pixel.

This per-pixel depth checking can be clearly seen in the DepthBuffer example project, shown in Figure 1. This figure displays two rotating cubes, positioned so that they intersect one another; and below them a third cube, squashed to form a "floor." Observe the behavior when the cubes intersect one another: at every single pixel position, the frontmost cube surface is always displayed.

Figure 1. The effect of the depth buffer on intersecting objects

The way that intersecting objects are handled can be very useful. For example, if you want to draw a landscape scene with water such as lakes or an ocean, the ground can be drawn in its entirety (the parts that are above the water level and also those that are below) and then a single semitransparent flat plane can be drawn at the water level across the entire scene. Only those parts of the scene that are below the water level will be affected by the water plane, providing a reasonably convincing approximation of water with very little complexity or processor cost.

1. Enabling and Disabling the Depth Buffer

Most of the time when you are rendering objects in your game, you will want the depth buffer to be available and active. Without it, distant objects will appear in front of nearer objects, destroying the illusion of the 3D world that you are trying to render.

On some occasions, however, you might want to render without updating the depth buffer. Examples include rendering background scenery that should never obscure any of the other graphics rendered and objects that are rendered in front of a scene to provide overlay content such as status bars or health displays.

The depth buffer can be temporarily disabled by setting the GraphicsDevice.DepthStencilState property to DepthStencilState.None. After this property has been set, graphics that are rendered will entirely ignore the depth buffer, neither observing values that are stored in it nor updating the values when new objects are rendered. To restore the normal behavior of the depth buffer, set the property back to its default value: DepthStencilState.Default.

You can see the effect of disabling the depth buffer by inserting the code from Listing 1 at the end of the LoadContent function in the Perspective example project.

Example 1. Disabling the depth buffer
// Disable the depth buffer
GraphicsDevice.DepthStencilState = DepthStencilState.None;

Once the depth buffer has been disabled, you will find that the objects appear in the order that they are rendered rather than being sorted by their depth. This can be seen in Figure 2, in which some of the smaller, more distant shapes are clearly being displayed in front of the larger closer objects.

Figure 2. The Perspective project with the depth buffer disabled


If you want to entirely disable the depth buffer, you can set the _graphics.PreferredDepthStencilFormat property to DepthFormat.None in your game class constructor. This setting will initialize the graphics device without creating a depth buffer, which can save you some memory and processing overhead if you have no need for it.

There is another mode that can be set for the depth buffer: read-only mode. In this mode, XNA will observe the values in the depth buffer when rendering objects and will use it to prevent objects from being drawn if they are behind existing objects, but the depth buffer will not be updated in response to rendered objects.

This mode might seem like an unlikely feature to need, but it has various uses. One such use is for drawing particles in a 3D scene. Although it is important that these correctly appear behind objects in the scene, we need to ensure that they don't obscure one another or else they won't display correctly.

XNA can be set to use a read-only depth buffer by setting the GraphicsDevice.DepthStencilState property to DepthStencilState.DepthRead. Don't forget to set it back to DepthStencilState.Default once you are finished with this mode.

2. Clearing the Depth Buffer

In some situations you might want to clear the values stored in the depth buffer. This might be the case if you are drawing two scenes, one in front of the other, and want to prevent each one from interfering with the other. The first scene can be drawn (with the depth buffer active and working), the depth buffer then cleared, and the second scene then drawn. The depth data from the first scene will not interfere with the second scene at all.

To clear the depth buffer, we can call the GraphicsDevice.Clear method, just as we do at the start of the game's Draw function, but instead of simply passing a color we pass some additional parameters that tell it to clear only the depth buffer, not the graphics that have been rendered. The code for clearing the depth buffer can be seen in Listing 2.

Example 2. Clearing the depth buffer
GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.White, 1, 0);

Because the Clear method's first parameter is set to ClearOptions.DepthBuffer, only the depth buffer will be affected. We still have to pass a color (which will be ignored) and a stencil value (which we are not using), but the value 1 passed for the depth buffer tells XNA to set the buffer so that the depths are all considered as being at the very back of the viewing frustum. Subsequently drawn objects will therefore appear in front of this far depth and will not be obscured by previously drawn objects.

3. Rendering Transparent Objects with the Depth Buffer

The depth buffer might not work exactly as you expect when it comes to drawing semitransparent objects. Although XNA's alpha blending feature can merge together objects that are being drawn with those already on the screen, the depth buffer can store only a single depth for each pixel. This means that, if you draw a semitransparent object and then draw an object behind it, the object behind will be completely eliminated by the depth buffer, even though the first object was transparent.

There are several approaches that can be employed to handle this. The first is to draw all your transparent objects so that those in the back of your scene are rendered first. This will ensure that objects in the front do not obscure those behind.

The second approach is to draw all your opaque objects first and then switch the depth buffer into DepthRead mode before drawing the transparent objects. This way the transparent objects will not obscure anything subsequently drawn behind them.

The final option is to use the AlphaTest effect (instead of the BasicEffect that we have been using so far), which can update the depth buffer only for pixels that match certain conditions in terms of their calculated alpha values.

Exactly which of these approaches is best will depend on what your game is drawing. Bear this limitation in mind when creating transparent objects in 3D space.

Other -----------------
- Windows Phone 7 Game Development : The World of 3D Graphics - Rendering 3D Objects
- Windows Phone 7 Game Development : The World of 3D Graphics - Perspective Projection
- Developing for Windows Phone and Xbox Live : Let the 3D Rendering Start
- Developing for Windows Phone and Xbox Live : Reach and HiDef Graphics Profiles
- Developing for Windows Phone and Xbox Live : Graphics Pipeline
- Developing for Windows Phone and Xbox Live : Graphics Pipeline
- Programming Windows Phone 7 : Elements and Properties - More on Images
- Programming Windows Phone 7 : TextBlock Properties and Inlines
- Programming Windows Phone 7 : The Phone’s Photo Library
- Programming Windows Phone 7 : Capturing from the Camera
- Windows Phone 7 : Loading Local Bitmaps from Code
- Windows Phone 7 : Image and ImageSource
- Windows Phone 7 : Images Via the Web
- Windows Phone 7 : Customizing Your E-Mail Signature
- Windows Phone 7 : Managing Mail Folders
- Windows Phone 7: The Silverlight Image Element
- Windows Phone 7: XNA Texture Drawing
- Windows Phone 7: An Introduction to Touch - Routed Events
- Windows Phone 7 : Working with Attachments
- Programming Windows Phone 7: An Introduction to Touch - The Manipulation Events
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us