フレームデバッガー
Texture Streaming

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

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

たとえば、スタンダードシェーダー 。完全にコンパイルされると、結局、わずかに異なる何千もの GPU プログラムになります。これによって 2 つの問題の可能性が発生します。

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

シェーダービルド時間の削減

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

  • #pragma shader_feature を使うシェーダーのための個々のシェーダーの機能。ある特定のバリアントが使用中のどのマテリアルにもまったく使用されない場合、そのバリアントをビルドに加えません。内部シェーダーバリアント に関するドキュメントを参照してください。ビルトインシェーダーのうち、スタンダードシェーダー は、内部シェーダーバリアントを使用しています。
  • Shader variants to handle Fog and Lightmapping modes not used by any of the scenes are not included into the game data. See the Graphics window if you want to override this behavior.

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

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

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

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

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

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

シェーダーバリアントコレクションは 1 つのアセットで、基本的に シェーダー のリストです。各シェーダーに関して、パスの種類と起動のためのシェーダーキーワードの組み合わせを表示します。

シェーダーバリアントコレクションのインスペクター
シェーダーバリアントコレクションのインスペクター

To help with creating these assets based on actually used shaders and their variants, the editor can track which shaders and their variants are actually used. In the Graphics window, there is a button to create a new ShaderVariantCollection out of currently tracked shaders, or to clear the currently tracked shader list.

Creating ShaderVariantCollection from Shaders used by editor
Creating ShaderVariantCollection from Shaders used by editor

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

Preloaded Shaders リストは、頻繁に使用されるシェーダーを対象としています。ここにリストされているシェーダーのバリアントは、アプリケーションの生存期間にわたってメモリに読み込まれます。これによって、多数のバリアントを含む ShaderVariantCollections アセットに著しい量のメモリが使用される場合があります。これを避けるには、ShaderVariantCollection アセットをより細かく作成し、スクリプトから読み込む必要があります。1つの方法としては、各シーンに使用されているシェーダーバリアントを記録し、別々の ShaderVariantCollections アセットに保存し、それらをシーン起動時に読み込むことです。

ShaderVariantCollection スクリプトクラスを参照してください。

参照

フレームデバッガー
Texture Streaming