Linear01Depth - is it working?

Camera is set to render depth texture.
I have few objects on screen.

And surface shader uses this:

Still, all objects on screen are white. Even that they have different distance.
I thought, Linear01Depth should return equalized depth buffer (0…1), which will contain full color range from 0 to 255, no matter what near or far clipping plane is.

Am I wrong on this?

Sight, I’m really lost on this one. was trying different shaders for more then 2 days now.
I have feeling, that I’m completely on the wrong track.

What I want to do, is always display depthbuffer within 0.255 range. Like, if I have 2 objects near the camera, and there is no more, then I want those object fully utilize 0-255 color range, without playing with near and far clip planes.

I guess it is not possible? Even if I will get linear depth buffer, still precision will be too small to cover whole 0.255 range for my objects?

I’ve tried many shaders from search result, and ones from Unity documentation. Even if I put Linear01Depth , still I do not see full color range outputed to screen. What is that linearization/normalization about then?

Does it just put object within 0.1 range, but do not guarantee, that they will cover it fully? just, that they will stay between those values, and that is all?

Ok… I am 8 years late to the party… but I don’t care… let’s try to answer the question anyway…

Here’s the code for Linear01Depth:

// Z buffer to linear 0..1 depth
inline float Linear01Depth( float z )
{
    return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
}

Unity Documentation states that _ZBufferParams are “Used to linearize Z buffer values. x is (1-far/near), y is (far/near), z is (x/far) and w is (y/far).”

Hence, if z is zero, LinearFloat01Depth will return near/far, and if z is one, it will return one (just substitute the values to see why). Therefore, your assumption is correct, the function maps z values within the [0,1] range, but it does not cover the full range. You can then remap [near/far, 1] to [0, 1] if you will.

Another related function is LinearEyeDepth:

// Z buffer to linear depth
inline float LinearEyeDepth( float z )
{
    return 1.0 / (_ZBufferParams.z * z + _ZBufferParams.w);
}

Using the same logic, it is easy to see that LinearEyeDepth maps the non-linear z values into the range [near, far].

4 Likes