Condividi tramite


Guida: Progettare uno shader dello scafo

Uno hull shader è la prima delle tre fasi che interagiscono per implementare tassellatura (le altre due fasi sono il tassellatore e uno shader di dominio). In questo argomento viene illustrato come progettare uno hull shader.

Uno hull shader richiede due funzioni, lo hull shader principale e una funzione costante patch. Lo hull shader implementa calcoli su ogni punto di controllo; lo hull shader chiama anche la funzione costante patch che implementa calcoli per ogni patch.

Dopo aver progettato uno hull shader, vedere Procedura: Creare un hull shader per informazioni su come creare uno hull shader.

Per progettare un hull shader

  1. Definire il controllo di input dello hull shader e i 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 di output della patch.

    // 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 tassellatura dei bordi (per tassellare i bordi), poiché il tassellatore a funzione fissa deve sapere quanto tassellare. Gli output necessari sono diversi per il triangolo e i domini isoline.

    Il tassellatore a funzione fissa non considera altri output dell'hull shader, come ad esempio altri dati costanti della patch o i punti di controllo. Lo shader di dominio richiamato per ogni punto generato dal tessellatore a funzione fissa vedrà come input tutti i punti di controllo di output dello hull shader e tutti i dati costanti della patch di output; lo shader valuta la patch nella sua posizione.

  3. Definire una funzione patch costante. Una funzione costante di patch viene eseguita una volta per ciascuna patch per calcolare tutti i dati che sono costanti per l'intera patch (anziché per i dati per punto di controllo, che vengono calcolati nell'hull shader).

    
    #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 di shader 4).
    • Un parametro di input è costituito dai 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, in questo esempio sono presenti 32 punti di controllo per patch.
    • Come minimo, la funzione deve calcolare i fattori di tassellatura per patch per la fase di tassellazione identificati con SV_TessFactor. Un dominio quad richiede quattro fattori di tassellazione per i bordi e due fattori aggiuntivi (identificati da SV_InsideTessFactor) per tassellare l'interno del pezzo. Il tassellatore a funzione fissa non esamina altri output dello hull shader (ad esempio i dati costanti della patch o dei punti di controllo).
    • Gli output sono in genere definiti da una struttura ed è identificato da HS_CONSTANT_DATA_OUTPUT in questo esempio; la struttura dipende dal tipo di dominio e sarebbe diversa per i domini triangoli o isoline.

    Viene invece richiamato uno shader di dominio per ogni punto generato dal tassellatore a funzione fissa e deve visualizzare i punti di controllo di output e i dati costanti della patch di output (entrambi dallo hull shader) per valutare una patch nella relativa posizione.

  4. Definire un hull shader. Uno hull shader identifica le proprietà di una patch, inclusa una funzione costante patch. Uno hull shader 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:

    • Attributo di dominio.
    • Attributo di partizionamento.
    • Attributo di outputtopology.
    • Un attributo outputcontrolpoints .
    • Un attributo patchconstantfunc. Lo hull shader calcola i punti di controllo di output. In questo esempio, sono presenti 16 punti di controllo di Bézier.

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

Uno hull shader viene richiamato 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 è calcolare l'output e, definiti come punti di controllo BEZIER (in questo esempio sono definiti 16 punti di controllo di output dai punti di controllo di uscita).

Uno shader dello scafo (hull shader) esegue una routine una volta per patch (funzione della costante della patch) per calcolare i dati costanti della patch (fattori di tassellatura come minimo). Separatamente, un hull shader esegue una funzione costante della patch (denominata SubDToBezierConstantsHS) su ogni patch per calcolare i dati costanti della patch, come i fattori di tassellatura per la fase di tassellatura.

Come usare Direct3D 11

Panoramica tassellatura