共用方式為


在效果中配置狀態(Direct3D 11)

使用 Direct3D 11 時,特定管線階段的效果狀態會依結構來組織。 以下是結構:

管線狀態 結構
點陣化 D3D11_RASTERIZER_DESC
輸出合併 D3D11_BLEND_DESCD3D11_DEPTH_STENCIL_DESC
著色器 請參閱下方

 

針對著色器階段,其中狀態變更數目需要由應用程式控制得比較多,狀態已分成常數緩衝區狀態、取樣器狀態、著色器資源狀態,以及未排序的存取檢視狀態(針對圖元和計算著色器)。 這可讓設計為只更新變更狀態的應用程式,藉由減少需要傳遞至 GPU 的數據量來改善效能。

那麼,您要如何以效果組織管線狀態?

答案是,順序並不重要。 全域變數不一定位於頂端。 不過,SDK 中的所有範例都遵循相同的順序,因為最好以相同方式組織數據。 因此,這是 DirectX SDK 範例中數據排序的簡短描述。

全域變數

就像標準 C 做法一樣,全域變數會先在檔案頂端宣告。 這些通常是由應用程式初始化的變數,然後在效果中使用。 某些時候會初始化它們,且永遠不會變更;其他時候則會更新每一幀。 就像 C 函式範圍規則一樣,在效果函式範圍之外宣告的效果變數在整個效果中都是可見的;在效果函式內宣告的任何變數,只會在該函式內顯示。

以下是 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;
};

效果變數的語法在 效果變數語法 (Direct3D 11)中更為詳細。 效果紋理取樣器的語法在 Sampler Type (DirectX HLSL)中更為完整。

著色器

著色器是小型可執行程式。 您可以將著色器視為封裝著色器狀態,因為 HLSL 程式代碼會實作著色器功能。 圖形管線最多五種不同的著色器。

  • 頂點著色器 - 執行頂點數據的運算。 "一個頂點進入會產生一個頂點出去。"
  • 船體著色器 - 在補丁數據上運算。 控制點階段:一個調用會產生一個控制點;針對每個分支和聯結階段:一個修補程式會產生一些修補程式常數數據。
  • 網域著色器 - 在基本數據上作。 一個基元可能會產生 0、1 或多個基元。
  • 幾何著色器 - 對基本幾何體數據進行運算。 在某一情境中的一個基元可能會產生 0、1 或許多基元。
  • 圖元著色器 - 對像素數據進行作。 輸入的一個像素會輸出一個像素(除非像素在渲染中被排除)。

計算著色器管線使用一個著色器:

  • 計算著色器 - 對任何類型的資料進行操作。 輸出與線程數目無關。

著色器是本地函式,並遵循 C 語言風格的函式規則。 當一個效果被編譯時,每個著色器都會被編譯,並且每個著色器函式的指標會被儲存於內部。 編譯成功時會傳回ID3D11Effect介面。 此時,編譯後的結果是中繼格式。

若要瞭解更多關於已編譯的著色器,您需要使用著色器反射。 這基本上就像要求執行時將著色器分解,並回傳著色器程式碼的資訊給您。

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

效果著色器的語法在 效果函式語法 (Direct3D 11)中更為詳細。

群組、技術和傳球

群組是技術集合。 渲染技巧是渲染處理步驟的集合(至少必須有一個步驟)。 每個效果傳遞(範圍類似於轉譯迴圈中的單一傳遞)都會定義著色器狀態和轉譯幾何所需的任何其他管線狀態。

群組是選擇性的。 有一個包含所有全域技術的單一未命名群組。 所有其他群組都必須命名。

以下是來自 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() ) );
        }
    }
}

效果著色器的語法在 效果技術語法 (Direct3D 11)中更詳細。

效果(Direct3D 11)