I'm on chapter 10 stenciling, question 8 dealing with Depth complexity.
Anyone read this book by Frank Luna?
Here is part of the question that im not understanding.
8. Depth complexity refers to the number of pixel fragments that compete, via the depth test, to be written to a particular entry in the back buffer. For example, a pixel we have drawn may be overwritten by a pixel that is closer to the camera (and this can happen several times before the closest pixel is actually figured out once the entire scene has been drawn). The pixel in Figure 10.12 has a depth complexity of 3 since three pixel fragments compete for the pixel. Potentially, the graphics card could fill a pixel several times each frame. This overdraw has performance implications, as the graphics card is wasting time processing pixels that eventually get overridden and are never seen. Consequently, it is useful to measure the depth complexity in a scene for performance analysis. We can measure the depth complexity as follows: Render the scene and use the stencil buffer as a counter; that is, each pixel in the stencil buffer is originally cleared to zero, and every time a pixel fragment is processed, we increment its count with D3D11_STENCIL_OP_INCR. The corresponding stencil buffer entry should always be incremented for every pixel fragment no matter what, so use the stencil comparison function D3D11_COMPARISON_ALWAYS. Then, for example, after the frame has been drawn, if the ijth pixel has a corresponding entry of five in the stencil buffer, then we know that those five pixel fragments were processed for that pixel during that frame (i.e., the pixel has a depth complexity of five). Note that when counting the depth complexity, technically you only need to render the scene to the stencil buffer. To visualize the depth complexity (stored in the stencil buffer), proceed as follows:
Associate a color ck for each level of depth complexity k. For example, blue for a depth complexity of one, green for a depth complexity of two, red for a depth complexity of three, and so on. (In very complex scenes where the depth complexity for a pixel could get very large, you probably do not want to associate a color for each level. Instead, you could associate a color for a range of disjoint levels. For example, pixels with depth complexity 1–5 are colored blue, pixels with depth complexity 6–10 are colored green, and so on.) (b) Set the stencil buffer operation to D3D11_STENCIL_OP_KEEP so that we do not modify it anymore. (We modify the stencil buffer with D3DSTENCILOP_INCR when we are counting the depth complexity as the scene is rendered, but when writing the code to visualize the stencil buffer, we only need to read from the stencil buffer and we should not write to it.) For each level of depth complexity k: (i) Set the stencil comparison function to D3D11_COMPARISON_EQUAL and set the stencil reference value to k.
(ii) Draw a quad of color ck that covers the entire projection window. Note that this will only color the pixels that have a depth complexity of k because of the preceding set stencil comparison function and reference value.
Figure 10.13. Sample screenshot of the solution to Exercise 8. With this setup, we have colored each pixel based on its depth complexity uniquely, and so we can easily study the depth complexity of the scene. For this exercise, render the depth complexity of the scene used in the “Blend” demo from Chapter 9. Figure 10.13 shows a sample screenshot.
The depth test occurs in the output merger stage of the pipeline, which occurs after the pixel shader stage. This means that a pixel fragment is processed through the pixel shader, even if it may ultimately be rejected by the depth test. However, modern hardware does an “early z-test” where the depth test is performed before the pixel shader. This way, a rejected pixel fragment will be discarded before being processed by a potentially expensive pixel shader. To take advantage of this optimization, you should try to render your non-blended game objects in front-to- back order with respect to the camera; in this way, the nearest objects will be drawn first, and objects behind them will fail the early z-test and not be processed further. This can be a significant performance benefit if your scene suffers from lots overdraw due to a high depth complexity. We are not able to control the early z-test through the Direct3D API; the graphics driver is the one that decides if it is possible to perform the early z-test. For example, if a pixel shader modifies the pixel fragment’s depth value, then the early z-test is not possible, as the pixel shader must be executed before the depth test since the pixel shader modifies depth values.
We mentioned the ability to modify the depth of a pixel in the pixel shader. How does that work? A pixel shader can actually output a structure, not just a single color vector as we have been doing thus far:
struct PixelOut
{
float4 color : SV_Target;
float depth : SV_Depth;
};
PixelOut PS(VertexOut pin)
{
PixelOut pout;
// … usual pixel work
pout.Color = float4(litColor, alpha);
// set pixel depth in normalized [0, 1] range
pout.depth = pin.PosH.z - 0.05f; return pout;
}
Im suppose to get a picture like the one on the right.
Can someone give me a idea on what I need to do here? Does this need to be done in the pixel shader?