Share via


資料轉換規則

下列章節說明 Direct3D 如何處理資料類型之間的轉換。

資料類型詞彙

下列詞彙組後續將用來描述各種不同的格式轉換。

詞彙 定義
SNORM 帶正負號的標準化整數,表示 n-位元 2 的補數,最大值是指 1.0f (例如 5-位元值 01111 對應至 1.0f),最小值是指 -1.0f (例如 5-位元值 10000 對應至 -1.0f)。 此外,第二小的數字對應至 -1.0f (例如 5-位元值 10001 對應至 -1.0f)。 因此,-1.0f 有兩種整數表示法。 0.0f 只有一種表示法,1.0f 也只有一種表示法。 這會對範圍 (-1.0f...0.0f) 中間隔平均的浮點值產生一組整數表示法,另外,範圍 (0.0f...1.0f) 中數字的補數也會有一組表示法
UNORM 不帶正負號的標準化整數,表示對於 n 位元數字,所有 0 都表示 0.0f,所有 1 都表示 1.0f。 表示從 0.0f 到 1.0f 間隔平均的浮點值序列。 例如 2-位元 UNORM 代表 0.0f、1/3、2/3 及 1.0f。
SINT 帶正負號的整數。 2 的整數補數。 例如 3-位元 SINT 代表整數值 -4、-3、-2、-1、0、1、2、3。
UINT 不帶正負號的整數。 例如 3-位元 UINT 代表整數值 0、1、2、3、4、5、6、7。
FLOAT Direct3D 定義的任何表示法中的浮點值。
SRGB 類似 UNORM,對於 n-位元數字,所有 0 都表示 0.0f,所有 1 都表示 1.0f。 不過,與 UNORM 不同的是,若是 SRGB,介於所有 0 到所有 1 之間不帶正負號的整數編碼序列代表數字 (介於 0.0f 到 1.0f) 的浮點轉譯中的非線性數列。 大致來說,如果這個非線性數列 SRGB 顯示為色彩序列,則會顯示為相對於「平均」觀察值的線性亮度等級坡形,在「平均」檢視條件下「平均」顯示。 如需完整的詳細資訊,請參考 IEC (國際電子電機委員會) 的 SRGB 色彩標準 IEC 61996-2-1。

 

浮點轉換

只要不同的表示法之間發生浮點轉換,包括非浮點表示法之間來回轉換,就適用下列規則。

從較高範圍表示法轉換成較低範圍表示法

  • 轉換成另一種浮點數格式時會使用 Round-to-zero (四捨五入至零)。 如果目標是整數或固定點格式,則會使用 round-to-nearest-even (四捨五入至最接近的偶數),除非轉換明確記載為使用另一種四捨五入行為,例如 FLOAT 轉換成 SNORM、FLOAT 轉換成 UNORM 或 FLOAT 轉換成 SRGB 使用的 round-to-nearest (四捨五入至最接近數字)。 其他例外狀況為 ftoi 和 ftou shader 指令,會使用 round-to-zero (四捨五入至零)。 最後,紋理取樣工具和點陣化使用的 float-to-fixed 轉換有指定的容錯,以來自無限精確概念的 Unit-Last-Place 計算。
  • 對於大於較低範圍目標格式之動態範圍的來源值 (,例如,例如大型 32 位浮點數會寫入 16 位浮點數 RenderTarget) ,最大可表示 (適當帶正負號的) 值結果,不包括帶正負號的無限大 (,因為上述四捨五入為零) 。
  • 採用較高範圍格式的 NaN 將轉換成採用較低範圍格式的 NaN 表示法,如果 NaN 表示法存在較低範圍格式中。 如果較低格式沒有 NaN 表示法,則結果會是 0。
  • 採用較高範圍格式的 INF 將會轉換成採用較低範圍格式的 INF (如有的話)。 如果較低格式沒有 INF 表示法,它將會轉換成可表示的最大值。 正負號將保留,如果目標格式中提供。
  • 採用較高範圍格式的 Denorm 將會轉換成採用較低範圍格式的 Denorm 表示法 (如較低範圍格式中有提供且可轉換),否則結果會是 0。 正負號位元將保留,如果目標格式中提供。

從較低範圍表示法轉換成較高範圍表示法

  • 採用較低範圍格式的 NaN 將轉換成採用較高範圍格式的 NaN 表示法 (如果較高範圍格式中有提供)。 如果較高範圍格式沒有 NaN 表示法,它將會轉換成 0。
  • 採用較低範圍格式的 INF 將轉換成採用較高範圍格式的 INF 表示法 (如果較高範圍格式中有提供)。 如果較高的格式沒有 INF 標記法,則會以該格式轉換成可表示的最大值 (MAX_FLOAT) 。 正負號將保留,如果目標格式中提供。
  • 採用較低範圍格式的 Denorm 將轉換成採用較高範圍格式的標準化表示法 (如有可能),或是轉換成採用較高範圍格式的 Denorm 表示法 (如果 Denorm 表示法存在)。 若較高範圍格式沒有 Denorm 表示法,則這些都會失敗,且它將會轉換成 0。 正負號將保留,如果目標格式中提供。 請注意,32 位元浮點數計算格式時不會採用 Denorm 表示法 (因為 32 位元浮點數運算中,Denorm 會清除為保留正負號的 0)。

