Udostępnij przez


Organizowanie stanu w efekcie Direct3D 11

W Direct3D 11 stan efektu dla niektórych etapach potoku jest zorganizowany za pomocą struktur. Oto struktury:

Stan rurociągu Struktura
Rasteryzacja D3D11_RASTERIZER_DESC
Fuzja danych wyjściowych D3D11_BLEND_DESC i D3D11_DEPTH_STENCIL_DESC
Shadery Zobacz poniżej

 

W przypadku etapów cieniowania, w których liczba zmian stanu musi być bardziej kontrolowana przez aplikację, stan został podzielony na stan stałego buforu, stan próbnika, stan cieniowania zasobów i stan widoku dostępu nieuporządkowanego (w przypadku cieniowania pikseli i obliczeń). Dzięki temu aplikacja, która jest starannie zaprojektowana, aktualizuje tylko zmieniający się stan, co poprawia wydajność, zmniejszając ilość danych, które należy przekazać do GPU.

Jak więc uporządkować stan pipeline'u w efekcie?

Odpowiedź brzmi: kolejność nie ma znaczenia. Zmienne globalne nie muszą znajdować się u góry. Jednak wszystkie przykłady w zestawie SDK są zgodne z tą samą kolejnością, ponieważ dobrym rozwiązaniem jest zorganizowanie danych w taki sam sposób. Dlatego jest to krótki opis kolejności danych w przykładach zestawu SDK DirectX.

Zmienne globalne

Podobnie jak w przypadku standardowej praktyki języka C zmienne globalne są deklarowane jako pierwsze w górnej części pliku. Najczęściej są to zmienne, które będą inicjowane przez aplikację, a następnie używane w efekcie. Czasami są one inicjowane i nigdy nie zmieniane, inne czasy są aktualizowane w każdej ramce. Podobnie jak reguły zakresu funkcji języka C, zmienne efektów zadeklarowane poza zakresem funkcji efektu są widoczne w całym efekcie; dowolna zmienna zadeklarowana wewnątrz funkcji efektu jest widoczna tylko w tej funkcji.

Oto przykład zmiennych zadeklarowanych w pliku 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;
};

Składnia zmiennych efektu jest bardziej szczegółowo opisana w Składnia zmiennej efektu (Direct3D 11). Składnia tekstur próbkowania efektu jest bardziej szczegółowo opisana w typie Sampler (DirectX HLSL).

Shadery

Shadery to małe programy wykonywalne. Moduły cieniowania można traktować jako hermetyzujące stan modułu cieniowania, ponieważ kod HLSL implementuje funkcjonalność modułu cieniowania. Potok przetwarzania grafiki do pięciu różnych rodzajów shaderów.

  • Shader wierzchołkowy — działają na danych wierzchołków. Jeden wierzchołek w daje jeden wierzchołek z.
  • Cieniowania kadłuba — działają na danych poprawek. Faza punktu kontrolnego: jedno wywołanie daje jeden punkt kontrolny; Dla każdej fazy rozwidlenia i sprzężenia: jedna poprawka dostarcza pewną ilość stałych danych poprawek.
  • Cieniowanie domenowe — działają na danych prymitywnych. Jeden prymityw może generować 0, 1 lub wiele prymitywów.
  • Cieniowania geometrii — działają na danych pierwotnych. Jeden z elementów pierwotnych może przynieść 0, 1 lub wiele elementów pierwotnych.
  • Cieniowanie pikseli — działa na danych pikseli. Jeden piksel wejściowy daje 1 piksel wyjściowy (chyba że piksel zostanie usunięty z renderowania).

Potok cieniowania obliczeń używa jednego cieniowania:

  • Cieniowania obliczeniowe — działają na dowolnym rodzaju danych. Dane wyjściowe są niezależne od liczby wątków.

Shadery są funkcjami lokalnymi, które postępują zgodnie z regułami funkcji w stylu języka C. Po skompilowaniu efektu każdy moduł cieniowania jest kompilowany, a wskaźnik do każdej funkcji cieniowania jest przechowywany wewnętrznie. Po pomyślnym zakończeniu kompilacji zwracany jest interfejs ID3D11Effect. W tym momencie skompilowany efekt jest w formacie pośrednim.

Aby dowiedzieć się więcej o skompilowanych shaderach, należy użyć refleksji shaderów. Zasadniczo przypomina to proszenie środowiska uruchomieniowego o dekompilację shaderów i zwrócenie Tobie informacji o kodzie shaderów.

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

Składnia cieniowania efektów jest bardziej szczegółowa w Składnia funkcji efektu (Direct3D 11).

Grupy, techniki i przebiegi

Grupa jest kolekcją technik. Technika jest kolekcją przebiegów renderowania (musi istnieć co najmniej jeden przebieg). Każdy przebieg efektu (podobny do pojedynczego przebiegu w pętli renderowania) definiuje stan shadera oraz inne stany potoku niezbędne do renderowania geometrii.

Grupy są opcjonalne. Istnieje jedna, nienazwana grupa, która obejmuje wszystkie techniki globalne. Wszystkie inne grupy muszą mieć nazwę .

Oto przykład jednej techniki (która obejmuje jedno przekazanie) z 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() ) );
        }
    }
}

Składnia shaderów efektów jest bardziej szczegółowo opisana w Składnia techniki efektu (Direct3D 11).

Efekty (Direct3D 11)