[英]Understanding how glm::ortho()'s arguments affect vertex location after projection
在搜索了许多页面,glm文档,教程等之后,我仍然对某些事情感到困惑。
我试图理解为什么我需要应用以下转换来获得我的800x600(全屏方块,假设用户的屏幕是800x600这个最小的例子)图像来绘制所有内容。 假设我只绘制CCW三角形。 我的代码中的所有内容都很好,但我必须执行以下操作:
// 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轴,但左/右界限在哪里? 这是否意味着x轴上的[-400,400]映射到[-1.0,1.0] NDC,或者[0,800]映射到它? (我假设这里的答案适用于y轴)。 然后文档说明Creates a matrix for an orthographic parallel viewing volume.
如果你翻转下面的第三和第四个论点会发生什么(我问,因为我看到人们这样做,我不知道这是一个错误/错字还是它是侥幸的......或者如果它能正常运作):
Args三和四:
_____________
| 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);
这个例子中提供的代码(减去变量名称)是我使用的唯一的东西,渲染工作完美......这只是我缺乏知识,为什么它的工作,我不满意。
编辑:试图通过使用网站上的图像和描述作为参考的一个例子从这里了解它。 我可能错过了这一点。
编辑2:作为一个随机问题,因为我总是在z = 1.0处绘制我的平面,我是否应该将我的正投影近/远平面限制为尽可能接近1.0(例如:0.99,1.01)? 假设没有绘制或将绘制任何其他内容。
您可以假设正交投影中的可见区域是视图空间中给出的多维数据集。 然后将此立方体映射到NDC坐标中的[-1,1]立方体,这样立方体内的所有内容都可见,并且外部的所有内容都将被剪掉。 通常,观察者沿负Z轴看,而+ x是右,+ Y是向上看。
如何将正交边界映射到NDC空间?
多维数据集的边长由传递给glOrtho
的参数glOrtho
。 在第一个示例中,左侧和右侧的参数是[0,800],因此沿X轴的0到800的空间沿NDC X轴映射到[-1,1]。 类似的逻辑沿着另外两个轴(沿着y的顶部/底部,沿着-z的近/远)发生。
顶部和底部参数交换后会发生什么?
例如,顶部和底部的交换相当于沿着该轴镜像场景。 如果查看正交矩阵的第二个对角线元素,则定义为2 / (top - bottom)
。 通过交换顶部和底部,只有这个元素的符号会发生变化。 同样也适用于左右交换或远近交换。 有时,当屏幕空间原点应该是左下角而不是左上角时使用。
为什么你必须将四边形旋转180°并镜像它?
如上所述,近和远值沿着负 Z轴。 在世界空间坐标中,[ - 1.5,1.5]的值沿-Zn表示[-0.5,-1.5]。 由于平面定义为az = 1.0,因此它位于可见区域之外。 通过绕原点旋转180度将其移动到z = -1.0,但现在你从后面看它,这意味着背面剔除打击。 通过沿X镜像,绕组顺序改变,从而改变后侧和前侧。
由于我总是在Z = 1.0处绘制我的平面,我应该将我的正投影近/远平面限制为尽可能接近1.0吗?
只要你不绘制任何其他东西,你基本上可以选择你想要的任何东西。 绘制多个对象时,near和far之间的范围定义了如何存储精确的深度差异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.