3D モデルはなぜこんなに重いのか?
モデルはこっそり太っている
GLB ファイルをエクスポートしました。10MB。まずまずでしょう。スマホで開くと——白画面、カクつき、あるいはそのままクラッシュ。
パソコンでは問題ないのに、スマホだと爆発します。これはコードのせいではありません。3D モデルには直感に反する性質があるからです:ディスク上と VRAM では、サイズがまったく違います。
JPG 画像はディスク上では 200KB 程度かもしれません。しかし GPU は JPG を理解できません。理解できるのは生のピクセルだけです。だから VRAM にアップロードする前に、画像は完全に展開されます。2048x2048 のテクスチャは、展開後に約 22MB の VRAM を消費します。6 枚のテクスチャ(albedo、normal、roughness、metallic、AO、emissive)を使えば、マテリアル 1 つで 132MB です。
スマホの VRAM は合計 2〜4GB 程度しかないかもしれません。それなのに 1 つのモデルのテクスチャだけで 3〜6% を占めます。シーンに 10 個のモデルがあったら?
分解してみよう:容量はどこへ行っているのか
典型的な GLB モデルは主に 3 つの部分で構成されます:頂点データ、テクスチャ、そしてメタデータとアニメーション。
実際の PBR モデルで見てみましょう:
| 構成要素 | 内容 | 典型的な割合 | 備考 |
|---|---|---|---|
| テクスチャ | albedo、normal、roughness、metallic、AO など | 70-85% | ほぼ常に容量の大部分 |
| 頂点データ | position、normal、UV、tangent、color | 10-20% | モデルの複雑さによる |
| アニメーションデータ | スケルトン、スキニング、キーフレーム | 0-15% | アニメーションがある場合のみ |
| その他 | マテリアル定義、シーン構造、カメラ | < 2% | 無視できる |
テクスチャが約 80% を占めます。多くの場合、最適化すべきは頂点だと思いがちですが、実際に場所を取っているのはテクスチャです。
「ディスクが小さい」は「VRAM も小さい」と同義ではない
3D パフォーマンスを理解する上で、おそらく最も重要なポイントです。
PNG と JPG はネットワーク転送のために設計されています——ディスクでは小さく、ダウンロードも速い。しかし GPU はこれらを直接使えません。生のピクセルに完全に展開する必要があります。計算式:
VRAM 使用量 = 幅 * 高さ * 4バイト(RGBA) * 1.333(mipmap含む)
4096x4096 の RGBA テクスチャ:
| 指標 | 値 |
|---|---|
| PNG ファイルサイズ | ~8MB |
| JPG ファイルサイズ | ~1.5MB |
| VRAM 使用量(mipmap 含む) | ~87MB |
1.5MB の JPG が、VRAM では 87MB になります。
mipmap とは? GPU はテクスチャに対して、段階的に小さくなる一連のバージョンを生成します。元のサイズから 1x1 ピクセルまで、各レベルは前のレベルの半分です。これにより遠くのオブジェクトがより速く、より鮮明にレンダリングされますが、VRAM を約 33% 余分に消費します。ほぼすべての 3D アプリが mipmap を使うため、このオーバーヘッドは実質的に標準です。
つまり PNG や JPG は圧縮収納袋のようなものです——旅行用に小さく圧縮しても、目的地では全部広げなければなりません。ダウンロードは速くなりましたが、VRAM の節約にはなりません。
VRAM が足りなくなるとどうなるか
「メモリ不足」という綺麗なダイアログは出ません。現実はもっと悪いです:
- モバイル:白画面、あるいは OS がタブを直接強制終了
- VR ヘッドセット:フレームドロップ。VR でのフレームドロップは「少しカクつく」ではなく、酔いを引き起こします
- デスクトップ:テクスチャのちらつき、品質低下、レンダリングの遅延
Reddit で、ある開発者が WebXR ギャラリーを作り、Quest に立体画像 60 枚を詰め込みました。最初は正常でしたが、次第に不安定になり、最終的にクラッシュしました。彼は何日もコードをデバッグした後、VRAM のことを真剣に考えたことがないことに気づきました——ただ GPU に JPG を送り続けていただけでした。
圧縮の 2 つの道
3D モデルの圧縮は 2 つの方向に分かれます:
頂点圧縮——頂点座標、法線、UV などのジオメトリデータをよりコンパクトに格納します。例えば 32 ビット浮動小数点を 16 ビット整数に変える(これは量子化と呼ばれます)。代表的なソリューション:Draco、MeshOpt、KHR_mesh_quantization。
テクスチャ圧縮——VRAM 内でもテクスチャを圧縮された状態に保ちます。GPU はサンプリング時に個々のピクセルをその場でデコードし、ほぼパフォーマンスコストなし。代表的なソリューション:KTX2 + Basis Universal。
| 頂点圧縮 | テクスチャ圧縮 | |
|---|---|---|
| 何を減らすか | ジオメトリデータ | テクスチャ |
| 典型的な効果 | 50-90% 縮小 | ディスクで 50-70% 縮小、VRAM で 75% 削減 |
| ロスありか | はい、精度低下 | はい、品質低下 |
| 適した場面 | 頂点が密集したモデル | ほぼすべての PBR モデル |
| 詳細 | 第 2 章 | 第 3、4 章 |
よくある誤解:Draco で頂点を圧縮して終わり。しかしテクスチャがモデル容量の 80% を占めます。頂点を半分にしても、全体で 10% しか小さくならないかもしれません。両方を扱う必要があります。
すべての場面で通用する単一の方法はない
これがシリーズ全体の中核となる主張です:
プラットフォーム、デバイス、用途が違えば、必要な圧縮戦略も違います。
| シナリオ | 主なボトルネック | 重点 |
|---|---|---|
| デスクトップ Web 表示 | ダウンロード速度 | ファイルサイズ |
| モバイルブラウザ | VRAM | テクスチャ圧縮 |
| VR ヘッドセット | VRAM + フレームレート | テクスチャ圧縮 + 頂点簡略化 |
| WeChat ミニプログラム | パッケージサイズ + 互換性 | 軽量ソリューション(MeshOpt) |
| 大規模シーン | VRAM + ドローコール | 包括的圧縮 + LOD |
これからの各記事は「X を使えば OK」と言うだけではありません。X が輝く場面、逆に裏目に出る場面、そして Y を選ぶべき場面を説明します。
次のステップ
この記事で問題を整理しました。次は実践です——頂点圧縮の 3 つのツール、量子化、MeshOpt、Draco に出会いましょう。