关于Opengl投影矩阵

时间:2024-10-31 17:37:03

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

0.投影矩阵的功能:

将眼睛空间中的坐标点 [图A的视椎体]     映射到     一个(-1, 1)的空间中[图B的立方体]

关于Opengl投影矩阵

图A 图B

1.我们要解的是什么问题:

我们要求一个矩阵,使得以下等式成立

[结果坐标]  = [待求矩阵] * [眼睛坐标系的坐标]

关于Opengl投影矩阵

2.大致思路是什么:

我们使等式左侧的[Xc, Yc, Zc, Wc]T 坐标  和
等式右侧的[Xe, Ye, Ze, We]T 变为已知, 逆推中间的未知矩阵。

3.推导过程:

不管矩阵的其他几何含义,纯粹从等式成立的角度

3.1求矩阵第四行


a.求眼睛空间中某一点坐标在*面的投影点坐标

从顶部y方向逆方向看向视椎体,求Xp
关于Opengl投影矩阵   ----------->>>>>>              关于Opengl投影矩阵     等式A

同理,从侧边x方向逆方向看向视椎体, 求Yp
关于Opengl投影矩阵 ----------->>>>>>关于Opengl投影矩阵   等式B


此时第三个分量Zp = -n


现在我们知道:

关于Opengl投影矩阵

而进行透视除法时:
关于Opengl投影矩阵


观察等式A 和等式B, 他们都除了一个 -Ze,为了好看,我们就设Wc = -Ze这样就能得到一个好看的矩阵第四行:

关于Opengl投影矩阵

即 [0, 0 , -1, 0]

3.2求矩阵第一,二行

我们想要将 [l, r]线性映射到 [-1, 1] 和 [b, t]线性映射到[-1,1](l,r,b,t的含义见最上面图A)

关于Opengl投影矩阵

该等式看做y = Ax + B, 即Xn = AXp + B

曲线的斜率是 (1 - (-1)) / (r - l ) = 2 / (r - l)

即Xn = Xp * 2 /(r - l) + B

代入(r, 1)这个点可求得Xn

详细计算过程为:
关于Opengl投影矩阵

同理,Yn的计算过程如下:
关于Opengl投影矩阵

关于Opengl投影矩阵

现在我们把Yp,Xp 用 Ye,Xe代替,则有


关于Opengl投影矩阵关于Opengl投影矩阵


观察上式他们都被-Ze = Wc 相除了, 于是我们的矩阵第一行,第二行变为



关于Opengl投影矩阵

3.3求矩阵第三行


我们知道Z与x,y没关系,参考上面的X,Y都除以了-Ze,这里我们也这样
于是:

关于Opengl投影矩阵

在眼睛空间中, We是1,等式变成;

关于Opengl投影矩阵



-n 对应 -1, -f 对应 1

关于Opengl投影矩阵

求出A和B
关于Opengl投影矩阵   

 关于Opengl投影矩阵

现在Zn变成了:

关于Opengl投影矩阵




终于我们求得最终的矩阵为:


关于Opengl投影矩阵


如果视锥体退步成一个上下对称,左右对称的视锥体,即:

关于Opengl投影矩阵

那么,投影矩阵就变为我们天天见到的投影矩阵:

关于Opengl投影矩阵