ETC(Ericsson Texture Compression)フォーマットで圧縮された ETC1 圧縮テクスチャは、ハードウェアでの展開に対応していますので、通常のテクスチャに比べて高速に処理することができます。さらに、24 bit カラー画像(RGB8)を 4x4 テクセルのブロックごとにわずか 8 バイト(64 bit)に圧縮することができるため、テクスチャで使用するメモリの削減も期待できます。しかし、ブロック内で使われている色が似たような色であることを利用した圧縮方法のため、風景や人物をカメラで撮影した画像の圧縮には向いていますが、赤と青のように RGB 各成分の値が極端に違う色が同じブロック内に存在する画像の圧縮には向いていません。
3DS 独自の仕様として、テクセルごとに 4 bit のアルファ値を付加したフォーマット(合計 128 bit)に対応しています。
この章では、ETC1 圧縮テクスチャのフォーマットを解説し、3DS で使用するために必要なフォーマットの変換についても説明します。
7.1. ETC フォーマット
ETC フォーマットは、4x4 テクセルを 4x2 または 2x4 テクセルで分割したサブブロック単位で、基準となる RGB 値(ベースカラー)と差分を表すテーブルを持っています。フォーマットには個別モード(Individual mode)と差分モード(Differential mode)の 2 種類が存在しますが、その違いは前半の 32 bit に含まれているベースカラーのフォーマットだけです。どちらのフォーマットも後半の 32 bit に違いはなく、ベースカラーの決定以外で展開のアルゴリズムにも違いはありません。
以下に ETC1 圧縮テクスチャのビットレイアウトを示します。データの並びとしては、アルファチャンネルがカラーチャンネルの前に配置されます。
7.1.1. テクセルの配置とブロックの分割
後半の 32 bit はさらに MSB と LSB の 16 bit ずつの領域に分かれています。各領域の最下位ビットから最上位ビットの並びは、左上のテクセルから縦方向に右下のテクセルと対応しています。つまり、最下位ビット(bit 0, 16)が左上に配置されたテクセルに対応し、そこから下方向に上位のビットが対応していきます。下端に到達したら、右隣の列の上端から下端に向かって対応し、最上位ビット(bit 15, 31)は右下のテクセルに対応しています。
Flipbit(bit 32)の値によって、ブロックは縦(2x4)または横(4x2)に分割されます。分割された 8 テクセルをサブブロックと呼び、左または上にあるサブブロックをサブブロック 1、右または下にあるサブブロックをサブブロック 2 とします。ブロックの分割方法によってテクセルの配置順は変化しません。
7.1.2. ベースカラーの決定
ベースカラーはサブブロックごとに決定されますが、Diffbit(bit 33)の値によってフォーマットとベースカラーの決定方法に違いがあります。
Diffbit が 0 のときは個別モード(Individual mode)となり、サブブロックごとに R、G、B の各成分が 4 bit ずつ割り当てられています。サブブロック 1 が R1/G1/B1、サブブロック 2 が R2/G2/B2 です。ベースカラーは、この 4 bit を連結して 8 bit に拡張した値(17 倍)です。R1 が 1001b(9)のとき、サブブロック 1 のベースカラーの赤成分は 10011001b(153)となります。
Diffbit が 1 のときは差分モード(Differential mode)となり、サブブロック 1 には R、G、B の各成分が 5 bit ずつ割り当てられ、サブブロック 2 にはサブブロック 1 の 5 bit との差分値として各成分 3 bit が割り当てられています。サブブロック 1 が R1' / G1' / B1'、サブブロック 2 が R1' + dR2 / G1' + dG2 / B1' + dB2 です。サブブロック 1 のベースカラーは、5 bit に上位 3 bit を連結して 8 ビットに拡張した値(8.25倍)です。サブブロック 2 のベースカラーは、5 bit に 2 の補数表現で表された 3 bit の差分値(+3 ~ -4)を加算した結果をサブブロック 1 と同様に拡張した値です。R1' が 11001b(25)、dR2 が 100b(-4)のとき、サブブロック 1 のベースカラーの赤成分は 11001110b(206)、サブブロック 2 のベースカラーの赤成分は 11001b(25)- 100b(4)= 10101b(21)を拡張した値のため 10101101b(173)となります。差分値を加算した結果が 0 ~ 31 の範囲内に収まらない組み合わせは動作が不定となりますので、圧縮時にそのような組み合わせが発生しないようにしなければなりません。
ビット列 | 値 | ビット列 | 値 | ビット列 | 値 | ビット列 | 値 |
---|---|---|---|---|---|---|---|
0000b | 0 | 0100b | 68 | 1000b | 136 | 1100b | 204 |
0001b | 17 | 0101b | 85 | 1001b | 153 | 1101b | 221 |
0010b | 34 | 0110b | 102 | 1010b | 170 | 1110b | 238 |
0011b | 51 | 0111b | 119 | 1011b | 187 | 1111b | 255 |
ビット列 | 値 |
100b |
101b |
110b |
111b |
000b |
001b |
010b |
011b |
---|---|---|---|---|---|---|---|---|---|
00000b | 0 | - | - | - | - | 0 | 8 | 16 | 24 |
00001b | 8 | - | - | - | 0 | 8 | 16 | 24 | 33 |
00010b | 16 | - | - | 0 | 8 | 16 | 24 | 33 | 41 |
00011b | 24 | - | 0 | 8 | 16 | 24 | 33 | 41 | 49 |
00100b | 33 | 0 | 8 | 16 | 24 | 33 | 41 | 49 | 57 |
00101b | 41 | 8 | 16 | 24 | 33 | 41 | 49 | 57 | 66 |
00110b | 49 | 16 | 24 | 33 | 41 | 49 | 57 | 66 | 74 |
00111b | 57 | 24 | 33 | 41 | 49 | 57 | 66 | 74 | 82 |
01000b | 66 | 33 | 41 | 49 | 57 | 66 | 74 | 82 | 90 |
01001b | 74 | 41 | 49 | 57 | 66 | 74 | 82 | 90 | 99 |
01010b | 82 | 49 | 57 | 66 | 74 | 82 | 90 | 99 | 107 |
01011b | 90 | 57 | 66 | 74 | 82 | 90 | 99 | 107 | 115 |
01100b | 99 | 66 | 74 | 82 | 90 | 99 | 107 | 115 | 123 |
01101b | 107 | 74 | 82 | 90 | 99 | 107 | 115 | 123 | 132 |
01110b | 115 | 82 | 90 | 99 | 107 | 115 | 123 | 132 | 140 |
01111b | 123 | 90 | 99 | 107 | 115 | 123 | 132 | 140 | 148 |
10000b | 132 | 99 | 107 | 115 | 123 | 132 | 140 | 148 | 156 |
10001b | 140 | 107 | 115 | 123 | 132 | 140 | 148 | 156 | 165 |
10010b | 148 | 115 | 123 | 132 | 140 | 148 | 156 | 165 | 173 |
10011b | 156 | 123 | 132 | 140 | 148 | 156 | 165 | 173 | 181 |
10100b | 165 | 132 | 140 | 148 | 156 | 165 | 173 | 181 | 189 |
10101b | 173 | 140 | 148 | 156 | 165 | 173 | 181 | 189 | 198 |
10110b | 181 | 148 | 156 | 165 | 173 | 181 | 189 | 198 | 206 |
10111b | 189 | 156 | 165 | 173 | 181 | 189 | 198 | 206 | 214 |
11000b | 198 | 165 | 173 | 181 | 189 | 198 | 206 | 214 | 222 |
11001b | 206 | 173 | 181 | 189 | 198 | 206 | 214 | 222 | 231 |
11010b | 214 | 181 | 189 | 198 | 206 | 214 | 222 | 231 | 239 |
11011b | 222 | 189 | 198 | 206 | 214 | 222 | 231 | 239 | 247 |
11100b | 231 | 198 | 206 | 214 | 222 | 231 | 239 | 247 | 255 |
11101b | 239 | 206 | 214 | 222 | 231 | 239 | 247 | 255 | - |
11110b | 247 | 214 | 222 | 231 | 239 | 247 | 255 | - | - |
11111b | 255 | 222 | 231 | 239 | 247 | 255 | - | - | - |
7.1.3. 差分テーブルとテクセルカラーの決定
決定したベースカラーに対して、差分テーブルから選択した差分値を加算した結果が最終的にテクセルカラーとなります。
差分テーブルはサブブロックごとに Table codeword(Table CW)で指定します。指定には、サブブロック 1 が Table CW1(bit 37 ~ 39)を、サブブロック 2 が Table CW2(bit 34 ~ 36)を使い、その値は 3 bit なので 8 種類から選択することができます。差分テーブルには 4 つの差分値が決められており、MSB と LSB の組み合わせでテクセルごとの差分値に使う値が決まります。選択された差分値はベースカラーの RGB 成分すべてに加算され、加算された結果は 0 ~ 255 の範囲にクランプされます。例えば、差分テーブルが 011b、MSB が 1、LSB が 1 のときは -42 がベースカラーの全成分に加算され、ベースカラーを(33, 198, 99)とするとテクセルカラーは(0, 156, 57)となります。
Table codeword | MSB=1 LSB=1 |
MSB=1 LSB=0 |
MSB=0 LSB=0 |
MSB=0 LSB=1 |
---|---|---|---|---|
000b | -8 | -2 | +2 | +8 |
001b | -17 | -5 | +5 | +17 |
010b | -29 | -9 | +9 | +29 |
011b | -42 | -13 | +13 | +42 |
100b | -60 | -18 | +18 | +60 |
101b | -80 | -24 | +24 | +80 |
110b | -106 | -33 | +33 | +106 |
111b | -183 | -47 | +47 | +183 |
7.2. PICA ネイティブフォーマットでの圧縮テクスチャ
3DS で ETC1 圧縮テクスチャを使用する場合、そのフォーマットは PICA ネイティブフォーマットでなければなりません。PICA ネイティブフォーマットは OpenGL ES の標準仕様とは、テクセルの参照開始座標やブロックの並び、バイトオーダーが異なります。
7.2.1. V フリップ
OpenGL ES ではテクセルの参照開始座標は(u, v)=(0.0, 0.0)ですが、3DS では(u, v)=(0.0, 1.0)となっています。そのため、テクスチャイメージを圧縮する前に v 座標方向のフリップ(V フリップ)を適用しなければなりません。
7.2.2. ブロックフォーマット
ETC1 圧縮テクスチャでは 4x4 テクセルのブロックを u、v 方向に 2 つずつ、8x8 テクセルをメタブロックとして定義しています。メタブロック内ではジグザグにブロックが配置され、メタブロックは u 方向に連続して配置されます。