Condividi tramite


Organizzazione dello stato in un effetto (Direct3D 11)

Con Direct3D 11, lo stato dell'effetto per determinate fasi della pipeline è organizzato da 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 dello stato deve essere più controllato da un'applicazione, lo stato è stato suddiviso in stato buffer costante, stato dell'esempio, 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.

Come organizzare lo stato della pipeline in un effetto?

La risposta è, l'ordine non importa. Le variabili globali non devono trovarsi 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

Analogamente alla pratica C standard, le variabili globali vengono dichiarate prima, nella parte superiore del file. La maggior parte delle volte, queste sono variabili che verranno inizializzate da un'applicazione e quindi usate in un effetto. A volte vengono inizializzati e mai modificati, altre volte vengono aggiornati ogni frame. Analogamente alle regole dell'ambito della funzione C, le variabili di effetto dichiarate all'esterno 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 nella sintassi delle variabili di effetto (Direct3D 11). La sintassi per gli esempi di trama degli effetti è più dettagliata in Sampler Type (DirectX HLSL).

Shader

Shader sono piccoli programmi eseguibili. È possibile pensare agli shader come incapsulare lo stato dello shader, poiché il codice HLSL implementa la funzionalità shader. La pipeline grafica fino a cinque tipi diversi di shader.

  • Vertex shader : opera sui dati dei vertici. Un vertice in restituisce un vertice fuori.
  • Shader di hull: opera sui dati delle patch. Fase punto di controllo: una chiamata restituisce un punto di controllo; Per ogni fork e fasi di join: una patch restituisce una quantità di dati costanti patch.
  • Shader di dominio: opera sui dati primitivi. Una primitiva può produrre 0, 1 o molte primitive.
  • Shader geometry: opera sui dati primitivi. Una primitiva in può produrre 0, 1 o molte primitive fuori.
  • Pixel shader: opera sui dati dei pixel. Un pixel in restituisce 1 pixel out (a meno che il pixel non venga eliminato da un rendering).

La pipeline dello shader di calcolo usa uno shader:

  • Shader di calcolo: opera su qualsiasi tipo di dati. L'output è indipendente dal numero di thread.

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

Per altre informazioni sui shader compilati, è necessario usare la reflection shader. Questo è essenzialmente come chiedere al runtime di decompilare gli shader e restituire le informazioni all'utente sul codice 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 nella sintassi della funzione di effetto (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 shader e qualsiasi altro stato della pipeline necessario per eseguire il rendering della geometria.

I gruppi sono facoltativi. Esiste un singolo 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 nella sintassi della tecnica degli effetti (Direct3D 11).

Effetti (Direct3D 11)