OpenGL 深度缓冲和正射投影

OpenGL Depth buffer & ortho projection

我正在使用 Java 和 JOGL 进行一些 3D 渲染。我使用 JOML 库生成视图和投影矩阵:

Matrix4f view = new Matrix4f()
    .lookAt(new Vector3f(1.0f, 0.0f, 0.0f), 
            new Vector3f(0.0f, 0.0f, 0.0f),
            new Vector3f(0.0f, 1.0f, 0.0f));

Matrix4f proj = new Matrix4f()
    .ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);

我像这样将这些矩阵发送到着色器:

gl.glUniformMatrix4fv(viewTransformLocation, 1, false, viewTransformMatrix, 0);
gl.glUniformMatrix4fv(projectionTransformLocation, 1, false, projectionTransformMatrix, 0);

在此过程中不转置矩阵。

填充我的 VAO 和 VBO 后,我简单地使用以下状态来渲染网格:

gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL.GL_CULL_FACE);
gl.glCullFace(GL.GL_BACK);
gl.glEnable(GL.GL_DEPTH_TEST);
...

生成的图像很奇怪,看起来深度缓冲区被颠倒了。在我尝试反转映射后,它就像一个魅力。

gl.glDepthRange(1,0);

谁能告诉我为什么会这样?我用C++写了一个类似的程序,使用glm库和相同的设置(当然除了反向映射),问题没有出现。

您在 ortho 调用中为 zNear 参数传递 -1 似乎很奇怪。通常 near 和 far 都是正值。

好的,将这些值传递给 glOrtho 是合法的,但它可能没有按照您的预期进行。远平面在相机前面 1 个单位,近平面在相机后面 1 个单位。但是由于相机朝 -z 方向看,远平面将位于 z = -1,而近平面将位于 z=1

您可能遇到过 Z 坐标较高(朝向 +inf)的表面隐藏了 Z 坐标较小(朝向 -inf)的表面。

如果您对 zMin 使用负值而对 zMax 使用正值,则这是正确的行为。 看看http://www.songho.ca/opengl/gl_projectionmatrix.html#ortho。 在 "Orthographic Projection" 部分,您会看到第一张图像,其中 +Z 矢量指向 "out of the screen" 观察者。这也是您的 Z 坐标的解释方式。较大的值比较小的值更接近观看者。

当您交换 zNear 和 zFar 的符号时,情况会发生变化,使 zNear 为正而 zFar 为负。然后,您的 +Z 指向 "into the screen" 并远离观众。在那里,您的表面的较小 Z 值(朝向 -inf)会离观察者更近。

我使用 JOML、GL11.glOrtho 以及 GLU.gluOrtho2D 进行了测试。这三个都表现出相同的行为。