共用方式為


著色器模型 3 (HLSL 參考)

頂點著色器和像素著色器可從舊版的著色器大幅簡化。 如果您要在硬體中實作著色器,則可能不會搭配任何其他著色器版本使用vs_3_0或ps_3_0,而且不能搭配固定函式管線使用任何一種著色器類型。 這些變更可讓您簡化驅動程式和運行時間。 唯一的例外是,僅限軟體vs_3_0著色器可以搭配任何像素著色器版本使用。 此外,如果您使用軟體專用vs_3_0著色器搭配舊版圖元著色器,頂點著色器只能使用與彈性頂點格式 (FVF) 程式代碼相容的輸出語意。

頂點著色器輸出上所使用的語意必須用於圖元著色器輸入。 語意可用來將頂點著色器輸出對應至圖元著色器輸入,類似於頂點宣告對應至頂點著色器輸入緩存器和先前著色器模型的方式。 請參閱 vs 3.0 和 ps 3.0 著色器的比對語意。

已新增其他換行模式轉譯狀態,以涵蓋這個新配置中其他紋理座標的可能性。 當設定對應的 D3DRS_WRAP* 時,具有D3DDECLUSAGE_TEXCOORD及使用索引從 0 到 15 的屬性會在換行模式中插補。

頂點著色器模型 3 功能

頂點著色器輸出緩存器類型已折疊成十二個緩存器(請參閱 輸出緩存器)。 每個使用的快取器都必須使用 dcl 指令和語意來宣告(例如,dcl_color0 o0.xyzw)。

3_0 頂點著色器模型(vs_3_0)擴充了 vs_2_0具有更強大緩存器索引編製、一組簡化輸出緩存器、取樣頂點著色器紋理的能力,以及控制著色器輸入初始化速率的功能。

編製任何緩存器索引

所有快取器(輸入快取器輸出快取器)都可以使用 循環計數器緩存器編製索引(只有常數緩存器可以在舊版中編製索引)。

您必須先宣告輸入和輸出緩存器,才能編製索引。 不過,您無法編製任何已宣告位置或點大小語意的輸出緩存器索引。 事實上,如果使用索引編製,則必須分別在 o0 和 o1 快取器中宣告位置和 psize 語意。

您只能編製連續緩存器範圍的索引;也就是說,您無法跨尚未宣告的緩存器編製索引。 雖然這項限制可能不方便,但它允許進行硬體優化。 嘗試跨非連續緩存器編製索引會產生未定義的結果。 著色器驗證不會強制執行此限制。

簡化輸出快取器

所有類型的輸出緩存器都已折迭成 12 個輸出緩存器:1 代表位置、2 代表色彩、8 代表紋理,1 代表霧或點大小。 這些快取器會插補它們針對圖元著色器所包含的任何數據。 輸出快取器宣告是必要的,並將語意指派給每個緩存器。

快取器可以細分如下:

  • 至少一個緩存器必須宣告為四元件位置緩存器。 這是唯一需要的頂點著色器緩存器。
  • 著色器取用的前十個緩存器最多可以使用四個元件 (xyzw) 最大值。
  • 最後一個(或第十二個)緩存器只能包含純量(例如點大小)。

如需快取器的清單,請參閱 Registers - vs_3_0

頂點著色器中的紋理範例

頂點著色器 3_0 支援頂點著色器中的紋理查閱,texldl - vs

圖元著色器模型 3 功能

圖元著色器色彩和紋理緩存器已折疊成十個輸入緩存器(請參閱 輸入緩存器類型)。 臉部快取器是浮點純量緩存器。 只有這個緩存器的正負號有效。 如果正負號,則基本類型為背面。 例如,這可以在圖元著色器內使用,以達到雙面光源。 位置快取器會參考目前的 (x,y) 圖元。

您可以使用下列項目來設定著色器常數快取器:

比對vs_3_0和ps_3_0著色器的語意

語意使用方式有一些限制,vs_3_0和ps_3_0。 一般而言,針對符合著色器輸出上所用語意的著色器輸入使用語意時,您必須小心。

例如,這個像素著色器會將多個名稱封裝成一個緩存器:

ps_3_0 
dcl_texcoord0 v0.x 
dcl_texcoord1 v0.yz // Valid to pack multiple names into one register 
dcl_texcoord2_centroid v1.w
...

每個快取器都有不同的語意。 請注意,您也可以使用寫入掩碼,將 v0.x 和 v0.yz 命名為具有不同(多個)語意。

假設圖元著色器,下列vs_3_0著色器無法與它配對:

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o6.yzw 
...

這兩個著色器會與其使用 D3DDECLUSAGE_TEXCOORD0 And D3DDECLUSAGE_TEXCOORD1 語意發生衝突。

請重寫這樣的頂點著色器,以避免語意衝突:

vs_3_0 
... 
dcl_texcoord2 o3 
dcl_texcoord3 o9 
...

同樣地,在圖元著色器的不同輸入緩存器上宣告的語意名稱(圖元著色器中的 v0 和 v1)不能用於這個頂點著色器中的單一輸出緩存器。 例如,這個頂點著色器無法與像素著色器配對,因為D3DDECLUSAGE_TEXCOORD1用於圖元著色器輸入緩存器 (v0, v1) 和頂點著色器輸出緩存器 o3。

vs_3_0 
... 
dcl_texcoord0 o3.x 
dcl_texcoord1 o3.yz 

dcl_texcoord2 o3.w // BAD! Would be valid if this were not o3 
dcl_texcoord3 o9 ... 

另一方面,這個頂點著色器無法與像素著色器配對,因為具有指定語意的參數輸出遮罩不提供圖元著色器所要求的數據:

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o5.yzw 
dcl_texcoord2 o7.yz // BAD! Would be valid if w were included 
dcl_texcoord3 o9 
... 

