Partilhar via


Organizando o estado em um efeito (Direct3D 10)

Com o Direct3D 10, o estado de efeito para determinados estágios de pipeline é organizado pelas seguintes estruturas:

Estado do gasoduto Estrutura
Montador de entrada D3D10_INPUT_ELEMENT_DESC
Rasterização D3D10_RASTERIZER_DESC
Fusão de Saída D3D10_BLEND_DESC e D3D10_DEPTH_STENCIL_DESC

 

Para os estágios de sombreador, onde o número de alterações de estado precisa ser mais controlado por um aplicativo, o estado foi dividido em estado de buffer constante, estado de amostrador e estado de recurso de sombreador. Isso permite que um aplicativo cuidadosamente projetado atualize apenas o estado que está mudando, o que melhora o desempenho reduzindo a quantidade de dados que precisam ser passados para a GPU.

Então, como você organiza o estado do pipeline em um efeito?

A resposta é: a ordem não importa. As variáveis globais não precisam estar localizadas na parte superior. No entanto, todos os exemplos no SDK seguem a mesma ordem, pois é uma boa prática organizar os dados da mesma maneira. Portanto, esta é uma breve descrição da ordem de dados nos exemplos do SDK do DirectX.

Variáveis globais

Assim como a prática C padrão, as variáveis globais são declaradas primeiro, na parte superior do arquivo. Na maioria das vezes, essas são variáveis que serão inicializadas por um aplicativo e, em seguida, usadas em um efeito. Às vezes eles são inicializados e nunca alterados, outras vezes eles são atualizados a cada quadro. Assim como as regras de escopo da função C, as variáveis de efeito declaradas fora do escopo das funções de efeito são visíveis em todo o efeito; Qualquer variável declarada dentro de uma função de efeito só é visível dentro dessa função.

Aqui está um exemplo das variáveis declaradas em 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;
};

A sintaxe das variáveis de efeito é mais detalhadamente detalhada em Sintaxe da Variável de Efeito (Direct3D 10). A sintaxe para amostradores de textura de efeito é mais detalhada em Tipo de amostrador (DirectX HLSL).

Sombreadores

Os sombreadores são pequenos programas executáveis. Você pode pensar em sombreadores como encapsulando o estado do sombreador, uma vez que o código HLSL implementa a funcionalidade do sombreador. A canalização utiliza três tipos diferentes de sombreadores.

  • Sombreadores de vértice - Operam em dados de vértice. Um vértice de entrada produz um vértice de saída.
  • Sombreadores de geometria - Operam em dados primitivos. Um único primitivo pode gerar 0, 1 ou vários primitivos de saída.
  • Sombreadores de pixel - Operam em dados de pixel. Um pixel de entrada gera 1 pixel de saída (a menos que o pixel seja removido de uma renderização).

Os sombreadores são funções locais e seguem regras de função de estilo C. Quando um efeito é compilado, cada sombreador é compilado e um ponteiro para cada função de sombreador é armazenado internamente. Uma interface ID3D10Effect é retornada quando a compilação é bem-sucedida. Neste ponto, o efeito compilado está em um formato intermediário.

Para obter mais informações sobre os sombreadores compilados, você precisará usar o reflexo do sombreador. Isso é essencialmente como pedir ao runtime para descompilar os shaders e retornar informações sobre o código do 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;
}

A sintaxe dos sombreadores de efeito é descrita de forma mais detalhada em Sintaxe da Função de Efeito (Direct3D 10).

Técnicas e Passes

Uma técnica é uma coleção de passes de renderização (deve haver pelo menos um passe). Cada passagem de efeito (que é semelhante em escopo a uma única passagem em um loop de renderização) define o estado do sombreador e qualquer outro estado de pipeline necessário para renderizar a geometria.

Aqui está um exemplo de técnica (que inclui uma só passagem) do BasicHLSL10.fx.

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

A sintaxe dos sombreadores de efeito é descrita de forma mais completa em Sintaxe da Técnica de Efeito (Direct3D 10).

Efeitos (Direct3D 10)