ゲーム開発における画像フォーマット選定 - テクスチャ圧縮と描画パフォーマンスの最適化
ゲーム開発における画像フォーマットの特殊性
ゲーム開発で使用する画像フォーマットは、Web やデスクトップアプリケーションとは根本的に異なる要件を持ちます。Web では「ファイルサイズの最小化」と「ブラウザ互換性」が最優先ですが、ゲームでは「GPU での描画パフォーマンス」と「VRAM (ビデオメモリ) 使用量」が最重要です。
ゲーム画像の特殊要件:
- GPU ネイティブ圧縮: JPEG や PNG は CPU でデコードしてから GPU に転送する必要がありますが、GPU テクスチャ圧縮フォーマット (BCn, ASTC, ETC2) は GPU が直接読み取れるため、デコード処理が不要でメモリ帯域を節約できます
- ランダムアクセス: GPU はテクスチャの任意のピクセルに即座にアクセスする必要があります。JPEG のようにブロック単位でデコードが必要なフォーマットは使用できません
- 固定圧縮率: GPU テクスチャ圧縮は固定ビットレート (例: 4bpp, 8bpp) で、任意のピクセル位置のメモリアドレスを即座に計算できます
- ミップマップ対応: 遠くのオブジェクトには低解像度のテクスチャを使用するミップマップチェーンを格納できる必要があります
一般的なゲームプロジェクトでは、テクスチャがアセット全体の 60-80% を占めます。AAA タイトルでは数十 GB のテクスチャデータを扱うため、フォーマット選定がゲームのダウンロードサイズ、ロード時間、描画パフォーマンスに直結します。適切なフォーマットを選ぶことで、VRAM 使用量を 50-75% 削減しながら視覚品質を維持できます。
GPU テクスチャ圧縮の仕組み - BCn ファミリー (DirectX)
BCn (Block Compression) は DirectX で標準的に使用される GPU テクスチャ圧縮フォーマットファミリーです。すべての BCn フォーマットは 4x4 ピクセルのブロック単位で圧縮し、GPU ハードウェアがリアルタイムでデコードします。
BCn フォーマットの種類:
- BC1 (DXT1): RGB + 1 ビットアルファ。4bpp (bits per pixel)。2 つの 16 ビット基準色と 2 ビットのインデックスで 4x4 ブロックを表現。最も軽量だが品質は低い。不透明テクスチャや遠景に適する
- BC3 (DXT5): RGB + 8 ビットアルファ。8bpp。BC1 の RGB 圧縮に加え、アルファチャンネルを独立して 4 ビット精度で圧縮。半透明テクスチャの標準フォーマット
- BC4: 単一チャンネル (グレースケール)。4bpp。ハイトマップ、ラフネスマップなど単一チャンネルデータに最適
- BC5: 2 チャンネル。8bpp。法線マップ (Normal Map) に最適。XY 成分を独立して高精度に圧縮し、Z 成分はシェーダーで再計算する
- BC6H: HDR (Half-Float) RGB。8bpp。環境マップ、HDR ライトマップなど高ダイナミックレンジのテクスチャに使用
- BC7: 高品質 RGB/RGBA。8bpp。BC1/BC3 の後継で、8 つのモードを持ち、ブロックごとに最適なモードを選択して最高品質を実現。現代のゲームでカラーテクスチャの標準
BC7 は BC1 と比較して同じ 8bpp でも PSNR が 2-4dB 向上し、特にグラデーションやエッジ部分でのアーティファクトが大幅に軽減されます。エンコード時間は BC1 の 10-50 倍かかりますが、デコードは GPU ハードウェアで行うため実行時のコストは同等です。
ASTC - モバイルとクロスプラットフォームの標準
ASTC (Adaptive Scalable Texture Compression) は ARM が開発し、Khronos Group が標準化した次世代テクスチャ圧縮フォーマットです。iOS (A8 以降)、Android (多くの Adreno/Mali GPU)、Nintendo Switch で広くサポートされ、モバイルゲーム開発の事実上の標準となっています。
ASTC の革新的な特徴:
- 可変ブロックサイズ: 4x4 から 12x12 まで 14 種類のブロックサイズを選択可能。ブロックサイズが大きいほど圧縮率が高く (ビットレートが低く)、品質は下がる。用途に応じて最適なバランスを選べる
- 柔軟なビットレート: 0.89bpp (12x12 ブロック) から 8bpp (4x4 ブロック) まで連続的に調整可能。BC7 は 8bpp 固定だが、ASTC は品質要件に応じて細かく制御できる
- 1-4 チャンネル対応: LDR (8 ビット)、HDR (16 ビット浮動小数点) の両方に対応。カラー、法線マップ、マスクなどあらゆる用途を 1 つのフォーマットでカバー
推奨ブロックサイズの選定:
- 4x4 (8bpp): UI テクスチャ、キャラクターの顔など品質最優先の箇所
- 5x5 (5.12bpp): 一般的なキャラクターテクスチャ、小道具
- 6x6 (3.56bpp): 背景テクスチャ、地形。品質とサイズのバランスが良い
- 8x8 (2bpp): 遠景、スカイボックス、大面積の低ディテールテクスチャ
- 12x12 (0.89bpp): 極端にサイズを削減したい場合。品質は低いがファイルサイズは最小
Unity では TextureImporter の設定で ASTC ブロックサイズを指定でき、Unreal Engine では Texture Compression Settings から ASTC プロファイルを選択できます。ビルドパイプラインに astcenc (ARM 公式エンコーダ) を組み込むことで、高品質なオフラインエンコードが可能です。
コンテナフォーマット - DDS, KTX2, Basis Universal
GPU テクスチャ圧縮データを格納するコンテナフォーマットの選択も重要です。コンテナはテクスチャデータ本体に加え、ミップマップチェーン、キューブマップの面、配列テクスチャのレイヤーなどのメタデータを管理します。
主要コンテナフォーマット:
- DDS (DirectDraw Surface): DirectX/Windows の標準。BCn 圧縮データの格納に最適。ヘッダーが 128 バイトと軽量で、パース処理が高速。DX10 拡張ヘッダーで BC6H/BC7 にも対応。PC ゲーム開発では最も一般的
- KTX2 (Khronos Texture 2.0): Vulkan/OpenGL の標準コンテナ。ASTC, ETC2, BCn すべてに対応し、Basis Universal のスーパー圧縮 (Supercompression) もサポート。クロスプラットフォーム開発に最適
- Basis Universal (.basis): Binomial が開発したトランスコード可能なフォーマット。1 つのファイルから BCn, ASTC, ETC2, PVRTC など任意のフォーマットにランタイムでトランスコードできる。ファイルサイズは各ネイティブフォーマットの 10-25% 増だが、プラットフォームごとに別ファイルを用意する必要がなくなる
Basis Universal の仕組み:
ETC1S モードでは画像を ETC1 互換の中間表現に圧縮し、ランタイムで対象 GPU に合わせてトランスコードします。UASTC モードでは ASTC 4x4 互換の高品質中間表現を使用し、BC7 や ASTC への高速トランスコードが可能です。Web 向けの glTF 3D モデルでは KTX2 + Basis Universal が標準的な選択肢となっており、Three.js や Babylon.js でネイティブサポートされています。
選定の指針: PC 専用なら DDS (BC7)、モバイル専用なら KTX2 (ASTC)、クロスプラットフォームなら KTX2 + Basis Universal が最適です。
プラットフォーム別の最適フォーマット選定
ゲームのターゲットプラットフォームによって、使用可能なテクスチャ圧縮フォーマットは大きく異なります。各プラットフォームの GPU がハードウェアレベルでサポートするフォーマットを選択しないと、CPU デコードが発生してパフォーマンスが大幅に低下します。
プラットフォーム別推奨フォーマット:
- PC (Windows/DirectX 12): BC7 (カラー)、BC5 (法線マップ)、BC6H (HDR)、BC4 (グレースケール)。すべての DirectX 11 以降の GPU でサポート
- PC (Vulkan/OpenGL): BC7 が基本。Linux/macOS では ASTC もサポートされる場合がある
- PlayStation 5: BC7 ベース。独自の GNF コンテナフォーマットを使用
- Xbox Series X/S: BC7 + BCPack (Xbox 独自の追加圧縮レイヤー)
- Nintendo Switch: ASTC が推奨。BC7 も Tegra X1 でサポート
- iOS (A8 以降): ASTC が標準。PVRTC は非推奨 (A15 以降で ASTC のみ推奨)
- Android: ASTC (Adreno 4xx 以降、Mali-T760 以降)。古い端末向けには ETC2 にフォールバック
- Web (WebGL/WebGPU): Basis Universal (KTX2) でランタイムトランスコード。対象 GPU に応じて BC7/ASTC/ETC2 に変換
マルチプラットフォーム開発のベストプラクティス:
- ソースアセットは非圧縮 (PNG/TGA/EXR) で管理し、ビルドパイプラインでプラットフォームごとに最適なフォーマットに変換する
- Unity の Texture Import Settings や Unreal の Texture Compression Settings でプラットフォーム別の設定を定義する
- CI/CD パイプラインに
texconv(DirectX)、astcenc(ARM)、basisu(Basis Universal) を組み込む
テクスチャアトラスとストリーミングの設計
テクスチャフォーマットの選定に加え、テクスチャの管理方法もゲームパフォーマンスに大きく影響します。テクスチャアトラスとストリーミングは、ドローコール削減と VRAM 効率化の 2 大テクニックです。
テクスチャアトラスの設計:
- 基本概念: 複数の小さなテクスチャを 1 枚の大きなテクスチャにパッキングする。GPU のステート切り替え (テクスチャバインド) を削減し、ドローコールをバッチ化できる
- 推奨サイズ: 2,048 × 2,048または 4,096 × 4,096が一般的。これ以上大きいとミップマップの最下位レベルでも大きなメモリを消費する
- パディング: テクスチャ間に 2-4 ピクセルのパディングを設け、バイリニアフィルタリングによるブリーディング (隣接テクスチャの色が漏れる現象) を防止する
- ミップマップ対応: アトラス内の各テクスチャが 2 のべき乗サイズでない場合、ミップマップ生成時にブリーディングが発生する。TextureArray を使用するか、各テクスチャを 2 のべき乗に揃える
テクスチャストリーミング (Virtual Texturing):
- 目的: ゲーム全体のテクスチャが VRAM に収まらない場合 (AAA タイトルでは 20-50GB のテクスチャデータ)、必要な部分だけを動的にロード/アンロードする
- Mip-Tail Streaming: 低解像度のミップレベル (mip tail) は常に VRAM に保持し、高解像度のミップレベルはカメラからの距離に応じてストリーミングする
- Sparse/Virtual Textures: DirectX 12 の Tiled Resources や Vulkan の Sparse Binding を使用し、巨大なテクスチャの一部だけを物理メモリにマッピングする
実装例として、Unreal Engine 5 の Virtual Texture Streaming は 16K テクスチャを 128 × 128のタイルに分割し、可視タイルのみを VRAM にストリーミングします。これにより、見た目の品質を維持しながら VRAM 使用量を 40-60% 削減できます。