変換の概要

3D グラフィックスの多くの低レベル数学演算は、行列変換によって処理されます。

ジオメトリ パイプラインは、頂点を入力として受け取ります。 変換エンジンは、ワールド変換、ビュー変換、射影変換を頂点に適用し、結果をクリッピングして、すべてをラスタライザーに渡します。

変換と空間 説明
モデル空間内のモデル座標 パイプラインの最初の処理では、モデルの頂点はローカル座標系を基準として相対的に宣言されます。 これはローカルの原点と方向です。 この座標の方向は、一般に "モデル空間" と呼ばれます。 個々の座標は "モデル座標" と呼ばれます。
ワールド空間へのワールド変換 ジオメトリ パイプラインの最初のステージでは、モデルの頂点が、ローカル座標系からシーン内のすべてのオブジェクトで使われる座標系に変換されます。 頂点の方向を再設定する処理はワールド変換と呼ばれ、モデル空間から "ワールド空間" という新しい方向への変換が行われます。 ワールド空間内の各頂点は、"ワールド座標" を使って宣言されます。
ビュー空間 (カメラ空間) へのビュー変換 次のステージでは、3D ワールドを記述する頂点が、カメラを基準とする方向に変換されます。 つまり、アプリケーションでシーンの視点を選択すると、ワールド空間座標が再配置されてカメラの視点を中心に回転し、ワールド空間から "ビュー空間" ("カメラ空間" とも呼ばれます) に切り替わります。 これが、ワールド空間からビュー空間に変換するビュー変換です。
射影空間への射影変換 次のステージは射影変換です。これにより、ビュー空間から射影空間への変換が行われます。 パイプラインのこの部分では、シーンに奥行き感を与えるために、オブジェクトが通常はビューアーからの距離に基づいてスケーリングされます。つまり、近くのオブジェクトは遠くのオブジェクトよりも大きく見えるように調整されます。 わかりやすくするために、このドキュメントでは、射影変換後に頂点が存在する空間を "射影空間" と呼びます。 グラフィックスの解説書によっては、射影空間を "透視射影変換後の同次空間" と呼ぶ場合もあります。 すべての射影変換でシーン内のオブジェクトのサイズが変更されるとは限りません。 このような射影は、"アフィン変換" や "直行変換" と呼ばれることがあります。
スクリーン空間でのクリッピング パイプラインの最後の部分では、画面に表示されない頂点がすべて削除されます。これにより、表示されないオブジェクトの色や影の計算にラスタライザーが時間を費やすことはなくなります。 このプロセスを "クリッピング" と呼びます。 クリッピング後、残りの頂点はビューポート パラメーターに従ってスケーリングされ、スクリーン座標に変換されます。 結果として得られる頂点は "スクリーン空間" に存在し、シーンがラスタライズされるときに画面に表示されます。

 

変換は、オブジェクト ジオメトリをある座標空間から別の座標空間に変換するために使われます。 Direct3D では、行列を使って 3D 変換を実行します。 行列は 3D 変換を作成します。 複数の行列を結合することで、複数の変換を含む 1 つの行列を作成できます。

モデル空間、ワールド空間、ビュー空間の間で座標を変換することができます。

  • ワールド変換 - モデル空間からワールド空間に変換します。
  • ビュー変換 - ワールド空間からビュー空間に変換します。
  • 射影変換 - ビュー空間から射影空間に変換します。

行列変換

3D グラフィックスを使用するアプリケーションでは、幾何学変換を使って次の操作を実行できます。

  • オブジェクトの位置を、別のオブジェクトからの相対的な位置で表現する。
  • オブジェクトを回転し、サイズを変更する。
  • 視点、向き、奥行きを変更する。

