ビューポート変換行列

最終更新日23 Jun 2017 02:58

正規デバイス座標系1からウィンドウ座標系に変換するための行列
glViewPort(左下x,左下y,width,height)を使っておこなう。大体はこんなかんじで使う

glViewPort(0,0,width,height);

glDepthRange(near,far)という関数でデプスレンジも決められるようだ。デフォルトでは0.0~1.0になっている。
これを使うとデプスバッファへの詰め方が変わるようだ。使ったことないけど。
正規デバイス座標系(NDC)からウィンドウ座標系への変換は線形である。

NDC ウィンドウ座標系 具体的な値
x -1 x 0
x 1 x+w width
y -1 y 0
y 1 y+h height
z -1 n 0.001
z 1 f 1000

行列としてまとめるとこうなる

glViewPort(xoff , yoff ,w,h);

と関数の引数を渡したとする

(1)
\begin{align} \left( \begin{array}{c} x_{win}\\ y_{win}\\ z_{win}\\ \end{array} \right) = \left( \begin{array}{cccc} \frac{w}{2}&0&0&(x_{off}+\frac{w}{2})\\ 0&\frac{h}{2}&0&(y_{off}+\frac{h}{2})\\ 0&0&\frac{f-n}{2}&(\frac{f+n}{2})\\ 0&0&0&1 \end{array} \right) \begin{pmatrix} x_{NDC}\\ y_{NDC}\\ z_{NDC}\\ 1 \end{pmatrix} =\begin{pmatrix} \frac{w}{2}x_{NDC}+(x_{off}+\frac{w}{2})\\ \frac{h}{2}y_{NDC}+(y_{off}+\frac{h}{2})\\ \frac{f-n}{2}z_{NDC}+(\frac{f+n}{2})\\ 1 \end{pmatrix} \end{align}

逆変換

(2)
\begin{align} \left[ \begin{array}{cc} x_{ndc} \\ y_{ndc} \\ z_{ndc} \\ w_{ndc}\\ \end{array} \right] = \left[ \begin{array}{cc} \frac{2(x_{win}-x_{off})}{w}-1 \\ \frac{2(y_{win}-y_{off})}{h}-1 \\ \frac{2z_{win}}{f-n}-1 \\ 1\\ \end{array} \right] \end{align}

zの変換

ndczからwindow座標のzにするには
単純に範囲を-1~1→near~farの範囲にするような変換を施せばよい[1]
順にステップを踏むと、

  1. *1/2+1/2して0~1の範囲にする。
  2. *(f-n)にして範囲を0~(f-n)の範囲にする
  3. +nしてn~fの範囲にする
(3)
\begin{align} z_{win} = (z_{ndc}\frac{1}{2}+\frac{1}{2})(f-n)+n \end{align}

これをまとめるとこんな式になる

(4)
\begin{align} z_{win}=\frac{f-n}{2}z_{ndc}+\frac{f-n}{2}+\frac{2n}{2}\\ =\frac{f-n}{2}z_{ndc}+\frac{f+n}{2} \end{align}
Bibliography

unproject viewing-pipeline viewport


ファイル

サポートサイト Wikidot.com unprojectviewing-pipelineviewport