原文:http://www.webtech.co.jp/blog/optpix_labs/format/6993/
http://www.webtech.co.jp/blog/optpix_labs/format/7006/
米Net Applications社の調査によると、Windows XPは2014年4月の時点でも26.3%と高いシェアを保ってるようです。しかし、いくらユーザが残っているとはいえ、末端の開発者がサポートが終了したOSの面倒をいつまでも見ているわけにもいきません。
最近ではWindowsアプリケーションの動作対象OSからWindows XPが外されることも普通のことになり、ようやくWindows XPの束縛から解放された、と内心安堵している開発者の方も多いのではないでしょうか。
そして、3D系アプリの最低動作環境の見直しとなると、Windows Vistaは飛ばして、Windows 7とDirectX 11を最低動作環境にする、という選択もそれほど無茶ではないように思えます。
今回は、DirectX 11で利用可能な圧縮テクスチャについて、解説いたします。
DirectX 11では、BC1~BC7(BC1、BC2、BC3、BC4、BC5、BC6H、BC7)の7種類の圧縮テクスチャが利用可能ですが、それぞれが実際にどのような圧縮フォーマットなのかという点についてはあまり詳しく知られていないようです。
今回は「前編」として、概要とBC1~BC5までを解説します。
概要
BC1~BC7のBCというのはブロック圧縮(Block Compression)の略で、画像を4×4ピクセル単位のブロックに分割して、それぞれのブロック毎に圧縮を行う方式です。
BC1~BC7という名前はDirectX固有の呼び方で、以下の表のように、それぞれに適した用途があります。
表1 BC1~BC7の用途
形式名 |
bpp |
用途 |
備考 |
BC1 |
4 |
RGB画像、または RGBA画像(二値アルファ) |
DXT1の代替 |
BC2 |
8 |
RGBA画像(16階調アルファ) |
DXT2~3の代替 |
BC3 |
8 |
RGBA画像(多階調アルファ) |
DXT4~5の代替 |
BC4 |
4 |
1成分のデータ(ハイトマップ等) |
ATI1Nの代替 |
BC5 |
8 |
2成分のデータ(法線マップ等) |
ATI2N(3Dc)の代替 |
BC6H |
8 |
HDR(ハイダイナミックレンジ)のRGB画像 |
|
BC7 |
8 |
RGB画像、または RGBA画像(多階調アルファ) |
|
※圧縮データは4×4ピクセル単位のブロック(4bpp では8バイト、8bpp では16バイト)
- BC1~7の圧縮は非可逆圧縮なので、データを圧縮する際には劣化が発生します。
- DirectX 11対応のGPUでは、BC1~BC7をGPUのハードウェアがサポートしています。
- DirectX 10以降では、テクスチャ形式の呼び方が一新されており、DirectX 9までのDXT1~DXT5という呼び方はしなくなりました。
- DirectX用のテクスチャファイルを格納するためのDDSファイルもDirectX 10以降でフォーマットが拡張されており、DirectX 10以降のテクスチャ形式で保存したDDSファイル(DX10拡張DDS)は、それ以前の(DirectX 9用の)DDSファイルとバイナリ互換性がなくなっています。
このため、DDSファイルをサポートしてるツールでも、DX10拡張DDS については扱えない場合が多いので注意が必要です。
BC1
- BC1は、DirectX 9ではDXT1と呼ばれていた圧縮テクスチャ形式と同等のもので、RGBのカラー値と1ビットのアルファ(完全透明と完全不透明のみの二値アルファ)を表現できる圧縮テクスチャ形式です。
- BC1には、表現するRGB値がリニアなBC1_UNORMと、RGB値がsRGBのBC1_UNORM_SRGBの2つのテクスチャ形式が用意されています。この形式の違いは表現するRGB値の色空間の識別のためで、圧縮アルゴリズム自体は共通です(他にもう1つ、BC1_TYPELESSという「型無し」のBC1のテクスチャ形式がありますが、通常は使用しません)。
- BC1では、4×4ピクセルの無圧縮のRGBデータ(48バイト)を8バイトに圧縮するので、圧縮率は1/6になります(アルファ付きの4×4ピクセルの無圧縮のRGBA データは64バイトなので、圧縮率が1/8と表記される場合もあります)。
- BC1は、4×4ピクセルの画像データをRGB565形式の代表色2色と、その中間の補間色(2色または1色+透明) の計4色(または計3色+透明)で表す、比較的シンプルな圧縮データです。
表2 BC1の圧縮データ構造(1ブロック)
2バイト |
代表色0(RGB565) |
2バイト |
代表色1(RGB565) |
4バイト |
ピクセル毎のインデックス値(各2ビット) |
- BC1は、4×4ピクセル内で色調が大きく変わらない画像に対しては優れた色再現性を持ちますが、4×4ピクセル内で色調が大きく変わる部分を持つ画像では、圧縮による劣化がブロック状のノイズとなって見えてしまうという欠点があります。
- マイクロソフト社のツールでDDSファイルに変換する場合、デフォルト設定では、BC1_UNORMは従来の(DirectX 9互換の)DXT1 形式で、BC1_UNORM_SRGBはDX10拡張DDSで保存されるようになっています。
BC2
- BC2は、DirectX 9ではDXT2やDXT3と呼ばれていた圧縮テクスチャ形式と同等のもので、RGBのカラー値と、4ビット精度(16階調)のアルファを表現できる圧縮テクスチャ形式です。
- BC2には、表現するRGB値がリニアなBC2_UNORMと、RGB値がsRGBのBC2_UNORM_SRGBの2つのテクスチャ形式が用意されています。この形式の違いは、表現するRGB値の色空間の識別のためで、圧縮アルゴリズム自体は共通です(他にもう1つ、BC2_TYPELESSという「型無し」のBC1のテクスチャ形式がありますが、通常は使用しません)。
- BC2ではアルファ付きの4×4ピクセルの無圧縮のRGBAデータ(64バイト)を16バイトに圧縮するので、圧縮率は1/4になります。
- BC2の圧縮データは、BC1のデータ構造の前にアルファ値のデータを格納した形になっています。
表3 BC2の圧縮データ構造(1ブロック)
8バイト |
各ピクセル毎のアルファ値(各4ビット) |
2バイト |
代表色0 (RGB565) |
2バイト |
代表色1 (RGB565) |
4バイト |
ピクセル毎のインデックス値(各2ビット) |
- BC2では各ピクセルのアルファ値は16階調に制限されますが、16階調の中からピクセル単位で任意の値を選択できるため、アルファが16階調でも十分であることが判っている場合や、アルファ値が大きく偏って分散していてBC3ではブロック状の劣化ノイズが目立つ場合だけBC2を使用する、という使い方が一般的です
BC3
- BC3は、DirectX 9ではDXT4やDXT5と呼ばれていた圧縮テクスチャ形式と同等のもので、RGBのカラー値と多階調のアルファを表現できる圧縮テクスチャ形式です。
- BC3には、表現するRGB値がリニアなBC3_UNORMと、RGB値がsRGBのBC3_UNORM_SRGBの2つのテクスチャ形式が用意されています。この形式の違いはRGB値の色空間の識別のためで、圧縮アルゴリズム自体は共通です(他にもう1つ、BC3_TYPELESSという「型無し」のBC3のテクスチャ形式がありますが、通常は使用しません)。
- BC3の圧縮データは、BC1のデータ構造の前にアルファ値のデータを格納した形になっています。BC3ではアルファ付きの4×4ピクセルの無圧縮のRGBAデータ(64バイト)を16バイトに圧縮するので、圧縮率は1/4になります。アルファ値の格納方法は、各ピクセル独立ではなく、BC1のRGB 値の圧縮データに似た代表値とインデックス値のセットになっています。
表4 BC3の圧縮データ構造(1ブロック)
1バイト |
アルファの代表値0 |
1バイト |
アルファの代表値1 |
6バイト |
ピクセル毎のインデックス値(各3ビット) |
2バイト |
代表色0 (RGB565) |
2バイト |
代表色1 (RGB565) |
4バイト |
ピクセル毎のインデックス値(各2ビット) |
- BC3では代表値2個を直線補間し、間の6個(または4個) の補間値を計算してアルファチャンネルを表現するため、グラデーションがかかったような滑らかな変化のあるアルファチャンネルを持つ画像の表現に適しています。しかし、アルファ値が急激に変化する透明境界部分などでは、アルファチャンネルにブロック状の劣化ノイズが発生しやすくなります。
- BC3で圧縮すると、アルファが0で完全に透明だったピクセルのアルファ値が1以上になって、見えないはずのピクセルがうっすらと見えたり、逆に、アルファが255で完全に不透明だったピクセルのアルファ値が255未満になり、背景がうっすらと透けてしまう、などの問題が起きる場合があります。
- アルファ付きの画像の場合は通常はBC3を使い、ブロック状の劣化ノイズの発生状況によっては、BC2やBC1でよい場合はそれらを選択する、という使い分けが適しています。
- DXT1~DXT5の圧縮アルゴリズムについては、既に当ブログにも解説記事がありますので、こちらも併せてご覧ください。
- DXTC(S3TC)圧縮のアルゴリズムとは?~前編~
- DXTC(S3TC)圧縮のアルゴリズムとは?~後編~
- BC1~BC3の詳細仕様については、マイクロソフト社の開発者向けページをご覧ください。
- マイクロソフト社 MSDN ブロック圧縮 (Direct3D 10)
BC4
- BC4はDirectX 10で追加された圧縮テクスチャ形式で、輝度データやアルファチャンネルやハイトマップなど、1成分(1チャンネル)の情報だけを格納するためのものです。1成分のデータ用の圧縮フォーマットであるため、通常のRGBカラー画像の格納には使用しません。
- BC4の圧縮データは、DirectX 9時代にATI1N(またはATI1)と呼ばれていた圧縮テクスチャ形式と基本的には同じものです。OpenGLではBC4と同様の圧縮フォーマットがRGTC(またはRGTC1)と呼ばれています。
- BC4には、表現できる値の範囲が0.0~1.0のBC4U(BC4_UNORM)というテクスチャ形式と、表現できる値の範囲が-1.0~1.0のBC4S(BC4_SNORM)というテクスチャ形式の2種類があります(他にBC4_TYPELESSという「型無し」のBC4のテクスチャ形式がありますが、通常は使用しません)。
- BC4では、圧縮は4×4ピクセル毎に行われ、4×4ピクセルの1成分の無圧縮の16バイトの情報を8バイトに圧縮しますので、圧縮率は1/2になります。
- BC4のデータ格納形式は、BC3(DXT5)のアルファチャンネル部分の圧縮データの格納形式と同じで、1バイトの代表値を2個と、4×4ピクセルの各ピクセル毎に3ビットのインデックス値を持ちます。
表5 BC4の圧縮データ構造(1ブロック)
1バイト |
代表値0 |
1バイト |
代表値1 |
6バイト |
各ピクセル毎のインデックス値(各3ビット) |
- BC4がBC3のアルファチャンネル部分の圧縮アルゴリズムと違う点は、表現する値が0~255の8ビット値ではなく、0.0~1.0(BC4Uの場合)の範囲、または、-1.0~1.0(BC4Sの場合)の範囲の値を表すテクスチャ形式であることと、補間計算が8ビットよりも少し高い精度で行われることです。
BC5
- BC5はDirectX 10で追加された圧縮テクスチャ形式で、法線マップ(ノーマルマップ)などのような2成分(2チャンネル)の情報を格納するためのものです。2成分のデータ用の圧縮テクスチャ形式であるため、通常のRGBカラー画像の格納には使用しません。
- BC5の圧縮データ構造は、DirectX 9時代にATI2N(またはATI2)や3Dc、あるいはDXNと呼ばれていた圧縮テクスチャ形式と基本的には同じものです。OpenGLではBC5と同様の圧縮フォーマットがRGTC(またはRGTC2)と呼ばれています。
- BC5には、表現できる値の範囲が0.0~1.0のBC5U(BC5_UNORM)というテクスチャ形式と、表現できる値の範囲が-1.0~1.0のBC5S(BC5_SNORM)というテクスチャ形式の2種類があります(他にBC5_TYPELESSという「型無し」のBC5のテクスチャ形式がありますが、通常は使用しません)。
- BC5は、4×4ピクセルの1ブロック単位でBC4の圧縮データをちょうど2個使うような構造になっています。
表6 BC5の圧縮データ構造(1ブロック)
1バイト |
成分1の代表値0 |
1バイト |
成分1の代表値1 |
6バイト |
成分1の各ピクセル毎のインデックス値(各3ビット) |
1バイト |
成分2の代表値0 |
1バイト |
成分2の代表値1 |
6バイト |
成分2の各ピクセル毎のインデックス値(各3ビット) |
- BC5では、圧縮は4×4ピクセル毎に行われ、4×4ピクセルの2成分の無圧縮の32バイトの情報を16バイトに圧縮しますので、圧縮率は1/2になります。
- BC5では表現できる値の精度はBC4と同様にあまり高くありませんので、1成分につき8ビット程度の精度で十分な用途にしか使えません。
- 法線マップは本来はx,y,zの3成分が必要ですが、正規化されているベクトルは2成分の値が判れば残りの1成分を計算で求められるので(誤差は大きくなりますが)、法線マップ用のデータとしては2成分のみを記録しておくだけで済みます。
このため、BC5は、法線マップを圧縮して格納するのに適しています。
BC6H
- BC6HはDirectX 11で追加された圧縮テクスチャ形式で、HDR(ハイダイナミックレンジ)のRGB画像データを格納するためのものです。BC6Hのことを単にBC6と呼ぶこともあります。なお、OpenGLでは、BC6Hに相当する圧縮テクスチャ形式はBPTCと呼ばれています。
- BC6Hでは、RGB各16ビットの無圧縮のHDR画像を4×4ピクセル毎に16バイトに圧縮できます。元画像データがRGB各16ビットの無圧縮のHDR画像は4×4ピクセルで96バイトになるので、圧縮率は1/6になります。
- BC6HではRGBのみで、アルファチャンネルはサポートしていません。BC6Hには、表現できる値が符号付きのBC6H_SF16と、符号なしのBC6H_UF16の2つのテクスチャ形式が用意されています(他にBC6H_TYPELESSという「型無し」のBC6Hのテクスチャ形式がありますが、通常は使用しません)。
- BC6Hでは、4×4ピクセル毎に16バイトの圧縮データを使用しますが、この16バイト(128ビット)の圧縮データには、以下の表のような、モードビット、インデックス値、パーティション、エンドポイントの情報がモード別に異なる形式で詰め込まれています。
表1 BC6Hの圧縮データ内の情報(1ブロック)
モード名 |
モードビット |
インデックス値 |
パーティション |
エンドポイント |
エンドポイントの表現形式 |
1 |
2ビット |
46ビット |
5ビット |
75ビット |
RGB101010 + 差分RGB555 × 3組 |
2 |
2ビット |
46ビット |
5ビット |
75ビット |
RGB777 + 差分RGB666 × 3組 |
3 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB111111 + 差分RGB544 × 3組 |
4 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB111111 + 差分RGB454 × 3組 |
5 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB111111 + 差分RGB445 × 3組 |
6 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB999 + 差分RGB555 × 3組 |
7 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB888 + 差分RGB655 × 3組 |
8 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB888 + 差分RGB565 × 3組 |
9 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB888 + 差分RGB556 × 3組 |
10 |
5ビット |
46ビット |
5ビット |
72ビット |
RGB666 × 4組 |
11 |
5ビット |
63ビット |
なし |
60ビット |
RGB101010 × 2組 |
12 |
5ビット |
63ビット |
なし |
60ビット |
RGB111111 + 差分RGB999 |
13 |
5ビット |
63ビット |
なし |
60ビット |
RGB121212 + 差分RGB888 |
14 |
5ビット |
63ビット |
なし |
60ビット |
RGB161616 + 差分RGB444 |
モードビット
- BC6Hでサポートされている14種類のモードを区別するためのビットパターンです(モード名の数字の二進数表現とは異なります)。
- 使用できるモードは4×4ピクセルのブロック毎に自由に選べますが、モードを選ぶのはエンコーダ(テクスチャ圧縮を行うプログラム) 側の話で、エンコーダがテクスチャ圧縮の際に自動的に各ブロックに適したモードを決定します。
- このモードビットにはいくつか使用されていないビットパターンがありますが、これらのビットパターンはリザーブとなっていて、エンコーダでの使用が禁止されています。
インデックス値
- インデックス値は4×4ピクセルの各ピクセルがどの色なのかを表した情報です。
- BC6H では、エンドポイントの表現形式からブロックの代表色を決め、その代表色を線形補間して8個または16個のパレットを計算しますが、4×4ピクセルの各ピクセルが、そのパレットの何番の色なのかを示す値がインデックス値です。パレットが8個ならインデックス値は各ピクセル3ビット、パレットが16個なら、インデックス値は各ピクセル4ビットになります。
- インデックス値の総ビット数が3ビット×4×4の48ビットではなく46ビットになっていたり、4ビット×4×4の64ビットではなく63ビットなどの中途半端な数字になっているのは、4×4ピクセルの中で特定の位置(モードやパーティションの値で変わる) のピクセルだけ、インデックス値として割り当てられるビット数が1ビット少なく、選べるパレットが制限されているためです。
パーティション
- BC6Hでは、ブロックノイズが目立つのを防ぐために、4×4ピクセルを2つの領域に分割して、それぞれの領域で代表色を変える事が可能になっています。
- パーティションは、この領域の分割パターンを示す値で、BC6Hではモード1~10のために以下のような32種類の分割パターンが予め固定的に規定されています。モード11~14では領域分割は行われません。
図1 2分割用の分割パターン(クリックで拡大)
※ ○=領域0、●=領域1
エンドポイント
BC7
- BC7はDirectX 11で追加された圧縮テクスチャ形式で、BC1~BC3よりも高品質な画像データを格納するためのものです。OpenGLでは、BC7に相当する圧縮テクスチャ形式はBPTCと呼ばれています。
- BC7は無圧縮のRGB画像やRGBA画像を4×4ピクセル毎に16バイトに圧縮します。元画像データが無圧縮のRGB画像の場合は4×4ピクセルで48バイトなので、圧縮率は1/3になります。また、元画像データが無圧縮のRGBA画像の場合は4×4ピクセルで64バイトなので、圧縮率は1/4になります。
- BC7には、表現するRGB値がリニアなBC7_UNORMと、RGB値がsRGBのBC7_UNORM_SRGBの2つのテクスチャ形式が用意されています。この形式の違いはRGB値の色空間の識別のためで、圧縮アルゴリズム自体は共通です(他にBC7_TYPELESSという「型無し」のBC7のテクスチャ形式がありますが、通常は使用しません)。
- BC7では、4×4ピクセル毎に16バイトの圧縮データを使用しますが、この16バイト(128ビット)の圧縮データには、以下の表のような、モードビット、インデックス値、パーティション、交換情報、エンドポイント、付加情報といった情報が詰め込まれています。
表2 BC7の圧縮データ内の情報(1ブロック)
モード名 |
モードビット |
インデックス値 |
パーティション |
交換情報 |
エンドポイント |
エンドポイントの表現形式 |
エンドポイントの表現形式 |
0 |
1ビット |
45ビット |
4ビット |
なし |
72ビット |
6ビット |
RGB444 × 6組 |
1 |
2ビット |
46ビット |
6ビット |
なし |
72ビット |
2ビット |
RGB666 × 4組 |
2 |
3ビット |
29ビット |
6ビット |
なし |
90ビット |
なし |
RGB555 × 6組 |
3 |
4ビット |
30ビット |
6ビット |
なし |
84ビット |
4ビット |
RGB777 × 4組 |
4 |
5ビット |
31+47ビット |
なし |
2ビット |
42ビット |
1ビット |
RGBA5556 × 2組 |
5 |
6ビット |
31+31ビット |
なし |
2ビット |
58ビット |
なし |
RGBA7778 × 2組 |
6 |
7ビット |
63ビット |
なし |
なし |
56ビット |
2ビット |
RGBA7777 × 2組 |
7 |
8ビット |
30ビット |
6ビット |
なし |
80ビット |
4ビット |
RGBA5555 × 4組 |
モードビット
- BC7でサポートされている8種類のモードを区別するためのビットパターンです。
- モードビットは「接頭符号」になっているため、モードによってビット数が違います。モードビットは、ビット1が出現するまでのビット0の個数がモード名の番号と一致するような符号になっています。たとえば、モード3は0001というビットパターンになっています。
- モードビットで使用されていないビットパターン(8ビットすべて0) はリザーブとなっていて、エンコーダでの使用が禁止されています。使用できるモードは4×4ピクセルのブロック毎に自由に選べますが、モードを選ぶのはエンコーダ(テクスチャ圧縮を行うプログラム) 側の話で、エンコーダがテクスチャ圧縮の際に自動的に各ブロックに適したモードを決定します。
インデックス値
- インデックス値は4×4ピクセルの各ピクセルがどの色なのかを表した情報です。
- BC7では、エンドポイントの表現形式からブロックの代表色を決め、その代表色を線形補間して4個または8個または16個のパレットを計算しますが、4×4ピクセルの各ピクセルが、そのパレットの何番の色なのかを示す値がインデックス値です。
- モード0,1ではインデックス値はピクセル毎に3ビット、モード2,3,5,7ではピクセル毎に2ビット、モード6ではピクセル毎に4ビットです。
- モード5では、RGB 用のインデックス値とアルファ用のインデックス値が独立していて、RGB 用が2ビット、アルファ用が2ビットです。
- モード4では、RGB用とアルファ用のインデックス値が独立していて、付加情報のインデックスセレクタによってRGB用が2ビットでアルファ用が3ビットの場合と、RGB用が3ビットでアルファ用が2ビットの場合があります。
- インデックス値の総ビット数が3ビット×4×4の48ビットではなく45ビットになっていたり、2ビット×4×4の32ビットではなく30ビットなどの中途半端な数字になっているのは、特定の(モードやパーティションで変わる)位置のピクセルだけインデックス値として割り当てられるビット数が1ビット少なく、選べるパレットが制限されているためです。
パーティション
- BC7では、ブロックノイズが目立つのを防ぐため、4×4ピクセルを2つまたは3つの領域に分割して、それぞれの領域で代表色を変える事が可能になっています。
- パーティションは、この領域分割のパターンを示す値で、BC7では以下のような2分割用の64種類の分割パターンと、3分割用の64種類の分割パターンが予め固定的に規定されています(モード0は先頭16種類のみ使用)。
図2 2分割用の分割パターン(クリックで拡大)

