繁体   English   中英

如何使用深度缓冲区的OpenGL正交投影?

[英]How to use OpenGL orthographic projection with the depth buffer?

我使用glFrustum()透视模式渲染了3D场景。 然后,我将一个2D对象放在3D场景上,作为特定3D对象的标签。 我使用gluProject()计算了3D对象的2D位置,然后放置我的2D标签对象。 使用glOrtho()正交模式渲染2D标签对象。 这完美地工作,并且2D标签对象悬停在3D对象上。

现在,我想要做的是给2D对象的az值,以便它可以使用深度缓冲区隐藏在场景中的其他3D对象后面。 我已经给出了我知道应该被深度缓冲区隐藏的2D对象az值,但是当我渲染对象时它总是可见的。

所以问题是,为什么2D对象仍然可见而不是隐藏?

我确实在某处读过正交和透视投影存储不兼容的深度缓冲值。 这是真的,如果是这样,我如何在它们之间进行转换?

我不希望它被转换,而是我希望它看起来像是平面的2D标签,它总是面向相机,并且始终保持在屏幕上的相同尺寸。 但是,如果隐藏在某些东西背后,我希望它隐藏起来。

首先,你应该把放在你的问题中; 它解释了你所做的比你的问题更多的事情。

要实现这一点,您需要做的是在正交投影中找到与您希望标签出现的前投影空间中的z坐标匹配的z坐标。

当你使用gluProject ,你有三个坐标。 Z坐标很重要。 您需要做的是根据您给glOrtho的zNear和zFar值反向变换Z坐标。

迂腐: gluProject不会将Z坐标转换为窗口空间。 为此,它必须采用glDepthRange参数。 它真正做的是假设深度范围接近= 0.0且远= 1.0。

所以我们的第一步是从窗口空间Z转换为规范化设备坐标(NDC)空间Z.我们使用这个简单的等式:

ndcZ = (2 * winZ) - 1

很简单。 现在,我们需要去剪辑空间。 这是一个无操作,因为使用正交投影,W坐标假定为1.0。 W的除法是剪辑空间和NDC空间之间的差异。

clipZ = ndcZ

但是我们不需要剪辑空间Z.我们需要预拼图投影空间Z(又名:相机空间Z)。 这需要你给glOrtho的zNear和zFar参数。 为了获得相机空间,我们这样做:

cameraZ = ((clipZ + (zFar + zNear)/(zFar - zNear)) * (zFar - zNear))/-2

而且你已经完成了。 在渲染中使用Z位置。 哦,并确保您的模型视图矩阵不包括Z方向上的任何变换(除非您使用模型视图矩阵将此Z位置应用于标签,这很好)。

基于Nicol的答案,您可以简单地将zNear设置为0(这通常对于作为GUI一部分的2D元素有意义),然后您只需:

cameraZ = -winZ*zFar

暂无
暂无

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

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