ジオメトリ ブレンド (Direct3D 9)

Direct3D を使用すると、セグメント化された多角形オブジェクト (特に文字) をスムーズにブレンドしたジョイントをレンダリングすることで、シーンのリアリズムを向上できます。 これらの効果は、多くの場合、スキニングと呼ばれます。 この効果を実現するには、1 つの頂点セットに追加のワールド変換行列を適用して複数の結果を作成し、結果の頂点間で線形ブレンドを実行してレンダリング用の 1 つのジオメトリ セットを作成します。 バナナの次の図は、このプロセスを示しています。

バナナテクスチャと2つのオブジェクトをブレンドするプロセスのイラスト

上の図は、ジオメトリ ブレンドプロセスを想像する方法を示しています。 1 回のレンダリング呼び出しで、システムはバナナの頂点を受け取り、2 回 (変更なしで 1 回、単純な回転で 1 回) 変換し、結果をブレンドして曲がったバナナを作成します。 照明を有効にすると、頂点の位置と頂点法線がブレンドされます。 アプリケーションは 2 つのブレンド パスに限定されません。Direct3D では、標準のワールド マトリックスを含む 4 つのワールド マトリックス間でジオメトリ をブレンドD3DTS_WORLD

Note

照明を有効にすると、頂点法線は、頂点位置計算と同じ方法で重み付けされた、対応する逆ワールド ビュー 行列によって変換されます。 D3DRS_NORMALIZENORMALSレンダリング状態が TRUE に設定されている場合、システムは結果の法線ベクトルを正規化 します

 

ジオメトリ ブレンドを使用しない場合、多くの場合、動的多関節モデルはセグメントでレンダリングされます。 たとえば、人間の腕の 3D モデルを考えてみましょう。 最も簡単なビューでは、腕には、体に接続する上腕と、手に接続する下腕の 2 つの部分があります。 2 つのはエルボで接続され、下腕はその時点で回転します。 アームをレンダリングするアプリケーションでは、上部と下部のアームの頂点データが保持され、それぞれ異なるワールド変換マトリックスが含まれる場合があります。 これを次のコード例に示します。

typedef struct _Arm
{
    VERTEX upper_arm_verts[200];
    D3DMATRIX matWorld_Upper;

    VERTEX lower_arm_verts[200];
    D3DMATRIX matWorld_Lower;
} ARM, *LPARM;

ARM MyArm; // This needs to be initialized.

arm をレンダリングするために、次のコードに示すように、2 つのレンダリング呼び出しが行われます。

// Render the upper arm.
d3dDevice->SetTransform( D3DTS_WORLD, &MyArm.matWorld_Upper );
d3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, numFaces );

// Render the lower arm, updating its world matrix to articulate
// the arm by pi/4 radians (45 degrees) at the elbow.
MyArm.matWorld_Lower = RotateMyArm(MyArm.matWorld, pi/4);
d3dDevice->SetTransform( D3DTS_WORLD, &MyArm.matWorld_Lower );
d3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, numFaces );

次の図は、この手法を使用するように変更されたバナナです。

ジオメトリブレンドのないブレンドバナナのイラスト

ブレンドジオメトリと非ブレンドジオメトリの違いは明らかです。 この例はやや極端です。 実際のアプリケーションでは、セグメント化されたモデルのジョイントは、継ぎ目がそれほど明白でないように設計されています。 しかし、縫い目は時々見えるので、モデルデザイナーにとって絶え間ない課題があります。

Direct3D のジオメトリ ブレンドは、従来のセグメント化モデリング シナリオに代わるものとなります。 ただし、セグメント化されたオブジェクトのビジュアル品質が向上すると、レンダリング中のブレンド計算が犠牲になります。 これらの追加操作の影響を最小限に抑えるために、Direct3D ジオメトリ パイプラインは、可能な限り最小限のオーバーヘッドでジオメトリをブレンドするように最適化されています。 Direct3D によって提供されるジオメトリ ブレンド サービスをインテリジェントに使用するアプリケーションでは、重大なパフォーマンスの反作用を回避しながら、キャラクターのリアリズムを向上させることができます。

ブレンド変換とレンダリングの状態

IDirect3DDevice9::SetTransform メソッドは、D3DTS_WORLDMATRIX マクロで定義できる値に対応するD3DTS_WORLDマクロとD3DTS_WORLDn マクロを認識します。 これらのマクロは、ジオメトリをブレンドするマトリックスを識別するために使用されます。

D3DRENDERSTATETYPE 列挙型には、ジオメトリ ブレンドを有効にして制御するためのD3DRS_VERTEXBLENDレンダリング状態が含まれます。 このレンダリング状態の有効な値は、 D3DVERTEXBLENDFLAGS 列挙型によって定義されます。 ジオメトリ ブレンドが有効になっている場合は、頂点形式に適切な数のブレンドウェイトを含める必要があります。

ブレンドの重み

ブレンドウェイト (ベータウェイトとも呼ばれます) は、特定のワールド マトリックスが頂点に影響を与える程度を制御します。 ブレンドの重みは、頂点形式でエンコードされた 0.0 から 1.0 の範囲の浮動小数点値です。値 0.0 は、頂点がその行列にブレンドされていないことを意味し、1.0 は頂点が行列によって完全に影響を受けるという意味です。

ジオメトリ ブレンドウェイトは、 固定関数 FVF コード (Direct3D 9) で説明されているように、各頂点の位置の直後に表示される頂点形式でエンコードされます。 レンダリング メソッドに指定する頂点の説明に FVF 定数 のいずれかを含めることで、頂点形式のブレンドウェイトの数を伝えます。

このシステムでは、ブレンド マトリックスの重み付け結果間で線形ブレンドが実行されます。 次の式は、完全なブレンド式です。

ワールド変換行列を使用した線形ブレンドの方程式

上の式では、vBlend は出力頂点であり、v 要素は適用されたワールド マトリックス (D3DTS_WORLDn) によって生成される頂点です。 W 要素は、頂点形式内の対応する重み値です。 n 個のマトリックス間でブレンドされる頂点には、ブレンドウェイト値が 1 つ(最後のブレンド マトリックスを除く各ブレンド マトリックスに対して 1 つ) を含めることができます。 すべての重みの合計が 1.0 になるように、システムは最後のワールド 行列の重みを自動的に生成します。ここでシグマ表記で表されます。 この数式は、次の式に示す Direct3D でサポートされているケースごとに簡略化できます。

3 つのブレンド ケースの線形ブレンドの数式

これらは、2 つ、3 つ、および 4 つのブレンド マトリックス ケースの完全なブレンド式の簡略化された形式です。

Note

Direct3D には最大 5 つのブレンドウェイトを含む頂点を定義する FVF 記述子が含まれていますが、DirectX のこのリリースでは 3 つだけ使用できます。

 

その他の情報については、次のトピックを参照してください。

頂点パイプライン