透視投影行列
near と far 面が $ z = -n, z = -f (n,f > 0) ,near 面の上下左右の端が $ t,b,r,lの視錐台を,左の立方体に変形させる変換,つまりカメラ座標系から正規化(同次)クリップ座標系への変換を考える( OpenGL と同じ).
https://scrapbox.io/files/67a6fb3865fc5f6b99782196.png
例えば,以下の射影変換で表現することができる:
code:tex
\begin{pmatrix}
x \\ y \\ z \\ 1
\end{pmatrix}
~
\begin{pmatrix}
-P_z x \\ -P_z y \\ -P_z z \\ -P_z
\end{pmatrix}
=
\begin{pmatrix}
\frac{2n}{r - l} & 0 & \frac{r+l}{r-l} & 0 \\
0 & \frac{2n}{t-b} & \frac{t+b}{t-b} & 0 \\
0 & 0 & - \frac{f+n}{f-n} & - \frac{2nf}{f-n} \\
0 & 0 & -1 & 0
\end{pmatrix}
\begin{pmatrix}
P_x \\ P_y \\ P_z \\ 1
\end{pmatrix} ,
fovY と aspect で指定する場合は
$ t = near \times \tan ( fovY \times 0.5), ~ b = -t,~ r = t \times aspect,~ l = -r
ちなみに Vulkan の場合は正規かクリップ座標系の z 軸の範囲が $ 0 \leq z \leq 1なので
code:tex
\begin{pmatrix}
\frac{2n}{r - l} & 0 & \frac{r+l}{r-l} & 0 \\
0 & \frac{2n}{t-b} & \frac{t+b}{t-b} & 0 \\
0 & 0 & - \frac{f}{f-n} & - \frac{nf}{f-n} \\
0 & 0 & -1 & 0
\end{pmatrix} ,
となる.必要に応じて y 軸を反転させる.
https://scrapbox.io/files/699c06dd3583dfb074de78d1.png
Reverse-Z の場合は上の通り,near を 1, far を 0 にマップする.
この場合の行列は
code:tex
\begin{pmatrix}
\frac{2n}{r - l} & 0 & \frac{r+l}{r-l} & 0 \\
0 & \frac{2n}{t-b} & \frac{t+b}{t-b} & 0 \\
0 & 0 & \frac{n}{f-n} & \frac{nf}{f-n} \\
0 & 0 & -1 & 0
\end{pmatrix} ,
となる.
最初の行列の導出は参考文献に書いてあります.
参考文献
ゲームプログラミングのための 3D グラフィックス数学,ボーンデジタル,2009.