デフォルトでは、Unity のランタイムシェーダーのロードの動作は以下の通りです。
この動作の利点は、シェーダーバリアントのための GPU メモリ使用量やロー ド時間が前もって発生しないことです。欠点は、グラフィックスドライバーがシェーダープログラムを GPU 上に作成し、追加の作業を行わなければならないため、バリアントが初めて使用されるときに、目に見えるストールが発生することです。
パフォーマンスに高負荷がかかる時の目に見えるストールを防ぐために、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 をオーバーライドすることも可能です。
Unity がシェーダーバリアントデータを作成して GPU に送信するためのプロファイラーマーカーは Shader.Parse
です。シェーダープログラムを GPU にアップロードして、GPU が必要な作業を実行するのを待つためのプロファイラマーカーは、CreateGPUProgram
です。
Unity Profiler の使用方法については、アプリケーションのプロファイル を参照してください。