Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Algumas constantes de efeito só precisam ser inicializadas. Uma vez inicializado, o estado do efeito é definido como o dispositivo para todo o loop de renderização. Outras variáveis precisam ser atualizadas cada vez que o loop de renderização é chamado. O código básico para definir variáveis de efeito é mostrado abaixo, para cada um dos tipos de variáveis.
Um efeito encapsula todo o estado de renderização necessário para fazer um passo de renderização. Em termos de API, existem três tipos de estado encapsulados em um efeito.
Estado constante
Primeiro, declare variáveis em um efeito usando tipos de dados HLSL.
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4 g_MaterialAmbientColor; // Material's ambient color
float4 g_MaterialDiffuseColor; // Material's diffuse color
int g_nNumLights;
float3 g_LightDir[3]; // Light's direction in world space
float4 g_LightDiffuse[3]; // Light's diffuse color
float4 g_LightAmbient; // Light'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
Em segundo lugar, declare as variáveis no aplicativo que podem ser definidas pelo aplicativo e, em seguida, atualize as variáveis de efeito.
D3DXMATRIX mWorldViewProjection;
D3DXVECTOR3 vLightDir[MAX_LIGHTS];
D3DXVECTOR4 vLightDiffuse[MAX_LIGHTS];
D3DXMATRIX mWorld;
D3DXMATRIX mView;
D3DXMATRIX mProj;
// Get the projection and view matrix from the camera class
mWorld = g_mCenterMesh * *g_Camera.GetWorldMatrix();
mProj = *g_Camera.GetProjMatrix();
mView = *g_Camera.GetViewMatrix();
OnD3D11CreateDevice()
{
...
g_pLightDir = g_pEffect11->GetVariableByName( "g_LightDir" )->AsVector();
g_pLightDiffuse = g_pEffect11->GetVariableByName( "g_LightDiffuse" )->AsVector();
g_pmWorldViewProjection = g_pEffect11->GetVariableByName(
"g_mWorldViewProjection" )->AsMatrix();
g_pmWorld = g_pEffect11->GetVariableByName( "g_mWorld" )->AsMatrix();
g_pfTime = g_pEffect11->GetVariableByName( "g_fTime" )->AsScalar();
g_pMaterialAmbientColor = g_pEffect11->GetVariableByName("g_MaterialAmbientColor")->AsVector();
g_pMaterialDiffuseColor = g_pEffect11->GetVariableByName(
"g_MaterialDiffuseColor" )->AsVector();
g_pnNumLights = g_pEffect11->GetVariableByName( "g_nNumLights" )->AsScalar();
}
Em terceiro lugar, use os métodos de atualização para definir o valor das variáveis no aplicativo nas variáveis de efeito.
OnD3D11FrameRender()
{
...
g_pLightDir->SetRawValue( vLightDir, 0, sizeof(D3DXVECTOR3)*MAX_LIGHTS );
g_pLightDiffuse->SetFloatVectorArray( (float*)vLightDiffuse, 0, MAX_LIGHTS );
g_pmWorldViewProjection->SetMatrix( (float*)&mWorldViewProjection );
g_pmWorld->SetMatrix( (float*)&mWorld );
g_pfTime->SetFloat( (float)fTime );
g_pnNumLights->SetInt( g_nNumActiveLights );
}
Duas maneiras de obter o estado em uma variável de efeito
Há duas maneiras de obter o estado contido em uma variável de efeito. Dado um efeito que foi carregado na memória.
Uma maneira é obter o estado do amostrador de um ID3DX11EffectVariable que foi convertido como uma interface de amostrador.
D3D11_SAMPLER_DESC sampler_desc;
ID3D11EffectSamplerVariable* l_pD3D11EffectVariable = NULL;
if( g_pEffect11 )
{
l_pD3D11EffectVariable = g_pEffect11->GetVariableByName( "MeshTextureSampler" )->AsSampler();
if( l_pD3D11EffectVariable->IsValid() )
hr = (l_pD3D11EffectVariable->GetBackingStore( 0,
&sampler_desc );
}
A outra maneira é obter o estado do amostrador de um ID3D11SamplerState.
ID3D11SamplerState* l_ppSamplerState = NULL;
D3D11_SAMPLER_DESC sampler_desc;
ID3D11EffectSamplerVariable* l_pD3D11EffectVariable = NULL;
if( g_pEffect11 )
{
l_pD3D11EffectVariable = g_pEffect11->GetVariableByName( "MeshTextureSampler" )->AsSampler();
if( l_pD3D11EffectVariable->IsValid )
{
hr = l_pD3D11EffectVariable->GetSampler( 0,
&l_ppSamplerState );
if( l_ppSamplerState )
l_ppSamplerState->GetDesc( &sampler_desc );
}
}
Estado de sombreamento
O estado de sombreador é declarado e atribuído em uma técnica de efeito, dentro de uma passagem.
VertexShader vsRenderScene = CompileShader( vs_4_0, RenderSceneVS( 1, true, true );
technique10 RenderSceneWithTexture1Light
{
pass P0
{
SetVertexShader( vsRenderScene );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
}
}
Isso funciona exatamente como se você não estivesse usando um efeito. Há três chamadas, uma para cada tipo de sombreador (vértice, geometria e pixel). O primeiro, SetVertexShader, chama ID3D11DeviceContext::VSSetShader. CompileShader é uma função de efeito especial que usa o perfil de sombreador (vs_4_0) e o nome da função de sombreador de vértice (RenderVS). Em outras palavras, cada uma dessas chamadas CompileShader compila sua função de sombreador associada e retorna um ponteiro para o sombreador compilado.
Observe que nem todo o estado do sombreador deve ser definido. Esta passagem não inclui nenhuma chamada SetHullShader ou SetDomainShader, o que significa que os sombreadores de casco e domínio atualmente vinculados permanecerão inalterados.
Estado da textura
O estado de textura é um pouco mais complexo do que definir uma variável, porque os dados de textura não são simplesmente lidos como uma variável, eles são amostrados a partir de uma textura. Portanto, você deve definir a variável de textura (assim como uma variável normal, exceto que usa um tipo de textura) e você deve definir as condições de amostragem. Aqui está um exemplo de uma declaração de variável de textura e a declaração de estado de amostragem correspondente.
Texture2D g_MeshTexture; // Color texture for mesh
SamplerState MeshTextureSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
Aqui está um exemplo de como definir uma textura de um aplicativo. Neste exemplo, a textura é armazenada nos dados de malha, que foram carregados quando o efeito foi criado.
O primeiro passo é obter um ponteiro para a textura do efeito (da malha).
ID3D11EffectShaderResourceVariable* g_ptxDiffuse = NULL;
// Obtain variables
g_ptxDiffuse = g_pEffect11->GetVariableByName( "g_MeshTexture" )->AsShaderResource();
A segunda etapa é especificar uma exibição para acessar a textura. O modo de exibição define uma maneira geral de acessar os dados do recurso de textura.
OnD3D11FrameRender()
{
ID3D11ShaderResourceView* pDiffuseRV = NULL;
...
pDiffuseRV = g_Mesh11.GetMaterial(pSubset->MaterialID)->pDiffuseRV11;
g_ptxDiffuse->SetResource( pDiffuseRV );
...
}
Do ponto de vista do aplicativo, as exibições de acesso não ordenado são tratadas de forma semelhante às exibições de recursos de sombreador. No entanto, nas funções de sombreador de pixel de efeito e sombreador de computação, os dados de exibição de acesso não ordenado são lidos/gravados diretamente. Não é possível obter amostras a partir de uma vista de acesso não ordenado.
Para obter mais informações sobre como exibir recursos, consulte Recursos.
Tópicos relacionados