2017-02-21 1611 views
2

在搜索很多页面之后,glm文档,教程等等,我仍然对某些事情感到困惑。了解glm :: ortho()的参数如何影响投影后的顶点位置

我想了解为什么我需要应用以下转换以获取我的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); 

(注意,只是因为我使用的变量名mv,并且p并不意味着他们实际上是为适当变换这个名字,以上只是我想要做什么它)

我很困惑在以下方面:

  • 哪里正投影界限?我认为它是指向负Z轴,但左/右边界在哪里进来?这是否意味着x轴上的[-400,400]映射到[-1.0,1.0] NDC,或者[0,800]映射到它? (我假设这里的任何答案适用于y轴)。然后文件只是说Creates a matrix for an orthographic parallel viewing volume.

  • 如果你翻转下面的第三和第四个参数会发生什么(我问,因为我看到人们这样做,我不知道这是一个错误/错字还是它通过侥幸工程..或者如果它正常工作,无论):

参数数量三,四的位置:

       _____________ 
          | 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); 
  • 现在,我认为这第三个问题将与上述两种回答,但我tryi要弄清楚这是为什么我的第一部分代码要求我翻转x轴上的所有东西来工作......我承认我只是搞乱了它,而且碰巧发生了。我想我需要一个180度的旋转来转动我的飞机,所以它的-Z侧,然而...所以这只是让我想出了-1.0,1.0,1.0的缩放。

本示例中提供的代码(减去变量名称)是我使用的唯一东西,并且渲染完美无缺......这仅仅是我缺乏关于它为什么会起作用的知识,我不满意。

编辑:试图从here通过使用网站上的图像和描述作为一个参考的例子来了解它。我可能错过了这一点。编辑2:作为一个随机问题,因为我总是在z = 1.0处绘制我的平面,所以我应该限制我的正投影近/远平面尽可能接近1.0(例如:0.99,1.01) ?假设没有其他东西被绘制或将被绘制。

回答

2

您可以假设正投影中的可见区域是视图空间中给出的立方体。然后将该立方体映射到NDC坐标系中的[-1,1]立方体,以便立方体内的所有内容都可见,并且外部的所有内容都将被剪切掉。通常,观看者沿着负Z轴看,而+ X是正确的,+ Y是向上的。

正交界限如何映射到NDC空间?

立方体的边长由传递给glOrtho的参数给出。在第一个示例中,左侧和右侧的参数为[0,800],因此沿着x轴的从0到800的空间沿着NDC x轴映射到[-1,1]。类似的逻辑发生在其他两个轴上(沿着y的顶部/底部,沿着-z的近/远)。

顶部和底部参数交换时会发生什么?

交换,例如,顶部和底部相当于沿着此轴镜像场景。如果您查看orthographic matrix的第二个对角线元素,则将其定义为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吗?

只要你不画什么东西,你可以基本上选择你想要的任何东西。当绘制多个对象时,near和far之间的范围定义了如何存储精确的深度差异。