メインコンテンツまでスキップ

パフォーマンス最適化ガイド

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 にはアバターとワールドに厳格なパフォーマンスランクがある。

アバターのパフォーマンスランク

ランクポリゴンマテリアルメッシュボーン
Excellent7,5001175
Good10,0001190
Medium15,00022150
Poor20,00042256

ワールドのガイドライン

項目推奨値
バッチ (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_calls200 以下
SRP Batchercheck_srp_batcher互換率 100%
GPU インスタンシングcheck_gpu_instancing同一メッシュは有効化
LODanalyze_lod_coverage遠景オブジェクトに必須
オクルージョンカリングcheck_occlusion屋内シーンで必須
テクスチャ圧縮analyze_texture_memoryプラットフォーム最適な圧縮
メッシュ結合analyze_mesh_count静的小物は結合
ライトマップcheck_lightmap_size不要に高解像度でないか
シャドウ距離get_shadow_settings必要最小限に設定
リアルタイムライト数count_realtime_lights可能な限りベイクに置換