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 进行了测试。这三个都表现出相同的行为。
我正在使用 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 进行了测试。这三个都表现出相同的行为。