Sign in to follow this  

Depth buffer value equation problem

Recommended Posts

Hi, community.

I was reading an old post from Steve Baker about Learning to Love your Z-Buffer (https://www.sjbaker.org/steve/omniv/love_your_z_buffer.html) where he explains that z buffer integer value is calculated in the following way:

z_buffer_value = (1 << N) * ( a + b / z)

where
N = number of bits of Z precision
a = zFar / (zFar - zNear)
b = zFar * zNear / ( zNear - zFar )
z = distance from the eye to the object
and z_buffer_value js an integer value.

I have 2 questions:
(1) What are the steps to get that equation?
(2) If you create your depth buffer with a floating point format. Is Z distance from the eye to the camera stored directly instead?

Share this post


Link to post
Share on other sites
To answer your question about the steps leading to the equation let's look at the row in our projection matrix which will effect the zbuffer (column in the case of directx).

We know that the row of the matrix (again, column in directx) will operate on the vector <x,y,z,1> to yield a value. This value will be divided by the whatever is in w after the matrix operation. The projection matrix will always have [0, 0, 1, 0] for the row operation on the w component, so when dotted with <x,y,z,1> will return 0x + 0y + 1z + 0, or z.

Back to the row that will operate on the z component, we have

new_z = Ax + By + Cz + D

Well, we don't want the x and y value to effect our z buffer, so A and B will be set to 0, leaving the following options for us

w = old_z
new_z = C*old_z + D*1

Zbuffer value = new_z / w.

Okay so now what? Well we know our zbuffer only goes from 0 to 1, but we want to cram our znear (z_n) and zfar (z_f) in it such that when old_z = z_n, zbuffer value is 0, and when the old_z = z_f, zbuffer value is 1.

So now, we have two unknowns (C and D) and 2 results. Guess what? Time to solve a 2 by 2 matrix.

If old_z = z_n, new_z/old_z = 0
(C * z_n + D)/z_near = 0, or
C*z_n + D = 0

If old_z = z_far, new_z/old_z = 1
(C * z_far + D)/z_far = 1, or
C*z_f + D = z_f

We have two equations, two constants (z_f and z_n) and two unknowns C and D. When you solve for C and D, you should have the values for a and b

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this