在模型空间(Local Space), 世界空间(World Space), 视空间(View/Eye Space)间变换点或向量是容易的, 只需要操作矩阵与逆矩阵即可.
将点或向量在NDC与屏幕空间(Screen Space)间变换也是容易的, 不做介绍.
真正的难点是如何将点或向量从NDC变换回到视空间.
将点从NDC变换回视空间(以透视投影为例)
有投影矩阵:
⎣⎡A0000B0000T1E100T20⎦⎤
有在视空间上的点(齐次坐标, Pw=1.0表示该齐次坐标代表一个点)
P=⎝⎛PxPyPz1.0⎠⎞
已知N=C/Cw(C:P在裁剪空间的表示,N:P在NDC中的表示), 可变形为C=NCw.
但Cw是未知量, 我们需要根据已有条件去推断它, 即建立这样一个关系: f:N→Cw.
推断f:N→Cw
已知
Cw=E1Pz(1)
∵C=NCw
∴Cz=NzCw⟹
T1Pz+T2=NzCw(2)
变形(1)式, 得:
Pz=Cw/E1
带入(2)式, 得:
E1T1Cw+T2=NzCw⇒(Nz−E1T1)Cw=T2⇒Cw=Nz−E1T1T2
已知Cw, 那么NDC到裁剪空间的变换即为
C=NCw⇒C=NNz−E1T1T2
从裁剪空间到视空间就简单了, 乘以一个投影矩阵的逆矩阵就可以了
P=Proj−1C⇒P=Proj−1(NNz−E1T1T2)
向量能否在视空间与NDC间自由变换(在透视变换中)
先说答案, 不能.
视空间上的向量可以用齐次坐标表示为
P=⎝⎛PxPyPz0.0⎠⎞
变换到裁剪空间为
C=⎝⎛APxBPyT1PzE1Pz⎠⎞
经过透视除法到NDC
N=⎝⎛APx/E1PzBPy/E1PzT1/E11.0⎠⎞
容易发现, Nz=T1/E1, T1/E1常大于1, 也就是说向量P经过变换后绝大多数情况下会被直接裁剪掉, 就算通过, P也会被拍扁到Z平面T1/E1上, 丢失深度信息.
所以向量P不可能从视空间变换到NDC; 同理, 向量N也不可能从NDC变换到视空间.
但要注意, 向量在视空间和裁剪空间间变换是没有问题的, 因为不牵涉到透视除法.
那么, 在正射投影中, 向量能否在视空间与NDC间自由变换呢?
能!
为什么?
因为没有该死的透视除法了🙃.
小贴士: 正射投影矩阵长这样👉
⎣⎡A0000B0000T1000T21⎦⎤
参考资料