しゅみぷろ読者になるしゅみぷろプログラミングとかこの広告は、90日以上更新していないブログに表示しています。Algebraはじめに基礎から勉強し直しています(というより基礎すらままならない状態なので...)。ビューイングパイプラインについて簡単にですがメモしておこうと思います。変換行列や各座標系に関してはDirectXやOpenGLで多少違いがあるので注意が必要です。ここで紹介する変換行列は列優先(OpenGL系)ですが、行優先(DirectX)の場合は行列とベクトルの順序が変わることになり、それに伴って変換行列を転置させる必要があります。変換行列の合成についても、掛け合わせる順序が変わってきます。UV座標もOpenGLとDirectXで異なり、OpenGLの場合原点は左下、DirectXの場合は左上になります。標準視体積についても多少違いがあり、本記事ではOpenGLでの標準視体積を紹介しています。この他にも様々な違いがあります。右手系と左手系デカルト座標で、上図のように右手系、左手系を区別します。両者はZ軸を基準に鏡に映すようにして変換することで要素を読み替えることができます(chirality)。座標系WorldSpaceScene内の全てのオブジェクトを含む空間。空間内でのオブジェクトの絶対的な位置を示す座標系。この空間内のオブジェクトをViewSpaceに変換することをView変換といいます。ModelSpace特定のオブジェクトが持つ固有の座標系。この空間内のオブジェクトをWorldSpaceに変換することをModel変換といいます。ViewSpaceカメラを基準とした座標系。この空間内のオブジェクトをProjectionSpaceに変換することをProjection変換といいます。Projection変換は正規化ビューボリュームを計算(ビューボリュームのScale変換)正規化ビューボリュームを投影(正規化デバイス座標の計算)といったことを行っています。Projection変換したジオメトリは同次座標であるため通常座標を求めるにはジオメトリの第四要素の$w$値で割る必要があります($w$で割った後の$(−1≤x≤1,−1≤y≤1,−1≤z≤1)$の空間を正規化デバイス座標と言います。ProjectionSpaceビューボリュームをProjection変換し、正規化デバイス座標に直した空間です。この空間内のジオメトリをScreenSpaceに変換することをScreen変換といいます。ScreenSpace画面左上(OpenGL系では画面左下)を原点として、画面の解像度に対応したピクセル位置を単位とする2Dデカルト座標系です。ViewportSpaceScreenSpaceを正規化した座標です。t_y\]ここで、\(t_x,t_y\)は\(x,y\)方向の移動量です。原点を中心とした変換が行われます。cos\theta\end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}\]拡大・縮小\[\begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}s_x&0\\0&s_y\end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}\]平行移動のみ変換を行列の積で表現できないため不便です。全て(平行移動を含め)行列の積で表すことができるようになります。同次座標系では、通常座標において\((x,y)\)と表す位置を実数\(w(w\not=0)\)を用いて\((wx,wy,w)\)と表します。通常座標の\((5,7)\)は同次座標では\((5,7,1),(10,15,2),...\)と複数の表し方があります。簡単のため、普通は\(w=1\)とし、2次元の場合\((x,y,1)\)と書きます。3次元の場合は\((x,y,z,1)\)と書きます。\[\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}1&0&t_x\\0&1&t_y\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}=T(t_x,t_y)\begin{bmatrix}x\\y\\1\end{bmatrix}\]回転\[\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}cos\theta&-sin\theta&0\\sin\theta&cos\theta&0\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}=R(\theta)\begin{bmatrix}x\\y\\1\end{bmatrix}\]拡大・縮小\[\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}s_x&0&0\\0&s_y&0\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}=S(s_x,s_y)\begin{bmatrix}x\\y\\1\end{bmatrix}\]\(平行移動変換行列をT(t_x,t_y)、回転行列をR(\theta)、拡大・縮小行列をS(s_x,s_y)としています。\)アフィン変換2次元の幾何学的変換の一般的な行列表現は\[\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}a&b&c\\d&e&f\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}\]で、このような座標変換をアフィン変換と呼びます(最下段は一番右のみ1で他は0。これにより幾何学的性質が保たれる)。3次元の場合は\[\begin{bmatrix}x'\\y'\\z'\\1\end{bmatrix}=\begin{bmatrix}a&b&c&d\\e&f&g&h\\i&j&k&l\\0&0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}\]のようになります。点Pに、最初に\(A_1\)、次に\(A_2\)、最後に\(A_3\)の変換を行う場合\[P'=A_3A_2A_1P\]となります。-sin\theta&0&cos\theta&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}=R_y(\theta)\begin{bmatrix}x\\y\\z\\1\end{bmatrix}\]z軸まわりの回転\[\begin{bmatrix}x'\\y'\\z'\\1\end{bmatrix}=\begin{bmatrix}cos\theta&-sin\theta&0&0\\sin\theta&cos\theta&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}=R_z(\theta)\begin{bmatrix}x\\y\\z\\1\end{bmatrix}\]拡大・縮小\[\begin{bmatrix}x'\\y'\\z'\\1\end{bmatrix}=\begin{bmatrix}s_x&0&0&0\\0&s_y&0&0\\0&0&s_z&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}=S(s_x,s_y,s_z)\begin{bmatrix}x\\y\\z\\1\end{bmatrix}\]これらは全て3次元アフィン変換です。透視投影変換Model変換、View変換は3次元同次座標変換で取り上げた変換行列の組み合わせによって成ります。Projection変換に関しては3次元アフィン変換以外に3次元射影変換(後述)が必要になります。今回は透視投影の場合のProjection変換について見ていきます。視点から投影面までの距離を$d$とし、投影面の$x$方向の大きさを$2a$、$y$方向の大きさを$2b$とします。ビューボリューム(カメラの視錐台領域)のクリッピング領域の$z$値をそれぞれ$z_{min}$、$z_{max}$とします。1)$の正方形になるようにビューボリュームを拡大・縮小したものです。\]を掛け合わせます。\]を掛け合わせます。$X',Y'$はもとの$x,y$から変化しないことに注目してください。$W'$は$z$の値がそのまま代入されることにも注目です。この変換で求められる座標は同次座標(変換行列$P(\widetilde{z}_{min})$の最下段に注目。アフィン変換ではなく射影変換。)であるため、通常座標に直すために求まった$X',Y',Z'$を$W'$で割る必要があります(この$W'$で割って通常座標を求めるという過程はProjection変換に含まれません)。頂点シェーダーの入出力と$w$頂点シェーダにはローカル座標にある頂点がそのまま入ってきます(POSITION/SV_POSITIONセマンティクス)。スクリーンにポリゴンを投影させるためには、ローカル座標の頂点にModel変換、View変換、Projection変換(MVP行列)を掛け算します。それを頂点シェーダの出力頂点として出力します。これでモデルはちゃんと画面に出ます(頂点シェーダーで明示的に$w$で割っていない!)。先に述べてきたように、ローカル座標にある頂点にMVP行列を掛け算すると、$w$で割る前の視錐台空間内の同次座標になります。頂点シェーダの出力頂点座標は、視錐台空間内の同次座標だったわけです。頂点シェーダを抜けた頂点(POSITION/SV_POSITIONセマンティクスのついたもの)はそこで初めてGPUによって$w$で割り算され、スクリーンの投影位置が確定し、どの点を穿つべきか決められてピクセルシェーダに情報が伝わります。(ホモグラフィ)は平面を別の平面に射影することができる変換です。斜めから見たものを、もし正面から見たらどうなるかを計算できます。3次元射影変換の一般形は\[\begin{bmatrix}X'\\Y'\\Z'\\W'\end{bmatrix}=\begin{bmatrix}a&b&c&d\\e&f&g&h\\i&j&k&l\\m&n&o&p\end{bmatrix}\begin{bmatrix}X\\Y\\Z\\W\end{bmatrix}\]です。サンプルは上のリンクから。)はてなブログをはじめよう!es_programさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。