資料轉換規則
下列章節說明 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],轉換成浮點數的方式如下所述。
|
FLOAT | SNORM | 假設有一個浮點數,轉換成代表帶正負號的範圍 [-1.0f 至 1.0f] 的 n-位元整數值的方式如下所述。
|
UNORM | FLOAT | 開始的 n 位元值會轉換成浮點數 (0.0f、1.0f、2.0f 等),然後除以 (2ⁿ-1)。 |
FLOAT | UNORM | 讓 c 代表開始值。
|
SRGB | FLOAT | 以下是理想的 SRGB 至 FLOAT 轉換。
|
FLOAT | SRGB | 以下是理想的 FLOAT -> SRGB 轉換。 假設目標 SRGB 色彩元件有 n 個位元:
|
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 是分數位元數。
|
固定點整數 | FLOAT | 假設要轉換成浮點數的特定固定點表示法未包含總計超過 24 個位元的資訊,則分數元件中不會超過其中的 23 個位元。 假設某個固定點數字 fxp 採用 i.f 形式 (i 位元整數,f 位元分數)。 轉換成浮點數類似下列虛擬程式碼。 float result = (float) (fxp >> f) + // extract integer
|
相關主題