Why can't the unfilled area of the _CameraDepthTexture be 1?

.This is original scene,test scene.
Here’s code used to visualize depth buffer of the scene. it doesn’t matter, even not depth-linear.

float4 pixel_shader (custom_type ps) : SV_TARGET
{
            float d = tex2D(_CameraDepthTexture,ps.screen.xy).r;  //non-linear distribution
               if(d < 0.00001)    // almost 0
                    return float4(1,0,0,1);
                else if( d < 0.005)
                    return float4(1,1,0,1);
                else if(d < 0.01)
                    return float4(0,1,0,1);
                else if(d < 0.02)
                    return float4(0,0,1,1);
                else if(d < 0.03)
                    return float4(0,1,1,1);
                else
                    return float4(d,d,d,1);   
  }

The resulting frame is: . the above code draw red fragment according to the first “if” condition statement.it indicate such area of no solid geometry drawing on is almost zero(black),instead of 1 (white) i was expecting.
To the best of my knowledge, with depth test function LessEqual as default setting,it should be 1(maximum),from back to front.so that’s the right thing to do in a depth test.but it consist with zero,did i make something wrong?

Unity uses a reversed depth buffer when the platform is using Direct3D. You can search for reversed depth or reversed Z if you want to learn more about that, but the short version is due to the interactions of floating point precision and projection space depth, reversing the depth buffer ends up working better.

This old post for Outerra goes into it well, and the reason why it’s not used for OpenGL.

Note: MacOS and Android do not support the depth extension mentioned in that post, which is where OpenGL is most commonly used for Unity, hence why it’s not used.

Since Unity uses a reversed depth buffer, reading the raw texture will result in “1.0” being at the camera’s near plane, which if anything is at that depth it will be culled. The only reason why the far plane can sometimes be “0.0” is because that’s the buffer’s clear depth.

A side effect of the depth buffer being reverse, the expectation for ZTest is inverted. Unity handles this automagically, so your shader with ZTest LEqual gets flipped to GEqual when rendered to a buffer with the inverted depth.

1 Like

@bgolus you’re right. unityengine is actually revert the depth value in somehow way. thank your replay.