パフォーマンス最適化ガイド
OpenForge MCP のプロファイラーツールと最適化ツールを使って、シーンのパフォーマンスを体系的に改善する。ボトルネックの特定から、ドローコール削減、LOD、メモリ最適化、VRChat 固有の制限対応まで扱う。
前提
- Unity が起動し、OpenForge MCP に接続済み
- 最適化対象のシーンが開いている
- Unity Profiler の基本概念を理解していること
最適化の進め方
1. 計測 (プロファイリング)
↓
2. ボトルネック特定
↓
3. 対策の実施
↓
4. 再計測 (効果確認)
↓
5. 目標未達なら 2 に戻る
推測で最適化しない。必ず計測から始める。
ステップ 1: プロファイリング
あなた:
シーンのパフォーマンスをプロファイリングして。FPS、ドローコール数、トライアングル数、メモリ使用量を出して。
AI の応答例:
プロファイラーを起動してデータを収集しました (5秒間)。
パフォーマンスサマリー:
FPS: 28 (平均) / 22 (最低)
フレーム時間: 35.7ms (平均)
CPU: 28.1ms
GPU: 31.2ms ← GPU バウンド
レンダリング:
ドローコール: 847
バッチ: 312
セットパスコール: 89
トライアングル数: 2,840,000
頂点数: 1,920,000
メモリ:
合計使用量: 1.82 GB
テクスチャ: 890 MB
メッシュ: 245 MB
マテリアル: 12 MB
オーディオ: 34 MB
ボトルネック判定: GPU バウンド
主要因: ドローコール数が多い (847)
副要因: テクスチャメモリが大きい (890 MB)
ステップ 2: ドローコール分析
あなた:
ドローコールの内訳を分析して。どのオブジェクトが多くのドローコールを使っているか。
AI の応答例:
ドローコール分析結果:
上位 10 オブジェクト:
1. Forest_Trees (312 calls) -- 個別マテリアルのツリーが 312 本
2. Building_Windows (128 calls) -- 窓ガラス 1 枚ごとに別マテリアル
3. Props_Furniture (87 calls) -- 家具アイテム群
4. Terrain (64 calls) -- テレインレイヤー
5. Characters (48 calls) -- NPC キャラクター群
6. Ground_Debris (45 calls) -- 小石や落ち葉
7. Lighting_Probes (38 calls)
8. UI_Elements (32 calls)
9. Particle_Systems (28 calls)
10. Other (65 calls)
改善提案:
- Forest_Trees: GPU インスタンシングまたは SRP Batcher を有効にする
- Building_Windows: マテリアルを統合する (同一シェーダーなら SRP Batcher が効く)
- Ground_Debris: メッシュ結合してドローコールを削減する
ステップ 3: ドローコール削減
3a: マテリアル統合
あなた:
Forest_Trees のマテリアルを統合して。テクスチャアトラスを作って、1つのマテリアルにまとめて。
AI の応答例:
テクスチャアトラスを作成しました。
変更前:
マテリアル数: 8 (樹種ごとに別マテリアル)
テクスチャ: 8 x 1024x1024 = 8 MB
変更後:
マテリアル数: 1 (アトラス化)
テクスチャアトラス: 1 x 4096x4096 = 16 MB
UV リマップ: 312 メッシュの UV を更新
ドローコール削減: 312 → 1 (GPU インスタンシング併用時)
アトラス化するとテクスチャメモリが増える場合がある (ミップマップの効率が下がるため)。ドローコール削減とメモリ増加のバランスを考慮すること。
3b: メッシュ結合
あなた:
Ground_Debris のメッシュを結合して。移動しない静的オブジェクトだけ対象にして。
AI の応答例:
メッシュ結合を実行しました。
変更前:
オブジェクト数: 45
ドローコール: 45
変更後:
オブジェクト数: 3 (エリアごとに結合)
ドローコール: 3
注意: 結合したメッシュは個別に移動・削除できなくなります。
Static フラグを設定しました。
3c: SRP Batcher 確認
あなた:
SRP Batcher の状態を確認して。無効なマテリアルがあれば修正して。
AI の応答例:
SRP Batcher 互換性チェック:
互換: 67 マテリアル
非互換: 12 マテリアル
- M_CustomGlass: カスタムシェーダーが CBUFFER を正しく宣言していない
- M_Legacy_*: Built-in シェーダーを使用 (11 個)
修正:
- M_CustomGlass: CBUFFER_START/CBUFFER_END を追加 → 互換に
- M_Legacy_*: URP Lit シェーダーに変更 → 互換に
SRP Batcher 互換率: 67/79 → 79/79 (100%)
ステップ 4: LOD (Level of Detail) 設定
あなた:
Forest_Trees 全体に LOD を設定して。3 段階で。各 LOD のポリゴン数も出して。
AI の応答例:
LOD グループを設定しました (312 オブジェクト)。
LOD 設定 (ツリー 1 本あたり):
LOD0 (画面比 50% 以上): 1,200 ポリゴン (オリジナル)
LOD1 (画面比 20% 以上): 400 ポリゴン (66% 削減)
LOD2 (画面比 5% 以上): 80 ポリゴン (93% 削減)
Culled: 画面比 5% 未満
合計ポリゴン削減効果 (カメラ位置による概算):
最悪ケース (全て LOD0): 374,400
一般ケース (混在): 約 120,000
削減率: 約 68%
ステップ 5: オクルージョンカリング
見えないオブジェクトの描画をスキップする。
あなた:
オクルージョンカリングを設定してベイクして。設定は以下:
- Smallest Occluder: 5m
- Smallest Hole: 0.25m
- Backface Threshold: 100
AI の応答例:
オクルージョンカリングを設定しました。
Static Occluder に設定: 48 オブジェクト (壁、床、大型建物)
Static Occludee に設定: 892 オブジェクト (全 Static オブジェクト)
ベイク設定:
Smallest Occluder: 5m
Smallest Hole: 0.25m
Backface Threshold: 100
ベイク完了 (12.4 秒)
セル数: 256
データサイズ: 1.2 MB
カメラ位置によるカリング効果 (テスト位置で計測):
屋内: 描画オブジェクト 180/892 (80% カリング)
屋外: 描画オブジェクト 450/892 (50% カリング)
ステップ 6: メモリ最適化
あなた:
テクスチャのメモリ使用量を分析して。不必要に大きいテクスチャを特定して。
AI の応答例:
テクスチャメモリ分析:
上位 10 テクスチャ (メモリ消費順):
1. T_Terrain_Splat (4096x4096, RGBA32) - 64 MB
2. T_Skybox_HDR (4096x2048, RGBAHalf) - 32 MB
3. T_Building_Albedo (4096x4096, RGBA32) - 64 MB
4. T_Building_Normal (4096x4096, RGBA32) - 64 MB
5. T_Tree_Atlas (4096x4096, RGBA32) - 64 MB
...
推奨圧縮設定:
T_Terrain_Splat: RGBA32 → ASTC 6x6 = 64 MB → 11 MB
T_Building_Albedo: RGBA32 → BC7 = 64 MB → 16 MB
T_Building_Normal: RGBA32 → BC5 (Normal用) = 64 MB → 16 MB
T_Tree_Atlas: RGBA32 → BC7 = 64 MB → 16 MB
合計削減見込み: 890 MB → 320 MB (64% 削減)
あなた:
推奨設定を全部適用して。
AI の応答例:
テクスチャ圧縮設定を適用しました。
変更したテクスチャ: 42 枚
テクスチャメモリ:
変更前: 890 MB
変更後: 315 MB
削減: 575 MB (65%)
注意: 圧縮による品質劣化がないか、主要なテクスチャを目視確認してください。
ステップ 7: ビフォー・アフター比較
全ての最適化を適用した後、再計測して効果を確認する。
あなた:
もう一度プロファイリングして。最適化前との比較を出して。
AI の応答例:
最適化後のプロファイリング結果:
最適化前 最適化後 改善率
FPS (平均): 28 72 +157%
フレーム時間: 35.7ms 13.9ms -61%
CPU: 28.1ms 11.2ms -60%
GPU: 31.2ms 12.8ms -59%
ドローコール: 847 186 -78%
バッチ: 312 142 -54%
トライアングル: 2,840,000 680,000 -76%
メモリ:
テクスチャ: 890 MB 315 MB -65%
メッシュ: 245 MB 198 MB -19%
合計: 1.82 GB 1.12 GB -38%
ボトルネック判定: なし (バランスが取れている)
目標 60 FPS を達成。
VRChat 固有の制限と対応
VRChat にはアバターとワールドに厳格なパフォーマンスランクがある。
アバターのパフォーマンスランク
| ランク | ポリゴン | マテリアル | メッシュ | ボーン |
|---|---|---|---|---|
| Excellent | 7,500 | 1 | 1 | 75 |
| Good | 10,000 | 1 | 1 | 90 |
| Medium | 15,000 | 2 | 2 | 150 |
| Poor | 20,000 | 4 | 2 | 256 |
ワールドのガイドライン
| 項目 | 推奨値 |
|---|---|
| バッチ (Batches) | 200 以下 |
| トライアングル | 500,000 以下 |
| ライトマップ解像度 | 合計 100 MB 以下 |
| テクスチャメモリ | 合計 256 MB 以下 |
VRChat 最適化チェック
あなた:
VRChat のパフォーマンスランクをチェックして。アバターは Good 以上を目指して。
AI の応答例:
VRChat パフォーマンスランク分析:
現在のアバター "MyAvatar":
ポリゴン数: 18,200 → ランク: Poor (Good は 10,000 以下)
マテリアル数: 3 → ランク: Medium (Good は 1)
メッシュ数: 2 → ランク: Medium (Good は 1)
ボーン数: 120 → ランク: Medium (Good は 90)
総合ランク: Poor
Good 達成に必要な作業:
1. ポリゴン数を 10,000 以下に削減 (Decimate で 45% 削減)
2. マテリアルを 1 つに統合 (テクスチャアトラス化)
3. メッシュを 1 つに結合
4. ボーンを 90 以下に削減 (不要なボーンをマージ)
あなた:
全部やって。Good ランクを達成して。
AI の応答例:
VRChat Good ランク最適化を実行しました。
1. ポリゴン削減:
18,200 → 9,800 (Decimate ratio: 0.54)
シルエットの品質を確認 -- 許容範囲内
2. マテリアル統合:
3 マテリアル → 1 マテリアル
テクスチャアトラス: 2048x2048 (Albedo, Normal, Emission をパック)
UV リマップ完了
3. メッシュ結合:
Body + Hair → 1 メッシュ
シェイプキーは維持
4. ボーン最適化:
120 → 88 ボーン
指ボーンの末端ノード 32 本をマージ
最適化後:
ポリゴン: 9,800 (Good: 10,000 以下)
マテリアル: 1 (Good: 1)
メッシュ: 1 (Good: 1)
ボーン: 88 (Good: 90 以下)
総合ランク: Good
最適化チェックリスト
最適化を進める際のチェックリスト。上から順に効果が大きい傾向がある。
| 項目 | 確認コマンド | 目安 |
|---|---|---|
| ドローコール | analyze_draw_calls | 200 以下 |
| SRP Batcher | check_srp_batcher | 互換率 100% |
| GPU インスタンシング | check_gpu_instancing | 同一メッシュは有効化 |
| LOD | analyze_lod_coverage | 遠景オブジェクトに必須 |
| オクルージョンカリング | check_occlusion | 屋内シーンで必須 |
| テクスチャ圧縮 | analyze_texture_memory | プラットフォーム最適な圧縮 |
| メッシュ結合 | analyze_mesh_count | 静的小物は結合 |
| ライトマップ | check_lightmap_size | 不要に高解像度でないか |
| シャドウ距離 | get_shadow_settings | 必要最小限に設定 |
| リアルタイムライト数 | count_realtime_lights | 可能な限りベイクに置換 |