Share via


Organizzazione dello stato in un effetto (Direct3D 10)

Con Direct3D 10, lo stato di effetto per determinate fasi della pipeline è organizzato dalle strutture seguenti:

Stato della pipeline Struttura
Assembler input D3D10_INPUT_ELEMENT_DESC
Rasterizzazione D3D10_RASTERIZER_DESC
Unione output D3D10_BLEND_DESC e D3D10_DEPTH_STENCIL_DESC

 

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 del campionatore e stato della risorsa shader. 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 si organizza lo stato della pipeline in un effetto?

La risposta è che l'ordine non è importante. 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 pratica 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 mai modificati, altre volte vengono aggiornati ogni fotogramma. Proprio come le regole dell'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 di effetto (Direct3D 10).The syntax for effect variables is more detailed in Effect Variable Syntax (Direct3D 10). La sintassi per gli esempi di trame degli effetti è più dettagliata in Sampler Type (DirectX HLSL).

Shader

Gli shader sono piccoli programmi eseguibili. È possibile considerare gli shader come incapsulare lo stato dello shader, poiché il codice HLSL implementa la funzionalità shader. La pipeline usa tre tipi diversi di shader.

  • Vertex shader: opera sui dati dei vertici. Un vertice in restituisce un vertice.
  • Geometry shader: opera sui dati primitivi. Una primitiva in può produrre 0, 1 o molte primitive.
  • Pixel shader: opera sui dati pixel. Un pixel in produce 1 pixel in uscita (a meno che il pixel non venga eliminato da un rendering).

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

Per altre informazioni sugli shader compilati, è necessario usare la reflection 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 Sintassi delle funzioni di effetto (Direct3D 10).The syntax for effect shader is more detailed in Effect Function Syntax (Direct3D 10).

Tecniche e passaggi

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.

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

La sintassi per gli shader degli effetti è più dettagliata in Sintassi della tecnica degli effetti (Direct3D 10).The syntax for effect shader is more detailed in Effect Technique Syntax (Direct3D 10).

Effetti (Direct3D 10)