フレームデバッガー
レイヤー

シェーダーのロード時間を最適化

シェーダーは GPU 上で実行する小さなプログラムであり、それらをロードするには時間がかかることがあります。個々の GPU プログラムは一般的にロードするのに時間がかかりませんが、シェーダーは、多くの場合、内部にバリアントがたくさんあります。

たとえば、スタンダードシェーダー 。完全にコンパイルした場合、結局、わずかに異なる何千もの GPU プログラムになってしまます。これは二つの潜在的な問題を生じさせます:

  • これらの多数のシェーダーバリアントは、ゲームのビルド時間とゲームのデータサイズを増加させます。
  • ゲームの最中、多数のシェーダーバリアントをロードすると、遅くなり、メモリを占めてしまいます。

シェーダー ビルド タイム ストリッピング

ゲームをビルドしている間、Unity は、内部シェーダーバリアントのいくつかがゲームで使用されていないことを検出し、ビルドデータからそれらをスキップすることができます。ビルドタイムストリッピングは、以下のために行われます:

  • #pragma shader_feature を使うシェーダーのための個々のシェーダーの機能。使用されるマテリアルのいずれもが特定のバリアントを使用しない場合、それはビルドに含まれません。* 複数のシェーダープログラムのバリアントを作る のドキュメントを参照してください。ビルトインシェーダーのうち、スタンダードシェーダー は、これを使用しています。
  • シーンのいずれでも使用されていない Fog とライトマッピングモードを処理するシェーダーバリアントは、ゲームデータに含まれていません。この動作をオーバーライドしたい場合、グラフィックス設定 を参照してください。

上記の組み合せは、シェーダーデータサイズをしばしば大幅に減らします。例えば、完全にコンパイルした Standard シェーダーは数百メガバイトを取るでしょう。しかし、典型的なプロジェクトでは、多くの場合、わずか数メガバイトを取ることになります(しばしばアプリケーションのパッケージングプロセスによってさらに圧縮されます)。

デフォルトの Unity シェーダーロードの動作

すべてのデフォルト設定で、Unity は、ShaderLab シェーダー オブジェクトをメモリへロードしますが、実際に必要になるまで、内部のシェーダーバリアント を作成しません。

これは、ゲームのビルドに含まれているシェーダーバリアントはまだ潜在的に使用できることを意味します。しかし、それらが必要になるまでメモリやロード時間のコストはかかりません。例えば、シェーダーは常にシャドウを持つポイントライトを処理するためのバリアントが含まれていますが、ゲーム内のシャドウにポイントライトを使うことにならない場合、この特定のバリアントをロードしても意味がありません。

しかし、このデフォルトの動作の一つの欠点は、いくつかのシェーダーバリアントが初めて必要になったときに出るかもしれない hiccup です。- 新しい GPU プログラムコードは、グラフィックスドライバにロードされなければならないからです。これはゲームプレーの間、多発してしまうと好ましくないので、Unity はそれを解決するために ShaderVariantCollection アセットを持っています。

シェーダー バリアント コレクション

ShaderVariantCollection は、基本的に シェーダーのリストであるアセットであり、それらの各々のために、ロードするパスの種類とシェーダーキーワードの組み合わせのリストです。

Shader variant collection inspector
Shader variant collection inspector

実際に使用したシェーダーとそのバリアントに基づいてこれらのアセットの作成を支援するために、エディターは実際に使用されているシェーダーとそのバリアントを追跡することができます。Graphics Settings に、現在追跡されたシェーダーから新しい ShaderVariantCollection を作成する、または現在追跡しているシェーダーリストをクリアするボタンがあります。

エディターが使用するシェーダーから ShaderVariantCollection を作成する
エディターが使用するシェーダーから ShaderVariantCollection を作成する

Once you have some ShaderVariantCollection assets, you can set for these variants to be automatically preloaded while loading the application (under Preloaded Shaders list in Graphics Settings), or you can preload an individual shader variant collection from a script.

The Preloaded Shaders list is intended for frequently used shaders. Shader variants that are listed there the are loaded into memory for entire lifetime of the application. This may use significant amount of memory for ShaderVariantCollections assets that include large number of variants. To avoid that, ShaderVariantCollection assets should be created at smaller granularity and loaded from a script. One strategy is to record used shader variants for each scene, save them into separate ShaderVariantCollections assets and load them on scene startup.

See ShaderVariantCollection scripting class.

参照

フレームデバッガー
レイヤー