using OpenGL depth buffer

hi,

I`ve got a problem when I read values from the z-buffer.

I draw a plane in front of the camera at distance 5. nearplane is at 2 and farplane at 500.

when I now use glReadPixels I get a value of 0.6 for the depth component. is this correct? I thought the depthbuffer gives the position between near- and farplane. so this would mean the plane I draw is at 60% in the frustrum.

Is there something I could be doing wrong?

The values stored in the depth buffer are not linear with respect to actual depth. Because of the nature of floating point values, more precision is available on the near end of the depth range. But I’m still not certain that 0.6 you have is correct. I’m too lazy to do the math right now.
Oh, and the value stored in the Z buffer is not between [0,1]. OpenGL maps the near and far depth ranges (not planes mind you) to the use the full extent of values available in the bits available. Or at least that’s how I understand it.

[This message has been edited by DFrey (edited 07-20-2000).]

I read something about that in the “OpenGL programming guide”, but it `s not very clear.

Id like to convert the values in the depth buffer to actual distances. Is there a way to convert the z-buffer values to distances from the camera? So in the example above Id like to get distance 5.

I`m using these values to make a semi-realtime Image Based renderer.

Howdy.

well, just look at the projection matrix and work out the inverse…

in this case,

z’ = (-(f+n)/(f-n))*z - (2fn/(f-n))*w

if you assume w is 1.0, then you have a eqn with one unkown (z), and the z’ (the value between 0.0 and 1.0) stored in the z buffer. just work out the inverse of that eqn…

cheers
John

Originally posted by DFrey:
[b]Oh, and the value stored in the Z buffer is not between [0,1]. OpenGL maps the near and far depth ranges (not planes mind you) to the use the full extent of values available in the bits available. Or at least that’s how I understand it.
B]

Not completely right. The values in the Z buffer are always between [0,1], but the range which is mapped on [0,1] differs on the near and far clipping planes you use. E.g. when you get a very small object, say 0.01 diameter and you use 20000 as far and -20000 as near clipping plane, the object will look very distorted, because the z-buffer gets too unprecise (40000 is mapped to 32bit, so 0.01 is not in the resolution).

To get your distance from the camera: I think you can do it by calling gluunproject with z as the z-buffer value. Then you get a point in object space from which you can calculate the distance to your camera.

Regards,

Kilam.

Yes this is possible. Easiest method would be to use gluUnproject and then take the resulting vector and subtract it from the camera’s vector and then find the length of the resulting vector.

Kilam: Are you suggesting that if I have a 32 bit depth buffer, that all 32 bits are used as mantissa? If not, then why waste bits for an unneeded exponent. Well, I could see 1 bit being needed as an exponent. I’m pretty sure that OpenGL does not waste bits of the Z-Buffer by only storing values between 0 and 1. To me that would just seem to be an inexcusable waste of bits. Unless it uses all bits (save 1) for mantissa.

[This message has been edited by DFrey (edited 07-20-2000).]