<p>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:</p>

<ul>
<li><a href="http://iquilezles.org/www/articles/raymarchingdf/raymarchingdf.htm">Distance-field ray marching</a>, 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.</li>
<li>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.</li>
<li><a href="http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262">Parallax occlusion mapping</a> techniques, in which a flat surface is given the appearance of depth by ray-marching against a heightfield.</li>
</ul>

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

<p>By the way, newer APIs and GPUs include support for a <a href="https://mynameismjp.wordpress.com/2010/11/14/d3d11-features/">conservative depth output</a> 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.</p>

CC BY-SA 3.0
2016-07-23T04:53:58.660Z
2016-07-23T04:53:58.660Z
Nathan Reed
<p>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.</p>

<p>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?</p>

<gpu><rasterizer><z-buffer>
What modern real-time rendering applications still use fragment shader depth writes / late-Z?
GroverManheim
# What modern real-time rendering applications still use fragment shader depth writes / late-Z?

(Asked by: username_0 on 2016-07-22)

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?

**Tags:** gpu, rasterizer, z-buffer


---

## 1 answers

### Answer by username_1 on 2016-07-23. Score: 10 | Accepted answer

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](http://iquilezles.org/www/articles/raymarchingdf/raymarchingdf.htm), 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](http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262) 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](https://mynameismjp.wordpress.com/2010/11/14/d3d11-features/) 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.


---

