简体   繁体   English

如何从2D屏幕鼠标单击中获取OpenGL中大型对象的准确3D深度?

[英]How to get accurate 3D depth from 2D screen mouse click for large scale object in OpenGL?

I am computing the 3D coordinates from the 2D screen mouse click. 我正在通过2D屏幕鼠标单击来计算3D坐标。 Then I draw point at the computed 3D coordinate. 然后,在计算出的3D坐标处绘制点。 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. 如果对象大小在(1000,1000,1000)左右,我将获得完整深度,即对象表面的精确3D坐标。 But when I load the object with size (20000, 20000, 20000), I do not the get the exact (depth) 3D coordinates. 但是,当我加载大小为(20000、20000、20000)的对象时,我没有获得确切的(深度)3D坐标。 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? 第二个问题是如何获得超大型物体的完整深度和准确的3D坐标?

I draw a 3D point with 我画一个3D点

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
}

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. 例如,一个8位深度的缓冲区只能存储2 ^ 8 = 256个不同的深度值。

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. 如果使用8位深度缓冲区将此范围设置为[0,100],则实际精度为100/256 =〜0.39,这意味着在眼睛空间中大约0.39单位将分配相同的深度值。

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. 这就是为什么这些点靠近表面,但不完全位于表面上的原因。

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. 因为OpenGL是状态机,所以我想我可能会在某个地方将深度范围更改为0.0到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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM