现代OpenGL中正交投影的问题

3

我直入主题。我已经进行了一些研究,但仍然没有弄清楚这个问题。

我有一个绘制每个面带有颜色的立方体的程序。 然后我在Y轴和X轴上旋转这个立方体(分别为-45和+45)。

问题是它的渲染不符合我的预期,立方体在某个点被剪裁。

代码:

projection = glm::ortho(-1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f);

camera = glm::lookAt(
                     glm::vec3(+0.0f,+0.0f,+1.0f),
                     glm::vec3(0.0f,0.0f,0.0f),
                     glm::vec3(0.0f,1.0f,0.0f)
                     );

model = glm::mat4(1.0f);
model = glm::rotate(model, -45.0f, glm::vec3(0.0f, 1.0f, 0.0f));
model = glm::rotate(model, +45.0f, glm::vec3(1.0f, 0.0f, 0.0f));

mvp = projection * camera * model;

裁剪的魔方体

我定义的所有顶点都使用±0.25。因此,我认为至少在我的这些zNear和zFar值下,它们仍适合于该空间,但是当我更改该行时

projection = glm::ortho(-1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f);

对于

projection = glm::ortho(-1.0f, +1.0f, -1.0f, +1.0f, +2.0f, -1.0f);

它很好地工作着。

正确的渲染

但它无法与以下内容一起使用:

projection = glm::ortho(-1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -2.0f);

有人能解释一下为什么吗?我的意思是,我知道如果添加更多的值投影立方体就会有更大的体积,所以渲染效果应该也会不错。我知道右下角的顶点处于 zNear 和 zFar 值为 +1.0 和 -1.0 的立方体外面(经过矩阵计算后的顶点值大概是 1.76),但如果我将 zFar 立方体扩展到 -2.0f,那应该就刚好适合了,不是吗?
我试着阅读了《OpenGL 编程指南》和 Peter Shirley 的《计算机图形学基础》,甚至自己制作了矩阵,但结果都一样。
无论如何,先提前感谢!
2个回答

4

正在发生的情况是,相机的远裁剪面将立方体裁剪。

超出远裁剪面的任何内容都不会被渲染。

在您的原始代码中,远裁剪面设置为+1,非常靠近相机。 超过1个单位的任何内容都不会被渲染。

在您的工作代码中,将远裁剪面设置为+2,因此超过2个单位的任何内容都不会被渲染。

由于立方体距离相机不到2个单位,因此整个立方体都被渲染。


谢谢回复! 但我以为近平面是+1 ortho(T const &left, T const &right, T const &bottom, T const &top, T const &zNear, T const &zFar)所以,我把远平面放到了-2,想尝试看看,因为通过矩阵对顶点的计算,左下角顶点的Z分量从+0.25变为-1.75。所以我理解这是被远平面裁剪了。但当我将远平面设为-2时,仍然会发生裁剪。 - Antonio Ribeiro
1
远平面的目的是定义相机可以渲染到的最远距离。将其设置为-2,远平面现在不仅在相机后面,而且在近平面后面(这通常不是您想要的)。相反,您想要的是一个具有正值且大于近平面的远平面。例如,我通常有一个近平面为0.01,远平面为100。 - K_Finlay
好的,可能我对法平面的位置有误解。因为我认为将相机放在(0,0,1)处并朝向(0,0,0)会使近平面非常接近,而远平面在其后,但相机仍能看到它。因此,如果将近值设置为0.01,将远值设置为100,则必须定义所有顶点组件在这两个值之间,对吗? - Antonio Ribeiro
听起来你对投影矩阵的工作原理有些不确定(如果我错了请纠正我)。我建议你查看这个教程:http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#The_Model__View_and_Projection_matrices它会详细介绍投影矩阵和视图矩阵是什么,它们如何工作以及如何使用它们。 - K_Finlay
2
@AntonioRibeiro:nearfar的值是相对于“相机”的距离(实际上没有相机,物体在全局移动,就好像相机被放置在0,0,0处)。这意味着用于移动物体(包括“相机”)的实际场景变换与剪辑平面无关。 - datenwolf
该死!非常感谢@datenwolf,现在一切都清楚了!同时也感谢Tiddlesworth先生的解释和链接帮助! - Antonio Ribeiro

1
通常情况下,你希望近截面在远截面之前。如果由于某种原因使远截面为负数且近截面为正数,我不确定会发生什么...请尝试交换它们。

就我所记得的,近平面是+1.0f,远平面是-1.0f,对吧?因此,将相机放置在位置0,0,1中,使近平面在远平面之前。或者我现在变成了"fulltard"(注:此处为不当用语,请勿模仿)? - Antonio Ribeiro
1
近/远数值是相对于相机的,如果我没记错的话,所以负数在相机后面,正数在前面。 - Jonny D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接