プロジェクトをビルドするたびに、Unity エディターはビルドに必要なすべてのシェーダーをコンパイルします。必要なグラフィックス API ごとに、必要なシェーダーバリアントをすべてコンパイルします。
Unity エディターでは、すべてを先行してコンパイルすることはありません。すべてのグラフィックス API に対応するすべてのバリアントをコンパイルするには、非常に長い時間がかかるからです。
その代わりに、Unity エディターは以下のようにしています。
Library/ShaderCache
フォルダーを確認します。シェーダーのコンパイルは、UnityShaderCompiler
というプロセスを使って行われます。複数の UnityShaderCompiler
プロセスを開始することができます (通常、マシンの CPU コアごとに 1 つ)。そのため、プレイヤーのビルド時にシェーダーのコンパイルを並行して行うことができます。エディターがシェーダーをコンパイルしていない間はコンパイラー処理は行われず、コンピューターのリソースを消費しません。
頻繁に変更されるシェーダーが沢山ある場合は、シェーダーキャッシュフォルダーが非常に大きくなる可能性もあります。このフォルダーの削除は安全で、Unity がシェーダーバリアントを再コンパイルするだけです。
プレイヤーのビルド時には、すべての “まだコンパイルされていない” シェーダーバリアントがコンパイルされるため、たまたまエディターがそれらを使用しなかった場合でもゲームデータに含まれます。
異なるプラットフォームは、シェーダープログラムのコンパイルに異なるシェーダーコンパイラーを使用します。以下はその例です。
pragma ディレクティブ を使用して、さまざまなシェーダーコンパイラーの設定を行うことができます。
シェーダのコンパイルにはいくつかのステップがあります。最初のステップの 1 つは前処理です。このステップでは、プリプロセッサー と呼ばれるプログラムが、コンパイラーのシェーダーソースコードを準備します。
以前のバージョンの Unity では、エディターは現在のプラットフォームのシェーダーコンパイラーが提供するプリプロセッサーを使用していました。現在では、Unity の Caching Shader Preprocessor (キャッシングシェーダープリプロセッサー) を使用するか、以前の動作に戻すかを選択することができます。問題がない限り、キャッシングシェーダープリプロセッサーを使用してください。
キャッシングシェーダープリプロセッサーは、シェーダーのインポートとコンパイルを高速化するために最適化されており、最大で 25% の高速化できます。これは、中間的な前処理データをキャッシュすることで機能します。そのため、エディターがそのファイルを解析する必要があるのは、インクルードファイルのコンテンツが変更されたときだけです。これにより、同じシェーダーの複数のバリアントをより効率的にコンパイルすることができます。キャッシングシェーダープリプロセッサーを有効にする際に最も著しい効果を発揮するのは、プロジェクト内のシェーダーが共通のインクルードファイルを大量に使用している場合です。
キャッシングシェーダープリプロセッサーは、パフォーマンスの向上のみでなく、以下のような利点も加えます。
#pragma
ディレクティブの条件内での限定的なサポート。#pragma warning
ディレクティブのサポート。#include_with_pragmas
ディレクティブのサポート。これにより、インクルードファイルに #pragma
ディレクティブを加えることができます。キャッシングシェーダープリプロセッサーと従来の動作の違いについての詳細は、Unity フォーラムの New shader preprocessor を参照してください。
キャッシングシェーダープリプロセッサーは、Editor settings ウィンドウの Shader Compilation セクションの Caching Shader Preprocessor チェックボックス、または EditorSettings.cachingShaderPreprocessor API で有効または無効にすることができます。
ゲームのビルド中、Unity は内部シェーダーバリアントの一部がゲームで使用されていないことを検出し、ビルドデータから削除 (“ストリップ”) します。詳しくは、シェーダーバリアント を参照してください。