次の方法で共有


Direct3D 変換パイプライン

この記事では、Direct3D マトリックスを直接操作して Direct3D 変換パイプラインのパラメーターを設定する方法について、Direct3D アプリケーション開発者向けに技術的な説明を提供します。

概要

Direct3D では、3 つの変換を使用して 3D モデル座標をピクセル座標 (スクリーン空間) に変更します。 これらの変換は、ワールド変換、ビュー変換、射影変換です。

ワールド変換は、モデル座標をワールド座標に変換する方法を制御します。 ワールド変換には、平行移動、回転、スケーリングを含めることができますが、ライトには適用されません。 ワールド変換の操作の詳細については、「 World Transform」を参照してください。

ビュー変換は、ワールド座標から "カメラ空間" への切り替えを制御し、ワールド内のカメラの位置を決定します。 ビュー変換を操作する例については、「ビュー 変換」を参照してください。

プロジェクション変換では、ジオメトリがカメラ空間から "クリップ空間" に変更され、パースペクティブの歪みが適用されます。 "クリップ空間" という用語は、この変換中にジオメトリをビュー ボリュームにクリップする方法を指します。 プロジェクション変換の使用例については、「プロジェクション 変換」を参照してください。

最後に、クリップ空間内のジオメトリがピクセル座標 (画面空間) に変換されます。 この変換は、ビューポート設定によって制御されます。

クリッピングと変換の頂点は、同種の空間 (単に座標系に 4 番目の要素が含まれる空間) で行う必要がありますが、ほとんどのアプリケーションの最終的な結果は、"画面空間" で定義された非同種の 3 次元 (3D) 座標である必要があります。つまり、クリッピングを実行するには、入力頂点とクリッピング ボリュームの両方を同種の空間に変換し、表示する非同種空間に変換する必要があります。

ワールド変換、ビュー変換、プロジェクション変換の 3 つの Direct3D 変換は、Direct3D マトリックスによって定義されます。 Direct3D 行列は、 D3DMATRIX 構造体によって定義される 4 x 4 の同種行列です。 Direct3D マトリックスは標準オブジェクトではありませんが、COM インターフェイスで表されません。他の Direct3D オブジェクトと同様に作成して設定できます。 Direct3D マトリックスの詳細については、「 変換」を参照してください。

変換パイプライン

モデル座標の頂点が Pm = (Xm, Ym, Zm, 1) で指定された場合、次の図に示す変換は、計算画面座標 Ps = (Xs、Ys、Zs、Ws) に適用されます。

モデル空間から画面空間への変換

前の図に示したステージの説明を次に示します。

  1. ワールド 行列 Mworld は、モデル空間からワールド空間に頂点を変換します。 このマトリックスは、次の方法で設定されます。

        d3dDevice->SetTransform (D3DTRANSFORMSTATE_WORLD, matrix address) 
    

    Direct3D 実装では、このマトリックスの最後の列が (0、0、0、1) であると想定しています。 ユーザーが別の最後の列を持つ行列を指定したが、照明と霧が正しくない場合、エラーは返されません。

  2. ビュー マトリックス Mview は、ワールド空間からカメラ空間に頂点を変換します。 このマトリックスは、次の方法で設定されます。

        d3dDevice->SetTransform (D3DTRANSFORMSTATE_VIEW, matrix address) 
    

    Direct3D 実装では、このマトリックスの最後の列が (0、0、0、1) であると想定しています。 ユーザーが最後の列が異なるマトリックスを指定したが、照明と霧が正しくない場合、エラーは返されません。

  3. 投影行列 Mproj は、カメラ空間から投影空間に頂点を変換します。 このマトリックスは、次の方法で設定されます。

        d3dDevice->SetTransform (D3DTRANSFORMSTATE_PROJECTION, matrix address) 
    

    プロジェクション マトリックスの最後の列は、正しい霧と照明効果を得るための (0、0、1、0)、または (0、0、a、0) にする必要があります。(0, 0, 1, 0) 形が好ましい。

    投影空間内のすべてのポイント Xp = (Xp、Yp、Zp、Wp) のクリッピングボリュームは、次のように定義されます。

        -Wp < Xp <= Wp 
        -Wp < Yp <= Wp 
        0 < Zp <= Wp 
    

    これらの数式を満たさない点はすべてクリップされます。

    ビュー ボリュームが次のように定義されている場合:

    • カメラ空間の領域の領域に近い領域の Sw 画面ウィンドウの幅
    • 領域の近くにあるカメラ空間の Sh 画面ウィンドウの高さ
    • カメラ空間の Z 軸に沿って近いクリッピング平面までの Zn 距離
    • カメラ空間内の Z 軸に沿った遠方クリッピング平面への Zf 距離

    次に、透視投影行列を次のように記述できます。

    透視投影行列を示します。

    ここで、Mij は Mproj のメンバーです。

    直交投影の場合、次のようになります。

    直交投影

    Direct3D は、パースペクティブ プロジェクション マトリックスの形式が次の形式であることを前提としています。

    遠近投影マトリックス

    パースペクティブ投影マトリックスにこの形式がない場合は、いくつかの成果物が存在します。 たとえば、テーブル の霧は機能しません。

  4. Direct3D を使用すると、ユーザーは次のようにクリップ ボリュームを変更できます。

    クリップの音量を変更する

    これは、次のように書き換えることができます。

    書き換えられたクリップボリュームを変更する

    ここで、

        Cx, Cy - dvClipX, dvClipY from D3DVIEWPORT9  
        Cw, Ch - dvClipWidth, dvClipHeight from D3DVIEWPORT9  
        Zmin, Zmax - dvMinZ, dvMaxZ from D3DVIEWPORT9  
    

    この変換により、精度が向上し、クリッピング ボリュームのスケーリングとシフトに相当します。

    対応する Mclip 行列は次のとおりです。

    mclip マトリックス

    頂点は次の方法で変換されます。

        dvClipWidth = 2   
        dvClipHeight = 2   
        dvClipX = -1   
        dvClipY = 1   
        dvMinZ = 0   
        dvMaxZ = 1   
    

    クリップ ボリュームをスケーリングしない場合は、ビューポート パラメータを既定値に設定できます。

        (Xc, Yc, Zc, Wc) = (Xp, Yp, Zp, Wp) * Mclip   
    
  5. ユーザーが DrawPrimitive 呼び出しでD3DDP_DONOTCLIP フラグを指定する場合、クリッピング ステージは省略可能です。 この場合、すべてのマトリックス (Mvs を含む) を組み合わせることができます。

  6. ビューポート スケール マトリックス Mvs は、ビューポート ウィンドウ内にある座標をスケーリングし、Y 軸を上下に反転します。

    ビューポート スケール マトリックス mvs

    ここで、

        dwX, dwY - viewport offsets in pixels from D3DVIEWPORT9 
        dwWidth, dwHeight - viewport width and height in pixels from D3DVIEWPORT9    
    
  7. 最後に、画面座標が計算され、ラスタライザーに渡されます。

    画面座標を計算し、ラスタライザーに渡す

使用に関するヒント

Direct3D 変換パイプラインの使用方法に関するヒントを次に示します。

  • ワールド マトリックスとビュー マトリックスの最後の列は (0、0、0、1)、または照明が正しくありません。

  • 必要な内容を正確に理解していない限り、ビューポート パラメーターを設定して ID Mclip マトリックスを作成します。

        dvClipWidth = 2 
        dvClipHeight = 2
        dvClipX = -1
        dvClipY = 1
        dvMinZ = 0 
        dvMaxZ = 1