Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用带有深度缓冲区的OpenGL正交投影?_Opengl_Buffer_Depth_Orthographic - Fatal编程技术网

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

如何使用带有深度缓冲区的OpenGL正交投影?,opengl,buffer,depth,orthographic,Opengl,Buffer,Depth,Orthographic,我已经使用透视模式渲染了一个3D场景。然后,我将一个2D对象放置在3D场景上,作为特定3D对象的标签。我使用gluProject()计算了三维对象的二维位置,然后将二维标签对象放置在该位置。二维标签对象是使用glOrtho()正交模式渲染的。这非常有效,二维标签对象悬停在三维对象上 现在,我想做的是给2D对象一个z值,这样它就可以使用深度缓冲区隐藏在场景中其他3D对象的后面。我给了2D对象一个z值,我知道它应该被深度缓冲区隐藏,但是当我渲染对象时,它总是可见的 所以问题是,为什么2D对象仍然可见

我已经使用透视模式渲染了一个3D场景。然后,我将一个2D对象放置在3D场景上,作为特定3D对象的标签。我使用
gluProject()
计算了三维对象的二维位置,然后将二维标签对象放置在该位置。二维标签对象是使用
glOrtho()
正交模式渲染的。这非常有效,二维标签对象悬停在三维对象上

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

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

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

我不希望它被转换,而是希望它显示为平面2D标签,始终面向相机,并且在屏幕上始终保持相同的大小。然而,如果它隐藏在某些东西后面,我希望它看起来是隐藏的

首先,你应该在你的问题中提到这一点;这比你的问题更能说明你想做什么

要实现这一点,您需要做的是在正交投影中找到与要显示标签的预投影空间中的z坐标匹配的z坐标

当您使用
gluProject
时,您得到了三个坐标。Z坐标很重要。您需要做的是根据您提供给
glOrtho
的zNear和zFar值对Z坐标进行反向变换

迂腐的注释:
gluProject
不会将Z坐标转换为窗口空间。为此,它必须采用
gldepsrange
参数。它真正做的是假设深度范围为近=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位置。哦,确保您的modelview矩阵不包含Z方向的任何变换(除非您使用modelview矩阵将此Z位置应用于标签,这很好)。

根据Nicol的回答,您可以简单地将zNear设置为0(这对于作为GUI一部分的2D元素通常是有意义的)然后你就有了:

cameraZ = -winZ*zFar

如果你想让标签像一个普通的3D对象一样(隐藏在其他对象后面)为什么不直接在被标签对象的正上方(或旁边)画一个普通的3D对象呢?我不想让它像一个普通的3D对象一样。我不希望它被转换,而是希望它显示为平面2D标签,始终面向相机,并且在屏幕上始终保持相同的大小。但是,如果它隐藏在某些东西后面,我希望它看起来隐藏。如何设置2D对象深度?提交Z值或使用PolygonOffset?我只是简单地将对象的Z值设置为一个很大的数字,理论上应该隐藏在场景中所有3D对象的后面只是为了澄清:必须这样做的原因是透视变换将非线性Z值映射到深度缓冲区值,而正交投影贴图Z值是线性的。因此,首先需要将透视深度取消投影到Z,以便找到在正交投影下产生相同深度的眼睛坐标。非常感谢,这非常有效。我认为这与线性和非线性深度有关,你解释得很好。干杯