整數轉換

下表描述從上述各種不同的表示法轉換成其他表示法。 只會顯示實際在 Direct3D 中發生的轉換。

來源資料類型 目的地資料類型 轉換規則
SNORM FLOAT 假設有一個 n-位元整數值,代表帶正負號的範圍 [-1.0f 至 1.0f],轉換成浮點數的方式如下所述。
  • 最大負值對應至 -1.0f。 例如 5-位元值 10000 對應至 -1.0f。
  • 其他每一個值都會轉換成浮點數 (稱為 c),然後結果 = c * (1.0f / (2⁽ⁿ⁻¹⁾-1))。 例如,5 位元值 10001 轉換成 -15.0f,然後除以 15.0f,得出 -1.0f。
FLOAT SNORM 假設有一個浮點數,轉換成代表帶正負號的範圍 [-1.0f 至 1.0f] 的 n-位元整數值的方式如下所述。
  • 讓 c 代表開始值。
  • 如果 c 是 NaN,則結果是 0。
  • 如果 c > 1.0f,包括 INF,則會限制為 1.0f。
  • 如果 c < -1.0f,包括 -INF,則會限制為 -1.0f。
  • 從浮點數進位法轉換成整數進位法:c = c * (2ⁿ⁻¹-1)。
  • 如下所述轉換成整數。
    • 如果 c >= 0,則 c = c + 0.5f,否則 c = c - 0.5f。
    • 去除小數,剩餘的浮點 (整數) 值就會直接轉換成整數。
此轉換容許的容錯為 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place Unit-Last-Place (整數端)。 這表示,從浮點數轉換成整數進位法之後,可表示的目標格式值的 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place 內的任何值都可對應至該值。 額外的資料可逆性需求可確保轉換在整個範圍內不減少,而且所有輸出值都可實現。 (在此處顯示的常數中,xx 應取代為 Direct3D 版本,例如 10、11 或 12)
UNORM FLOAT 開始的 n 位元值會轉換成浮點數 (0.0f、1.0f、2.0f 等),然後除以 (2ⁿ-1)。
FLOAT UNORM 讓 c 代表開始值。
  • 如果 c 是 NaN,則結果是 0。
  • 如果 c > 1.0f,包括 INF,則會限制為 1.0f。
  • 如果 c < 0.0f,包括 -INF,則會限制為 0.0f。
  • 從浮點數進位法轉換成整數進位法:c = c * (2ⁿ-1)。
  • 轉換成整數。
    • c = c + 0.5f。
    • 小數會去除,剩餘的浮點 (整數) 值就會直接轉換成整數。
此轉換容許的容錯為 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (整數端)。 這表示,從浮點數轉換成整數進位法之後,可表示的目標格式值的 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place 內的任何值都可對應至該值。 額外的資料可逆性需求可確保轉換在整個範圍內不減少,而且所有輸出值都可實現。
SRGB FLOAT 以下是理想的 SRGB 至 FLOAT 轉換。
  • 取一個開始的 n 位元值,將它轉換成浮點數 (0.0f、1.0f、2.0f 等);將此稱為 c。
  • c = c * (1.0f / (2ⁿ-1))
  • 如果 (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) 則: result = c / D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_1,else: result = ( (c + D3D xx_SRGB_TO_FLOAT_OFFSET) /D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_2) D3Dxx_SRGB_TO_FLOAT_EXPONENT
此轉換容許的容錯為 D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP Unit-Last-Place (SRGB 端)。
FLOAT SRGB 以下是理想的 FLOAT -> SRGB 轉換。
假設目標 SRGB 色彩元件有 n 個位元:
  • 假設開始值是 c。
  • 如果 c 是 NaN,則結果是 0。
  • 如果 c > 1.0f,包括 INF,則會限制為 1.0f。
  • 如果 c < 0.0f,包括 -INF,則會限制為 0.0f。
  • 如果 (c <= D3Dxx_FLOAT_TO_SRGB_THRESHOLD) 則: c = D3D xx_FLOAT_TO_SRGB_SCALE_1 * c, else: c = D3Dxx_FLOAT_TO_SRGB_SCALE_2 * c (D3D xx_FLOAT_TO_SRGB_EXPONENT_NUMERATOR/D3Dxx_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR) - D3Dxx_FLOAT_TO_SRGB_OFFSET
  • 從浮點數進位法轉換成整數進位法:c = c * (2ⁿ-1)。
  • 轉換成整數:
    • c = c + 0.5f。
    • 小數會去除,剩餘的浮點 (整數) 值就會直接轉換成整數。
