Condividi tramite


Organizzazione dello stato in un effetto (Direct3D 11)

Con Direct3D 11, lo stato di effetto per determinate fasi della pipeline è organizzato in base alle strutture. Ecco le strutture:

Stato della pipeline Struttura
Rasterizzazione D3D11_RASTERIZER_DESC
Unione output D3D11_BLEND_DESC e D3D11_DEPTH_STENCIL_DESC
Shader Vedere di seguito

 

Per le fasi dello shader, in cui il numero di modifiche di stato deve essere più controllato da un'applicazione, lo stato è stato suddiviso in stato di buffer costante, stato del campionatore, stato della risorsa shader e stato di visualizzazione di accesso non ordinato (per pixel e shader di calcolo). Ciò consente a un'applicazione progettata con attenzione di aggiornare solo lo stato che sta cambiando, migliorando le prestazioni riducendo la quantità di dati che devono essere passati alla GPU.

In che modo è possibile organizzare lo stato della pipeline in un effetto?

La risposta è che l'ordine non importa. Le variabili globali non devono essere posizionate nella parte superiore. Tuttavia, tutti gli esempi nell'SDK seguono lo stesso ordine, perché è consigliabile organizzare i dati nello stesso modo. Si tratta quindi di una breve descrizione dell'ordinamento dei dati negli esempi di DirectX SDK.

Variabili globali

Proprio come la procedura C standard, le variabili globali vengono dichiarate per prime, all'inizio del file. Nella maggior parte dei casi, si tratta di variabili che verranno inizializzate da un'applicazione e quindi usate in un effetto. A volte vengono inizializzati e non vengono mai modificati, altre volte vengono aggiornati ogni fotogramma. Proprio come le regole di ambito della funzione C, le variabili di effetto dichiarate al di fuori dell'ambito delle funzioni di effetto sono visibili in tutto l'effetto; qualsiasi variabile dichiarata all'interno di una funzione di effetto è visibile solo all'interno di tale funzione.

Ecco un esempio delle variabili dichiarate in BasicHLSL10.fx.

// Global variables
float4 g_MaterialAmbientColor;      // Material's ambient color

Texture2D g_MeshTexture;            // Color texture for mesh

float    g_fTime;                   // App's time in seconds
float4x4 g_mWorld;                  // World matrix for object
float4x4 g_mWorldViewProjection;    // World * View * Projection matrix


// Texture samplers
SamplerState MeshTextureSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

La sintassi per le variabili di effetto è più dettagliata in sintassi delle variabili effetto (Direct3D 11). La sintassi per i sampler di texture degli effetti è più dettagliata in Tipo sampler (DirectX HLSL).

Shader

Gli shader sono programmi eseguibili di piccole dimensioni. È possibile considerare gli shader come incapsulare lo stato dello shader, poiché il codice HLSL implementa la funzionalità dello shader. La pipeline grafica supporta fino a cinque diversi tipi di shader.

  • Vertex shader: opera sui dati dei vertici. Un vertice in restituisce un vertice.
  • Gli hull shader operano sui dati delle patch. Fase di controllo: un'invocazione fornisce un punto di controllo; Per ogni fase di fork e di join: una patch fornisce una certa quantità di dati costanti della patch.
  • Domain shader: opera sui dati primitivi. Una primitiva può produrre 0, 1 o molte primitive.
  • Shader di geometria - Opera su dati primitivi. Una primitiva in può produrre 0, 1 o molte primitive.
  • Gli shader dei pixel elaborano i dati dei pixel. Un pixel in genera 1 pixel di uscita (a meno che il pixel non venga eliminato da un rendering).

La pipeline di calcolare shader utilizza un solo shader.

  • Compute shader : funziona su qualsiasi tipo di dati. L'output è indipendente dal numero di thread.

Gli shader sono funzioni locali e seguono le regole delle funzioni di stile C. Una volta compilato un effetto, ogni shader viene compilato e un puntatore a ogni funzione dello shader viene memorizzato internamente. Quando la compilazione ha esito positivo, viene restituita un'interfaccia ID3D11Effect. A questo punto l'effetto compilato è in un formato intermedio.

Per ottenere ulteriori informazioni sugli shader compilati, è necessario utilizzare la riflessione degli shader. Si tratta essenzialmente di chiedere al runtime di decompilare gli shader e restituire informazioni sul codice dello shader.

struct VS_OUTPUT
{
    float4 Position   : SV_POSITION; // vertex position 
    float4 Diffuse    : COLOR0;      // vertex diffuse color
    float2 TextureUV  : TEXCOORD0;   // vertex texture coords 
};

VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
                         float3 vNormal : NORMAL,
                         float2 vTexCoord0 : TEXCOORD,
                         uniform int nNumLights,
                         uniform bool bTexture,
                         uniform bool bAnimate )
{
    VS_OUTPUT Output;
    float3 vNormalWorldSpace;
 
    ....    
    
    return Output;    
}


struct PS_OUTPUT
{
    float4 RGBColor : SV_Target;  // Pixel color
};

PS_OUTPUT RenderScenePS( VS_OUTPUT In,
                         uniform bool bTexture ) 
{ 
    PS_OUTPUT Output;

    if( bTexture )
        Output.RGBColor = g_MeshTexture.Sample(MeshTextureSampler, In.TextureUV) * In.Diffuse;
    ....

    return Output;
}

La sintassi per gli shader degli effetti è più dettagliata in Effect Function Syntax (Direct3D 11).

Gruppi, tecniche e passaggi

Un gruppo è una raccolta di tecniche. Una tecnica è una raccolta di passaggi di rendering (deve essere presente almeno un passaggio). Ogni passaggio di effetto (simile nell'ambito a un singolo passaggio in un ciclo di rendering) definisce lo stato dello shader e qualsiasi altro stato della pipeline necessario per eseguire il rendering della geometria.

I gruppi sono facoltativi. Esiste un unico gruppo senza nome che comprende tutte le tecniche globali. Tutti gli altri gruppi devono essere denominati.

Ecco un esempio di una tecnica (che include un passaggio) da BasicHLSL10.fx.

technique10 RenderSceneWithTexture1Light
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
    }
}

fxgroup g0
{
    technique11 RunComputeShader
    {
        pass P0
        {
            SetComputeShader( CompileShader( cs_5_0, CS() ) );
        }
    }
}

La sintassi per gli shader degli effetti è più dettagliata in Effect Technique Syntax (Direct3D 11).

Effetti (Direct3D 11)