Version: 2023.1
言語: 日本語
分岐、バリアント、キーワード
シェーダーにおける分岐

シェーダーにおける条件

時には、状況に応じてシェーダーの動作を変えたい場合もあります。例えば、異なるマテリアルに対して異なる設定を行いたい場合や、異なるハードウェア用に機能を定義したい場合、あるいはランタイムでシェーダーの動作を動的に変更したい場合などです。また、テクスチャの読み取りや頂点の入力、補間器、ループなどの、計算負荷が高いコードの不必要な実行を回避したいケースも考えられます。

条件を使用することで、GPU が特定の条件下でのみ実行する動作を定義することができ ます。

条件のタイプ

シェーダーでの条件の使用には、以下アプローチがあります。

  • 静的分岐: シェーダーコンパイラーがコンパイル時に条件付きコードを評価します。
  • 動的分岐: GPU がランタイムに条件付きコードを評価します。
  • シェーダーバリアント: Unity は、静的分岐を使用して、シェーダーソースコードを複数のシェーダープログラムにコンパイルします。その上で Unity は、ランタイムで条件に一致するシェーダープログラムを使用します。

どちらのタイプの条件をどのような場合に使用するか

シェーダーにおける条件には、“全てのケースに適したアプローチ” はありません。個々のプロジェクトで、使用しているシェーダーを踏まえて、それぞれのアプローチのメリットとデメリットを検討する必要があります。

どちらの条件を使用すべきかは、どのタイミングでシェーダーを別のコードブランチに切り替える必要があるかによって変わります。

編集中のコードブランチの切り替え

ランタイムでシェーダーを別のコードブランチに切り替える必要がない場合は、Unity が編集中にのみ評価する条件を使用できます。

例えば、マテリアルの Inspector ウィンドウでプロパティを設定して、シェーダーに以下のような動作をさせることができます。

  • マテリアルの一部のインスタンスに鏡面反射を追加し、他のインスタンスには追加しない。
  • 特定のオブジェクト (水中シーンに登場するオブジェクトなど) に、異なる外観を追加する。

このアプローチを用いることで、シェーダーコードの記述と管理が行いやすくなり、ビルド時間やファイルサイズ、パフォーマンスに悪影響を及ぼしにくくなります。

これを行うには、以下のいずれかを使用してください。

shader_feature キーワード定義を使用すると、Unity はビルドでマテリアルが使用するシェーダーバリアントを保持し、他のシェーダーバリアントを削除 (“ストリップ”) します。これにより、ビルド時間を短く、ファイルサイズを小さく抑えることができます。

C# スクリプトを使用してランタイムで shader_feature キーワードを有効にしたり無効にしたりすることは避けてください。なぜなら、欠落したシェーダーバリアントをマテリアルが使用している場合、Unity は代わりに別の使用可能なバリアントを選択するからです。ランタイムでキーワードの有効化や無効化を行う必要がある場合は、以下のいずれかの方法を使用して、必要な全てのバリアントがビルドに含まれていることを確認してください。

ランタイムでのコードブランチの切り替え

C# スクリプティングを使用してランタイムでシェーダーを別のコードブランチに切り替える必要がある場合は、Unity が編集中およびランタイムの両方で評価する条件式を使用できます。

例えば、C# スクリプトを使ってシェーダーに以下のような処理をさせることができます。

  • マテリアルを動的に変更して、特定の時間に雪が積もるようにする。
  • ユーザーが品質設定を変更した時にマテリアルを変更する。例えば、フォグを表示するかどうかをユーザーが動的に制御できるようにする。

これを行うには、以下のいずれかを使用してください。

multi_compile キーワード定義を使用すると、Unity は、ビルドのマテリアルで使用されていない組み合わせも含めて、シェーダーコードブランチの考えられる全ての組み合わせに対して、シェーダーバリアントをビルドします。これは、ランタイムでキーワードの有効化/無効化が行えることを意味しますが、ビルド時間、ファイルサイズ、ロード時間、メモリ使用量を大幅に増加させる可能性もあります。シェーダーバリアント を参照してください。

動的分岐はシェーダーバリアントを作成しませんが、特に、以下のいずれかが当てはまる場合には、GPU でのシェーダーの動作が遅くなる可能性があります。

  • シェーダーが性能の低い GPU で実行されている場合。
  • 条件コードに “非対称な分岐” があり、一方のブランチが他方より長い場合や、より複雑なコードになっている場合。

シェーダーバリアントの数をチェック することで、GPU パフォーマンスにあまり影響を与えずに動的分岐を使用できるかどうか確認することができます。動的分岐のメリットとデメリットについては、シェーダーにおける分岐 を参照してください。

分岐、バリアント、キーワード
シェーダーにおける分岐