DXTC(S3TC)圧縮のアルゴリズムとは?~後編~

R&D部 上田です。

DXTC(S3TC)圧縮のアルゴリズム解説、後編です。前回のエントリーでは「DXTCとは何か?」「どんなところで使われているのか?」といった基本的な解説と、DXT1のアルゴリズムをご説明しました。今回はDXT2~DXT5のアルゴリズムについて解説していきます。

DXT2~5って何?

DXTC(S3TC)圧縮には、DXT1~5の5種類のアルゴリズムが存在します。前回解説したのはDXT1のアルゴリズムです。

何が違うの?

DXT1はアルファ(α,alpha)チャネル付き画像(32bit ARGBカラー)に対応していませんでした(完全透明色=抜き色のみ対応)。これに対して、DXT2~5はアルファチャンネル付き画像に対応しています。

その代わり、DXT1が24bit RGBカラー画像を圧縮すると圧縮率が1/6 (4×4ブロック=16ピクセルあたり8バイト)となるのに対して、DXT2~DXT5は32bit ARGBカラー画像を圧縮すると圧縮率が1/4 (4×4ブロック=16ピクセルあたり16バイト)になります。

DXT2~5のアルゴリズム

DXT2~5で共通する基本原理

まず、4×4ピクセルを1ブロックとして扱うことは、DXT1~5の全てで同じです。

さて、改めて説明するまでもないことですが、32bit ARGBカラー画像というのは、24bit RGBカラー画像に8bitのアルファ成分を加えた画像です。

ARGBimage_half

32bit ARGBカラー画像はRGB成分とアルファ成分でできている

まず、24bit RGBカラー画像部分については、DXT1と同じ圧縮するアルゴリズムを使用します。

DXT1_half

DXT1で24bit RGBカラー画像を圧縮できる

32bit ARGBカラー画像の圧縮では、RGB成分はDXT1と同じ手法で圧縮し、アルファ成分のみを1ブロック64bit として圧縮します。

DXT2to5_half

DXT2~5では、RGB成分はDXT1で圧縮し、アルファ成分は別に圧縮する

このアルファ成分の圧縮アルゴリズムが4種類あり、それらがDXT2~5となります。

DXT3のアルゴリズム

まずDXT2は飛ばして、先にDXT3のアルゴリズムから解説します(その方が都合が良いので…)。

一つ前の図で、DXT2~5ではアルファ成分を1ブロックあたり64bitに圧縮する、と書きました。DXT3ではこの64bitを単純にアルファ成分の表現に使います。まず圧縮前と圧縮後について、1ピクセルあたりのビット数を比べると以下のようになります。

DXT3_alpha_half

DXT3での1ピクセルあたりの階調数は1/16になる

圧縮前後で1ピクセルあたりのビット数が半分になるのに対し、そのビット数で表現できる階調数は1/16になります。表現できる階調数が256階調から16階調になる、ということをグラフにしてみると以下のようになります。

DXT3_graph_half

256階調(圧縮前)と16階調(圧縮後)の比較

グラフにすると表現力が大幅に落ちているのが良く分かりますね。

DXT3の実際の処理としては、圧縮前のアルファ値が0~8なら圧縮後は0、9~25なら17、26~42なら34、…というようにアルファ値を置き換えていきます。

DXT3_example_half

DXT3でアルファ成分を圧縮するとこうなる

上の図を見るとわかるように、DXT3のアルゴリズムではアルファ値の細かい変化は圧縮後に反映されず、アルファ値が滑らかに変化していくような画像をDXT3で圧縮すると、劣化が激しくなってしまいます。

DXT5のアルゴリズム

今度はDXT4を飛ばしてDXT5のアルゴリズムを解説します。

DXT5ではDXT3の欠点を克服するようにアルゴリズムが修正されています。まず、DXT1と同じように代表的な8bitアルファ値を二つ決め、それらから補間したアルファ値を作り、合計8個のアルファ値を表現します。

DXT5_alpha_half

DXTC5ではアルファ値を2個取り出し、それらから補間アルファ値を作る

また、ここでもDXT1と同様に「代表アルファ値二つの大小関係」によってアルファ値の表現方法が異なる点に注目してください。
具体的には、上の図で示したように、アルファ値8個の内容は

  • 代表アルファ値二つの間を8階調で表現する
  • 代表アルファ値二つの間を6階調で表現し、更に「完全透明(0)」「完全不透明(255)」の二つの値を持つ

のいずれかになります。
後者は、半透明を使った文字やアイコンで、周囲を完全透明にしているような場合に有用です。

そしてこれら8個のアルファ値について、ブロック内の各ピクセルにインデックスを付けます。
今回は8個の値があるので、各ピクセル3bit使います。こうすることで、64bitに圧縮できます。

DXT5_bit_half

DXT5圧縮後のアルファ成分は、2個のアルファ値と3bitのインデックスになる

このように補間したアルファ値を用いることで、DXT3よりも圧縮後のアルファ値の表現力を向上することが可能になります。

DXT5_graph_half

DXT5では256階調を任意の範囲で8階調にする

ただし、上図で示したようにアルファ値の範囲が広くなると階調表現力が下がってしまうので、使用する場面を選ぶ必要があります。例えば、アルファ値の範囲が0~255という一番極端な場合では、DXT3よりもDXT5のほうが階調表現が劣ることになります。

DXT2とDXT4のアルゴリズム

飛ばしていたDXT2とDXT4についてですが、基本的なアルゴリズムはDXT2がDXT3と、DXT4がDXT5と同じです。違う点は、DXT2とDXT4ではRGB値にアルファ値が予め乗算されて格納されていることです。これを乗算済みアルファと言います。乗算済みアルファについては、3D描画の領域の話題になりますので、興味のある方は「乗算済みアルファ」で検索してみてください。

DXTC 1~5 特徴のまとめ

DXTC 1~5の特徴
名前 RGBチャネル アルファチャンネル 圧縮率 備考
DXT1 代表2値+補間2値 なし 1/6 元画像αなし
DXT1 代表2値+補間1値 1bit 1/8 元画像αあり
DXT2 代表2値+補間2値 4bit 1/4 乗算済α
DXT3 代表2値+補間2値 4bit 1/4
DXT4 代表2値+補間2値 代表2値+補間6値  または
0+代表2値+補間4値+255
1/4 乗算済α
DXT5 代表2値+補間2値 代表2値+補間6値  または
0+代表2値+補間4値+255
1/4
タグ , , , , | 2020/06/16 更新 |