OpenGL-- projection Matrix 翻译

原博客英文版地址:

http://www.songho.ca/opengl/gl_projectionmatrix.html

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

翻译如下:

相关话题:OpenGL Transformation

  • 概述
  • 透视投影
  • 正交投影

更新:MathML 版本在这里 here

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------概述

计算机显示器是2D表面。必须将OpenGL渲染的3D场景作为2D图像投影到计算机屏幕上。GL_PROJECTION矩阵用于此投影变换。首先,它将所有顶点数据从视点坐标转换为剪切坐标。然后,通过用剪切坐标的w分量划分,这些剪切坐标也被变换为标准化设备坐标(NDC)。

被截头体夹住的三角形

 
                                                                                      被视椎体夹住的三角形

因此,我们必须记住,剪切(视锥体剔除)和NDC变换都集成到GL_PROJECTION矩阵中。以下部分描述了如何从6个参数构建投影矩阵,这6个参数分别是: 远的边界值。

注意,在除以之前,在剪切坐标中执行视椎体剔除(剪切)。剪切坐标通过和比较,如果任何剪辑坐标小于或大于,则该顶点将被丢弃。 也就是

然后,OpenGL将在剪切发生的地方重建多边形边缘。

需要解释的名词:视锥体(frustum),是指场景中摄像机的可见的一个锥体范围。它有上、下、左、右、近、远,共6个面组成。在视锥体内的景物可见,反之则不可见。为提高性能,只对其中与视锥体有交集的对象进行绘制。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

透视投影

在透视投影中,截断的金字塔视椎体(视点坐标)中的3D点被映射到立方体(NDC); x坐标范围从[l,r]到[-1,1],y坐标范围从[b,t]到[-1,1],z坐标范围从[-n,-f]到[-1,1]。

请注意,视点坐标是在右手坐标系中定义的,但NDC使用左手坐标系。也就是说,在视点空间中,原点的相机是沿着-z轴看的,但它在NDC中沿着+ Z轴看。由于glFrustum()只接受近(near)及远(far)的距离是正值,所以我们在构建GL_PROJECTION矩阵的时候需要消除它们的区别。

在OpenGL中,视点空间中的3D点被投影到平面(投影平面)上。下图显示了视点空间中的点如何投影到平面上的

从视椎体的顶视图可以看出,视点空间的x坐标,x e被映射到x p,其通过使用相似三角形的比率来计算; 

从视椎体的侧视图可以看出,视点空间的y坐标,yp也是通过相似三角形计算的;

注意,x p和y p都取决于z e ; 它们与-z e成反比。换句话说,它们都被-z e除以。这是构建GL_PROJECTION矩阵的第一条线索。在通过乘以GL_PROJECTION矩阵变换视点坐标之后,裁剪坐标(剪切坐标)仍然是齐次坐标。通过除以w分量,它最终变为归一化设备坐标(NDC)。

因此,我们可以将裁剪坐标的w分量设置为-z e。并且,GL_PROJECTION矩阵的第4个向量变为(0,0,-1,0)。

接下来,我们将x p和y p映射到具有线性关系的NDC的x n和y n ;[l,r]⇒[-1,1]和[b,t]⇒[-1,1]。

然后,我们将x p和y p代入上述方程式

注意,我们使每个方程的两个项都可被-z e整除以用于透视分割(x c / w c,y c / w c)。我们之前将w c设置为-z e,括号内的项变为裁剪坐标的x c和y c。

从这些方程式中,我们可以找到GL_PROJECTION矩阵的第1行和第2行。

现在,我们只有第3行的GL_PROJECTION矩阵亟待解决。寻找z n与其他略有不同,因为视点空间中的z e总是被投射到近平面上的-n。但是我们需要唯一z值用于剪切和深度测试。另外,我们应该能够取消投影(逆变换)。由于我们知道z不依赖于x或y值,因此我们借用w分量来找到z n和z e之间的关系。因此,我们可以这样指定GL_PROJECTION矩阵的第3行。

在视点空间中,w e=1.因此,等式变为; 

为了找到系数AB,我们使用(z e,z n)关系; (-n,-1)和(-f,1),并将它们放入上面的等式中。

为了求解AB的等式,重写B的等式(1); 

将方程(1')代入方程(2)中的B,然后求解A; 

A放入方程(1)中以找到B ; 

我们发现A和B,因此ze和zn的关系变成:

最终,我们发现GL_PROJECTION矩阵的所有值,完整的投影矩阵是

该投影矩阵用于一般的视椎体。如果观看体积是对称的,这是,那么它可以被简化为; 

在我们继续之前,请再次看一下z e和z n,eq。(3)之间的关系。您注意到它是一个有理函数,并且是z e和z n之间的非线性关系。这意味着平面的精度非常高,但平面的精度非常低。如果范围[-n,-f]越来越大,则会导致深度精度问题(z-fighting); 平面周围的z e的小变化不会影响z n值。nf之间的距离应尽可能短,以最小化深度缓冲精度问题。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

正交投影

构造用于正投影的GL_PROJECTION矩阵比透视模式简单得多。

视点空间中的 所有x e,y e和z e分量线性映射到NDC。我们只需要将矩形体积缩放到立方体,然后将其移动到原点。让我们使用线性关系找出GL_PROJECTION的元素。

由于正交投影不需要w分量,因此GL_PROJECTION矩阵的第4行保持为(0,0,0,1)。因此,正交投影的完整GL_PROJECTION矩阵是

它可以进一步简化,如果观察体是对称的,。 

猜你喜欢

转载自blog.csdn.net/keneyr/article/details/87798884