Procedura: Progettare uno shader di dominio

Un domain shader è il terzo di tre fasi che interagiscono per implementare la tassellatura. Il domain shader genera la geometria della superficie dai punti di controllo trasformati da uno hull shader e dalle coordinate UV. Questo argomento illustra come progettare uno shader di dominio.

Un domain shader viene richiamato una volta per ogni punto generato dal tassellatore a funzione fissa. Gli input sono le coordinate UV[W] del punto sulla patch, nonché tutti i dati di output dello hull shader, inclusi i punti di controllo e le costanti patch. L'output è un vertice definito in qualsiasi modo. Se l'output viene inviato al pixel shader, l'output deve includere una posizione (indicata con una semantica SV_Position).

Per progettare uno shader di dominio

  1. Definire l'attributo di dominio.

    [domain("quad")]
    

    Il dominio è definito per una patch quad.

  2. Dichiarare la posizione sullo scafo con il valore del sistema di posizione del dominio .

    • Per una patch quad, usare un float2.
    • Per una tri patch, usare un float3 (per le coordinate bariche)
    • Per un isoline, usare un float2.

    Di conseguenza, il percorso del dominio per una patch quad è simile al seguente:

    float2 UV : SV_DomainLocation
    
  3. Definire gli altri input.

    Gli altri input provengono dallo hull shader e sono definiti dall'utente. Sono inclusi i punti di controllo di input per patch, di cui possono essere presenti tra 1 e 32 punti e i dati costanti della patch di input.

    I punti di controllo sono definiti dall'utente, in genere con una struttura come questa (definita in Procedura: Progettare uno Hull Shader):

    const OutputPatch<BEZIER_CONTROL_POINT, 16> bezpatch
    

    I dati costanti patch sono definiti anche dall'utente e potrebbero essere simili a questo (definito in Procedura: Progettare uno Hull Shader):

    HS_CONSTANT_DATA_OUTPUT input
    
  4. Aggiungere codice definito dall'utente per calcolare gli output; questo costituisce il corpo dello shader di dominio.

    Questa struttura contiene output di domain shader definiti dall'utente.

    struct DS_OUTPUT
    {
        float3 vNormal    : NORMAL;
        float2 vUV        : TEXCOORD;
        float3 vTangent   : TANGENT;
        float3 vBiTangent : BITANGENT;
    
        float4 vPosition  : SV_POSITION;
    };
    

    La funzione accetta ogni uv di input (dal tassellatore) e valuta la patch di Bezier in questa posizione.

    [domain("quad")]
    DS_OUTPUT BezierEvalDS( HS_CONSTANT_DATA_OUTPUT input, 
                            float2 UV : SV_DomainLocation,
                            const OutputPatch<BEZIER_CONTROL_POINT, 16> bezpatch )
    {
        DS_OUTPUT Output;
    
        // Insert code to compute the output here.
    
        return Output;    
    }
    

    La funzione viene richiamata una volta per ogni punto generato dal tassellatore a funzione fissa. Poiché in questo esempio viene usata una patch quad, la posizione del dominio di input (SV_DomainLocation) è float2 (UV); una patch tri avrebbe una posizione di input float3 (coordinate barycentriche UVW) e una isoline avrebbe una posizione di dominio di input float2.

    Gli altri input per la funzione provengono direttamente dallo hull shader. In questo esempio sono 16 punti di controllo ognuno dei quali è un BEZIER_CONTROL_POINT, nonché i dati costanti patch (HS_CONSTANT_DATA_OUTPUT). L'output è un vertice contenente i dati desiderati, DS_OUTPUT in questo esempio.

Dopo aver progettato uno shader di dominio, vedere Procedura: Creare uno shader di dominio.

Come usare Direct3D 11

Panoramica della tassellatura