Search Unity

Depth Buffer Precision Issues on DX11

Discussion in 'Shaders' started by Tinus, Sep 10, 2014.

  1. Tinus

    Tinus

    Joined:
    Apr 6, 2009
    Posts:
    437
    I'm going through all aspects of my game to make sure they work under DX11 rendering on Unity 4.5.3f3.

    One of the last issues remaining is that post effects reading from the depth buffer suffer from huge losses in precision. Here's a comparison of my faked atmospheric scattering shader on DX9 and DX11.



    As you can see I am dealing with huge draw distances, but this hasn't been a problem on DX9 or OpenGL, just on DX11. Any hints as to what might cause this? I'm out of ideas, myself.

    Stripping the shader down until it's just showing a grayscale gradient based on a depth buffer read still results in the same precision problem:

    Code (csharp):
    1. float depth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.uv_depth)));
    Standard depth based effect such as DepthOfFieldDX11 also show this problem.

    For full reference, here's my shader implementation, which is based on the GlobalFog standard image effect and this article.

    AtmosphericFog.cs
    AtmosphericFog.shader
     
    Last edited: Sep 10, 2014
  2. Aieth

    Aieth

    Joined:
    Apr 13, 2013
    Posts:
    805
    On DX11 Unity uses the hardware depth buffer, while on DX9 and I think also OpenGL it uses a separate depth pass. The hardware depth buffer sacrifices far precision for near precision, meaning you get bad precision with huge draw distances. I do not know if there is a way to force Unity to do a depth pass on DX11, if I were you I'd try that. If that doesn't work, you could render your own depth texture if DX11 and use that instead. If you want the performance boost from not doing a separate render pass, look into custom depth output and logarithmic depth buffers.
     
  3. Tinus

    Tinus

    Joined:
    Apr 6, 2009
    Posts:
    437
    Thanks Aieth, that gives me something to go on!