DirectX 透视投影矩阵推导,DX和OpenGL有一些区别
- 坐标系不同:DirectX LHS左手坐标系Z反向指向屏幕,而OpenGL是右手坐标系
- NDC定义不同: Z的范围为
[0,1]
OpenGL中为[-1,1]
- DirectX HLSL中的Matrix默认为 column major(本文中我们还是以row-major来进行推导)
由此我们按照Part1的方法,以DirectX环境中值来进行一遍推导
Step1 正交化处理
对于点P(x,y,z,1),经过投影变换乘以透视矩阵得到P′,P′位于Normalized Device Coordinates(NDC)中。
MprojP=P′Px′∈[−1,1]Py′∈[−1,1]Pz′∈[0,1]
更具三角形等比公式
P′=(znx,zny,f(z),1), 正交化之前P′=(nx,ny,g(z),z)
设 g(z)=az+b
⎣⎢⎢⎢⎡??00??00??a1??b0⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡xyz1⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡nxnyaz+bz⎦⎥⎥⎥⎤
取NDC近平面左下角Plbn=(l,b,n,1)和远平面右上角Prtf=(r,t,f,1)。
经过投影变换
Plbn=(l,b,n,1)→(−1,−1,0,1)↔(−n,−n,0,n)
Prtf=(r,t,f,1)→(1,1,1,1)↔(f,f,f,f)
得到
an+b=0af+b=f
求得
a=f−nfb=f−nfn
⎣⎢⎢⎢⎡??00??00??f−nf1??f−nfn0⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡xyz1⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡??f−nf(z+n)z⎦⎥⎥⎥⎤
Step2 求解前两行
类似Part1 我们定义8个矩阵变量.
⎣⎢⎢⎢⎡AE00BF00CGf−nf1DHf−nfn0⎦⎥⎥⎥⎤
可以得到 B D E H为0
⎣⎢⎢⎢⎡A0000F00CGf−nf100f−nfn0⎦⎥⎥⎥⎤
取两点 S(l,b,n,1)→(−n,−n,0,n) 和 T(r,t,n,1)→(n,n,0,n),代入矩阵得到方程组
Al+Cn=−nAr+Cn=nFb+Gn=−nFt+Gn=n
求解
A=r−l2nC=−r−lr+lF=t−b2nG=−t−bt+b
设viewport对称:
r+l=0r−l=wt+b=0t−b=h
得到最终矩阵
⎣⎢⎢⎢⎡w2n0000h2n0000f−nf100f−nfn0⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡xyz1⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡w2nxh2nyf−nf(z+n)z⎦⎥⎥⎥⎤