多くの場合、固定されたシェーダーコードの断片の大部分を保持するだけでなく、わずかに異なるシェーダー「バリアント」を作成できるようにしておくと便利です。一般に「メガシェーダー」や「ウーバーシェーダー」と呼ばれ、ケースごとに異なるプリプロセッサーディレクティブでシェーダーコードを複数回コンパイルすることで達成されます。
Unity では、これは シェーダースニペットに #pragma multi_compile
または #pragma shader_feature
を追加することによって達成することができます。これも サーフェースシェーダー で動作します。
実行時には、適切なシェーダーバリアントは、マテリアルのキーワード (Material.EnableKeyword と DisableKeyword) またはグローバルシェーダーキーワード (Shader.EnableKeyword と DisableKeyword ) からピックアップされます。
以下はディレクティブの例です。
# pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON
上のディレクティブは 2 つのシェーダーバリアント、FANCY_STUFF_OFF
定義のものと、FANCY_STUFF_ON
定義のものを生産します。実行時に、そのうちの 1 つは、マテリアルとグローバルシェーダーキーワードを基にアクティベートされます。これら 2 つのキーワードのどちらも使用可能になっていない場合、最初のもの (“off”) が使用されます。
multi_compile の行に複数の 2 つのキーワードがある場合もあります。例えば、これは 4 つのシェーダーバリアントを生成します。
# pragma multi_compile SIMPLE_SHADING BETTER_SHADING GOOD_SHADING BEST_SHADING
名前のいずれかがすべてのアンダースコアの場合、シェーダーバリアントはプリプロセッサーマクロの定義なしで生成されます。2 つのキーワードを使い果たすことを避けるために、これはシェーダー機能のために一般的に用いられます (下のキーワード制限の注意を参照してください)。例えば、下のディレクティブは 2 つのシェーダーバリアントを生成します。最初のは、何も定義されてないもので、2 番目は FOO_ON
定義されたものです。
# pragma multi_compile __ FOO_ON
#pragma shader_feature
は、#pragma multi_compile
と非常によく似ています。唯一の違いは、shader_feature のシェーダーの未使用のバリアントがゲームのビルドに含まれないことです。ですから、shader_feature はキーワードのためにもっとも理にかなっているマテリアル上に設定され、キーワードのための multi_compile はグローバルコードから設定されます。
さらに、1 つのキーワードから成る簡略表記があります。
# pragma shader_feature FANCY_STUFF
上記は #pragma shader_feature _ FANCY_STUFF
のためのショートカットです。すなわち、2 つのシェーダーバリアントに展開されます (最初のひとつは定義なし、もう 1 つは定義あり)。
複数の multi_compile の行が可能で、そして得られたシェーダーが行の可能な組み合わせすべてのためにコンパイルされます。
# pragma multi_compile A B C
# pragma multi_compile D E
これは、最初の行の 3 つのバリアントと 2 行目の 2 つ、または合計 6 のシェーダーバリアント( A+ D、B + D、C + D、A+ E、B+ E、C+ E )を生成します。
各 multi_compile 行を、制御を行う 1 つのシェーダー「関数」と考えると簡単です。シェーダーバリアントの総数は、このようにとても急速に増えることに注意してください。たとえば、 2 つのオプションがついた 10 の multi_compile 関数は、それぞれ合計で 1024 シェーダーバリアントを生成します。
シェーダーバリアントを使用する場合、Unity には 256個というキーワードの制限があり、約 60 個が内部で使用される (したがって使用可能な制限数が減る) ことに注意してください。 また、キーワードは特定の Unity プロジェクト全体でグローバルに有効になっています。そのため、複数のキーワードが複数の異なるシェーダで定義されている場合は、制限を超えないように注意が必要です。
複数のシェーダーバリアントをコンパイルするのに、いくつかの「ショートカット」表記があります。それらは Unity の異なる種類のライト、影、ライトマップに対処します。詳しくは Unity のレンダリングパイプライン を参照してください。
multi_compile_fwdbase
は、ForwardBase
(フォワードレンダリングベース)
パスタイプに必要なすべてのバリアントをコンパイルします。これらのバリアントは異なるライトマップタイプや、影をオン/オフに切り替える主要なディレクショナルライトに対応します。multi_compile_fwdadd
は、ForwardAdd
(付加的なフォワードレンダリング) のパスタイプのためのバリアントをコンパイルします。これは、ディレクショナルライト、スポットライト、ポイントライトタイプを処理するためのバリアントと、クッキーテクスチャを持つバリアントをコンパイルします。multi_compile_fwdadd_fullshadows
- 上記と同じですが、ライトにリアルタイムシャドウを加える機能も含まれています。multi_compile_fog
は、異なるフォグの種類(off/linear/exp/exp2)を処理するいくつかのバリアントを展開します。組み込みのショートカットのほとんどが、かなり多くのシェーダーバリアントを生成します。それらが不要なことを分かっている場合、#pragma skip_variants
を使用して、いくつかのコンパイルをスキップすることが可能です (以下はその例)。
# pragma multi_compile_fwdadd
// すべてのバリアントを作成します
// "POINT" と "POINT_COOKIE" はスキップされます
# pragma skip_variants POINT POINT_COOKIE
シェーダーバリアントを使用する一般的な理由の1つは、OpenGL ES などの 1 つのターゲットプラットフォーム内でハイエンドとローエンドのハードウェアがある場合、その両方で効率的に実行できるフォールバックまたは簡易化したシェーダを作成するためです。互換性のレベルが異なるハードウェアに対し、それぞれに最適化したバリアントを提供するために、シェーダーハードウェアバリアントを利用できます。
シェーダーハードウェアバリアントの生成を可能にするためには、#pragma hardware_tier_variants renderer
を加え、 renderer
を シェーダープログラム を利用可能なレンダリングプラットフォームの 1つにします。他のキーワードに関係なく、この #pragma
で、各シェーダーごとに 3つのシェーダーバリアントが生成されます。それぞれのバリアントは、以下の定義ざれたもののうち 1つを持ちます。
UNITY_HARDWARE_TIER1
UNITY_HARDWARE_TIER2
UNITY_HARDWARE_TIER3
これらを使用して、ローエンドまたはハイエンドのために、条件付きフォールバックや追加機能を作成できます。ティアの変更を行える Graphics Emulation メニューを使用して、どのティアのテストもエディターで行えます。
これらのバリアントの影響をできるだけ少なく保つように、1組のシェーダーのみがプレイヤーに読み込まれます。さらに、例えば、特別なバージョンを TIER1 のみに書き、残りはすべて同じである場合にように、同一のシェーダーはすべて、ディスク上で余分なスペースを取りません。
読み込み時には、Unity は使用中の GPU を検証して、ティアの値を自動検出します。GPU が自動検出されない場合は、デフォルトで最も高いティア値へ設定します。Shader.globalShaderHardwareTier
を設定してこのティアの値をオーバーライドできます。ただし、変更したいシェーダーが読み込みされないうちに行わなくてはなりません。一度、シェーダーが読み込まれると、それに付随するバリアントがあるため、値が有効になりません。主要シーンを読み込む前に、読み込みをまだ行っていないシーンで行うとよいでしょう。
これらのシェーダーハードウェアティアは、プレイヤーの Quality 設定に関連していないことに注意してください。シェーダーは、プレイヤーが作動している GPU の相対的な能力を基に検出されます。
さまざまな端末ティアのシェーダーコードを調整する以外にも、Unity 内部の定義を調節したい場合があるかもしれません (例えば、モバイルでカスケードシャドウを強制する場合など)。これについての詳細は、UnityEditor.Rendering.PlatformShaderSettings を参照してください。ここでは、ティアごとにオーバーライドするために現在サポートされている機能の一覧を提供しています。 プラットフォームごと、ティアごとに、プラットフォームシェーダー設定を調節するには、UnityEditor.Rendering.EditorGraphicsSettings.SetShaderSettingsForPlatform を使用してください。
異なるティアに設定した PlatformShaderSetting
が異なる場合は、たとえ #pragma hardware_tier_variants
がなくても、ティアのバリアントはそのシェーダー用に生成されます。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.