方法: ハル シェーダーを設計する

ハル シェーダーは、 テセレーション を実装するために連携する 3 つのステージの最初の段階です (他の 2 つのステージはテセレータとドメイン シェーダーです)。 このトピックでは、ハル シェーダーを設計する方法について説明します。

ハル シェーダーには、メイン ハル シェーダーとパッチ定数関数の 2 つの関数が必要です。 ハル シェーダーは、各コントロール ポイントに計算を実装します。ハル シェーダーは、各パッチに計算を実装するパッチ定数関数も呼び出します。

ハル シェーダーを設計したら、「 方法: ハル シェーダーを作成 する」を参照して、ハル シェーダーを作成する方法を確認してください。

ハル シェーダーを設計するには

  1. ハル シェーダーの入力コントロールと出力コントロール ポイントを定義します。

    // 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;
    };
    
  2. 出力パッチ定数データを定義します。

    // 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 つ定義します (エッジをテセレーションするため)。 必要な出力は、三角形ドメインと等線ドメインで異なります。

    固定関数テセレータは、他のパッチ定数データやコントロール ポイントなど、他のハル シェーダー出力を確認しません。 固定関数テセレータによって生成される各ポイントに対して呼び出されるドメイン シェーダー () は、その入力として、ハル シェーダーのすべての出力コントロール ポイントとすべての出力パッチ定数データが表示されます。シェーダーは、その場所でパッチを評価します。

  3. パッチ定数関数を定義します。 パッチ定数関数は、パッチごとに 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 によって識別されます。構造はドメインの種類に依存し、三角形ドメインまたは等線ドメインでは異なります。

    一方、固定関数テセレータが生成する各ポイントに対してドメイン シェーダーが呼び出され、出力コントロール ポイントと出力パッチ定数データ (ハル シェーダーの両方) を確認して、その場所でパッチを評価する必要があります。

  4. ハル シェーダーを定義します。 ハル シェーダーは、パッチ定数関数を含むパッチのプロパティを識別します。 ハル シェーダーは、出力コントロール ポイントごとに 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;
    }
    

    ハル シェーダーでは、次の属性が使用されます。

すべての入力コントロール ポイント ( VS_CONTROL_POINT_OUTPUTで識別) は、各ハル シェーダー呼び出しに表示されます。 この例では、32 個の入力制御ポイントがあります。

ハル シェーダーは、(SV_PrimitiveIDで識別される) パッチごとに出力コントロール ポイント ( SV_OutputControlPointID で識別) ごとに 1 回呼び出されます。 この特定のシェーダーの目的は、BEZIER コントロール ポイントとして定義された出力 i を計算することです (この例では、outputcontrolpoints によって定義された 16 個の出力制御ポイントがあります)。

ハル シェーダーは、パッチごとに 1 回ルーチンを実行し (パッチ定数関数)、パッチ定数データ (テセレーション係数を最小として) を計算します。 個別に、ハル シェーダーは各パッチでパッチ定数関数 (SubDToBezierConstantsHS と呼ばれます) を実行して、テセレータ ステージのテセレーション 係数などのパッチ定数データを計算します。

Direct3D 11 の使用方法

テセレーションの概要