理解glm::ortho()函数的参数如何影响投影后顶点位置

5
在搜索了许多页面、glm文档、教程等之后,我仍然对一些事情感到困惑。
我试图理解为什么我需要应用以下转换才能使我的800x600(全屏正方形,假设用户的屏幕为800x600,以此为最小示例)图像在所有内容上绘制。假设我只绘制逆时针三角形。在我的代码中,所有东西都渲染得很好,但我必须执行以下操作:
// Vertex data (x/y/z), using EBOs
  0.0f, 600.0f, 1.0f,
800.0f,   0.0f, 1.0f,
  0.0f,   0.0f, 1.0f,
800.0f, 600.0f, 1.0f

// Later on...
glm::mat4 m, v, p;
m = scale(m, glm::vec3(-1.0, 1.0, 1.0));
v = rotate(v, glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f));
p = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, 0.5f, 1.5f);

请注意,仅因为我使用了变量名m、v和p并不意味着它们实际上是该名称的正确转换,以上代码只是我想要的结果。
以下是我的困惑:
1. 正交边界在哪里?我假设它指向负z轴,但左/右边界何时出现?这是否意味着x轴上的[-400, 400]映射到[-1.0, 1.0]的NDC,或者是[0, 800]映射到它?(我假设此处的答案适用于y轴)。文档仅表示“创建正交平行视图体的矩阵”。
2. 如果你颠倒下面的第三个和第四个参数会发生什么(我问这个问题是因为我看到有人这样做,我不知道它是一个错误/打字错误还是它可以运行。。。或者它是否正确工作):
这里是第三个和第四个参数:
                              _____________
                             |  These two  |
p1 = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, 0.5f, 1.5f);
p2 = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.5f, 1.5f);

现在我假设前两个问题已经得到了解答,但是我正在尝试弄清楚这是否是为什么我的第一段代码需要翻转x轴才能起作用......我承认我只是在随意尝试,结果它可以正常工作。我想我需要一个180度的旋转来把我的平面转向它在-z侧的位置......所以这就让我需要弄清楚-1.0、1.0、1.0缩放的原因。
在此示例中提供的代码(除了变量名称)是我使用的唯一内容,渲染效果完美......只是我对它为什么可行的理由不满意。
编辑:我试图从这里理解它,使用该网站上的图片和描述作为单个参考示例。我可能误解了重点。
编辑2:作为一个随机问题,既然我总是在z = 1.0处绘制我的平面,那么我应该尽可能将正交投影的近/远平面限制在接近1.0的范围内(例如:0.99、1.01),有什么原因吗?假设没有其他东西被绘制或将被绘制。
1个回答

6
你可以假设正交投影中的可见区域是在视图空间中给定的一个立方体。然后将该立方体映射到NDC坐标系中的[-1,1]立方体,使得立方体内的所有内容都是可见的,而立方体外的所有内容都将被剪切掉。通常情况下,观察者沿着负Z轴望去,同时+x表示向右,+Y表示向上。
正交投影边界如何映射到NDC空间?
立方体的边长由传递给glOrtho的参数给出。在第一个示例中,左侧和右侧的参数为[0,800],因此沿X轴从0到800的空间被映射到NDC X轴上的[-1,1]。类似的逻辑发生在另外两个轴上(top/bottom沿y,near/far沿-z)。
当顶部和底部参数交换时会发生什么?
交换,例如,顶部和底部是等同于沿此轴镜像场景。如果您查看正交矩阵的第二个对角线元素,则定义为2 / (top-bottom)。通过仅交换顶部和底部,仅更改此元素的符号。交换左侧和右侧或近处和远处也适用。有时,当屏幕空间原点应该是左下角而不是左上角时,会使用它。 为什么要将四边形旋转180°并镜像呢? 如上所述,近和远值沿着Z轴。在-Z沿[0.5,1.5]的值在世界坐标系中意味着[-0.5,-1.5]。由于平面定义为z = 1.0,因此超出了可见区域。通过围绕原点旋转它180度,将其移动到z = -1.0,但现在您是从后面看它,这意味着背面剔除。通过沿X轴镜像,更改了绕组顺序,从而更改了前面和后面。

由于我总是在Z = 1.0处绘制飞机,所以我应该将正交投影的近/远平面限制在尽可能接近1.0的位置吗?

只要您不绘制其他任何内容,基本上可以选择任何您想要的。当绘制多个对象时,近和远之间的范围定义了深度差异可以存储的精确度。


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