投影矩阵到视锥体平面
描述:在进入渲染管线前,对场景进行剔除,对性能的提升很大。我通过投影矩阵得到视锥体的六个面,然后根据模型相对于视锥体的位置进行剔除。那么如何通过投影矩阵获的那六个面呢?
步骤描述
- 相关参数:假设世界坐标系下点 p 的齐次坐标(X, Y, Z, W), 点 p 在规范化设备坐标系下映射点 p’(X’, Y’, Z’)。
- 世界坐标系到规范化设备坐标系:
世界坐标系下点 p,进过投影(乘以投影矩阵M),得到点在投影坐标系下的点 Mp。然后经过规范(乘以规范化矩阵A),得到AMp。
假设: AMp = (aX, bY, cZ, dW)
那么(X’, Y’, Z’)= (aX/dW, bY/dW, cZ/dW)
//AM为投影规范化矩阵
AM = { a0, a1, a2, a3
a4, a5, a6, a7
a8, a9, a10, a11
a12, a13, a14, a15}
AMp=(aX, bY, cZ, dW)=
{ a0X + a4Y + a8Z + a12W
a1X + a5Y + a10Z + a13W
a2X + a6Y + a11Z + a14W
a3X + a7Y + a12Z + a15W}
-
在规范设备坐标系下:
Left Plane: x’ = -1
Left Plane: x’ = -1
Right Plane: x’ = 1
Top Plane: y’ = 1
Bottom Plane: y’ = -1
Near Plane: z’ = -1
Far Plane: z’ = 1
这些面就是将视锥体平面映射后的规范六面体(映射过程如下图)
-
点p’满足:
-1 < X’ < 1
-1 < Y’ < 1
-1 < Z’ < 1
推导出:
-1 < aX/dW < 1
-1 < bY/dW < 1
-1 < cZ/dW < 1
继续推导:
-dW < aX, aX < dW
-dW < bY, bY < dW
-dW < cZ, cZ < dW
就-dW < aX,推到 -( a3X + a7Y + a12Z + a15W)<a0X + a4Y + a8Z + a12W
得到(a0 + a3)X + (a4 + a7)Y + (a8 + a12)Z + (a12 + a15)d < 0
可得,当X’ = -1 时为视锥平面,
(a0 + a3)X + (a4 + a7)Y + (a8 + a12)Z + (a12 + a15)d = 0为视锥体面的平面方程。
这是面的一般表达式,可以转化为方向量加到原点距离的表达式:
向量((a0 + a3),(a4 + a7), (a8 + a12)),
距离:| (a12 + a15)|/sqrt((a0 + a3^ 2 + (a4 + a7)^2 + (a8 + a12) ^ 2)
此方法的具体实现可以参见three.js Frustum的setFromMatrix()方法。
其他5各面的平面方程同理可得(在此不细写)。