问题:我正在阅读“OpenGL ES 2 for Android:快速入门指南”并进入第5章,他们开始考虑设备的宽高比,我似乎无法理解他们在拼写之间建立的联系投影和设备纵横比。在书中他们提到使用正交投影,这将允许人们走出OpenGL使用的标准化坐标空间,并进入虚拟坐标空间,以便能够考虑纵横比。然后,一旦考虑了纵横比,就必须将虚拟坐标带回标准化系统。我对他们在这里使用“虚拟坐标系”这个词感到有点困惑。
我理解的是:我明白,如果要制作一个圆并将其放置在OpenGL的标准化坐标系中,则圆会根据设备的方向拉伸和压扁,因为设备的纵横比不同于纵横比1 OpenGL的规范化坐标系有。我不明白的是,使用正交投影将如何帮助我们解决问题。我想我理解正投影是什么,但万一我不能用简单的术语来定义它?
我想我理解正投影是什么,但万一我不能用简单的术语来定义它?
我认为这是问题的一部分。您理解数学意义上的投影一词 - 幂等映射,这在减少数据维度时是典型的。在典型的渲染管道中,“投影”矩阵根本不进行任何投影。相反,渲染API定义了3D视图卷的一些约定。在OpenGL中,查看体积被定义为标准化设备坐标中的立方体-1 <= x,y,z <= 1
。每个立方体的边形成六个剪裁平面。这些平面之外的任何几何体都将被剪裁或剔除 - 因此这些平面仅代表屏幕的边缘(或实际上是视口,但想象这里的屏幕更直观)。
投影矩阵的任务(结合w
的透视分割)只是从3D眼睛空间(相对于“相机”的某些笛卡尔坐标系,如果想要用这些术语思考)转换为3D标准化设备空间。在正常情况下没有发生数学预测。这也意味着投影矩阵定义了眼睛空间中的6个剪切平面的位置。您基本上可以在标准化的设备空间中拍摄明确定义的视角体积角,并应用投影矩阵的反转(并进行另一个透视分割)并在眼睛空间中取回观察体积的八个角。结果,投影矩阵定义了世界的哪个范围被映射到屏幕,并且如果对象看起来没有失真,则视锥体的纵横比必须等于用于渲染的视口的纵横比。
对于正交“投影”,投影矩阵所做的就是在眼睛空间中定义一些长方体(通常是轴对齐的一个,因此它按比例缩小,每个维度平移)。通常,通过直接指定眼睛空间中的观察体积来定义这种正交变换,即指定left
,right
,top
,bottom
和near
以及far
值。现在,投影矩阵简单地将x_eye=left
映射到-1(NDC中的左剪裁平面),并将x_eye=right
映射到1(NDC中的右剪裁平面),依此类推。
在透视“投影”的情况下,观看体积将是眼睛空间中的金字塔平截头体。因为我们必须使用同质的w
组件,所以数学有点复杂,我不想在这里详细介绍,但我试图通过这里得到的关键点是仍然没有投影。透视投影将金字塔视锥体转换为NDC中的立方体,并用它来转换此体积内的所有内容 - 视锥体中的立方体实际上将变形为稍微“倒”的金字塔截头体,其中实际上距离较远的部分在NDC中变得更小。
实际投影发生的唯一情况是在光栅化过程中只考虑x
和y
coordiantes - 这始终是沿着z
m的正交投影,并且它不是由任何投影矩阵完成的。