LinearEyeDepth and Linear01Depth in a Compute Shader returning infinity

I’m trying to recreate a normal shader in a compute shader. I managed to get the depth texture passed over to it in a RenderTexture, but it seems neither LinearEyeDepth nor Linear01Depth are working, they both seem to be returning infinity, though the raw depth values are things like 0.04765708 or 0.00293625.

Here’s the relevant Compute Shader code:

#pragma kernel CSMain
#include "UnityCG.cginc"

Texture2D<float4> _DepthTexture;

[numthreads(32,32,1)]
void CSMain (uint3 uv : SV_DispatchThreadID)
{
    float depth = LinearEyeDepth(_DepthTexture[uv.xy].r);
}

This is (basically) the same code from the normal shader:

          #include "UnityCG.cginc"
          sampler2D _CameraDepthTexture;

           half4 frag(v2f i) : COLOR
           {
                 half depth = LinearEyeDepth(tex2D(_CameraDepthTexture, i.uv).r) ;
           }

Does it matter that I’m not “sampling” the Depth Texture? I couldn’t get that working in the Compute Shader. Or is this because UnityCG.inc doesn’t have access to the camera clipping planes?

I found the algorithm behind LinearEyeDepth and rewrote it manually (with help from Google), I guess something the built-in function needs isn’t included in Compute Textures. Here’s the code, for future Compute Shader experimenters:

float LinearEyeDepth( float rawdepth )
{
    float x, y, z, w;
#if SHADER_API_GLES3 // insted of UNITY_REVERSED_Z
    x = -1.0 + _NearClip/ FarClip;
    y = 1;
    z = x / _NearClip;
    w = 1 / _NearClip;
#else
    x = 1.0 - _NearClip/ FarClip;
    y = _NearClip / _FarClip;
    z = x / _NearClip;
    w = y / _NearClip;
#endif

  return 1.0 / (z * rawdepth + w);
}

Edit: for some reason FarClip and NearClip need to be reversed from how Unity does it, to match the same results as a LinearEyeDepth in the normal shader; I’ve edited the code to swap them.

6 Likes