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 pipeline | Estrutura |
---|---|
Assembler de entrada | D3D10_INPUT_ELEMENT_DESC |
Rasterization | D3D10_RASTERIZER_DESC |
Fusão de saída | D3D10_BLEND_DESC e D3D10_DEPTH_STENCIL_DESC |
Para os estágios do sombreador, em que 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 do sampler e estado do recurso de sombreador. Isso permite que um aplicativo cuidadosamente projetado atualize apenas o estado que está sendo alterado, o que melhora o desempenho reduzindo a quantidade de dados que precisam ser passados para a GPU.
Então, como organizar o estado do pipeline em um efeito?
A resposta é que 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, essa é uma breve descrição da ordenação 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 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 durante 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 para variáveis de efeito é mais detalhada em Sintaxe variável de efeito (Direct3D 10). A sintaxe para amostradores de textura de efeito é mais detalhada em Tipo de Amostra (DirectX HLSL).
Sombreadores
Sombreadores são pequenos programas executáveis. Você pode pensar em sombreadores como encapsulando o estado do sombreador, já que o código HLSL implementa a funcionalidade do sombreador. O pipeline usa três tipos diferentes de sombreadores.
- Sombreadores de vértice – operar em dados de vértice. Um vértice em produz um vértice.
- Sombreadores de geometria – operar em dados primitivos. Um primitivo em pode produzir 0, 1 ou muitos primitivos.
- Sombreadores de pixel – operar em dados de pixel. Um pixel em produz 1 pixel para fora (a menos que o pixel seja retirado de uma renderização).
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 saber mais sobre os sombreadores compilados, você precisará usar a reflexão do sombreador. Isso é essencialmente como pedir ao runtime para descompilar os sombreadores e retornar informações sobre o código do sombreador.
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 para sombreadores de efeito é mais detalhada na Sintaxe da Função de Efeito (Direct3D 10).
Técnicas e passagens
Uma técnica é uma coleção de passes de renderização (deve haver pelo menos uma passagem). Cada passagem de efeito (que é semelhante no 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 uma técnica (que inclui uma passagem) de 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 para sombreadores de efeito é mais detalhada em Sintaxe de Técnica de Efeito (Direct3D 10).
Tópicos relacionados