テッセレーションの概要
Direct3D 11 ランタイムは、テッセレーションを実装する 3 つの新しいステージをサポートします。テッセレーションは、GPU 上の詳細でないサブディビジョン サーフェスをより詳細なプリミティブに変換します。テッセレーションは、高次サーフェスをレンダリングに適した構造体にタイル化 (または分割) します。
ハードウェアでテッセレーションを実装することにより、グラフィック パイプラインは、詳細でない (低いポリゴン カウントの) モデルを評価し、より詳細にレンダリングできます。ソフトウェア テッセレーションも可能ですが、ハードウェアによって実装されたテッセレーションは、モデル サイズへの表示の詳細の追加およびリフレッシュ レートの無効化を行うことなく、非常に精細な表示 (ディスプレースメント マッピングのサポートを含む) を生成できます。
- 新しいパイプライン ステージ
- テッセレーション ステージを初期化する API
- 方法:
テッセレーション:
- 大量のメモリーおよび帯域幅を節約します。これにより、アプリケーションがより詳細なサーフェスを低解像度モデルからレンダリングできるようになります。Direct3D 11 パイプラインで実装されているテッセレーション テクニックも、非常に鮮明なサーフェス詳細を作成可能なディスプレースメント マッピングをサポートします。
- 実行中に計算可能な連続的な詳細レベル、または表示依存の詳細レベルなどのスケーラブルなレンダリング テクニックをサポートします。
- 負荷の大きい計算の頻度を下げることにより (計算を詳細でないモデルで実行することにより)、パフォーマンスが向上します。これには、リアルなアニメーションにブレンド形状またはモーフ ターゲットを使用したブレンディング計算、または衝突検出用あるいは軟体の力学用の物理計算があります。
Direct3D 11 パイプラインは、ハードウェアにテッセレーションを実装することによって、CPU 処理を GPU に負担させます。アプリケーションが多数のモーフ ターゲットまたは洗練されたスキニング/変形モデル (あるいはその両方) を実装している場合、パフォーマンスの大幅な向上を実現できます。新しいテッセレーション機能にアクセスするには、新しいパイプライン ステージについて理解する必要があります。
新しいパイプライン ステージ
テッセレーションは GPU を使用して、クワッド パッチ、トライアングル パッチまたは等値線から作成されたサーフェスから、より詳細なサーフェスを計算します。高次サーフェスを概算するには、テッセレーション係数を使用して各パッチを三角形、点、線に分割します。Direct3D 11 パイプラインは、次の 3 つの新しいパイプライン ステージを使用してテッセレーションを実装します。
- ハル シェーダー ステージ - 入力コントロール ポイントから出力コントロール ポイント (およびパッチ定数) を作成するプログラム可能なシェーダー ステージです。これらのコントロール ポイントの次元および使用はユーザーが決定します。
- テッセレータ ステージ - ドメイン (クワッド、トライアングル、またはライン) を多数のより小さいオブジェクト (三角形、点または線) に分割する固定機能パイプライン ステージです。
- ドメイン シェーダー ステージ - 出力パッチ内でさらに分割された点の頂点位置を計算するプログラム可能なシェーダー ステージです。
ハル シェーダー ステージ
(パッチごとに 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] |
ドメイン シェーダー ステージ
ドメイン シェーダーは、出力パッチ内でさらに分割された点の頂点位置を計算します。ドメイン シェーダーは、テッセレータ ステージの出力ポイントごとに 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 です。すべてのプログラム可能なシェーダー ステージと同様に、ハードウェア用のコードは、ID3D11DeviceContext::DSSetShader や ID3D11DeviceContext::HSSetShader などの API を使用してシェーダーがパイプラインにバインドされるときにランタイムに渡されたコンパイル済みのシェーダーから抽出されます。ただし最初にシェーダーは、ID3D11Device::CreateHullShader や ID3D11Device::CreateDomainShader などの API を使用して作成される必要があります。
ハル シェーダーを作成し、これをハル シェーダー ステージにバインドすることによりテッセレーションを有効にします (これにより、テッセレータ ステージが自動的にセットアップされる)。テッセレーションされたパッチから最終的な頂点位置を生成するには、ドメイン シェーダーを作成し、これをドメイン シェーダー ステージにバインドする必要があります。テッセレーションが有効になると、入力アセンブラー ステージに入力するデータは、パッチ データである必要があります。つまり、入力アセンブラー トポロジは、ID3D11DeviceContext::IASetPrimitiveTopology を使用して設定された D3D11_PRIMITIVE_TOPOLOGY のパッチ定数トポロジである必要があります。
テッセレーションを無効にするには、ハル シェーダーおよびドメイン シェーダーを NULL に設定します。ジオメトリ シェーダー ステージとストリーム出力ステージのいずれも、ハル シェーダーの出力コントロール ポイントまたはパッチ データを読み取れません。
次の列挙型への拡張である入力アセンブラー ステージの新しいトポロジ。
enum D3D11_PRIMITIVE_TOPOLOGY
このトポロジは、ID3D11DeviceContext::IASetPrimitiveTopology を使用して入力アセンブラー ステージに設定されます。
当然、この新しいプログラム可能なシェーダー ステージでは、他のステートを設定してから、定数バッファー、サンプル、およびシェーダー リソースを適切なパイプライン ステージにバインドする必要があります。これらの新しい ID3D11Device メソッドは、このステートを設定するために実装されます。
- ID3D11DeviceContext::DSGetConstantBuffers
- ID3D11DeviceContext::DSGetSamplers
- ID3D11DeviceContext::DSGetShader
- ID3D11DeviceContext::DSGetShaderResources
- ID3D11DeviceContext::DSSetConstantBuffers
- ID3D11DeviceContext::DSSetSamplers
- ID3D11DeviceContext::DSSetShader
- ID3D11DeviceContext::DSSetShaderResources
- ID3D11DeviceContext::HSGetConstantBuffers
- ID3D11DeviceContext::HSGetShaderResources
- ID3D11DeviceContext::HSGetSamplers
- ID3D11DeviceContext::HSGetShader
- ID3D11DeviceContext::HSSetConstantBuffers
- ID3D11DeviceContext::HSSetSamplers
- ID3D11DeviceContext::HSSetShader
- ID3D11DeviceContext::HSSetShaderResources
方法:
このドキュメントには、テッセレーション ステージを初期化する例も含まれます。
- 方法 :ハル シェーダーの作成
ハル シェーダーを作成します。 - 方法 :ハル シェーダーの設計
ハル シェーダーを設計します。 - 方法 :テッセレータ ステージの初期化
テッセレーション ステージを初期化します。 - 方法 :ドメイン シェーダーの作成
ドメイン シェーダーを作成します。 - 方法 :ドメイン シェーダーの設計
ドメイン シェーダーを作成します。