プロジェクトをビルドするたびに、Unity エディターはビルドに必要なすべてのシェーダーをコンパイルします。必要なグラフィックス API ごとに、必要なシェーダーバリアントをすべてコンパイルします。
Unity エディターで作業している場合、先行してすべてコンパイルされることはありません。すべてのグラフィックス API に対応するすべてのバリアントをコンパイルするには、非常に時間がかかるからです。
その代わりに、Unity エディターは以下のようにしています。
Library/ShaderCache フォルダーを確認します。シェーダーコンパイルには、UnityShaderCompiler と呼ばれるプロセスが使用されます。複数の UnityShaderCompiler プロセスを開始 (通常は、マシンの CPU コアごとに 1 つ) できるため、プレイヤービルド時にシェーダーコンパイルを並行して実行することが可能です。エディターがシェーダーのコンパイルの実施中でなければ、コンパイラープロセスは何も行わず、コンピューターリソースを消費しません。
頻繁に変更されるシェーダーが多数ある場合は、シェーダーキャッシュフォルダーが非常に大きくなる可能性もあります。このフォルダーは、削除しても Unity がシェーダーバリアントを再コンパイルするだけで、問題ありません。
プレイヤーのビルド時には、すべての “まだコンパイルされていない” シェーダーバリアントがコンパイルされるため、たまたまエディターがそれらを使用しなかった場合でもゲームデータに含まれます。
プラットフォームが異なれば、シェーダープログラムのコンパイルに使用されるシェーダーコンパイラーも異なります。以下はその例です。
pragma ディレクティブを使用して、さまざまなシェーダーコンパイラーの設定を行うことができます。
シェーダーのコンパイルにはいくつかのステップがあります。最初のステップの 1 つは前処理です。このステップでは、プリプロセッサーと呼ばれるプログラムが、コンパイラーのシェーダーソースコードを準備します。
以前のバージョンの Unity では、エディターは、その時の最新プラットフォームのシェーダーコンパイラーが提供するプリプロセッサーを使用していましたが、現在では、キャッシングシェーダープリプロセッサーとも呼ばれる、独自のプリプロセッサーを使用しています。
キャッシングシェーダープリプロセッサーは、より高速なシェーダーインポートとコンパイルに合わせて最適化されています。このプリプロセッサーは、中間的な前処理データをキャッシュすることで機能します。そのためエディターは、インクルードファイルのみを、そのコンテンツが変更されたときに解析すればよく、同じシェーダーの複数のバリアントをより効率的にコンパイルできます。
キャッシングシェーダープリプロセッサーと以前の動作の違いについて、詳細は Unity フォーラムを参照してください: 新しいシェーダープリプロセッサー。
ゲームのビルド中、Unity は、ゲームで使用されていない内部シェーダーのバリアントの一部を検出し、ビルドデータから削除 (“ストリップ”) できます。詳しくは、シェーダーバリアントを参照してください。