2

I am computing the 3D coordinates from the 2D screen mouse click. Then I draw point at the computed 3D coordinate. Nothing is wrong in the code, nothing is wrong in the method, everything is working fine. But there is one issue which is relevant to depth.

If the object size is around (1000, 1000, 1000), I get the full depth, the exact 3D coordinate of the object's surfel. But when I load the object with size (20000, 20000, 20000), I do not the get the exact (depth) 3D coordinates. I get some offset from the surface. The point draws with a some offset from the surface. So my first question is that why it is happening? and the second question is how can I get the full depth and the accurate 3D coordinate for very large scale objects?

I draw a 3D point with

glDepthFunc(GL_LEQUAL);
glDepthRange(0.0, 0.999999);

and using

glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &wz);
if(wz > 0.0000001f && wz < 0.999999f)
{
gluUnProject()....saving 3D coordinate
}
maxpayne
  • 1,111
  • 2
  • 21
  • 41

2 Answers2

2

The reason why this happens is the limited precision of the depth buffer. A 8-bit depth buffer can, for example, only store 2^8=256 different depth values.

The second parameter set that effects the depth precision are the settings for near and far plane in the projection, since this is the range that has to be mapped to the available data values in the depth buffer. If one sets this range to [0, 100] using a 8-bit depth buffer, then the actual precision is 100/256 = ~0.39, which means, that approximately 0.39 units in eye space will have the same depth value assigned.

Now to your problem: Most probably you have too less bits assigned to the depth buffer. As described above this introduces an error since the exact depth value can not be stored. This is why the points are close to the surface, but not exactly on it.

BDL
  • 21,052
  • 22
  • 49
  • 55
  • thanks, your valuable explanation will surely be considered. The issue was the depth range which should be 0.0 to 1.0. I might changed it somewhere. – maxpayne Jun 09 '15 at 22:23
  • In practice, 8-bit depth buffers don't exist. 16-bit depth buffers are usually just as inadequate though ;) It's also worth mentioning that precision in a fixed-point perspective depth buffer (traditional) is biased such that objects closer to the near plane have more and precision falls apart as you move toward the far plane. I'd never expect to get an "exact" value out of the depth buffer, but it's even less "exact" the farther away you get. – Andon M. Coleman Jun 10 '15 at 12:10
0

I have solved this issue that was happening because of depth range. Because OpenGL is a state machine, so I think I might somewhere changed the depth range which should be from 0.0 to 1.0. I think its always better to put depth range just after clearing the depth buffer, I used to have following settings just after clearing the depth and color buffers.

Solution:

{
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glDepthRange(0.0, 1.0);
    glDepthMask(GL_TRUE);
}
maxpayne
  • 1,111
  • 2
  • 21
  • 41