這個頂點著色器不提供具有圖元著色器所要求之其中一個語意名稱的輸出,因此著色器配對無效:

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o5.yzw 
dcl_texcoord3 o9 
// The pixel shader wants texcoord2, with a w component, 
// but it isn't output by this vertex shader at all! 
... 

霧、深度和底紋模式變更

當D3DRS_SHADEMODE在裁剪和三角形點陣化期間設定平面底紋時,具有D3DDECLUSAGE_COLOR的屬性會以平面陰影插入。 如果緩存器的任何元件都以色彩語意宣告,但相同緩存器的其他元件會獲得不同的語意,則該緩存器中的元件上不會定義平面底紋插補點(線性與平面),而不會有色彩語意。

如果需要霧轉譯,vs_3_0和ps_3_0著色器必須實作霧。 著色器之外不會進行霧化計算。 vs_3_0中沒有霧緩存器,其他語意D3DDECLUSAGE_FOG(針對每個頂點計算的霧混合因數)和D3DDECLUSAGE_DEPTH(用於將深度值傳遞至圖元著色器以計算霧混合因數) 已加入。

使用圖元著色器 3.0 時,會忽略紋理階段狀態D3DTSS_TEXCOORDINDEX。

已新增下列值以容納這些變更:

// Fog and Depth usages
D3DDECLUSAGE_FOG 
D3DDECLUSAGE_DEPTH 

// Additional wrap states for vs_3_0 attributes with D3DDECLUSAGE_TEXCOORD 
D3DRS_WRAP8 
D3DRS_WRAP9 
D3DRS_WRAP10 
D3DRS_WRAP11 
D3DRS_WRAP12 
D3DRS_WRAP13 
D3DRS_WRAP14 
D3DRS_WRAP15

浮點數和整數轉換

浮點數學發生在管線不同部分的不同精確度和範圍(16 位、24 位和 32 位)。 大於輸入該管線之管線的動態範圍值(例如,32 位浮點數紋理圖會取樣到ps_2_0中的 24 位浮點數管線中),會建立未定義的結果。 針對可預測的行為,您應該將這類值限制在動態範圍上限。

從浮點值轉換成整數會發生在數個位置,例如:

  • 遇到 mova - vs 指示時。
  • 在紋理尋址期間。
  • 寫出至非浮點轉譯目標時。

指定完整或部分有效位數

ps_3_0和ps_2_x都支援兩種精確度層級:

ps_3_0 ps_2_0 精度 價值
x 滿 fp32 或更高版本
x 部分有效位數 fp16=s10e5
x x 滿 fp24=s16e7 或更高版本
x x 部分有效位數 fp16=s10e5

 

ps_3_0支援比ps_2_0更高的精確度。 根據預設,所有作業都會在完整有效位數層級進行。

部分精確度(請參閱 像素著色器緩存器修飾詞),方法是將_pp修飾詞新增至著色器程式代碼(前提是基礎實作支援它)。 實作一律可以忽略 修飾詞,並以完整精確度執行受影響的作業。

_pp修飾詞可以發生在兩個內容中:

  • 在紋理座標宣告上,將部分精確度紋理座標傳遞至圖元著色器。 當紋理座標將色彩數據轉接至圖元著色器時,可能會比某些實作中的完整精確度更快。
  • 在任何要求使用部分精確度的指令上,包括紋理載入指令。 這表示允許實作以部分有效位數執行指令,並儲存部分有效位數結果。 如果沒有明確的修飾詞,指令必須以完整精確度執行(不論輸入作數的有效位數為何)。

應用程式可能會刻意選擇取捨效能的精確度。 有數種著色器輸入數據是部分精確度處理的自然候選專案:

  • 色彩反覆運算器會以部分有效位數值表示。
  • 大部分格式的紋理值都可以以部分精確度值準確表示(從32位取樣的浮點格式紋理值是明顯的例外狀況)。
  • 常數可能會根據著色器的適當部分精確度表示來表示。

在這些情況下,開發人員可以選擇指定部分精確度來處理數據,知道不會遺失任何輸入數據精確度。 在某些情況下,著色器可能需要以完整精確度執行計算的內部步驟,即使輸入和最終輸出值沒有超過部分有效位數也一定。

軟體頂點和像素著色器

2_0 版著色器及更新版本的軟體實作(頂點著色器的運行時間和參考和圖元著色器的參考)具有一些寬鬆的驗證。 這對於偵錯和原型設計用途很有用。 應用程式會向運行時間/組譯工具指出,它需要使用組合器中的_sw旗標來放寬某些驗證(例如,vs_2_sw)。 軟體著色器不適用於硬體。

vs_2_sw是放寬vs_2_x上限:同樣地,ps_2_sw是放寬ps_2_x上限。 具體來說,下列驗證是寬鬆的:

著色器模型 資源 限制
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw 指令計數 無限
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw Float 常數緩存器 8192
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw 整數常數緩存器 2048
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw 布爾常數緩存器 2048
ps_2_sw 相依讀取深度 無限
vs_2_sw 流程控制指令和標籤 無限
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw 循環啟動/步驟/計數 代表和迴圈指令的反覆項目開始和反覆專案步驟大小為32位帶正負號的整數。 計數最多可MAX_INT/64。
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw 埠限制 所有註冊檔案的埠限制都會放寬。
vs_3_sw 插補器的數目 vs_3_sw中的16個輸出緩存器。
ps_3_sw 插補器的數目 14(16-2) 輸入緩存器用於ps_3_sw。

 

著色器模型 3 (DirectX HLSL)