ビルド時に発生するシェーダーバリアント爆発フリーズの回避策は、実機テストやレンダリングパイプライン拡張において頻発する重度なテクニカルバグです。Unityのプロジェクトビルド時に、シェーダーコンパイルステップでプログレスバーが何十分もフリーズし停止するバリアント爆発の解決策の解説。
不具合の具体的な症状
Unityでプロジェクトのビルド(Build)を実行した際、「Compiling Shader...」のプログレスバーが表示された瞬間にUnityエディタが完全にフリーズし、30分以上全く進まないか、最悪の場合メモリ不足でエディタが強制終了(クラッシュ)する。
現実世界での例え:万能十徳ナイフの『使わないアタッチメントの全組み合わせ実物』をあらかじめ何十万本も無駄に大量製造する工場パンク
「ハサミ・爪切り・栓抜き」がついた十徳ナイフを、客が注文する可能性のある「全パターン(ハサミだけ出ているナイフ、ハサミと栓抜きが出ているナイフなど)」ごとに、あらかじめ別の実物ナイフとして何万本も工場で製造して倉庫に陳列しようとした結果、工場(コンパイラ)がパンクしてフリーズしています。実際に注文があったパターン(使用されているマテリアル)だけをその場で作るシステム(Shader Feature)に変えることで、製造数を一瞬で数本に抑えます。
図:ビルド時に発生するシェーダーバリアント爆発フリーズの回避策の不具合発生メカニズムと解決アプローチの概要図
想定される原因と詳細な仕組み
シェーダー内に定義した複数のカスタムキーワード(Shader Keyword:#pragma multi_compile等)の組み合わせが掛け算式に爆発し、内部的に数百万個もの「シェーダーバリアント(実体プログラム)」が自動生成され、CPUの事前コンパイル処理が限界に達してパンクしているためです。
解決アプローチと最適化手順
Shader Graphのカスタムキーワード設定を開き、定義タイプを「Multi Compile(全組み合わせを強制生成)」から「Shader Feature(プロジェクト内で実際に使用されている組み合わせのみを自動検出して生成)」に切り替えます。また、ビルド時に自動で不要な組み合わせを間引く「IPreprocessShaders」スクリプト(Shader Stripping)を導入し、バリアントの総数を劇的に削減します。