Procedura: Progettare uno shader di hull

Uno shader dello scafo è la prima delle tre fasi che collaborano per implementare la tessellazione (le altre due fasi sono il tessellatore e uno shader di dominio). Questo argomento illustra come progettare uno shader dello scafo.

Un shader dello scafo richiede due funzioni, lo shader principale dello scafo e una funzione costante patch. Lo shader dello scafo implementa i calcoli su ogni punto di controllo; lo shader dello scafo chiama anche la funzione costante patch che implementa i calcoli su ogni patch.

Dopo aver progettato uno shader dello scafo, vedere How To: Create a Hull Shader to learn how to create a hull shader.

Per progettare uno shader dello scafo

  1. Definire i punti di controllo di input dello shader dello scafo e dei punti di controllo di output.

    // 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. Definire i dati costanti delle patch di output.

    // 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;
    };
    

    Per un dominio quad, SV_TessFactor definisce 4 fattori di tessellazione perimetrale (per tessellare i bordi), poiché il tessellatore della funzione fissa deve sapere quanto tessellare. Gli output necessari sono diversi per il triangolo e i domini isoline.

    Il tessellatore della funzione fissa non esamina altri output dello shader dello scafo, ad esempio altri dati costanti patch o uno dei punti di controllo. Il domain shader , richiamato per ogni punto generato dal tessellatore di funzione fissa, vedrà come input tutti i punti di controllo di output dello shader dello hull e tutti i dati costanti delle patch di output; lo shader valuta la patch nella sua posizione.

  3. Definire una funzione costante patch. Una funzione costante patch viene eseguita una volta per ogni patch per calcolare tutti i dati costanti per l'intera patch (anziché i dati del punto di controllo, calcolati nello shader dello scafo).

    
    #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;
    }
    

    Le proprietà della funzione costante patch includono:

    • Un input specifica una variabile contenente un ID patch e viene identificata dal valore di sistema SV_PrimitiveID (vedere semantica nel modello shader 4).
    • Un parametro di input è i punti di controllo di input, dichiarati in VS_CONTROL_POINT_OUTPUT in questo esempio. Una funzione patch può visualizzare tutti i punti di controllo di input per ogni patch, sono presenti 32 punti di controllo per patch in questo esempio.
    • Come minimo, la funzione deve calcolare i fattori di tessellatura per patch per la fase di tessellatore identificata con SV_TessFactor. Un dominio quad richiede quattro fattori di tessellazione per i bordi e due fattori aggiuntivi (identificati da SV_InsideTessFactor) per la tessellatura all'interno della patch. Il tessellatore della funzione fissa non esamina altri output dello shader dello scafo,ad esempio i dati costanti patch o uno dei punti di controllo.
    • Gli output sono in genere definiti da una struttura e vengono identificati da HS_CONSTANT_DATA_OUTPUT in questo esempio; la struttura dipende dal tipo di dominio e sarebbe diversa per i domini triangoli o isoline.

    Un domain shader viene richiamato per ogni punto in cui viene generato il tessellatore a funzione fissa e deve visualizzare i punti di controllo di output e i dati costanti delle patch di output (entrambi dallo shader dello hull) per valutare una patch nella sua posizione.

  4. Definire uno shader dello scafo. Uno shader dello scafo identifica le proprietà di una patch, inclusa una funzione costante patch. Un shader dello scafo viene richiamato una volta per ogni punto di controllo di output.

    [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;
    }
    

    Uno hull shader usa gli attributi seguenti:

Tutti i punti di controllo di input (identificati da VS_CONTROL_POINT_OUTPUT) sono visibili a ogni chiamata dello shader dello scafo. In questo esempio sono presenti 32 punti di controllo di input.

Viene richiamato uno shader dello scafo una volta per ogni punto di controllo di output (identificato con SV_OutputControlPointID) per ogni patch (identificata con SV_PrimitiveID). Lo scopo di questo particolare shader consiste nel calcolare l'output i, definito come punto di controllo BEZIER( in questo esempio sono presenti 16 punti di controllo di output definiti dai punti di controllo output definiti dai punti di controllo output).

Uno shader dello scafo esegue una routine una volta per patch (la funzione costante patch) per calcolare i dati costanti delle patch (fattori di tessellazione come minimo). Separatamente, uno shader dello scafo esegue una funzione costante patch (denominata SubDToBezierConstantsHS) in ogni patch per calcolare i dati costanti delle patch, ad esempio i fattori di tessellazione per la fase di tessellator.

Come usare Direct3D 11

Panoramica della tessellazione