方法: ハル シェーダーを設計する
ハル シェーダーは、 テセレーション を実装するために連携する 3 つのステージの最初の段階です (他の 2 つのステージはテセレータとドメイン シェーダーです)。 このトピックでは、ハル シェーダーを設計する方法について説明します。
ハル シェーダーには、メイン ハル シェーダーとパッチ定数関数の 2 つの関数が必要です。 ハル シェーダーは、各コントロール ポイントに計算を実装します。ハル シェーダーは、各パッチに計算を実装するパッチ定数関数も呼び出します。
ハル シェーダーを設計したら、「 方法: ハル シェーダーを作成 する」を参照して、ハル シェーダーを作成する方法を確認してください。
ハル シェーダーを設計するには
ハル シェーダーの入力コントロールと出力コントロール ポイントを定義します。
// Input control point struct VS_CONTROL_POINT_OUTPUT { float3 vPosition : WORLDPOS; float2 vUV : TEXCOORD0; float3 vTangent : TANGENT; }; // Output control point struct BEZIER_CONTROL_POINT { float3 vPosition : BEZIERPOS; };
出力パッチ定数データを定義します。
// Output patch constant data. struct HS_CONSTANT_DATA_OUTPUT { float Edges[4] : SV_TessFactor; float Inside[2] : SV_InsideTessFactor; float3 vTangent[4] : TANGENT; float2 vUV[4] : TEXCOORD; float3 vTanUCorner[4] : TANUCORNER; float3 vTanVCorner[4] : TANVCORNER; float4 vCWts : TANWEIGHTS; };
四角形ドメイン の場合、固定 関数テセレータはテセレーションする量を認識する必要があるため、SV_TessFactorはエッジテセレーション係数を 4 つ定義します (エッジをテセレーションするため)。 必要な出力は、三角形ドメインと等線ドメインで異なります。
固定関数テセレータは、他のパッチ定数データやコントロール ポイントなど、他のハル シェーダー出力を確認しません。 固定関数テセレータによって生成される各ポイントに対して呼び出されるドメイン シェーダー () は、その入力として、ハル シェーダーのすべての出力コントロール ポイントとすべての出力パッチ定数データが表示されます。シェーダーは、その場所でパッチを評価します。
パッチ定数関数を定義します。 パッチ定数関数は、パッチごとに 1 回実行され、パッチ全体の定数であるデータを計算します (ハル シェーダーで計算されるコントロール ポイントごとのデータとは対照的)。
#define MAX_POINTS 32 // Patch Constant Function HS_CONSTANT_DATA_OUTPUT SubDToBezierConstantsHS( InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, uint PatchID : SV_PrimitiveID ) { HS_CONSTANT_DATA_OUTPUT Output; // Insert code to compute Output here return Output; }
パッチ定数関数のプロパティは次のとおりです。
- 1 つの入力では、パッチ ID を含む変数を指定し、 SV_PrimitiveID システム値によって識別されます (シェーダー モデル 4 の セマンティクス を参照)。
- 1 つの入力パラメーターは、この例の VS_CONTROL_POINT_OUTPUT で宣言されている入力コントロール ポイントです。 パッチ関数では、各パッチのすべての入力コントロール ポイントを確認できます。この例では、パッチごとに 32 個のコントロール ポイントがあります。
- 最小として、関数は、 SV_TessFactorで識別されるテセレータ ステージのパッチごとのテセレーション係数を計算する必要があります。 1 つのクワッド ドメインでは、エッジに 4 つのテセレーション 係数が必要であり、パッチの内側をテセレーションするために 2 つの追加の要因 ( SV_InsideTessFactorで識別されます) が必要です。 固定関数テセレータは、他のハル シェーダー出力 (パッチ定数データやコントロール ポイントなど) を確認しません。
- 出力は通常、 構造体によって定義され、この例 のHS_CONSTANT_DATA_OUTPUT によって識別されます。構造はドメインの種類に依存し、三角形ドメインまたは等線ドメインでは異なります。
一方、固定関数テセレータが生成する各ポイントに対してドメイン シェーダーが呼び出され、出力コントロール ポイントと出力パッチ定数データ (ハル シェーダーの両方) を確認して、その場所でパッチを評価する必要があります。
ハル シェーダーを定義します。 ハル シェーダーは、パッチ定数関数を含むパッチのプロパティを識別します。 ハル シェーダーは、出力コントロール ポイントごとに 1 回呼び出されます。
[domain("quad")] [partitioning("integer")] [outputtopology("triangle_cw")] [outputcontrolpoints(16)] [patchconstantfunc("SubDToBezierConstantsHS")] BEZIER_CONTROL_POINT SubDToBezierHS( InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, uint i : SV_OutputControlPointID, uint PatchID : SV_PrimitiveID ) { VS_CONTROL_POINT_OUTPUT Output; // Insert code to compute Output here. return Output; }
ハル シェーダーでは、次の属性が使用されます。
- ドメイン属性。
- パーティション分割属性。
- outputtopology 属性。
- outputcontrolpoints 属性。
- patchconstantfunc 属性。 ハル シェーダーは出力コントロール ポイントを計算します。この例では、16 個の出力ベジエ制御ポイントがあります。
すべての入力コントロール ポイント ( VS_CONTROL_POINT_OUTPUTで識別) は、各ハル シェーダー呼び出しに表示されます。 この例では、32 個の入力制御ポイントがあります。
ハル シェーダーは、(SV_PrimitiveIDで識別される) パッチごとに出力コントロール ポイント ( SV_OutputControlPointID で識別) ごとに 1 回呼び出されます。 この特定のシェーダーの目的は、BEZIER コントロール ポイントとして定義された出力 i を計算することです (この例では、outputcontrolpoints によって定義された 16 個の出力制御ポイントがあります)。
ハル シェーダーは、パッチごとに 1 回ルーチンを実行し (パッチ定数関数)、パッチ定数データ (テセレーション係数を最小として) を計算します。 個別に、ハル シェーダーは各パッチでパッチ定数関数 (SubDToBezierConstantsHS と呼ばれます) を実行して、テセレータ ステージのテセレーション 係数などのパッチ定数データを計算します。
関連トピック