投影矩阵推导
# 正交矩阵推导
正交矩阵6个面
x = l, x = r, y = b, y = t, z = n, z = f
原来的点(x,y,z)映射到(x`,y`,z`),其中x`,y` [-1, 1],z`[0,1]之间(dx的ndc空间z是0-1,opengl的是-1-1)
x` = 2*(x-l)/(r-l)-1
y`= 2*(y-b)/(t-b)-1
z`= (z-n)/(f-n)-1
2/(r-l) 0 0 -(r+l)/(r-l)
0 2/(t-b) 0 -(t+b)/(t-b)
(x`, y`, z`,1) = 0 0 1/(f-n) -(f+n)/(f-n) *(x, y, z,1)
0 0 0 1
认为正交投影是堆成,即:
r = -l t = -b
化简后为:
-1/l 0 0 0
0 -1/b 0 0
(x`, y`, z`,1) = 0 0 1/(f-n) -(f+n)/(f-n) *(x, y, z,1)
0 0 0 1
#透视投影矩阵推导
透视投影矩阵变换分2步,1转成clip空间,即为齐次坐标系,2转成ndc空间。
转齐次坐标系
x` = n*x/z
y` = n*y/z
再把x`,y`转换到-1-1之间
x`` = 2*(x`-l)/(r-l)-1 = 2nx/z(r-l) - (r+l)/(r-l)
y``= 2*(y`-b)/(t-b)-1= 2ny/z(t-b) - (t+b)/(t-b)
等价于:
x``z = 2nx/(r-l)-(r+l)z/(r-l)
y``z = 2ny/(t-b)-(t+b)z/(t-b)
z``需要特别处理,按照z``z的形式,改成
z``z = (z-n)*f/(f-n) = f*z/(f-n) -nf/(f-n)
写成
2n/(r-l) 0 -(r+l)/(r-l) 0
0 2n/(t-b) -(t+b)/(t-b) 0
(x`z, y`z, z`z,z) = 0 0 f/(f-n) -fn/(f-n) *(x, y, z,1)
0 0 1 0
视椎体对称,r=-l, t = -b,化简为:
-n/l 0 0 0
0 -n/b 0 0
(x`z, y`z, z`z,z) = 0 0 f/(f-n) -fn/(f-n) *(x, y, z,1)
0 0 1 0
思考
其实用下面的投影矩阵是不是也可以
2n/(r-l) 0 -(r+l)/(r-l) 0
0 2n/(t-b) -(t+b)/(t-b) 0
(x`z, y`z, z`z,z) = 0 0 -1 0 *(x, y, z,1)
0 0 1 0
视椎体对称,r=-l, t = -b,化简为:
-n/l 0 0 0
0 -n/b 0 0
(x`z, y`z, z`z,z) = 0 0 -1 0 *(x, y, z,1)
0 0 1 0
其实是不可以的,投影矩阵是为了把坐标映射到立方体,而不是一个平面
竖界截面上
tan (fov/2) = -b/n
定义横纵比为r
l/b = r
投影矩阵等于与
ctan(fov/2)/r 0 0 0
0 ctan(fov/2) 0 0
(x`z, y`z, z`z,z) = 0 0 f/(f-n) -fn/(f-n) *(x, y, z,1)
0 0 1 0
和
ctan(fov/2)/r 0 0 0
0 ctan(fov/2) 0 0
(x`z, y`z, z`z,z) = 0 0 -1 0 *(x, y, z,1)
0 0 1 0