7
$\begingroup$

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?

$\endgroup$
10
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.