Platform SDK: DirectX |
There are two ways to encode texture maps that exhibit more complex transparency. In each case, a block that describes the transparency precedes the 64-bit block already described. The transparency is either represented as a 4x4 bitmap with four bits per pixel (explicit encoding), or with fewer bits and linear interpolation analogous to what is used for color encoding.
The transparency block and the color block are laid out as follows:
Word Address | 64-bit Block |
---|---|
3:0 | Transparency block |
7:4 | Previously described 64-bit block |
Explicit Texture Encoding
For explicit texture encoding (DXT2 and DXT3 formats), the alpha components of the texels that describe transparency are encoded in a 4x4 bitmap with 4 bits per texel. These 4 bits can be achieved through a variety of means such as dithering or by simply using the 4 most significant bits of the alpha data. However they are produced, they are used just as they are, without any form of interpolation.
Note The compression method of DirectDraw uses the 4 most significant bits.
The following tables illustrate how the alpha information is laid out in memory, for each 16-bit word.
This is the layout for Word 0:
Bits | Alpha |
---|---|
3:0 (LSB) | [0][0] |
7:4 | [0][1] |
11:8 | [0][2] |
15:12 (MSB) | [0][3] |
This is the layout for Word 1:
Bits | Alpha |
---|---|
3:0 (LSB) | [1][0] |
7:4 | [1][1] |
11:8 | [1][2] |
15:12 (MSB) | [1][3] |
This is the layout for Word 2:
Bits | Alpha |
---|---|
3:0 (LSB) | [2][0] |
7:4 | [2][1] |
11:8 | [2][2] |
15:12 (MSB) | [2][3] |
This is the layout for Word 3:
Bits | Alpha |
---|---|
3:0 (LSB) | [3][0] |
7:4 | [3][1] |
11:8 | [3][2] |
15:12 (MSB) | [3][3] |
Three-Bit Linear Alpha Interpolation
The encoding of transparency for the DXT4 and DXT5 formats is based on a concept similar to the linear encoding used for color. Two 8-bit alpha values and a 4x4 bitmap with three bits per pixel are stored in the first eight bytes of the block. The representative alpha values are used to interpolate intermediate alpha values. Additional information is available in the way the two alpha values are stored. If alpha_0 is greater than alpha_1, then six intermediate alpha values are created by the interpolation. Otherwise, four intermediate alpha values are interpolated between the specified alpha extremes. The two additional implicit alpha values are 0 (fully transparent) and 255 (fully opaque).
The following pseudo-code illustrates this algorithm.
// 8-alpha or 6-alpha block? if (alpha_0 > alpha_1) { // 8-alpha block: derive the other 6 alphas. // 000 = alpha_0, 001 = alpha_1, others are interpolated alpha_2 = (6 * alpha_0 + alpha_1) / 7; // bit code 010 alpha_3 = (5 * alpha_0 + 2 * alpha_1) / 7; // Bit code 011 alpha_4 = (4 * alpha_0 + 3 * alpha_1) / 7; // Bit code 100 alpha_5 = (3 * alpha_0 + 4 * alpha_1) / 7; // Bit code 101 alpha_6 = (2 * alpha_0 + 5 * alpha_1) / 7; // Bit code 110 alpha_7 = (alpha_0 + 6 * alpha_1) / 7; // Bit code 111 } else { // 6-alpha block: derive the other alphas. // 000 = alpha_0, 001 = alpha_1, others are interpolated alpha_2 = (4 * alpha_0 + alpha_1) / 5; // Bit code 010 alpha_3 = (3 * alpha_0 + 2 * alpha_1) / 5; // Bit code 011 alpha_4 = (2 * alpha_0 + 3 * alpha_1) / 5; // Bit code 100 alpha_5 = (alpha_0 + 4 * alpha_1) / 5; // Bit code 101 alpha_6 = 0; // Bit code 110 alpha_7 = 255; // Bit code 111 }
The memory layout of the alpha block is as follows:
Byte | Alpha |
---|---|
0 | Alpha_0 |
1 | Alpha_1 |
2 | [0][2] (2 LSBs), [0][1], [0][0] |
3 | [1][1] (1 LSB), [1][0], [0][3], [0][2] (1 MSB) |
4 | [1][3], [1][2], [1][1] (2 MSBs) |
5 | [2][2] (2 LSBs), [2][1], [2][0] |
6 | [3][1] (1 LSB), [3][0], [2][3], [2][2] (1 MSB) |
7 | [3][3], [3][2], [3][1] (2 MSBs) |
[C++,Visual Basic]