Unity は、以下の方法で、ビルドされたアプリケーションから コンパイルされたシェーダー をロードします。
このアプローチを用いた場合、Unity とグラフィックスドライバーは、Unity がシェーダーバリアントを必要とするまでは、全てのシェーダーバリアントの処理および GPU への保存を行いません。ただし、グラフィックスドライバーが初めて GPU 固有のシェーダーバリアントを作成する時に、目に見えるストールが発生する可能性があります。
Unity は、それぞれの GPU 固有シェーダーバリアントをキャッシュして、そのシェーダーバリアントが再び必要になった時に再度ストールが発生するのを防ぎます。
シェーダーバリアントを参照するオブジェクトがなくなると、Unity は、そのシェーダーバリアントを CPU および GPU メモリから完全に削除します。
Unity は、プラットフォームのグラフィックス API、ハードウェア、および グラフィックスティア と互換性のあるコンパイル済みシェーダーのみをロードします。
(開発者または Unity が、ビルドしたアプリケーションから シェーダーバリアントをストリッピング したために) 必要なシェーダーバリアントが見つからない場合、Unity は、類似したシェーダーバリアントの選択を試みます。類似したシェーダーバリアントが見つからない場合、Unity は、マゼンタの エラーシェーダー を使用します。
シェーダーバリアントの厳密な照合を有効にする ことで、Unity が類似のシェーダーバリアントの選択を試みないようにすることができます。
シェーダーバリアントに複数の サブシェーダー が含まれている場合、Unity は、以下の全てと互換性のある 1 つのサブシェーダーの選択と使用を試みます。
Unity は、以下の要素の中から、以下の順番で、互換性のある最初のサブシェーダーを探します。
Unity は、互換性のあるサブシェーダーが見つからない場合には、マゼンタのエラーシェーダーを使用します。
ShaderLab タグを使用して、どのサブシェーダーにどのハードウェアと互換性を持たせるか設定できます。ShaderLab: タグを SubShader に割り当てる を参照してください。
パフォーマンスに高負荷がかかる時の目に見えるストールを防ぐために、Unity はグラフィックスドライバーに対して、シェーダーバリアントが初めて必要になる前にその表現を GPU 内に作成するようリクエストすることができます。これは事前準備と呼ばれます。
事前準備は、以下に挙げる方法で行えます。
また、Graphics Settings ウィンドウの Preloaded shaders セクション にシェーダーバリアントコレクションを追加することもできます。Unity は、ビルド済みアプリケーションの起動時に、ShaderVariantCollection.WarmUp
API を使用してシェーダーバリアントコレクションのロードと事前準備を行います。
DirectX 12、Metal、または Vulkan 用にビルドする場合、グラフィックスドライバーは、正確な頂点データレイアウトとレンダー状態が分かる場合にのみ、シェーダーバリアントの正確な GPU 表現を作成できます。事前準備された GPU 表現が不正確な場合、Unity が正確な表現を作成しなければならない時点でストールが発生する可能性が残ります。
正確なバリアントを作成してストールを回避するには、マテリアルをオフスクリーンでレンダリングすることによって、事前準備を行う必要があります。
また、以下を行うことも可能です。
Experimental.Rendering.ShaderWarmup
を使用して、シェーダーオブジェクトまたはシェーダーバリアントコレクションの事前準備が行えます。ただし、頂点データレイアウトを提供してレンダー状態を正確に設定できる場合に限ります。ShaderVariantCollection.Warmup
または Shader.WarmupAllShaders
が使用できます。頂点データレイアウトやレンダー状態を提供できないため、これによって作成される事前準備された GPU 表現は不正確になる可能性があります。Unity は、ビルドしたアプリケーション内に、圧縮されたシェーダーバリアントデータの複数の “チャンク” を格納します。各チャンクには複数のシェーダーバリアントが含まれます。Unity は、ランタイムでシーンをロードする際に、全てのシーンのチャンクを CPU メモリ内にロードし、それらを解凍します。
メモリ制限のあるプラットフォームでメモリ使用量を削減するために、チャンクのサイズと、Unity がメモリ内に保持する解凍されたチャンクの数を制限することができます。
これを行うには、Player 設定で、Other Settings > Shader Variant Loading を選択し、以下の設定を調整します。
0
、つまり制限はありません。詳細は PlayerSettings.SetDefaultShaderChunkCount を参照してください。
Override を使用して、各プラットフォームの値を個別にオーバーライドできます。詳細は PlayerSettings.SetShaderChunkCountForPlatform を参照してください。
また、Shader.maximumChunksOverride を使用して、ランタイムに Default chunk count をオーバーライドすることも可能です。
以下のプロファイラーマーカーを使用して、プロファイラー でシェーダーのローディングを確認できます。
Shader.ParseThreaded
と Shader.ParseMainThread
(Unity の、シリアライズされたデータからのシェーダーオブジェクトのローディング)Shader.CreateGPU
(Unity の、シェーダーバリアントの GPU 固有バージョンの作成)