※ ○=領域0、●=領域1 (前半の32種類の分割パターンはBC6Hの分割パターンと同じです)
図3 3分割用の分割パターン(クリックで拡大)

※ ○=領域0、◎=領域1、●=領域2
交換情報
- BC7 のモード4とモード5では、インデックス値が2組あり、通常はRGB 用とアルファ用で使い分けますが、その使い分けを変更できる機能があります。この指定をするのが交換情報で、インデックス値を他の成分とは別にしたい成分(補間計算で他の要素から独立させたい成分) を指定する2ビットの値になっています。
表3 BC7の交換情報
交換情報 |
独立成分 |
運動成分 |
00 |
A |
R,G,B |
01 |
R |
G, B, A |
10 |
G |
R, B, A |
11 |
B |
R, G, A |
エンドポイント
- 4×4ピクセル毎の、そのブロックの代表色となる色情報を即値で表したもので、モードによって色情報が何組あるのかが決まっています。
- 4×4ピクセルが複数の領域に分割されるモードの場合は、それぞれの領域ごとに代表色が記録されています。この代表色を元に、インデックス値が2ビットなら4個、3ビットなら8個、4ビットなら16個のパレットを直線補間計算で求めると、この計算結果のパレットと各ピクセルのインデックス値から各ピクセルの表現する値が判ります。
表4 補間計算(2ビットのインデックス用)
パレット番号 |
計算式(2ビットのインデックス用) |
0 |
A |
1 |
(A * (64 – 21) + B * 21 + 32) / 64 |
2 |
(A * (64 – 43) + B * 43 + 32) / 64 |
3 |
B |
表5 補間計算(3ビットのインデックス用)
パレット番号 |
計算式(3ビットのインデックス用) |
0 |
A |
1 |
(A * (64 – 9) + B * 9 + 32) / 64 |
2 |
(A * (64 – 18) + B * 18 + 32) / 64 |
3 |
(A * (64 – 27) + B * 27 + 32) / 64 |
4 |
(A * (64 – 37) + B * 37 + 32) / 64 |
5 |
(A * (64 – 46) + B * 46 + 32) / 64 |
6 |
(A * (64 – 55) + B * 55 + 32) / 64 |
7 |
B |
表6 補間計算(4ビットのインデックス用)
パレット番号 |
計算式(4ビットのインデックス用) |
0 |
A |
1 |
(A * (64 – 4) + B * 4 + 32) / 64 |
2 |
(A * (64 – 9) + B * 9 + 32) / 64 |
3 |
(A * (64 – 13) + B * 13 + 32) / 64 |
4 |
(A * (64 – 17) + B * 17 + 32) / 64 |
5 |
(A * (64 – 21) + B * 21 + 32) / 64 |
6 |
(A * (64 – 26) + B * 26 + 32) / 64 |
7 |
(A * (64 – 30) + B * 30 + 32) / 64 |
8 |
(A * (64 – 34) + B * 34 + 32) / 64 |
9 |
(A * (64 – 38) + B * 38 + 32) / 64 |
10 |
(A * (64 – 43) + B * 43 + 32) / 64 |
11 |
(A * (64 – 47) + B * 47 + 32) / 64 |
12 |
(A * (64 – 51) + B * 51 + 32) / 64 |
13 |
(A * (64 – 55) + B * 55 + 32) / 64 |
14 |
(A * (64 – 60) + B * 60 + 32) / 64 |
15 |
B |
付加情報
- モード0,1,3,6,7には、エンドポイントのRGB値の精度不足を補うために「Pビット」という付加情報が用意されています。これは、RGBの各ビット数を1ビット増やし、その最下位ビットを1ビットのPビットで表す、というような処理になっていて、表現できる輝度成分の階調数を倍増する効果があります。たとえば、RGB555+Pビットの場合、色の輝度成分の階調に関してはRGB666と同等になります。
- Pビットは、モード0のようにエンドポイントの各RGB値に1個が付く場合と、モード1のようにサブセットに対して1個が付く場合があります。
- モード4には、インデックスセレクタという1ビットの付加情報が用意されています。モード4では2ビットのインデックス値と3ビットのインデックス値が格納されていて、どちらがRGB用でどちらがアルファ用なのかを、このインデックスセレクタで指定するようになっています。
- BC7 の詳細仕様については、マイクロソフト社の開発者向けページ(MSDN BC7 Format)をご覧ください。
まとめ
DirectX 11ではBC1~BC7(BC1、BC2、BC3、BC4、BC5、BC6H、BC7)の圧縮テクスチャが使用できますが、BC1_UNORM~BC3_UNORMに関してはDXT1~DXT5の呼び方が変わったもの程度の理解で問題ないでしょう。
たとえば、マイクロソフト社のツールでも、デフォルト設定ではBC1_UNORM形式は従来の(DirectX 9互換の)DXT1形式で出力されるようになっています。これは、対応ツールが少ないDX10拡張DDSでBC1_UNORM~BC3_UNORMで保存するより、対応ツールが多いDXT1~DXT5互換形式で保存するほうが何かと都合が良いためです。
BC1_UNORM_SRGBなどのsRGB形式に関してはDirectX 9互換形式では保存できないので、DX10拡張DDS で保存するしかありません。
なお、DX10拡張DDSは従来のDirectX 9のDDSファイルとは異なる形式となります。このあたりの都合に関しては使用する3Dエンジンなどにも依存する話なので、プログラマーとデザイナー間で予め使用するファイルフォーマットの調整をしておきましょう。
BC4~BC5についてはRGB画像データ以外の1成分や2成分のデータを扱う場合のフォーマットなので、BC4~BC5が利用可能なデータで、その形式を使うことが指示されていたら使用する、という、どちらかというと消極的な用途になる場合が多いと思います。
BC6はHDR(ハイダイナミックレンジ)のRGB画像専用なので、HDRを使わない場合は利用価値がありませんが、HDRを使う場合は、他のHDR画像用のフォーマットよりも高圧縮率なので、ファイルサイズを抑えたい場合は便利に使えるでしょう。
BC7は、従来ではDXT2~DXT5を使用していたテクスチャを置き換えるのに最適なフォーマットですが、当初(2009年~2011年頃)はマイクロソフト社が提供していた変換ツールが正常に動かなかったり処理が非常に遅かったりと色々と問題があり、BC7形式を利用する際の障害になっていました。しかし、現在はそれもほぼ解決されています。
表7 BC7形式への変換時間と変換後の画質
マイクロソフト社の変換ツール |
変換時間 |
画質 |
texconvex.exe(2010年版) |
正常に動作しない |
texconvex.exe(2011年版) |
110秒 |
高 |
texconv.exe(DirectXTex version), CPU使用 |
12秒 |
高 |
texconv.exe(DirectXTex version), GPU使用 |
1秒 |
中 |
* 画像サイズ:256×256ドット
* PC環境:Windows 7(Core i7 2700K + GeForce GTX 650 Ti)
texconv.exe(DirectXTex version)をデフォルトのGPU使用モードで変換した場合と、明示的にCPU使用モードを指定(-nogpuオプション)して変換した場合を比較すると、圧縮結果は同じにはならず、高速なGPU使用モードの方が画質が低くなってしまうようです。おそらく、GPGPU使用モードは画質よりも変換速度を重視して圧縮処理を行っているためだと思いますが、同一の画質で処理速度だけが違う、という訳ではない点には注意が必要です。このため、アプリの開発中は高速なGPU使用モードでBC7への変換を行い、マスター作成など開発の終盤ではCPU使用モードでBC7への変換をやりなおす、などの運用でカバーする必要があるかもしれません。
以上、DirectX系のアプリケーションの開発に携わっている方々の参考になれば幸いです。