アルファ チャネルを含むテクスチャ (Direct3D 9)
複雑な透明度を表現するテクスチャ マップには 2 つのエンコード方法があります。 いずれの場合も、既に説明した 64 ビットのブロックの前に、透明度を記述したブロックを配置します。 透明度は、1 ピクセルあたり 4 ビットの 4 x 4 ビットマップ (明示的エンコード)、またはこれよりも少ないビット数およびカラー エンコードで使用されるものに類似した線形補完で表現します。
透明度ブロックと色ブロックは、次の表に示すように配置されます。
ワード アドレス | 64 ビットのブロック |
---|---|
3:0 | 透明度ブロック |
7:4 | 既に説明した 64 ビットのブロック |
明示的なテクスチャ エンコード
明示的なテクスチャ エンコード (DXT2 および DXT3 形式) の場合、透明度を記述するテクセルのアルファ コンポーネントは、テクセルあたり 4 ビットの 4 x 4 ビットマップでエンコードされます。 これらの 4 ビットは、ディザリングなどのさまざまな手法によるか、アルファ データの 4 つの最上位ビットを使用して取得できます。 ただし、これらは生成されると、どのような補間もされずに、そのままの状態で使用されます。
次の図に、64 ビットの透明度ブロックを示します。
注意
Direct3D の圧縮方法では、最も重要な 4 つのビットが使用されます。
次の表に、16 ビット ワードごとにメモリ内のアルファ情報のレイアウト方法を示します。
この表には、単語 0 のレイアウトが含まれています。
Bits | [アルファ] |
---|---|
3:0 (LSB*) | [0][0] |
7:4 | [0][1] |
11:8 | [0][2] |
15:12 (MSB*) | [0][3] |
*最下位ビット、最上位ビット (MSB)
この表には、単語 1 のレイアウトが含まれています。
Bits | [アルファ] |
---|---|
3:0 (LSB) | [1][0] |
7:4 | [1][1] |
11:8 | [1][2] |
15:12 (MSB) | [1][3] |
この表には、単語 2 のレイアウトが含まれています。
Bits | [アルファ] |
---|---|
3:0 (LSB) | [2][0] |
7:4 | [2][1] |
11:8 | [2][2] |
15:12 (MSB) | [2][3] |
この表には、単語 3 のレイアウトが含まれています。
Bits | [アルファ] |
---|---|
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 形式の透過性のエンコードは、色に使用される線形エンコードと同様の概念に基づいています。 2 つの 8 ビット アルファ値、およびピクセルあたり 3 ビットの 4 x 4 ビットマップが、ブロックの最初の 8 バイトに格納されます。 代表的なアルファ値を使用して、中間アルファ値が補間されます。 追加の情報は、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
}
アルファ ブロックのメモリ レイアウトは次のとおりです。
Byte | [アルファ] |
---|---|
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) {
関連トピック