Getting world position from depth buffer...

I’m trying to get the world position from the depth buffer for an image effect. I have actually got it working for standalone builds using the following code snippet:

    // for fast world space reconstruction
    uniform float4x4 _FrustumCornersWS;
    uniform float3 _CameraWS; // camera's world space position (ie camera's Transform.position)
    uniform float4 _CameraDir; // xyz = camera forward direction, w = near plane distance
   
    struct v2f
    {
        float4 pos : SV_POSITION;
        float2 uv : TEXCOORD0;
        float2 uv_depth : TEXCOORD1;
        float4 interpolatedRay : TEXCOORD2;
    };
   
    v2f vert (appdata_img v)
    {
        v2f o;
        half index = v.vertex.z;
        v.vertex.z = 0.1;
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
        o.uv = v.texcoord.xy;
        o.uv_depth = v.texcoord.xy;
       
        #if UNITY_UV_STARTS_AT_TOP
        if (_MainTex_TexelSize.y < 0)
            o.uv.y = 1-o.uv.y;
        #endif               
       
        o.interpolatedRay = _FrustumCornersWS[(int)index];
        o.interpolatedRay.w = index;
       
        return o;
    }
   
    half4 frag (v2f i) : SV_Target
    {
        // Reconstruct world space position and direction
        float rawdpth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, -i.uv_depth);
        #ifdef CAMERA_ORTHOGRAPHIC
            float3 nearPlaneDist = _CameraDir.w; // from camera
            float3 camDir = _CameraDir.xyz;
            float3 nearPlaneOffset = camDir * nearPlaneDist; // relative to camera pos
            float3 camPos = _CameraWS + nearPlaneOffset; // pretend the camera pos is at the near plane
            float3 rayFar = i.interpolatedRay - nearPlaneOffset; // relative to camera near plane
       
            float3 rayVec = camDir * dot(rayFar, camDir); // relative to rayOrigin
            float3 rayOrigin = rayFar - rayVec; // relative to camera
            // apparently unity inverted the Z buffer when not using Linear01Depth: https://docs.unity3d.com/Manual/UpgradeGuide55.html
            #if UNITY_VERSION >= 550
                rawdpth = 1 - rawdpth;
            #endif
            float3 rayCast = (rayFar - rayOrigin) * rawdpth; // just use the raw depth texture for ortho
            float3 wsPos = camPos + rayOrigin + rayCast;
       
        #else
            float3 wsDir = i.interpolatedRay * Linear01Depth(rawdpth); // for PERSPECTIVE
            float3 wsPos = _CameraWS + wsDir;
        #endif
       
        // other stuff is here...
    }

So this appears to work fine for windows, but doesn’t work for android. On android, the positions are all skewed. I don’t know if my solution is best (it seems quite convoluted for orthographic).
I have looked at the source for Unity’s global fog, and it appears that it doesn’t support orthographic cameras. I’m not sure where to look next.

Has anyone got experience with reconstructing positions in image effects?

Cheers.

It appears that my depth buffer is black, as though it’s not rendering the depth buffer at all. I have tried disabling the 32-bit depth and it didn’t make a difference.

This thread suggests that it’s a bug in unity, but I’m not sure why other’s aren’t talking about it more since the lack of a depth buffer would seem to be a major issue in my mind. So the suggested solution is to render your own depth buffer, which sounds quite sucky.

Has anyone else come across this?

Try lowering your upper clipping distance for the camera.