7

It is pretty well known that writing depth in your fragment shader generally disables "early Z" test/write optimizations that modern GPUs rely on for fastness. Nonetheless, APIs still allow it and GPUs still provide support for correct visibility when shaders write arbitrary depth.

The question is: are there any state of the art real-time effects in today's game engines that require writing Z in the fragment shader?

GroverManheim
  • 593
  • 3
  • 8

1 Answers1

10

Any techniques that involve raytracing in the fragment shader might want to write Z in order that the depth buffer contain an accurate representation of the raytraced surface. For example:

  • Distance-field ray marching, as seen in many shadertoys and demoscene productions. Here, only a full-screen quad gets rasterized, and all the geometry is generated by the fragment shader. Writing Z would be necessary if you want to use the depth buffer for deferred lighting or post-effects, or to composite distance fields with ordinary triangle geometry and get correct occlusion.
  • Voxel ray marching, similar to the above. Even when the voxels are translucent (as in a smoke cloud or suchlike), it may be useful to write Z when the voxel density is high enough to become opaque; for instance, that can be useful for later motion blur / depth-of-field calculations.
  • Parallax occlusion mapping techniques, in which a flat surface is given the appearance of depth by ray-marching against a heightfield.

There are probably other similar cases where the shape of a surface is defined by the fragment shader rather than by the rasterized triangles.

By the way, newer APIs and GPUs include support for a conservative depth output mode, in which the shader-written Z is only allowed to be greater-equal to the geometric Z, but not less. This allows early-Z / hierarchical-Z optimizations to still work based on the geometric Z: if the rasterized geometry gets culled for being behind something, then you know the shader-written Z would have been culled as well. This is a good fit for cases like the above, as you can rasterize some bounding geometry for the distance-field / voxel / heightfield object; then the actual depth will be greater-equal to that of the bounding geometry.

Nathan Reed
  • 24,302
  • 2
  • 63
  • 103