次の方程式に示すように、4x4 行列を使うことで任意の点 (x,y,z) を別の点 (x', y', z') に変換できます。

任意の点を別の点に変換する方程式

(x, y, z) と行列に対して次の方程式を実行すると、点 (x', y', z') が生成されます。

新しい点を求める方程式

最も一般的な変換は、平行移動、回転、スケーリングです。 これらの効果を生成する行列を結合して 1 つの行列にすると、複数の変換を一度に計算できます。 たとえば、一連の点に平行移動と回転を適用する 1 つの行列を作成することができます。

行列は、行、列の順番に記述されます。 各軸に対して頂点を均等にスケーリングする処理は均等スケーリングと呼ばれ、これを実行する行列は数学的に次のように表記されます。

均等スケーリングの行列を表す式

C++ の場合、Direct3D は行列構造体を使って、行列を 2 次元配列として宣言します。 次の例は、D3DMATRIX 構造体を初期化して、均等スケーリング行列 (スケール ファクター "s") として動作するように設定する方法を示しています。

D3DMATRIX scale = {
    5.0f,            0.0f,            0.0f,            0.0f,
    0.0f,            5.0f,            0.0f,            0.0f,
    0.0f,            0.0f,            5.0f,            0.0f,
    0.0f,            0.0f,            0.0f,            1.0f
};

平行移動

次の方程式は、点 (x, y, z) を新しい点 (x', y', z') に平行移動します。

新しい点を求める平行移動行列の方程式

C++ では、平行移動行列を手動で作成することができます。 次の例は、頂点を平行移動する行列を作成する関数のソース コードを示しています。

D3DXMATRIX Translate(const float dx, const float dy, const float dz) {
    D3DXMATRIX ret;

    D3DXMatrixIdentity(&ret);
    ret(3, 0) = dx;
    ret(3, 1) = dy;
    ret(3, 2) = dz;
    return ret;
}    // End of Translate

スケーリング

次の方程式は、点 (x, y, z) を x 方向、y 方向、z 方向に任意の値でスケーリングして、新しい点 (x', y', z') を求めます。

新しい点を求めるスケーリング行列の方程式

回転

ここで説明する変換は左手座標系を想定しているため、他の場所に記述されている変換行列とは異なる場合があります。

次の方程式は、x 軸を中心に点 (x, y, z) を回転し、新しい点 (x', y', z') を求めます。

新しい点を求める x 軸回転行列の方程式

次の方程式は、y 軸を中心に点を回転します。

新しい点を求める y 軸回転行列の方程式

次の方程式は、z 軸を中心に点を回転します。

新しい点を求める z 軸回転行列の方程式

これらの行列の例において、ギリシャ文字シータはラジアン単位の回転角度を表しています。 角度は、回転軸に沿って原点を見た状態で時計回りに測定されます。

次のコードは、X 軸周りの回転を処理する関数を示しています。

    // Inputs are a pointer to a matrix (pOut) and an angle in radians.
    float sin, cos;
    sincosf(angle, &sin, &cos);  // Determine sin and cos of angle

    pOut->_11 = 1.0f; pOut->_12 =  0.0f;   pOut->_13 = 0.0f; pOut->_14 = 0.0f;
    pOut->_21 = 0.0f; pOut->_22 =  cos;    pOut->_23 = sin;  pOut->_24 = 0.0f;
    pOut->_31 = 0.0f; pOut->_32 = -sin;    pOut->_33 = cos;  pOut->_34 = 0.0f;
    pOut->_41 = 0.0f; pOut->_42 =  0.0f;   pOut->_43 = 0.0f; pOut->_44 = 1.0f;

    return pOut;
}

行列の連結

行列を使う利点の 1 つは、2 つ以上の行列を掛け合わせて、それらの効果を組み合わせることができる点にあります。 つまり、モデルを回転した後で別の場所へ平行移動する場合でも、2 つの行列を適用する必要はありません。 代わりに、回転行列と平行移動行列を掛け合わせて、両方の効果を含む合成行列を生成します。 このプロセスは行列の連結と呼ばれ、次の方程式によって記述できます。

行列の連結の方程式

この方程式では、C は作成される合成行列を表し、M ~ Mₙ は個々の行列を表します。 ほとんどの場合、連結される行列は 2 ~ 3 個だけですが、数に制限はありません。

行列の乗算を実行する順序は非常に重要です。 上の式は、行列が左から右へ連結されることを示しています。 つまり、合成行列の作成に使われる各行列の視覚効果は、左から右へ順番に適用されます。 ここで、典型的なワールド行列の例を考えてみましょう。 たとえば、よくある空飛ぶ円盤を表すワールド行列を作成するとします。 空飛ぶ円盤に期待されるのは、その中心点 (モデル空間の y 軸) で回転しながら、シーン内の別の場所に平行移動するという動作です。 この効果を実現するには、まず回転行列を作成し、それに平行移動行列を掛け合わせます。この方程式を次に示します。

回転行列と平行移動行列に基づく回転の方程式

この式では、Ry は y 軸周りの回転行列を表し、Tw はワールド座標の別の場所への平行移動を表します。

2 つのスカラー値を乗算する場合とは異なり、行列の乗算は非可換であるため、行列を乗算する順序には重要な意味があります。 行列を逆の順序で乗算すると、空飛ぶ円盤をワールド空間の場所へ平行移動させてから、ワールド原点を中心に回転させるという視覚効果になります。

どのような種類の行列を作成する場合でも、期待どおりの効果を得るためには、左から右という規則を覚えておくことが重要です。

変換