具有 Alpha 色板的紋理 (Direct3D 9)
有兩種方式可以編碼紋理地圖,以呈現更複雜的透明度。 在每個案例中,描述透明度的區塊在已經描述的64位區塊之前。 透明度會以 4x4 位表示,每圖元 4 位(明確編碼),或具有較少位和線性插補,類似於用於色彩編碼的位和線性插補。
透明度區塊和色彩區塊的排列方式如下表所示。
文字位址 | 64 位區塊 |
---|---|
3:0 | 透明度區塊 |
7:4 | 先前描述的64位區塊 |
明確紋理編碼
針對明確的紋理編碼(DXT2 和 DXT3 格式),描述透明度的紋素的 Alpha 元件會以每紋素 4 位 4 位編碼。 這四個位可以透過各種方式達成,例如分流,或使用Alpha資料的四個最大有效位。 不過,它們會像它們一樣使用,而不需要任何形式的插補。
下圖顯示64位透明度區塊。
64 位透明度區塊的
注意
Direct3D 的壓縮方法會使用四個最重要的位。
下表說明每個16位單字在記憶體中配置Alpha資訊的方式。
下表包含 word 0 的配置。
位 | 阿爾法 |
---|---|
3:0 (LSB*) | [0][0] |
7:4 | [0][1] |
11:8 | [0][2] |
15:12 (MSB*) | [0][3] |
*最小有效位,最大有效位 (MSB)
此表格包含 word 1 的配置。
位 | 阿爾法 |
---|---|
3:0 (LSB) | [1][0] |
7:4 | [1][1] |
11:8 | [1][2] |
15:12 (MSB) | [1][3] |
此表格包含 Word 2 的配置。
位 | 阿爾法 |
---|---|
3:0 (LSB) | [2][0] |
7:4 | [2][1] |
11:8 | [2][2] |
15:12 (MSB) | [2][3] |
此表格包含 Word 3 的配置。
位 | 阿爾法 |
---|---|
3:0 (LSB) | [3][0] |
7:4 | [3][1] |
11:8 | [3][2] |
15:12 (MSB) | [3][3] |
DXT2 和 DXT3 之間的差異在於,在 DXT2 格式中,會假設色彩數據已由 Alpha 預乘。 在 DXT3 格式中,假設色彩不是 Alpha 預乘的。 這兩種格式是必要的,因為在大部分情況下,使用紋理時,只是檢查數據不足以判斷色彩值是否已乘以Alpha。 由於運行時間需要這項資訊,因此會使用這兩個FOURCC程式碼來區分這些案例。 不過,這兩種格式所使用的數據和插補方法完全相同。
DXT1 中使用的色彩比較,以判斷材質是否為透明格式。 假設沒有色彩比較,色彩數據一律會被視為在 4 色模式中。 換句話說,DXT1 程式代碼頂端的 if 語句應該如下:
if ((color_0 > color_1) OR !DXT1) {
Three-Bit 線性 Alpha 插補
DXT4 和 DXT5 格式的透明度編碼是以類似用於色彩之線性編碼的概念為基礎。 兩個 8 位 Alpha 值和一個 4x4 位位陣圖,每個圖元有三個位,會儲存在區塊的前 8 個字節中。 代表性 Alpha 值是用來插補中繼 Alpha 值。 儲存兩個 Alpha 值的方式提供其他資訊。 如果alpha_0大於alpha_1,則插補會建立六個中繼 Alpha 值。 否則,在指定的Alpha極端之間會插補四個中繼Alpha值。 另外兩個隱含Alpha值是0(完全透明) 和255(完全不透明)。
下列程式代碼範例說明此演算法。
// 8-alpha or 6-alpha block?
if (alpha_0 > alpha_1) {
// 8-alpha block: derive the other six alphas.
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
alpha_2 = (6 * alpha_0 + 1 * alpha_1 + 3) / 7; // bit code 010
alpha_3 = (5 * alpha_0 + 2 * alpha_1 + 3) / 7; // bit code 011
alpha_4 = (4 * alpha_0 + 3 * alpha_1 + 3) / 7; // bit code 100
alpha_5 = (3 * alpha_0 + 4 * alpha_1 + 3) / 7; // bit code 101
alpha_6 = (2 * alpha_0 + 5 * alpha_1 + 3) / 7; // bit code 110
alpha_7 = (1 * alpha_0 + 6 * alpha_1 + 3) / 7; // bit code 111
}
else {
// 6-alpha block.
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
alpha_2 = (4 * alpha_0 + 1 * alpha_1 + 2) / 5; // Bit code 010
alpha_3 = (3 * alpha_0 + 2 * alpha_1 + 2) / 5; // Bit code 011
alpha_4 = (2 * alpha_0 + 3 * alpha_1 + 2) / 5; // Bit code 100
alpha_5 = (1 * alpha_0 + 4 * alpha_1 + 2) / 5; // Bit code 101
alpha_6 = 0; // Bit code 110
alpha_7 = 255; // Bit code 111
}
Alpha 區塊的記憶體配置如下所示:
位元組 | 阿爾法 |
---|---|
0 | Alpha_0 |
1 | Alpha_1 |
2 | [0][2] (2 個 MSB),[0][1], [0][0] |
3 | [1][1] (1 MSB), [1][0], [0][3], [0][2] (1 LSB) |
4 | [1][3], [1][2], [1][1] (2 LSB) |
5 | [2][2] (2 個 MSB),[2][1], [2][0] |
6 | [3][1] (1 MSB), [3][0], [2][3], [2][2] (1 LSB) |
7 | [3][3], [3][2], [3][1] (2 LSB) |
DXT4 和 DXT5 之間的差異在於,在 DXT4 格式中,它假設色彩數據已被 Alpha 預乘。 在 DXT5 格式中,會假設色彩不是 Alpha 預乘的。 這兩種格式是必要的,因為在大部分情況下,使用紋理時,只是檢查數據不足以判斷色彩值是否已乘以Alpha。 由於運行時間需要這項資訊,因此會使用這兩個FOURCC程式碼來區分這些案例。 不過,這兩種格式所使用的數據和插補方法完全相同。
DXT1 中使用的色彩比較,以判斷材質是否為透明,不會與這些格式搭配使用。 假設沒有色彩比較,色彩數據一律會被視為在 4 色模式中。 換句話說,DXT1 程式代碼頂端的 if 語句應該是:
if ((color_0 > color_1) OR !DXT1) {
相關主題