Udostępnij przez


Organizowanie stanu w efekcie (Direct3D 10)

W przypadku Direct3D 10 stan efektów dla niektórych etapów potokowych został zorganizowany przez następujące struktury:

Stan przepływu Struktura
Asembler wejściowy D3D10_INPUT_ELEMENT_DESC
Rasteryzacja D3D10_RASTERIZER_DESC
Fuzja danych wyjściowych D3D10_BLEND_DESC i D3D10_DEPTH_STENCIL_DESC

 

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 i stan zasobu cieniowania. To pozwala aplikacji, która została starannie zaprojektowana, aby aktualizować tylko zmieniający się stan, co zwiększa wydajność przez zmniejszenie ilości danych przekazywanych do procesora graficznego.

Jak więc uporządkować stan potoku 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 efektów jest szczegółowo opisana w Składnia zmiennej efektu (Direct3D 10). Składnia próbek tekstury efektów jest bardziej szczegółowo opisana w Typ Sampler (DirectX HLSL).

Shadery

Shadery to małe programy wykonywalne. Moduły cieniowania można traktować jako hermetyzujące stan cieniowania, ponieważ kod HLSL implementuje funkcję cieniowania. Pipeline używa trzech różnych rodzajów shaderów.

  • Cieniowania wierzchołków — działają na danych wierzchołków. Jeden wierzchołek w przekształca się w jeden wierzchołek na zewnątrz.
  • Cieniowania geometrii — działają na danych pierwotnych. Jeden prymityw na wejściu może dać 0, 1 lub wiele prymitywów na wyjściu.
  • Cieniowanie pikseli — działa na danych pikseli. Jeden piksel wchodzący wychodzi 1 piksel (chyba że piksel zostanie usunięty z procesu renderowania).

Funkcje cieni są lokalne i przestrzegają reguł 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 ID3D10Effect. W tym momencie skompilowany efekt jest w formacie pośrednim.

Aby dowiedzieć się więcej informacji o skompilowanych shaderach, należy użyć refleksji shaderów. To w zasadzie tak, jakby prosić środowisko wykonawcze o dekompilację shaderów i zwrócenie Ci 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 10).

Techniki i przejścia

Technika jest kolekcją przebiegów renderowania (musi istnieć co najmniej jeden przebieg). Każdy przebieg efektu (który jest podobny w zakresie do pojedynczego przekazywania w pętli renderowania) definiuje stan cieniowania i dowolny inny stan potoku niezbędny do renderowania geometrii.

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

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

Efekty (Direct3D 10)