此轉換容許的容錯為 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (整數端)。 這表示,從浮點數轉換成整數進位法之後,可表示的目標格式值的 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place 內的任何值都可對應至該值。 額外的資料可逆性需求可確保轉換在整個範圍內不減少,而且所有輸出值都可實現。
SINT SINT 與更多位元 若要從 SINT 轉換為具有更多位的 SINT,起始數位的 MSB) 最顯著位 (會「帶正負號」,以目標格式提供的額外位。
UINT SINT 與更多位元 若要從 UINT 轉換成 SINT 與更多位元,數字會複製到目標格式的最低有效位元 (LSB),且其他 MSB 會以 0 填入。
SINT UINT 與更多位元 若要從 SINT 轉換成 UINT 與更多位元:如果是負數,值會限制為 0。 否則數字會複製到目標格式的 LSB,且其他 MSB 會以 0 填入。
UINT UINT 與更多位元 若要從 UINT 轉換成 UINT 與更多位元,數字會複製到目標格式的 LSB,且其他 MSB 會以 0 填入。
SINT 或 UINT SINT 或 UINT 與更少或等於位元 若要從 SINT 或 UINT 轉換成 SINT 或 UINT 與更少或等於位元 (和/或正負號變更),只會將開始值限制為目標格式的範圍。

 

固定點整數轉換

固定點整數單純是某個位元大小的整數,其中某個固定位置有隱含的小數點。

普遍的「整數」資料類型是固定點整數的特殊案例,小數點位於數字結尾。

固定點數字表示法描述如下:i.f,其中 i 是整數位元數,f 是分數位元數。 例如 16.8 表示 16 位元整數,後面接著 8 位元分數。 整數部分是以 2 的補數儲存,至少如此處鎖定一 (雖然它同樣可以對不帶正負號的整數定義)。 分數部分是以不帶正負號的形式儲存。 分數部分一律代表正分數,介於最接近的兩個整數值之間,從最大負數開始。

固定點數字的加減運算是單純使用標準整數算術執行,不考慮隱含的小數點位置。 將 16.8 固定點數字加 1,僅表示加上 256,因為小數點在數字最低有效結尾起算的第 8 位。 其他運算像是乘法,同樣可以單純使用整數算術執行,假設考慮對固定小數點的效果。 例如,使用整數乘法將兩個 16.8 整數相乘,會得到 32.16 的結果。

固定點整數表示法在 Direct3D 中使用的方式有兩種。

  • 點陣化中後續剪裁的頂點位置會貼齊固定點,以便跨 RenderTarget 區域統一分配精確度。 許多點陣化運算 (例如面消除) 是在固定點貼齊位置上發生,其他運算 (像是屬性 Interpolator 設定) 則使用已從固定點貼齊位置轉換回浮點數的位置。
  • 取樣作業的紋理座標會貼齊固定點 (經過紋理大小縮放後),以跨紋理空間統一分配精確度,以便選擇篩選點選位置/權重。 權重值會在進行實際篩選算術之前轉換回浮點數。
來源資料類型 目的地資料類型 轉換規則
FLOAT 固定點整數 以下是將浮點數 n 轉換成固定點整數 i.f 的一般程序,其中 i 是 (帶正負號的) 整數位元數,f 是分數位元數。
  • 計算 FixedMin = -2⁽ⁱ⁻¹⁾
  • 計算 FixedMax = 2⁽ⁱ⁻ー⁾ - 2 (-f)
  • 如果 n 是 NaN,result = 0;如果 n 是 +Inf,result = FixedMax*2f;如果 n 是 -Inf,result = FixedMin*2f
  • 如果 n >= FixedMax,result = Fixedmax*2f;如果 n <= FixedMin,result = FixedMin*2f
  • 否則計算 n*2f 並轉換成整數。
實作在整數結果中容許 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place 容錯,而非上方最後一個步驟之後的無限精確值 n*2f
固定點整數 FLOAT 假設要轉換成浮點數的特定固定點表示法未包含總計超過 24 個位元的資訊,則分數元件中不會超過其中的 23 個位元。 假設某個固定點數字 fxp 採用 i.f 形式 (i 位元整數,f 位元分數)。 轉換成浮點數類似下列虛擬程式碼。
float result = (float) (fxp >> f) + // extract integer
( (float) (fxp & (2f - 1) ) / (2f) ) ;擷取

 

資源 (Direct3D 10)