行列変換は、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 次元配列として宣言します。 次の例は、均一なスケーリング マトリックス (スケール ファクター "s") として機能するように D3DMATRIX 構造体を初期化する方法を示しています。
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 回転行列の数式を
これらの行列の例では、ギリシャ文字 theta は回転角度をラジアンで表します。 角度は、原点に向かって回転軸に沿って見るときに時計回りに測定されます。
次のコードは、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₁ から Mn は個々の行列です。 ほとんどの場合、連結される行列は 2 つまたは 3 つだけですが、制限はありません。
行列乗算が実行される順序は非常に重要です。 上記の数式は、行列連結の左から右の規則を反映しています。 つまり、複合行列の作成に使用するマトリックスの可視効果は、左から右の順序で発生します。 一般的なワールド マトリックスを次の例に示します。 あなたは、典型的な空飛ぶ円盤の世界のマトリックスを作成していると想像してください。 あなたはおそらく、その中心(モデル空間のy軸)を中心に飛ぶソーサーを回転させ、それをシーン内の他の場所に翻訳したいと思うでしょう。 この効果を実現するには、次の式に示すように、最初に回転行列を作成し、それを平行移動行列で乗算します。
スピンの方程式 に基づいている。
この式では、Ry は y 軸を中心に回転するための行列であり、Tw はワールド座標内のある位置への平行移動です。
行列を乗算する順序は重要です。これは、2 つのスカラー値を乗算するのとは異なり、行列乗算は可換ではないためです。 行列を逆の順序で乗算すると、空飛ぶソーサーをワールド空間の位置に変換し、ワールド原点を中心に回転させる視覚効果があります。
作成するマトリックスの種類に関係なく、予想される効果を確実に得られるように、左から右のルールを覚えておいてください。
関連トピック