次の方法で共有


変換 (Direct3D 9)

固定関数ジオメトリ パイプラインを介してジオメトリをプッシュする Direct3D の部分は、変換エンジンです。 ワールド内でモデルとビューアーを検索し、画面上に表示する頂点を投影し、頂点をビューポートにクリップします。 また、変換エンジンは、各頂点の拡散および反射コンポーネントを決定するための照明計算も実行します。

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

パイプラインの先頭では、モデルの頂点はローカル座標系に対して相対的に宣言されます。 これは、ローカル原点と方向です。 この座標の向きは、多くの場合、モデル空間と呼ばれ、個々の座標はモデル座標と呼ばれます。

ジオメトリ パイプラインの最初のステージでは、モデルの頂点がローカル座標系から、シーン内のすべてのオブジェクトによって使用される座標系に変換されます。 頂点の向きを変更するプロセスは、ワールド変換と呼ばれます。 この新しい向きは、一般にワールド空間と呼ばれ、ワールド空間内の各頂点はワールド座標を使用して宣言されます。

次のステージでは、3D ワールドを記述する頂点がカメラに対して向いています。 つまり、アプリケーションはシーンの視点を選択し、ワールド空間座標が再配置され、カメラのビューの周りに回転され、ワールド空間がカメラ空間に変わります。 これがビュー変換です。

次のステージは、プロジェクション変換です。 パイプラインのこの部分では、オブジェクトは通常、シーンに奥行きの錯覚を与えるために、ビューアーからの距離に関連してスケーリングされます。閉じるオブジェクトは、離れたオブジェクトよりも大きく表示されます。 わかりやすくするために、このドキュメントでは、投影変換の後に頂点が存在する空間を投影空間とします。 一部のグラフィックス ブックでは、投影空間をポストパースペクティブの同種空間と見なす場合があります。 すべてのプロジェクション変換でシーン内のオブジェクトのサイズがスケーリングされるわけではありません。 このような投影は、アフィン投影または直交投影と呼ばれることもあります。

パイプラインの最後の部分では、画面に表示されない頂点が削除されるため、ラスタライザーは決して表示されないものに対する色と網かけの計算に時間がかかりません。 このプロセスはクリッピングと呼ばれます。 クリッピング後、残りの頂点はビューポートパラメーターに従ってスケーリングされ、画面座標に変換されます。 シーンがラスタライズされるときに画面に表示される結果の頂点は、画面空間に存在します。

変換は、ある座標空間から別の座標空間にオブジェクト ジオメトリを変換するために使用されます。 Direct3D では、マトリックスを使用して 3D 変換を実行します。 このセクションでは、マトリックスが 3D 変換を作成する方法、変換の一般的な用途、および複数の変換を含む 1 つの行列を生成するためにマトリックスを結合する方法について詳しく説明します。

行列変換

3D グラフィックスを使用するアプリケーションでは、ジオメトリ変換を使用して次の操作を行うことができます。

  • オブジェクトの位置を別のオブジェクトに対して相対的に表します。
  • オブジェクトを回転およびサイズ変更します。
  • 表示位置、方向、およびパースペクティブを変更します。

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

点を別の点に変換する式

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

新しい点する

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

マトリックスは行列の順序で書き込まれます。 各軸に沿って頂点を均等にスケーリングする行列 (均一スケーリングと呼ばれます) は、数学表記を使用して次の行列で表されます。

均一なスケーリング式

C++ では、Direct3D は、D3DMATRIX 構造体を使用して、行列を 2 次元配列として宣言します。 次の例は、均一なスケーリング マトリックスとして機能するように D3DMATRIX 構造体を初期化する方法を示しています。

// In this example, s is a variable of type float.

D3DMATRIX scale = {
    s,               0.0f,            0.0f,            0.0f,
    0.0f,            s,               0.0f,            0.0f,
    0.0f,            0.0f,            s,               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

便宜上、D3DX ユーティリティ ライブラリは、D3DXMatrixTranslation 関数を提供します。

規模

次の式では、x、y、z 方向の任意の値によって、新しい点 (x'、y'、z') にポイント (x、y、z) がスケーリングされます。

新しいポイントする

回転

ここで説明する変換は左手座標系用であるため、他の場所で見た変換行列とは異なる場合があります。

次の式は、x 軸を中心に点 (x,y, z) を回転させ、新しい点 (x', y', z') を生成します。

新しい点する

次の式は、y 軸を中心に点を回転させます。

新しい点する

次の式は、z 軸を中心に点を回転させます。

新しい点する

これらの行列の例では、ギリシャ文字 theta は回転角度をラジアンで表します。 角度は、原点に向かって回転軸に沿って見るときに時計回りに測定されます。

C++ アプリケーションでは、D3DX ユーティリティ ライブラリによって提供される D3DXMatrixRotationXD3DXMatrixRotationY、および D3DXMatrixRotationZ 関数を使用して回転行列を作成します。 D3DXMatrixRotationX 関数のコードを次に示します。

D3DXMATRIX* WINAPI D3DXMatrixRotationX
    ( D3DXMATRIX *pOut, float angle )
{
#if DBG
    if(!pOut)
        return NULL;
#endif

    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 つだけですが、制限はありません。

行列乗算を実行するには、D3DXMatrixMultiply 関数を使用します。

行列乗算が実行される順序は非常に重要です。 上記の数式は、行列連結の左から右の規則を反映しています。 つまり、複合行列の作成に使用するマトリックスの可視効果は、左から右の順序で発生します。 一般的なワールド マトリックスを次の例に示します。 あなたは、ステレオタイプの空飛ぶソーサーのワールドマトリックスを作成しているとします。 あなたはおそらく、その中心(モデル空間のy軸)を中心に飛ぶソーサーを回転させ、それをシーン内の他の場所に翻訳したいと思うでしょう。 この効果を実現するには、次の式に示すように、最初に回転行列を作成し、それを平行移動行列で乗算します。

回転行列と平行移動行列する

この式では、Ry は y 軸を中心に回転するための行列であり、Tw はワールド座標内のある位置への平行移動です。

行列を乗算する順序は重要です。これは、2 つのスカラー値を乗算するのとは異なり、行列乗算は可換ではないためです。 行列を逆の順序で乗算すると、空飛ぶソーサーをワールド空間の位置に変換し、ワールド原点を中心に回転させる視覚効果があります。

作成するマトリックスの種類に関係なく、予想される効果を確実に得られるように、左から右のルールを覚えておいてください。

作業の開始