Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Einige Effektkonstanten müssen nur initialisiert werden. Nach der Initialisierung wird der Effektstatus für die gesamte Renderschleife auf das Gerät festgelegt. Andere Variablen müssen jedes Mal aktualisiert werden, wenn die Renderschleife aufgerufen wird. Der grundlegende Code zum Festlegen von Effektvariablen wird unten für jeden Variablentyp angezeigt.
Ein Effekt kapselt den gesamten Renderzustand, der zum Ausführen eines Renderingdurchlaufs erforderlich ist. In Bezug auf die API gibt es drei Typen von Status, die in einem Effekt gekapselt sind.
Konstanter Zustand
Deklarieren Sie zunächst Variablen in einem Effekt mithilfe von HLSL-Datentypen.
//--------------------------------------------------------------------------------------
// 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
Deklarieren Sie anschließend Variablen in der Anwendung, die von der Anwendung festgelegt werden können, und aktualisieren Sie dann die Effektvariablen.
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();
}
Verwenden Sie drittens die Updatemethoden, um den Wert der Variablen in der Anwendung in den Effektvariablen festzulegen.
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 );
}
Zwei Möglichkeiten zum Abrufen des Zustands in einer Effektvariable
Es gibt zwei Möglichkeiten zum Abrufen des In einer Effektvariablen enthaltenen Zustands. Aufgrund eines Effekts, der in den Arbeitsspeicher geladen wurde.
Eine Möglichkeit besteht darin, den Samplerstatus aus einer ID3DX11EffectVariable- abzurufen, die als Samplerschnittstelle umgestellt wurde.
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 );
}
Die andere Möglichkeit besteht darin, den Samplerstatus aus einem ID3D11SamplerState-abzurufen.
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 );
}
}
Shaderstatus
Der Shaderstatus wird innerhalb eines Durchlaufs in einer Effekttechnik deklariert und zugewiesen.
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 ) ) );
}
}
Dies funktioniert genauso wie wenn Sie keinen Effekt verwenden würden. Für jeden Shadertyp (Vertex, Geometrie und Pixel) gibt es drei Aufrufe. Der erste, SetVertexShader, ruft ID3D11DeviceContext::VSSetShaderauf. CompileShader ist eine Spezialeffektfunktion, die das Shaderprofil (vs_4_0) und den Namen der Vertex-Shaderfunktion (RenderVS) verwendet. Anders ausgedrückt: Jeder dieser CompileShader-Aufrufe kompiliert die zugehörige Shaderfunktion und gibt einen Zeiger auf den kompilierten Shader zurück.
Beachten Sie, dass nicht der gesamte Shaderstatus festgelegt werden muss. Dieser Pass enthält keine SetHullShader- oder SetDomainShader-Aufrufe, was bedeutet, dass die derzeit gebundenen Hull- und Domänen-Shader unverändert bleiben.
Texturzustand
Der Texturzustand ist etwas komplexer als das Festlegen einer Variablen, da Texturdaten nicht einfach wie eine Variable gelesen werden, wird sie aus einer Textur entnommen. Daher müssen Sie die Texturvariable (genau wie eine normale Variable mit Ausnahme eines Texturtyps) definieren und die Samplingbedingungen definieren. Nachfolgend sehen Sie ein Beispiel für eine Texturvariablendeklaration und die entsprechende Samplingzustandsdeklaration.
Texture2D g_MeshTexture; // Color texture for mesh
SamplerState MeshTextureSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
Hier ist ein Beispiel für das Festlegen einer Textur aus einer Anwendung. In diesem Beispiel wird die Textur in den Gitterdaten gespeichert, die beim Erstellen des Effekts geladen wurden.
Der erste Schritt besteht darin, einen Zeiger auf die Textur vom Effekt (aus dem Gitter) zu erhalten.
ID3D11EffectShaderResourceVariable* g_ptxDiffuse = NULL;
// Obtain variables
g_ptxDiffuse = g_pEffect11->GetVariableByName( "g_MeshTexture" )->AsShaderResource();
Im zweiten Schritt wird eine Ansicht für den Zugriff auf die Textur angegeben. Die Ansicht definiert eine allgemeine Methode für den Zugriff auf die Daten aus der Texturressource.
OnD3D11FrameRender()
{
ID3D11ShaderResourceView* pDiffuseRV = NULL;
...
pDiffuseRV = g_Mesh11.GetMaterial(pSubset->MaterialID)->pDiffuseRV11;
g_ptxDiffuse->SetResource( pDiffuseRV );
...
}
Aus Anwendungsperspektive werden ungeordnete Zugriffsansichten ähnlich wie Shaderressourcenansichten behandelt. In den Effekt-Pixelshader- und Compute-Shaderfunktionen werden ungeordnete Zugriffsansichtsdaten jedoch direkt gelesen/geschrieben. Sie können keine Stichproben aus einer nicht angeordneten Zugriffsansicht ausführen.
Weitere Informationen zum Anzeigen von Ressourcen finden Sie unter Resources.
Verwandte Themen