より複雑な透明度を示すテクスチャ マップをエンコードする方法は 2 つあります。 いずれの場合も、透明度を記述するブロックは、既に説明されている 64 ビット ブロックの前にあります。 透明度は、ピクセルあたり 4 ビット (明示的なエンコード) を持つ 4 x 4 ビットマップとして表されるか、カラー エンコードに使用されているものに似たビット数と線形補間が少なくなります。
透明度ブロックとカラー ブロックは、次の表に示すように配置されます。
Word アドレス | 64 ビット ブロック |
---|---|
3:0 | 透過性ブロック |
7:4 | 前述の 64 ビット ブロック |
明示的なテクスチャ エンコード
明示的なテクスチャ エンコード (DXT2 および DXT3 形式) の場合、透明度を記述するテクセルのアルファ コンポーネントは、テクセルあたり 4 ビットの 4 x 4 ビットマップでエンコードされます。 これら 4 つのビットは、ディザリングなどのさまざまな方法で、またはアルファ データの 4 つの最も重要なビットを使用して実現できます。 ただし、これらは生成されますが、補間の形式なしで、そのまま使用されます。
次の図は、64 ビットの透過性ブロックを示しています。
64 ビット透明度ブロック図
手記
Direct3D の圧縮方法では、最も重要な 4 つのビットが使用されます。
次の表は、16 ビット ワードごとにアルファ情報をメモリに配置する方法を示しています。
この表には、単語 0 のレイアウトが含まれています。
ビット | アルファ |
---|---|
3:0 (LSB*) | [0][0] |
7:4 | [0][1] |
11:8 | [0][2] |
15:12 (MSB*) | [0][3] |
*最下位ビット、最上位ビット (MSB)
この表には、単語 1 のレイアウトが含まれています。
ビット | アルファ |
---|---|
3:0 (LSB) | [1][0] |
7:4 | [1][1] |
11:8 | [1][2] |
15:12 (MSB) | [1][3] |
この表には、単語 2 のレイアウトが含まれています。
ビット | アルファ |
---|---|
3:0 (LSB) | [2][0] |
7:4 | [2][1] |
11:8 | [2][2] |
15:12 (MSB) | [2][3] |
この表には、単語 3 のレイアウトが含まれています。
ビット | アルファ |
---|---|
3:0 (LSB) | [3][0] |
7:4 | [3][1] |
11:8 | [3][2] |
15:12 (MSB) | [3][3] |
DXT2 と DXT3 の違いは、DXT2 形式では、カラー データがアルファで事前に乗算されているものと見なされます。 DXT3 形式では、色がアルファで事前に乗算されていないと見なされます。 これらの 2 つの形式が必要なのは、ほとんどの場合、テクスチャが使用される時点では、色の値にアルファが乗算されているかどうかを判断するには、データを調べるだけでは不十分であるためです。 この情報は実行時に必要であるため、これらのケースを区別するために 2 つの FOURCC コードが使用されます。 ただし、これら 2 つの形式に使用されるデータと補間方法は同じです。
DXT1 でテクセルが透明かどうかを判断するために使用される色の比較は、この形式では使用されません。 色を比較しないと、色データは常に 4 色モードの場合と同様に扱われることを前提としています。 つまり、DXT1 コードの先頭にある if ステートメントは次のようになります。
if ((color_0 > color_1) OR !DXT1) {
線形アルファ補間の Three-Bit
DXT4 および DXT5 形式の透明度のエンコードは、色に使用される線形エンコードに似た概念に基づいています。 ブロックの最初の 8 バイトには、2 つの 8 ビットアルファ値と 1 ピクセルあたり 3 ビットの 4 x 4 ビットマップが格納されます。 代表的なアルファ値は、中間アルファ値を補間するために使用されます。 追加情報は、2 つのアルファ値を格納する方法で使用できます。 alpha_0がalpha_1より大きい場合、補間によって 6 つの中間アルファ値が作成されます。 それ以外の場合、4 つの中間アルファ値が、指定されたアルファ極値の間で補間されます。 2 つの追加の暗黙的なアルファ値は、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
}
アルファ ブロックのメモリ レイアウトは次のとおりです。
バイト | アルファ |
---|---|
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 形式では、カラー データがアルファによって事前に乗算されていると想定されていることです。 DXT5 形式では、色がアルファで事前に乗算されていないと見なされます。 これらの 2 つの形式が必要なのは、ほとんどの場合、テクスチャが使用される時点では、色の値にアルファが乗算されているかどうかを判断するには、データを調べるだけでは不十分であるためです。 この情報は実行時に必要であるため、これらのケースを区別するために 2 つの FOURCC コードが使用されます。 ただし、これら 2 つの形式に使用されるデータと補間方法は同じです。
DXT1 でテクセルが透明かどうかを判断するために使用される色の比較は、これらの形式では使用されません。 色を比較しないと、色データは常に 4 色モードの場合と同様に扱われることを前提としています。 言い換えると、DXT1 コードの先頭にある if ステートメントは次のようになります。
if ((color_0 > color_1) OR !DXT1) {
関連トピック
-
圧縮テクスチャ リソース を する