ホーム < ゲームつくろー! < DirectX技術編 < クォータニオンを学んでみよう!


その11 カメラの正面を向くビルボード


 ビルボード(Billboard)は板ポリゴンに貼り付けられた看板です。本当に看板として扱っても良いのですが、アルファブレンドによる加算合成等を用いると非常に美しい効果を作る事が出来ます。

 多くの局面で、ビルボードをカメラの正面を常に向かせる必要に駆られます。この計算は少し面倒です。しかし、Direct3Dの関数を用いるとびっくりするほど簡単になります。ここではビルボードをカメラ方向に向かせる方法を紹介します。



@ 決め手はビュー行列

 DirectXのカメラは実は「固定」されています。XYZ座標の原点にありZ軸方向を眺めています。自由なカメラワークは、カメラを動かしているのではなく、実はワールドにあるオブジェクトをごっそり動かして実現しています。大胆不敵です。
 そのカメラ目線にオブジェクトを強引に動かす行列が「ビュー行列」です。この行列は平行移動や回転の入った立派な頂点変換行列です。この行列によってワールドに配置されたオブジェクトは再び動かされるのです。

 さて、ビュー行列によってオブジェクトが+90度回転させられるとします。ということは、このオブジェクトが最初から-90度回転してワールドに配置されていれば、回転が打ち消されてオブジェクトはカメラの正面を向く事になります。つまり、ビュー行列から平行移動やスケール部分をごっそり取り除き、回転部分だけを逆にし、それをワールド変換行列の回転行列とすれば、ビルボードの問題はあっさり解決してしまいます。

 ビュー変換行列は十中八九は「D3DXMatrixLookAtRH 関数」もしくは「D3DXMatrixLookAtLH 関数」を用いて作成していると思います。例としてD3DXMatrixLookAtLH関数を見てみます。

D3DXMatrixLookAtLH 関数
D3DXMATRIX *D3DXMatrixLookAtLH(      
   D3DXMATRIX *pOut,
   CONST D3DXVECTOR3 *pEye,
   CONST D3DXVECTOR3 *pAt,
   CONST D3DXVECTOR3 *pUp
);

pOutにビュー行列が返ります。pEyeはカメラの位置、pAtはカメラの見つめる点、そしてpUpがカメラの上方向です。

では、いつもカメラの正面を向く回転行列を作成します。
 まずpEyeを原点にします。これで純粋に回転行列のみとなります。pAtをカメラの視線ベクトルの逆に設定します。視線ベクトルはカメラの位置とカメラの見つめる点から簡単に計算できますね。pUpはカメラの上方向をそのまま適用します。こうして出来た回転行列の「逆行列を求めます」。ここが肝です。逆行列はDirect3DXのD3DXMatrixInverse関数でさっくり計算できます。4次の行列の逆行列計算は胃が痛いものですから、ありがたいです。そうして求めた行列をビルボードのワールド変換行列を作成する際の回転行列として適用すると、ビルボードはカメラの目線方向に常に向くようになります。

 Direct3DXのヘルパー関数を用いた実際の回転行列取得プログラムはなんとたったのこれだけです。

// カメラと対峙する回転行列を取得
D3DXMATRIX GetInvRotateMat()
{
   D3DXMATRIX Inv;
   D3DXMatrixIdentity(&Inv);
   D3DXMatrixLookAtLH(&Inv, &D3DXVECTOR3(0,0,0), &GetLookAtVct(), &m_UpVct);
   D3DXMatrixInverse(&Inv, NULL, &Inv);

   return Inv;
}

これでビルボードを扱うのが楽しくなってきます(^-^)

 ただし、ローカル座標でビルボードをY軸を上にして立たせておく必要があります。固定されたカメラの上方向と一致させるためです。これが異なるとあらぬ方向を向いてくれます。それもそれで楽しかったりしますが・・・。