Organisieren des Zustands in einem Effekt (Direct3D 10)

Mit Direct3D 10 wird der Effektzustand für bestimmte Pipelinephasen durch die folgenden Strukturen organisiert:

Pipelinestatus Struktur
Eingabe-Assembler D3D10_INPUT_ELEMENT_DESC
Rasterung D3D10_RASTERIZER_DESC
Ausgabezusammenführung D3D10_BLEND_DESC und D3D10_DEPTH_STENCIL_DESC

 

Für die Shaderphasen, in denen die Anzahl der Zustandsänderungen stärker von einer Anwendung gesteuert werden muss, wurde der Zustand in konstanten Pufferzustand, Samplerzustand und Shaderressourcenzustand unterteilt. Dies ermöglicht es einer Anwendung, die sorgfältig entwickelt wurde, nur den zustand zu aktualisieren, der sich ändert, wodurch die Leistung verbessert wird, indem die Datenmenge reduziert wird, die an die GPU übergeben werden muss.

Wie organisieren Sie also den Pipelinestatus in einem Effekt?

Die Antwort lautet, die Reihenfolge spielt keine Rolle. Globale Variablen müssen sich nicht oben befinden. Alle Beispiele im SDK folgen jedoch der gleichen Reihenfolge, da es sich bewährt hat, die Daten auf die gleiche Weise zu organisieren. Dies ist also eine kurze Beschreibung der Datenreihenfolge in den DirectX SDK-Beispielen.

Globale Variablen

Genau wie die C-Standardpraxis werden globale Variablen zuerst am Anfang der Datei deklariert. In den meisten Fällen handelt es sich dabei um Variablen, die von einer Anwendung initialisiert und dann in einem Effekt verwendet werden. Manchmal werden sie initialisiert und nie geändert, manchmal werden sie bei jedem Frame aktualisiert. Genau wie C-Funktionsbereichsregeln sind Effektvariablen, die außerhalb des Bereichs der Effektfunktionen deklariert wurden, während des gesamten Effekts sichtbar. Jede Variable, die innerhalb einer Effektfunktion deklariert wird, ist nur innerhalb dieser Funktion sichtbar.

Hier sehen Sie ein Beispiel für die Variablen, die in BasicHLSL10.fx deklariert wurden.

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

Die Syntax für Effektvariablen ist ausführlicher unter Effektvariablensyntax (Direct3D 10). Die Syntax für Effekttextur-Sampler ist ausführlicher unter Sampler Type (DirectX HLSL).

Shader

Shader sind kleine ausführbare Programme. Sie können sich Shader als Kapselung des Shaderzustands vorstellen, da der HLSL-Code die Shaderfunktionalität implementiert. Die Pipeline verwendet drei verschiedene Arten von Shadern.

  • Vertexshader: Arbeiten mit Vertexdaten. Ein Scheitelpunkt in ergibt einen Scheitelpunkt.
  • Geometry-Shader: Arbeiten mit primitiven Daten. Ein Grundtyp in ergibt möglicherweise 0, 1 oder viele Grundtypen.
  • Pixelshader: Arbeiten sie mit Pixeldaten. Ein Pixel in ergibt 1 Pixel (es sei denn, das Pixel wird aus einem Rendern herausgekullt).

Shader sind lokale Funktionen und folgen den Funktionsregeln im C-Stil. Wenn ein Effekt kompiliert wird, wird jeder Shader kompiliert, und ein Zeiger auf jede Shaderfunktion wird intern gespeichert. Bei erfolgreicher Kompilierung wird eine ID3D10Effect-Schnittstelle zurückgegeben. An diesem Punkt befindet sich der kompilierte Effekt in einem Zwischenformat.

Um weitere Informationen zu den kompilierten Shadern zu erhalten, müssen Sie die Shaderreflektion verwenden. Dies ist im Wesentlichen so, als ob Die Runtime aufgefordert wird, die Shader zu dekompilieren und Informationen über den Shadercode an Sie zurückzugeben.

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

Die Syntax für Effektshader ist ausführlicher unter Effektfunktionssyntax (Direct3D 10) beschrieben.

Techniken und Pässe

Eine Technik ist eine Sammlung von Renderingdurchläufen (es muss mindestens ein Durchlauf vorhanden sein). Jeder Effektdurchlauf (der im Bereich einem einzelnen Durchlauf in einer Renderschleife ähnelt) definiert den Shaderzustand und jeden anderen Pipelinezustand, der zum Rendern der Geometrie erforderlich ist.

Hier ist ein Beispiel für eine Technik (die einen Durchlauf umfasst) aus BasicHLSL10.fx.

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

Die Syntax für Effektshader ist ausführlicher unter Effect Technique Syntax (Direct3D 10) beschrieben.

Effekte (Direct3D 10)