Jump to content
  • Advertisement
Sign in to follow this  

Depth buffer value equation problem

This topic is 713 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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)

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
Thanks for your detailed explanation. I was doing the opposite in the shaders to get view position from depth buffer value :P

Happy New Year!

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!