在效果中配置狀態(Direct3D 11)
使用 Direct3D 11 時,特定管線階段的效果狀態會依結構來組織。 以下是結構:
管線狀態 | 結構 |
---|---|
點陣化 | D3D11_RASTERIZER_DESC |
輸出合併 | D3D11_BLEND_DESC 和 D3D11_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)中更詳細。
相關主題