入門ガイド
テクスチャは GPU の中でどうなるのか
300 KB の PNG が、知らないうちに 5 MB のグラフィックスメモリを占めることがあります。このガイドでは、その理由、GPU がブロック圧縮でテクスチャを小さくする仕組み、そしてフォーマットの選び方を説明します。どの考え方にも実際に試せるデモがあります。
第 1 章
ファイルサイズはメモリサイズではない
PNG や JPEG は画像を保存・送信するための形式です。GPU がテクスチャを描画する前に、画像は生のテクセルに展開されます。通常は 1 テクセルあたり 4 バイトです。
GPU はフレームごとにテクセルを何百万回もサンプリングするため、いつでも読める状態にしておく必要があります。そのためメモリ使用量は解像度とピクセル形式だけで決まり、ファイルの圧縮率とは関係ありません。遠くの面に使う縮小コピーであるミップマップを加えると、さらに約 3 分の 1 増えます。
- RGBA81 テクセルあたり 32 ビット213 MiB基準1 枚あたり 21.3 MiB
- BC7 · ASTC 4×41 テクセルあたり 8 ビット53.3 MiB4 分の 11 枚あたり 5.3 MiB
- BC1 · ETC2 RGB1 テクセルあたり 4 ビット26.7 MiB8 分の 11 枚あたり 2.7 MiB
- ASTC 6×61 テクセルあたり 3.56 ビット23.8 MiB9 分の 11 枚あたり 2.4 MiB
- ASTC 8×81 テクセルあたり 2 ビット13.3 MiB16 分の 11 枚あたり 1.3 MiB
- ASTC 12×121 テクセルあたり 0.89 ビット6 MiB35.7 分の 11 枚あたり 612 KiB
ブロックフォーマットは各ミップレベルで完全なブロック単位に切り上げているため、GPU が実際に確保する量と一致します。
第 2 章
GPU が PNG をそのまま使えない理由
シェーダーがテクスチャをサンプリングするとき、どのテクセルをどの順番で要求するかはわかりません。ハードウェアはそのテクセルをすぐに見つける必要があります。
PNG や JPEG は可変長の符号化を使うため、途中のピクセルを読むにはその前をすべてデコードしなければなりません。GPU フォーマットは固定レートで、どの 4×4 ブロックもまったく同じバイト数を使います。そのため任意のテクセルのアドレスは掛け算一つで求まります。テクスチャはメモリ内で圧縮されたまま保持され、テクスチャユニットが読み込み時にブロックをデコードします。
矢印キーで選択位置を移動できます。
- 選択中のテクセル
- x 13、y 18
- 所属するブロック
- 3 列、4 行
- BC1 でのアドレス
- (4 × 8 + 3) × 8 バイト = 280 バイト目
メモリ上に並んだ 64 個のブロック
同じテクセルを PNG で読む場合
先に 0 行目から 18 行目まで展開が必要(32 行中 19 行)
第 3 章
4×4 ブロックの中身
最も古くから広く使われている BC1 は、考え方を一番わかりやすく示してくれます。16 テクセルのブロックをわずか 8 バイトに収めます。
エンコーダーは 2 つの端点カラーを選びます。デコーダーはそれらを混ぜて直線上の 4 色を作り、各テクセルは最も近い色を指す 2 ビットの番号だけを持ちます。色がなめらかに変化するブロックはきれいに残りますが、無関係な色が混在するブロックは崩れます。
第 4 章
フォーマットごとに異なるトレードオフ
新しいフォーマットは BC1 より賢くビットを使います。端点を増やしたり、ブロック内に複数のカラーラインを持たせたり、アルファを改善したり、ブロックサイズを選べるようにしたりしています。
BC7 と ASTC 4×4 は 1 テクセルあたり 8 ビットで、原画にかなり近い見た目になります。ASTC はブロックサイズで品質とサイズを調整できます。ブロックは常に 128 ビットなので、12×12 ブロックでは 1 テクセルあたり 1 ビット未満になります。Basis Universal は別の方法を取ります。コンパクトなファイルを 1 つだけ配布し、端末上でその GPU が対応するフォーマットにトランスコードします。
| フォーマット | テクセルあたりのビット数 | アルファ | 主なプラットフォーム | 向いている用途 |
|---|---|---|---|---|
| BC1 | 4 | 1 ビット | デスクトップ、ゲーム機 | メモリに余裕がないときの不透明なカラー |
| BC3 | 8 | あり | デスクトップ、ゲーム機 | 古いコンテンツでのなめらかなアルファ付きカラー |
| BC4 | 4 | データチャンネル | デスクトップ、ゲーム機 | 単一チャンネル:マスク、ラフネス、高さ |
| BC5 | 8 | データチャンネル | デスクトップ、ゲーム機 | 法線マップ(X と Y) |
| BC6H | 8 | なし | デスクトップ、ゲーム機 | スカイボックスやライトマップなどの HDR カラー |
| BC7 | 8 | あり | デスクトップ、ゲーム機 | アルファの有無を問わない高品質なカラー |
| ETC1 | 4 | なし | ほぼすべての Android | 非常に古い端末での不透明なカラー |
| ETC2 | 4–8 | あり | Android、iOS | 広く対応しているモバイル向けの代替 |
| ASTC | 0.89–8 | あり | 新しめの Android と iOS、Apple Silicon | モバイルで調整可能な品質 |
| PVRTC | 2–4 | あり | 古い iPhone と iPad | 古い Apple 端末専用 |
| Basis ETC1S | 変換先によって異なる | あり | あらゆる GPU(KTX2 経由) | 小さなダウンロードで、どの GPU でも動作 |
| Basis UASTC | 変換先によって異なる | あり | あらゆる GPU(KTX2 経由) | 高品質で、どの GPU でも動作 |
「エンコーダーを実行」を押すとサンプルを圧縮します。初回はエンコーダーをダウンロードします。
第 5 章
フォーマットの選び方
2 つの質問で候補はすぐに絞れます。どの GPU がこのテクスチャを読み込むのか、そして中身は何のデータなのか。
カラーテクスチャ、法線マップ、単一チャンネルのマスクは、圧縮に対する反応がそれぞれ異なります。また、デスクトップ、モバイル、Web では対応するフォーマットの系統も違います。自分のケースを選んで出発点を決め、実際のテクスチャで結果を確認してください。
まずはこれ
ASTC 6×6
ほかの候補: ASTC 4×4 · ETC2 RGB
ASTC は新しめの Android と iOS の GPU で使えます。6×6 がバランスの良い選択で、重要なアセットには 4×4、古い端末には ETC2 を使います。
ASTC エンコーダーを開く第 6 章
実践的なヒント
いくつかの習慣で、テクスチャ圧縮の問題のほとんどを防げます。
- 01
カラーは sRGB、データはリニアに
アルベドや UI のテクスチャは sRGB です。法線やラフネスなどのデータマップはリニアのままにしないと、ライティングが正しくなりません。
- 02
法線マップには専用のフォーマットを
BC5 や EAC RG11 のような 2 チャンネルフォーマットを使い、Z はシェーダーで復元します。カラー用フォーマットではビットが無駄になり、目に見える凹凸が生じます。
- 03
ミップマップを生成する
メモリは約 33% 増えますが、遠くの面のちらつきを防ぎ、サンプリングも速くなります。
- 04
サイズはブロックに合わせる
ほとんどのフォーマットは 4×4 ブロック単位なので、4 で割り切れるサイズならパディングが不要です。PVRTC などの古いフォーマットは、正方形かつ 2 のべき乗のサイズも必要です。
- 05
実際のコンテンツを実機で確認する
等倍に拡大してデコード結果と元画像を比較し、対象の GPU がそのフォーマットに対応しているか確認しましょう。
よくある質問
GPU テクスチャ圧縮は可逆ですか?
いいえ。BC、ETC、ASTC、PVRTC はブロックごとのサイズが固定された非可逆フォーマットです。どれだけ品質が落ちるかは、フォーマット、ブロックサイズ、画像の内容によります。
PNG や JPEG をそのままテクスチャに使えないのはなぜですか?
ダウンロードは速くなりますが、GPU は直接サンプリングできないため、生のテクセルにデコードされてメモリをフルに使います。GPU フォーマットはメモリ上でも小さいままです。
どのテクスチャフォーマットが一番良いですか?
デスクトップでは BC7、新しめのモバイル端末では ASTC が無難な選択です。Web のように 1 つのファイルを多くの GPU で動かす必要がある場合は、KTX2 と Basis Universal を使います。
テクセルあたりのビット数とは何ですか?
1 テクセルあたりの平均的な保存コストです。生の RGBA8 は 32 ビット、BC1 は 4 ビット、BC7 は 8 ビットで、ASTC はブロックサイズに応じて 8 ビットから約 0.89 ビットまで変わります。
自分のテクスチャで試してみましょう
すべてのエンコーダーはブラウザー内で動作します。PNG や JPEG をアップロードし、フォーマットを選んで結果を比較してください。