平行投影とは
ビュー座標系からクリッピング座標系への変換を投影変換といい、平行投影とはその1種です。
具体的には、空間上に直方体(視体積)を定め、それを原点が中心とした辺の長さが2の直方体(標準視体積)へ移す変換のことです。
ビュー座標系の視体積が直方体なら、「平行投影」で、錐台の時は「透視投影」と言います。(透視投影のときは、視体積と言わず視錐台ということもあるようです。)
クリッピング座標系と正規化デバイス座標系
クリッピング座標系は4次元です。なので、図示ができません。
それを標準座標に直した(xyz成分をw成分で除算した)のが正規化デバイス座標系です。
本記事では、平行投影に関する説明ですが、ビュー座標系における視体積を正規化デバイス座標系の標準視体積に変換することで求めます。
平行投影変換行列
ビュー座標系は右手座標系、正規化デバイス座標系は左手座標系とします。
ビュー座標系における視体積のxyz軸の最小値最大値をそれぞれ とします。
まずは、zを-1倍することにより、右手座標系から左手座標系へ変換します。
この変換で、 となります。
次に、視体積の中心を原点に移します。
この変換前の視体積の中心の座標は、 です。
このときの変換行列 は以下のようになります。
最後に、視体積の辺の長さを2にします。
この変換前の視体積のxyz軸の長さは、 です。
このときの変換行列 は以下のようになります。
求める平行投影の変換行列を とします。それは、 を掛け合わせたものとなります。
near,farの値は何を渡せばよいのか?
検算すると、 が へ、 が へ移ります。
よって、 と渡してください。
z反転に関する考察
平行投影変換行列によって、 が へ、 が へ移るんですが、これは望んだ変換ではありませんよね。
これを解決する、すなわち、 を へ、 を に移すには、 の行列の右側にz反転する行列を掛ければよいです。
ですがそうしなかったのは、平行投影変換行列といえば の形が一般的だからです。
WebGL/OpenGLはGPUに自分で作成した行列が渡せますので、 の形が使いたくない人は、自身で作成してみてください。
は上図を見てもらえばわかりますが、前方面を 、後方面を とする視体積を標準視体積に変換するだけですから、
前方面、後方面についているマイナスを呼び出す側で相殺(-1をかける)しなければならないというわけです。