テセレーション ステージ
Direct3D 11 ランタイムでは、テセレーションを実装する 3 つの新しいステージがサポートされています。これにより、詳細度の低いサブディビジョン サーフェスが GPU 上のより詳細なプリミティブに変換されます。 テッセレーションは、高次サーフェスをレンダリングに適した構造体にタイル化 (または分割) します。
ハードウェアにテッセレーションを実装すると、グラフィック パイプラインは、詳細度の低い (ポリゴン数の少ない) モデルを評価して、より高い詳細度でレンダリングできます。 ソフトウェア テッセレーションも可能ですが、ハードウェアにより実装されたテッセレーションでは、モデル サイズに表示の詳細を追加したり、リフレッシュ レートを無効化しなくても、非常に精細な表示 (ディスプレースメント マッピングのサポートを含む) を実現できます。
テセレーションの利点
テセレーション:
- メモリと帯域幅を大量に節約します。これにより、アプリケーションは低解像度モデルからより詳細なサーフェスをレンダリングできます。 Direct3D 11 パイプラインで実装されたテセレーション手法では、ディスプレイスメント マッピングもサポートされており、サーフェスの詳細を大量に生成できます。
- 継続的またはビューに依存する詳細レベルなど、スケーラブルなレンダリング手法をサポートします。これらは、その場で計算できます。
- より低い頻度で高価な計算を実行することでパフォーマンスを向上させます (詳細度の低いモデルで計算を行います)。 これには、リアルなアニメーションを実現するためのブレンド形状またはモーフ ターゲットを使用したブレンディング計算、または衝突検出用や軟体力学用の物理計算があります。
Direct3D 11 パイプラインはハードウェアにテセレーションを実装し、CPU から GPU に作業をオフロードします。 アプリケーションが多数のモーフ ターゲットや洗練されたスキニング/変形モデルを実装している場合、パフォーマンスの大幅な向上を実現できます。 新しいテセレーション機能にアクセスするには、いくつかの新しいパイプライン ステージについて学習する必要があります。
新しいパイプライン ステージ
テッセレーションは GPU を使用して、クワッド パッチ、トライアングル パッチまたは等値線から作成されたサーフェスから、より詳細なサーフェスを計算します。 高次サーフェスを概算するには、テッセレーション係数を使用して各パッチを三角形、点、線に分割します。 Direct3D 11 パイプラインは、次の 3 つの新しいパイプライン ステージを使用してテセレーションを実装します。
- ハル シェーダー ステージ - 各入力パッチ (四角形、三角形、または線) に対応するジオメトリ パッチ (およびパッチ定数) を生成するプログラム可能なシェーダー ステージ。
- テッセレータ ステージ - ジオメトリ パッチを表すドメインのサンプリング パターンを作成し、これらのサンプルを接続する一連の小さなオブジェクト (三角形、ポイント、または線) を生成する固定関数パイプライン ステージ。
- ドメイン シェーダー ステージ - 各ドメイン サンプルに対応する頂点の位置を計算するプログラミング可能なシェーダー ステージ。
次の図は、Direct3D 11 パイプラインの新しいステージを示しています。
次の図は、テッセレーション ステージのプログレッションを示しています。 プログレッションは、詳細度の低いサブ サーフェスから開始します。 次に、これらのサンプルを接続する、対応するジオメトリ パッチ、ドメイン サンプル、および三角形を使用して入力パッチがハイライトされます。 最後に、これらのサンプルに対応する頂点がハイライトされます。
Hull-Shader ステージ
ハル シェーダー (パッチごとに 1 回呼び出されます) は、低次サーフェスを定義する入力コントロール ポイントを、パッチを構成するコントロール ポイントに変換します。 また、パッチごとに計算を行い、テセレーション ステージとドメイン ステージのデータを提供します。 最も単純なブラックボックス レベルでは、ハル シェーダー ステージは次の図のようになります。
ハル シェーダーは HLSL 関数を使用して実装され、次のプロパティがあります。
- シェーダー入力は 1 から 32 のコントロール ポイントの間です。
- シェーダーの出力は、テセレーション係数の数に関係なく、1 ~ 32 個の制御点です。 ハル シェーダーから出力された制御点は、ドメイン シェーダー ステージで使用できます。 パッチ定数データは、ドメイン シェーダーによって使用できます。テセレーション 係数は、ドメイン シェーダーとテセレーション ステージで使用できます。
- テセレーション係数は、各パッチを分割する程度を決定します。
- シェーダーは、テセレータ ステージで必要な状態を宣言します。 これには、テセレーションで使用する制御点の数、パッチ面の種類、分割の種類などの情報が含まれます。 この情報は、通常、シェーダー コードの最初に宣言として表示されます。
- ハルシェーダー ステージでエッジ テセレーション係数を = 0 または NaN に設定すると、パッチがカリングされます。 その結果、テッセレータ ステージは実行される場合と実行されない場合があり、ドメイン シェーダーは実行されず、そのパッチの表示出力は生成されません。
より深いレベルでは、ハル シェーダーは実際には、コントロール ポイント フェーズとパッチ定数フェーズの 2 つのフェーズで動作します。これはハードウェアによって並列に実行されます。 HLSL コンパイラは、ハル シェーダーの並列処理を抽出し、ハードウェアを駆動するバイトコードにエンコードします。
- 制御点フェーズは制御点ごとに 1 回実行され、パッチの制御点を読み取り、1 つの出力制御点 (ControlPointID で識別される) を生成します。
- パッチ定数フェーズは、パッチごとに 1 回実行され、エッジ テセレーション係数とその他のパッチごとの定数を生成します。 内部的には、複数のパッチ定数フェーズが同時に実行される場合があります。 パッチ定数フェーズでは、すべての入力制御点と出力制御点に対して読み取り専用アクセスの権限があります。
ハル シェーダーの例を次に示します。
[patchsize(12)]
[patchconstantfunc(MyPatchConstantFunc)]
MyOutPoint main(uint Id : SV_ControlPointID,
InputPatch<MyInPoint, 12> InPts)
{
MyOutPoint result;
...
result = TransformControlPoint( InPts[Id] );
return result;
}
ハル シェーダーを作成する例については、「 方法: ハル シェーダーを作成する」を参照してください。
テセレータ ステージ
テセレータは、ハル シェーダーをパイプラインにバインドすることによって初期化される固定関数ステージです (「 方法: テセレータ ステージを初期化する」を参照)。 テッセレータ ステージの目的は、ドメイン (クワッド、トライアングル、またはライン) を多数のより小さいオブジェクト (三角形、点または線) に分割することです。 テッセレータは、正規のドメインを標準化された (0 ~ 1 の) 座標系でタイル化します。 たとえば、クワッド ドメインは、単位正方形にテッセレーションされます。
テッセレータは、ハル シェーダー ステージから渡されるテッセレーション係数 (ドメインをどの程度詳細にテッセレーションするかを指定する) およびパーティションの種類 (パッチのスライスに使用するアルゴリズムを指定する) を使用して、パッチごとに 1 回動作します。 テッセレータは、uv (およびオプションとして w) 座標およびサーフェス トポロジをドメイン シェーダー ステージに出力します。
内部的には、テセレータは次の 2 つのフェーズで動作します。
- 最初のフェーズでは、32 ビット浮動小数点演算を使用して、テッセレーション係数を処理して丸めの問題を解決した後、非常に小さい係数を処理することで係数の削減および結合を行います。
- 2 番目のフェーズでは、選択したパーティションの種類に基づいてポイント リストまたはトポロジ リストを生成します。 これはテッセレータ ステージの中核タスクで、固定小数点演算の 16 ビットの小数を使用します。 固定小数点演算により、許容範囲内の精度を維持しつつハードウェアを加速化できます。 たとえば、64 メートル幅のパッチの場合、この精度を 2mm の解像度の点にできます。
パーティションの種類 | 範囲 |
---|---|
fractional_odd | [1...63] |
fractional_even | TessFactor 範囲: [2..64] |
整数 (integer) | TessFactor 範囲: [1..64] |
pow2 | TessFactor 範囲: [1..64] |
Domain-Shader ステージ
ドメイン シェーダーは、出力パッチ内の細分化された点の頂点位置を計算します。 ドメイン シェーダーは、テセレータ ステージ出力ポイントごとに 1 回実行され、次の図に示すように、テセレータ ステージ出力 UV 座標、ハル シェーダー出力パッチ、およびハル シェーダー出力パッチ定数への読み取り専用アクセス権を持ちます。
ドメイン シェーダーのプロパティは次のとおりです。
- ドメイン シェーダーは、テセレータ ステージから出力座標ごとに 1 回呼び出されます。
- ドメイン シェーダーは、ハル シェーダー ステージからの出力制御ポイントを使用します。
- ドメイン シェーダーは、頂点の位置を出力します。
- 入力は、コントロール ポイント、パッチ定数データ、テセレーション 係数を含むハル シェーダー出力です。 テセレーション 係数には、固定関数テセレータで使用される値と、たとえば、ジオモーフィングを容易にする生の値 (たとえば、整数テセレーションによる丸め前) を含めることができます。
ドメイン シェーダーが完了すると、テセレーションが完了し、パイプライン データは次のパイプライン ステージ (ジオメトリ シェーダー、ピクセル シェーダーなど) に進みます。 隣接性を持つプリミティブ (三角形ごとに 6 個の頂点など) を想定するジオメトリ シェーダーは、テセレーションがアクティブな場合には有効ではありません (これは未定義の動作となり、デバッグ レイヤーで問題が検出されます)。
ドメイン シェーダーの例を次に示します。
void main( out MyDSOutput result,
float2 myInputUV : SV_DomainPoint,
MyDSInput DSInputs,
OutputPatch<MyOutPoint, 12> ControlPts,
MyTessFactors tessFactors)
{
...
result.Position = EvaluateSurfaceUV(ControlPoints, myInputUV);
}
テセレーション ステージを初期化するための API
テセレーションは、ハル シェーダーとドメイン シェーダーという 2 つの新しいプログラム可能なシェーダー ステージで実装されます。 これらの新しいシェーダー ステージは、シェーダー モデル 5 で定義されている HLSL コードでプログラミングされます。 新しいシェーダー ターゲットは、hs_5_0とds_5_0です。 すべてのプログラミング可能なシェーダー ステージと同様に、 DSSetShader や HSSetShader などの API を使用してシェーダーがパイプラインにバインドされるときに、ランタイムに渡されるコンパイル済みシェーダーからハードウェアのコードが抽出されます。 ただし、最初に、 CreateHullShader や CreateDomainShader などの API を使用してシェーダー を作成する必要があります。
テッセレーションは、ハル シェーダーを作成し、これをハル シェーダー ステージにバインドすることによって有効にします (これにより、テッセレータ ステージが自動的にセットアップされます)。 テッセレーションされたパッチから最終的な頂点位置を生成するには、ドメイン シェーダーを作成し、これをドメイン シェーダー ステージにバインドする必要があります。 テセレーションが有効になったら、input-assembler ステージへのデータ入力はパッチ データである必要があります。 つまり、入力アセンブラー トポロジは、IASetPrimitiveTopologyで設定D3D11_PRIMITIVE_TOPOLOGYパッチ定数トポロジである必要があります。
テッセレーションを無効にするには、ハル シェーダーおよびドメイン シェーダーを NULL に設定します。 geometry-shader ステージもストリーム出力ステージも、ハル シェーダー出力制御ポイントまたはパッチ データを読み取れありません。
入力アセンブラー ステージの新しいトポロジ。これは、この列挙体の拡張機能です。
enum D3D11_PRIMITIVE_TOPOLOGY
もちろん、新しいプログラム可能なシェーダー ステージでは、定数バッファー、サンプル、シェーダー リソースを適切なパイプライン ステージにバインドするために、他の状態を設定する必要があります。 これらの新しい ID3D11Device メソッドは、この状態を設定するために実装されます。
方法:
このドキュメントには、テセレーション ステージを初期化する例も含まれています。
Item | 説明 |
---|---|
方法: ハル シェーダーを作成する |
ハル シェーダーを作成します。 |
方法: ハル シェーダーを設計する |
ハル シェーダーを設計する。 |
方法: テセレータ ステージを初期化する |
テセレーション ステージを初期化します。 |
方法: ドメイン シェーダーを作成する |
ドメイン シェーダーを作成します。 |
方法: ドメイン シェーダーを設計する |
ドメイン シェーダーを作成します。 |