著色器模型 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 語意。

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

簡化輸出暫存器

所有不同類型的輸出暫存器都已折迭成十二個輸出暫存器:1 代表位置、2 代表色彩、8 代表紋理,1 代表水或點大小。 這些暫存器會插補它們針對圖元著色器包含的任何資料。 輸出暫存器宣告是必要的,且語意會指派給每個暫存器。

暫存器可以細分如下:

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

如需暫存器的清單,請參閱 暫存器 - 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 - 與 指示時。
  • 在紋理定址期間。
  • 寫出至非浮點轉譯目標時。

指定完整或部分精確度

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 迴圈開始/步驟/計數 Rep 和迴圈指令的反復專案開始和反覆運算步驟大小為 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)