了解 glm::ortho() 的参数如何影响投影后的顶点位置
Understanding how glm::ortho()'s arguments affect vertex location after projection
在搜索了很多页面、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
并不意味着它们实际上是该名称的正确转换,上面只是做我想做的事)
我对以下内容感到困惑:
拼字边界在哪里?我假设它指向负 z 轴,但是 left/right 边界从哪里来?这是否意味着 x 轴上的 [-400, 400] 映射到 [-1.0, 1.0] NDC,或者 [0, 800] 映射到它? (我假设这里的任何答案都适用于 y 轴)。然后文档只是说 Creates a matrix for an orthographic parallel viewing volume.
如果你翻转以下第三个和第四个参数会发生什么(我问是因为我看到有人这样做但我不知道这是 mistake/typo 还是侥幸...或者不管它是否正常工作):
这里是参数三和参数四:
_____________
| 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 缩放比例了。
此示例中提供的代码(减去变量名称)是我唯一使用的东西,而且渲染效果非常好...只是我不了解它为什么起作用,这让我很不满意。
编辑:试图通过使用网站上的图像和描述作为参考示例从 here 中理解它。我可能错过了重点。
EDIT2:作为一个随机问题,因为我总是在 z = 1.0 处绘制我的平面,我是否应该限制我的正交投影 near/far 平面尽可能接近 1.0(例如:0.99、1.01)出于什么原因?假设没有绘制或将绘制任何其他内容。
您可以假设正射投影中的可见区域是视图中给定的立方体 space。然后将这个立方体映射到 NDC 坐标中的 [-1,1] 立方体,这样立方体内部的所有内容都是可见的,外部的所有内容都将被剪掉。一般情况下,观看者的视线方向为负Z-axis,而+x为右,+Y为上。
如何将正字法边界映射到 NDC space?
立方体的边长由传递给 glOrtho
的参数给出。在第一个示例中,左右参数为 [0, 800],因此沿 X 轴从 0 到 800 的 space 映射到沿 NDC X 轴的 [-1, 1]。类似的逻辑发生在其他两个轴上(top/bottom 沿 y,near/far 沿 -z)。
交换top和bottom参数会发生什么?
互换,例如top和bottom,相当于沿着这个轴镜像场景。如果您查看 orthographic matrix 的第二个对角线元素,它被定义为 2 / (top - bottom)
。通过交换顶部和底部,只有这个元素的符号会改变。这同样适用于交换左与右或近与远。有时当 screen-space 原点应该是左下角而不是左上角时使用。
为什么要把四边形旋转180°镜像呢?
如上所述,近值和远值沿 负值 Z-axis。 [0.5, 1.5] 沿 -Z 的值表示世界 space 坐标中的 [-0.5, -1.5]。由于平面定义为 z=1.0,因此它位于可见区域之外。通过将它围绕原点旋转 180 度,将它移动到 z=-1.0,但现在你从后面看它,这意味着 back-face 剔除罢工。通过沿 X 镜像它,缠绕顺序发生变化,因此背面和正面发生变化。
因为我总是在 Z = 1.0 绘制平面,我是否应该限制我的正投影 near/far 平面尽可能接近 1.0?
只要不画别的,基本可以随便选。当绘制多个对象时,远近之间的范围定义了深度差异的存储精度。
在搜索了很多页面、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
并不意味着它们实际上是该名称的正确转换,上面只是做我想做的事)
我对以下内容感到困惑:
拼字边界在哪里?我假设它指向负 z 轴,但是 left/right 边界从哪里来?这是否意味着 x 轴上的 [-400, 400] 映射到 [-1.0, 1.0] NDC,或者 [0, 800] 映射到它? (我假设这里的任何答案都适用于 y 轴)。然后文档只是说
Creates a matrix for an orthographic parallel viewing volume.
如果你翻转以下第三个和第四个参数会发生什么(我问是因为我看到有人这样做但我不知道这是 mistake/typo 还是侥幸...或者不管它是否正常工作):
这里是参数三和参数四:
_____________
| 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 缩放比例了。
此示例中提供的代码(减去变量名称)是我唯一使用的东西,而且渲染效果非常好...只是我不了解它为什么起作用,这让我很不满意。
编辑:试图通过使用网站上的图像和描述作为参考示例从 here 中理解它。我可能错过了重点。
EDIT2:作为一个随机问题,因为我总是在 z = 1.0 处绘制我的平面,我是否应该限制我的正交投影 near/far 平面尽可能接近 1.0(例如:0.99、1.01)出于什么原因?假设没有绘制或将绘制任何其他内容。
您可以假设正射投影中的可见区域是视图中给定的立方体 space。然后将这个立方体映射到 NDC 坐标中的 [-1,1] 立方体,这样立方体内部的所有内容都是可见的,外部的所有内容都将被剪掉。一般情况下,观看者的视线方向为负Z-axis,而+x为右,+Y为上。
如何将正字法边界映射到 NDC space?
立方体的边长由传递给 glOrtho
的参数给出。在第一个示例中,左右参数为 [0, 800],因此沿 X 轴从 0 到 800 的 space 映射到沿 NDC X 轴的 [-1, 1]。类似的逻辑发生在其他两个轴上(top/bottom 沿 y,near/far 沿 -z)。
交换top和bottom参数会发生什么?
互换,例如top和bottom,相当于沿着这个轴镜像场景。如果您查看 orthographic matrix 的第二个对角线元素,它被定义为 2 / (top - bottom)
。通过交换顶部和底部,只有这个元素的符号会改变。这同样适用于交换左与右或近与远。有时当 screen-space 原点应该是左下角而不是左上角时使用。
为什么要把四边形旋转180°镜像呢?
如上所述,近值和远值沿 负值 Z-axis。 [0.5, 1.5] 沿 -Z 的值表示世界 space 坐标中的 [-0.5, -1.5]。由于平面定义为 z=1.0,因此它位于可见区域之外。通过将它围绕原点旋转 180 度,将它移动到 z=-1.0,但现在你从后面看它,这意味着 back-face 剔除罢工。通过沿 X 镜像它,缠绕顺序发生变化,因此背面和正面发生变化。
因为我总是在 Z = 1.0 绘制平面,我是否应该限制我的正投影 near/far 平面尽可能接近 1.0?
只要不画别的,基本可以随便选。当绘制多个对象时,远近之间的范围定义了深度差异的存储精度。