Freigeben über


Organisieren des Zustands in einem Effekt (Direct3D 11)

Mit Direct3D 11 wird der Effektzustand für bestimmte Pipelinephasen nach Strukturen organisiert. Dies sind die Strukturen:

Pipelinestatus Struktur
Rasterung D3D11_RASTERIZER_DESC
Ausgabezusammenführung D3D11_BLEND_DESC und D3D11_DEPTH_STENCIL_DESC
Shader Siehe unten

 

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, Shaderressourcenstatus und ungeordneten Zugriffsansichtszustand (für Pixel- und Compute-Shader) 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 11) beschrieben. 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 Grafikpipeline kann bis zu fünf verschiedene Arten von Shadern verwenden.

  • Vertexshader: Arbeiten mit Vertexdaten. Ein Scheitelpunkt in ergibt einen Scheitelpunkt.
  • Hull-Shader: Arbeiten sie mit Patchdaten. Kontrollpunktphase: Ein Aufruf ergibt einen Kontrollpunkt; Für jede Fork- und Joinphase: Ein Patch liefert eine bestimmte Menge an Patchkonstantendaten.
  • Domänenshader: Arbeiten mit primitiven Daten. Ein Grundtyp kann 0, 1 oder viele Grundtypen ergeben.
  • 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).

Die Compute-Shaderpipeline verwendet einen Shader:

  • Compute-Shader: Arbeiten sie mit jeder Art von Daten. Die Ausgabe ist unabhängig von der Anzahl der Threads.

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 ID3D11Effect-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 11) beschrieben.

Gruppen, Techniken und Pässe

Eine Gruppe ist eine Sammlung von Techniken. 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.

Gruppen sind optional. Es gibt eine einzelne, unbenannte Gruppe, die alle globalen Techniken umfasst. Alle anderen Gruppen müssen benannt werden.

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

fxgroup g0
{
    technique11 RunComputeShader
    {
        pass P0
        {
            SetComputeShader( CompileShader( cs_5_0, CS() ) );
        }
    }
}

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

Effekte (Direct3D 11)