光线投射(raycast)公式中的far-clip

光线投射公式

从相机发出一条光线,穿过与相机距离为1的屏幕上的某点,已知相机参数和点在屏幕空间上的位置(sx,sy),计算世界空间中投影到该点的对应点的坐标的公式为: \[ P = ViewMat^{-1} * ProjMat^{-1} * ((sx, sy, 1, 1) * farClip). \]

使用下面的公式得到的结果实际上是一样的。 \[ P = ViewMat^{-1} * ProjMat^{-1} * (sx, sy, 1, 1), \] 但是需要对向量进行规范化,即:

\[ P=[p.x,p.y,p.z,p.w]/p.w. \]

证明

投影公式ProjMat为: \[ P=\begin{bmatrix} \frac{1}{A\tan(FOV/2)} & 0 & 0 & 0 \\ 0 & \frac{1}{\tan(FOV/2)} & 0 & 0 \\ 0 & 0 & \frac{f}{f-n} & \frac{-fn}{f-n}\\ 0 & 0 & 1 & 0 \end{bmatrix}. \] 因为ViewMat是齐次矩阵,不修改w,所以只考虑投影公式。首先计算它的逆。 因为左下角与右上角为0,可以视为\(2\times 2\)的分块矩阵,计算逆时只需要计算右下角的逆即可。左上角为对角矩阵,逆是对角元素的倒数。2维矩阵较小,可以用伴随矩阵计算逆。伴随矩阵公式为: \[ adj({ {\begin{bmatrix}{a}&{b}\\{c}&{d}\end{bmatrix} }})={ {\begin{bmatrix}\,\,\,{d}&\!\!{-b}\\{-c}&{a}\end{bmatrix} }}. \] 关于n×n矩阵A,有 \[ \mathbf{A}\, \mathrm{adj}(\mathbf{A}) = \mathrm{adj}(\mathbf{A})\, \mathbf{A} = \det(\mathbf{A})\, \mathbf{I}. \]\[ \mathbf{A}^{-1} = \det(\mathbf{A})^{-1}\, \mathrm{adj}(\mathbf{A}) \]\[ A=\begin{bmatrix} \frac{f}{f-n} & \frac{-fn}{f-n}\\ 1 & 0 \end{bmatrix} \]

\[ det(A)=\frac{fn}{f-n}.\\ A^{-1}=\frac{1}{\frac{fn}{f-n} }\begin{bmatrix} 0 & \frac{fn}{f-n}\\ -1 & \frac{f}{f-n} \end{bmatrix}=\begin{bmatrix} 0 & 1\\ -\frac{f-n}{fn} & \frac{1}{n} \end{bmatrix} \] 因此投影矩阵的逆为: \[ P^{-1}=\begin{bmatrix} {A\tan(FOV/2)} & 0 & 0 & 0 \\ 0 & {\tan(FOV/2)} & 0 & 0 \\ 0 & 0 & 0 & 1\\ 0 & 0 & -\frac{f-n}{fn} & \frac{1}{n} \end{bmatrix} \] 根据公式: \[ \begin{bmatrix} sx\\ sy\\ 1\\ 1 \end{bmatrix} \times farClip= \begin{bmatrix} sx\times farClip\\ sy\times farClip\\ farClip\\ farClip \end{bmatrix}, \] \[ P^{-1}\begin{bmatrix} sx\times farClip\\ sy\times farClip\\ farClip\\ farClip \end{bmatrix}= \begin{bmatrix} {A\tan(FOV/2)}sx\times farClip\\ {\tan(FOV/2)}sy\times farClip\\ farClip\\ 1 \end{bmatrix} \] 对比直接相乘的结果: \[ P^{-1}\begin{bmatrix} sx\\ sy\\ 1\\ 1 \end{bmatrix}= \begin{bmatrix} {A\tan(FOV/2)}sx\\ {\tan(FOV/2)}sy\\ 1\\ 1 \end{bmatrix}= \begin{bmatrix} {A\tan(FOV/2)}sx\\ {\tan(FOV/2)}sy\\ 1\\ \frac{1}{f} \end{bmatrix} \] 可以看出,无论乘不乘farClip规范化后的结果确实是一样的。但是因为glm并没有提供我们需要的规范化的函数,所以通过乘farClip来省去手动规范化的步骤是可以提高效率的。

光线投射(raycast)公式中的far-clip

https://grahamzen.github.io/2023/01/14/raycast-formula/

作者

Gehan Zheng

发布于

2023-01-14

更新于

2023-12-18

许可协议

评论