具有 Alpha 通道的纹理 (Direct3D 9)

有两种方法可用于对展现更复杂透明度的纹理贴图进行编码。 在每种情况下,描述透明度的块都在已描述的 64 位块之前。 透明度以 4 x 4 位图表示,其中每个像素具有 4 位(显式编码)或者具有更少位和线性插值(与用于颜色编码的值类似)。

透明数据块和颜色块的排列方式如下表所示。

字地址 64 位块
3:0 透明数据块
7:4 之前所述的 64 位块

 

显式纹理编码

对于) (DXT2 和 DXT3 格式的显式纹理编码,描述透明度的纹素的 alpha 分量在 4x4 位位图中编码,每个纹素 4 位。 这些四位组可以通过多种方式实现,比如抖动或通过使用四个最高有效位的 alpha 数据。 但它们只能产生并且按本身用途使用,不得有任何形式的内插。

以下图表显示 64 位透明数据块。

64 位透明数据块图示

注意

Direct3D 的压缩方法使用四个最有效位。

 

下表描述了 alpha 信息(16 位词)如何在内存中分布。

此表包含 Word 0 的布局。

Bits Alpha
3:0 (LSB*) [0][0]
7:4 [0][1]
11:8 [0][2]
15:12 (MSB*) [0][3]

 

*最低有效位,最高有效位 (MSB)

此表包含第 1 个字的布局。

Bits Alpha
3:0 (LSB) [1][0]
7:4 [1][1]
11:8 [1][2]
15:12 (MSB) [1][3]

 

此表包含第 2 字的布局。

Bits Alpha
3:0 (LSB) [2][0]
7:4 [2][1]
11:8 [2][2]
15:12 (MSB) [2][3]

 

此表包含 Word 3 的布局。

Bits Alpha
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 位图(每个像素为 3 位)保存在块的前八个字节中。 典型的 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 块的内存布局如下所示:

Byte 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) {

压缩的纹理资源