繁体   English   中英

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

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

我正在通过2D屏幕鼠标单击来计算3D坐标。 然后,在计算出的3D坐标处绘制点。 代码没什么不对,方法没什么不对,一切正常。 但是有一个与深度有关的问题。

如果对象大小在(1000,1000,1000)左右,我将获得完整深度,即对象表面的精确3D坐标。 但是,当我加载大小为(20000、20000、20000)的对象时,我没有获得确切的(深度)3D坐标。 我从表面有些偏移。 该点从表面偏移一些。 所以我的第一个问题是为什么会这样? 第二个问题是如何获得超大型物体的完整深度和准确的3D坐标?

我画一个3D点

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

和使用

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

发生这种情况的原因是深度缓冲区的精度有限。 例如,一个8位深度的缓冲区只能存储2 ^ 8 = 256个不同的深度值。

影响深度精度的第二个参数集是投影中近平面和远平面的设置,因为这是必须映射到深度缓冲区中可用数据值的范围。 如果使用8位深度缓冲区将此范围设置为[0,100],则实际精度为100/256 =〜0.39,这意味着在眼睛空间中大约0.39单位将分配相同的深度值。

现在您要解决的问题:分配给深度缓冲区的位很可能太少了。 如上所述,由于不能存储精确的深度值,因此引入了错误。 这就是为什么这些点靠近表面,但不完全位于表面上的原因。

我已经解决了由于深度范围而引起的这个问题。 因为OpenGL是状态机,所以我想我可能会在某个地方将深度范围更改为0.0到1.0。 我认为在清除深度缓冲区后立即放置深度范围总是更好的选择,过去我在清除深度和颜色缓冲区后进行以下设置。

解:

{
    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