はじめに
こんにちは!セカンドライフが大好きななたでです(宣伝)。
今回は、前回に引き続き座標変換を勉強したいと思います。その中でも、ビュートランスフォームの部分の計算式に着目して調べていきたいと思います。また今回も、DirectXとOpenGLとで違いがあるのかという点に着目して比較していきます。
前回の関連記事
・3DCGの座標系の紹介
・DirectXとOpenGLの回転行列、回転軸、回転方向
DirextXのビュートランスフォーム
DirectXのヘルパー関数
ビュートランスフォームを作るために、DirectXでは次のヘルパー関数が用意されています。
matrix *D3DXMatrixLookAtLH( matrix *pOut, vector *pEye, vector *pAt, vector *pUp);
左手座標系ビュー行列を作成する
matrix *D3DXMatrixLookAtRH( matrix *pOut, vector *pEye, vector *pAt, vector *pUp);
右手座標系ビュー行列を作成する
DirectXのビュー行列
DirectXは左手座標系といわれていますが、右手座標系と左手座標系の両方の行列が用意されています。
引数のベクトルは、次の3つです。
・カメラの座標の位置ベクトル e
・カメラの注視点の位置ベクトル a
・カメラの上への方向ベクトル u
数式の意味について
D3DXMatrixLookAtLH
とD3DXMatrixLookAtRH
の違いは、最初のベクトルzを反転しているかしていないかとなっております。最初に出てくる主要なベクトルをまとめ、行列が何しているか調べていきます。
ベクトル z
カメラ座標から注視点座標への単位方向ベクトル。X から Y への方向ベクトルを求めるには、「 Y ― X 」となります。normalze(正規化)により距離を1にして単位方向ベクトルにしています。これが、ワールド座標系にて、カメラ座標系で使用したいz軸方向になります。ここでは、奥行きベクトル z と呼ぶことにしましょう。
ベクトル x
カメラの上向きのベクトル u と、奥行きベクトル z のクロス積です。クロス積は、ベクトルXとベクトルYに直行する単位方向ベクトルを計算することができます。左手座標系で、uとzのクロス積の結果は、右側への方向ベクトルになります。なお、右手座標系で、uとzのクロス積の結果は、左側への方向ベクトルになりますが、zを計算した時点で、右手座標系では値を反転させているため、この結果も右側への方向ベクトルになります。ここでは、右ベクトルxと呼ぶことにしましょう。(座標系の違いの話は、DirectXとOpenGLの回転行列、回転軸、回転方向を参照)
ベクトル y
奥行きベクトルzと、右ベクトルxのクロス積です。左手座標系で、zとxのクロス積の結果は、上側への方向ベクトルになります。これもまた、右手座標系で、zとxのクロス積の結果は、上側への方向ベクトルになりますが、zを計算した時点で、右手座標系では値を反転させているため、この結果も上側への方向ベクトルになります。ここでは、上ベクトルyと呼ぶことにしましょう。
ビュー行列の回転行列
ビュー行列の左上の3×3がベクトル x, y, zとなっております。ここはカメラが向く回転情報となり、回転行列となります。つまり、上のクロス積などの計算はこの回転行列を求めていたこととなります。
ビュー行列の移動行列
ビュー行列の下のeがある部分が移動行列となります。カメラの座標に、 x, y, zでドット積をしているのですが、各方向成分を抜き出すことに相当します。通常、カメラの位置まで移動させてから回転の場合は、カメラの座標まで引き算すればいいのですが、今回は、回転させてからカメラの位置まで移動させるということをしているため、ドット積になっています。
参考
- matrix *D3DXMatrixLookAtLH( matrix *pOut, vector *pEye, vector *pAt, vector *pUp);
- matrix *D3DXMatrixLookAtRH( matrix *pOut, vector *pEye, vector *pAt, vector *pUp);
OpenGLのビュートランスフォーム
OpenGLのヘルパー関数
OpenGLでは、次のヘルパー関数が用意されています。
matrix gluLookAt( vector &eye, vector ¢er, vector &up )
ビュー行列を作成する
OpenGLのビュー行列
OpenGLは、右手座標系です。従って、ビュー行列は、DirectXのD3DXMatrixLookAtRH
と同等のはずですが、上記のリンク先の式が少し違うように見えます。一度、書いてある式をまとめてみましょう。
掛ける順序をDirectXに合わせて式変形する
ここで、OpenGLの行列は、DirectXと比べると転置行列となっているため、DirectXの式と比較できるよう転置させます。
さらに、ベクトル z を反転させてみましょう。反転させたあとに、xとyの値は以前のままとしたいため、クロス積の計算順序を反転させます。
このように変形させると、D3DXMatrixLookAtRH
と同じ式であることが分かります。
参考
おわりに
これでDirectXとOpenGLの違いシリーズの第2弾は終わりです。今回は、ビュートランスフォームの違いを見てみました。OpenGLのgluLookAt
は、DirectXのD3DXMatrixLookAtRH
は一見違うような行列ですが、本質は同じでした。今度は、プロジェクショントランスフォーム、ビューポート変換などに違いがないか、調べていきたいです。
以上、ありがとうございました!
コメント