minMatrix.js と座標変換行列
座標変換行列の基本
座標変換は行列で表現できる
モデル変換行列はその名のとおり、描画されるモデルに対して影響を与えます。
モデルの位置、モデルの回転、モデルの拡大縮小(スケーリング)に関する情報を持たせるのが普通です。
三次元空間を撮影するカメラを定義するためのもの
カメラの位置、カメラの注視点、カメラの上方向を定義することで、カメラがどのように振舞うのかを決めます。
三つ目はプロジェクション変換行列です。この座標変換ではスクリーンの縦横比や、クリッピング領域などを定義します。また遠近法のような効果を得るためにもこの変換行列が必要になります。
これらのことを踏まえると、行列に対してどのような操作が必要になるのかおおよそ見えてきます。
あくまでも基本的な部分に限定されますが、minMatrix.js で出来ることについて見ていきましょう。
当サイトオリジナルの行列演算ライブラリである minMatrix.js では、
行列を生成したり、
あるいは行列に操作を加えたり
することができます。
matIV オブジェクトを生成するコード
var m = new matIV();
かなり機能が限定されたシンプル設計なのがわかると思います。手抜きとも言えますけれどもね……
行列変換の流れ
まずは、モデル変換行列だろうとビュー・プロジェクション変換行列だろうと、
行列自体を生成しなければ何もできません。
最初は matIV.create を実行して行列を生成しましょう。
生成した行列は、基本的に matIV.identity を通して初期化します。
ここまでをコードにすると、以下のようになりますね。
matIV オブジェクトを使った行列の初期化
code:js
// matIVオブジェクトを生成
var m = new matIV();
// 行列の生成と初期化
var Matrix = m.identity(m.create());
これで変数 Matrix は使える状態の行列になりました。
あとはこの初期化済み行列に対して、目的の操作を行なっていきます。
たとえば、モデル変換行列を用意したいとして、
モデルの座標を X 方向に 1.0 移動したモデル変換行列を生成するには次のようにします。
モデル変換行列に移動成分を与える例
code:js
var Matrix = m.identity(m.create());
このようなコードが実行されると、配列 Matrix には X 方向へ 1.0 移動したモデル変換行列が入っている状態になります。
同様に、回転やスケーリングなどを行うことが可能です。
ただし、ここで注意点があります。
それは、移動・回転・拡大縮小を行なう順序です。
移動してから回転するのと、回転してから移動するのでは、結果がまるで変わってきます。
これは、回転が原点(0.0, 0.0, 0.0)を中心に行なわれるためです。
モデル変換を行なう順序には十分に気を配りましょう。
具体的には、拡大縮小 > 回転 > 移動、という順序で変換を行なうようにすることで、回転・拡大縮小した状態のモデルを任意の位置に移動させることができるはずですね。
ただし、これで話は終わりません。
OpenGL は行列が列オーダーになっているため、掛け合わせる順序が真逆になります。
ベクトルに対して、拡大縮小 > 回転 > 移動で作用させればいいが、
列オーダーはmat * vecなので
移動行列 * 回転行列 * 拡大縮小行列 * vecとなる
見た目としては逆になるが、これは、
「列オーダーで、はベクトルに対して行列は左から作用するから」
であるのがわかる。
ビュー変換行列を生成するには matIV.lookAt を、
プロジェクション行列を生成するには matIV.perspective を使えばいいですね。
ここまでくると、モデル・ビュー・プロジェクションの各変換行列が生成されているはずですので、これら三つの行列を掛け合わせて最終的な座標変換行列を生成します。
配列同士を掛け合わせるには matIV.multiply を使えばいいですね。
座標変換行列は、モデル・ビュー・プロジェクションの頭文字を採って mvpMatrix などと表記されることが多いのですが、掛け合わせる順序は mvp ではなく、p > v > m の順序で掛け合わせます。
上の列オーダーの話に注意
minMatrix.js を用いた場合のコードの一例を示すと次のようになります。
座標変換行列を用意する際の例
code:js
// 各種行列の生成と初期化
var mMatrix = m.identity(m.create()); // モデル変換行列
var vMatrix = m.identity(m.create()); // ビュー変換行列
var pMatrix = m.identity(m.create()); // プロジェクション変換行列
var mvpMatrix = m.identity(m.create()); // 最終座標変換行列
// 各行列を掛け合わせる順序を示す一例
m.multiply(pMatrix, vMatrix, mvpMatrix); // p に v を掛ける
m.multiply(mvpMatrix, mMatrix, mvpMatrix); // さらに m を掛ける
ここまで見てきたような手順で、無事に座標変換行列が生成できたら、それを最終的に WebGL に通知します。その方法については次回以降、解説する予定です。
まとめ
今回は当サイトオリジナルの行列演算ライブラリである minMatrix.js の基本的な使い方と、座標変換行列を用意する手順を解説しました。
minMatrix.js では、 matIV というオブジェクトを介して行列を操作します。各種メソッドの内容は、今はよくわからなくても大丈夫です。必要なときになったら適宜解説を追加していきます。座標変換行列を生成できたらポリゴンをレンダリングできるところまであと少しです。
次回は、いよいよポリゴンが画面に映し出されるところまで解説します。