シェーダーは GPU 上で実行する小さなプログラムであり、それらをロードするには時間がかかることがあります。個々の GPU プログラムは一般的にロードするのに時間がかかりませんが、シェーダーは、多くの場合、内部にバリアントがたくさんあります。
たとえば、スタンダードシェーダー 。完全にコンパイルされると、結局、わずかに異なる何千もの GPU プログラムになります。これによって 2 つの問題の可能性が発生します。
ゲームのビルド中に、Unity は内部シェーダーバリアントの一部がゲームで使用されていないことを検出し、ビルドデータから除外 (ストリップ) することができます。ビルド時のストリッピングは以下のように行われます。
#pragma shader_feature
を使用するシェーダーでは、Unity はバリアントが使用されているかどうかを自動的にチェックします。ビルド内のマテリアルのどれもがバリアントを使用していない場合、そのバリアントはビルドに含まれません。内部シェーダーバリアント ドキュメントを参照してください。スタンダードシェーダー はこれを使用します。上記の組み合せは、シェーダーデータサイズをしばしば大幅に減らします。例えば、完全にコンパイルしたスタンダードシェーダーは数百メガバイトを消費することもあります。しかし、典型的なプロジェクトでは、大抵、わずか数メガバイトを消費します (アプリケーションのパッケージングプロセスによってさらに圧縮されることもよくあります)。
Under all default settings, Unity loads the shaderlab Shader object into memory at runtime, but does not create the internal shader variants until they are actually needed.
This means that all shader variants that are included in the build can still potentially be used, but there’s no memory or load time cost paid until they are needed. For example, a shader might always include a variant to handle point lights with shadows, but if you never end up using a point light with shadows in your game, then there’s no point in loading this particular variant.
One downside of this default behavior, however, is a possible hiccup for when a shader variant is needed for the first time - since a new GPU program code has to be loaded into the graphics driver. This is often undesirable during gameplay, so Unity has ShaderVariantCollection assets to help solve that.
ShaderVariantCollection is an asset that is basically a list of Shaders, and for each of them, a list of Pass types and shader keyword combinations to load in advance, rather than wait until they are needed.
実際に使用されたシェーダーとそのバリアントに基づいてアセットの作成を支援するために、エディターは実際に使用されているシェーダーとそのバリアントを追跡することができます。Graphics ウィンドウに、現在追跡しているシェーダーから新しいシェーダーバリアントコレクションを作成するボタンと、現在追跡しているシェーダーリストを削除するボタンがあります。
ShaderVariantCollection アセットをいくつか取得したら、これらのバリアントを (Graphics Settings の Preloaded Shaders の下にある) アプリケーションのロード中に自動的にプリロードされるか、またはスクリプトから個々のシェイダーバリアントコレクションをプリロードするようにように設定することができます。
Preloaded Shaders リストは、頻繁に使用されるシェーダーを対象としています。ここにリストされているシェーダーのバリアントは、アプリケーションの生存期間にわたってメモリに読み込まれます。これによって、多数のバリアントを含む ShaderVariantCollections アセットに著しい量のメモリが使用される場合があります。これを避けるには、ShaderVariantCollection アセットをより細かく作成し、スクリプトから読み込む必要があります。1つの方法としては、各シーンに使用されているシェーダーバリアントを記録し、別々の ShaderVariantCollections アセットに保存し、それらをシーン起動時に読み込むことです。
ShaderVariantCollection スクリプトクラスを参照してください。