Version: 2021.3
HLSLで特定のグラフィックス API とプラットフォームを対象にする方法
シェーダーセマンティクス

HLSL のシェーダーキーワードの宣言と使用

このページでは、HLSL コードでシェーダーキーワードを使用する際の情報を提供します。シェーダーキーワードの一般的な導入は、シェーダーキーワード を参照してください。Shader Graph でのシェーダーキーワードの宣言と使用については、Keywords を参照してください。

HLSL コードでは、#pragma ディレクティブを使って、シェーダーキーワードと #if ディレクティブを宣言し、コードがシェーダーキーワードの状態に依存することを示します。シェーダーキーワードは、通常のグラフィックシェーダー (サーフェスシェーダー を含む) と コンピュートシェーダー で使用できます。

シェーダーキーワードの宣言

シェーダーキーワードを宣言するには、HLSL コードの中で次の #pragma ディレクティブのいずれかを使用します。

ディレクティブ 説明
#pragma multi_compile 一群のキーワードを宣言します。

デフォルトでは、これらのキーワードはグローバルスコープを持ち、すべてのシェーダーステージに影響を与えます。

ビルドプロセスは、このセットのすべてのキーワードを含みます。
#pragma shader_feature 一群のキーワードを宣言します。また、これらのキーワードのがひとつも有効になっていないバリアントをコンパイルするようにコンパイラーに指示します。

デフォルトでは、これらのキーワードはグローバルスコープを持ち、すべてのシェーダーステージに影響を与えます。

ビルドプロセスは、ビルド時に使用されているこの一群のキーワードを含みます。

#pragma multi_compile#pragma shader_feature の違いと、いつどちらを使うべきかのガイダンスについては、シェーダーキーワード を参照してください。

Note: If you add a shader to the list of Always Included Shaders in the Graphics settings window, Unity includes all keywords from all sets in the build, even if they were declared with #pragma shader_feature.

また、これらのディレクティブにサフィックスを追加して、その動作を変更することもできます。

  • Add _local to indicate that a set of keywords has local scope and cannot be overridden by global keywords; otherwise, the keywords have global scope and can be overridden by global keywords. For more information, see Shader keywords: global and local scope.

    You can add this suffix to #pragma multi_compile, or #pragma shader_feature directives; for example, #pragma multi_compile_local, and #pragma shader_feature_local are valid.
  • Add _vertex, _fragment, _hull, _domain, _geometry, or _raytracing to indicate that a set of keywords only affects a given shader stage, which can reduce the number of unneeded shader variants. For more information, see Shader keywords: Stage-specific keywords.

    You can add these suffixes to #pragma multi_compile or #pragma shader_feature directives, either standalone or after a _local modifier; for example, #pragma multi_compile_vertex and #pragma shader_feature_local_fragment are valid.

さらに、#pragma multi_compile には、あらかじめ定義されたキーワード群を追加する “ショートカット” があります。これらの詳細については、multi_compile shortcuts を参照してください。

キーワード群の宣言

一群のキーワードをまとめて宣言します。群には、相互に排他的なキーワードが含まれます。

一群のキーワードを宣言するには、#pragma multi_compile または #pragma_shader_feature ディレクティブの後に、スペースで区切られたキーワードのリストを使用します。

この例では、4 つのキーワードをまとめて宣言する方法を示します。

# pragma multi_compile QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_ULTRA

内部的には、#define ディレクティブを使うことで動作します。Unity がシェーダーをコンパイルするとき、QUALITY_LOW 定義されているもの、QUALITY_MEDIUM が定義されているもの、QUALITY_HIGH が定義されているもの、QUALITY_ULTRA が定義されているもの、の 4 つのバリアントが生成されます。ランタイムには、どのキーワードが有効になっているかに基づいて、適切なバリアントを使用します。

#pragma shader_feature を使って一群のキーワードを宣言すると、Unity はそれらのキーワードが一切定義されていないバリアントもコンパイルします。これにより、追加のキーワードを使わずに動作を定義することができます。キーワードの数を減らすことにはいくつかの利点があります。Unity がコンパイルするバリアントの総数を減らすことができ、これによってビルド時間とランタイムパフォーマンスの両方が改善されます。シェーダーが使用するキーワードの総数を減らし、これによって シェーダーキーワードの制限 に達するのを防ぐことができます。また、有効/無効にするキーワードの数が減るため、C# スクリプトからキーワードの状態を管理するのが簡単になります

この例では、1 つのキーワードのみを含む群を宣言する方法を示します。

# pragma shader_feature EXAMPLE_ON

また、#pragma multi_compile を使用する際に、このように Unity に指示することもできます。そのためには、空白のキーワードと、1 つ以上のアンダースコア (_) を持つ名前をを群に追加します。

# pragma multi_compile __ EXAMPLE_ON

複数のキーワード群の宣言

異なる機能を表現するために、複数のキーワード群を宣言することができます。これを行うには、複数の #pragma multi_compile または #pragma_shader_feature ディレクティブを使用します。

この例では、4 つのキーワードから成る 1 群と、3 つのキーワードから成る 1 群を宣言する方法を示しています。

# pragma multi_compile QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_ULTRA
# pragma multi_compile COLOR_RED COLOR_GREEN COLOR_BLUE

制限

キーワード群を宣言する方法にはいくつかの制限があります。

  • 同じ群に同じキーワードを複数回入れることはできませんが、同じキーワードを異なる群で宣言することは可能です。
  • シェーダープログラムでは、同じキーワードから成る群を複数回宣言することはできません。
  • シェーダーが使用できるキーワードの数には制限があります。シェーダーのソースファイルで宣言されたすべてのキーワードとその依存関係は、この制限に数えられます。詳細については、シェーダーキーワードの制限 を参照してください。

シェーダーキーワードの使用

特定のシェーダーキーワードが有効なときにのみ使用されるコードをコンパイルするには、次のように #if ディレクティブを使用します。

// キーワード群を宣言
# pragma multi_compile QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_ULTRA


# if QUALITY_ULTRA
// ここのコードは、キーワード QUALITY_ULTRA が有効であるときに使用されるバリアント用にコンパイルされます
# endif

This works because Unity’s shader compiler represents disabled shader variant keywords as constant variables with a value of 0.

Note: You can also use #if, #elif, #else, and #endif preprocessor directives, and #ifdef and #ifndef preprocessor directives with keywords that use shader variants; however, if you do this, it will be more difficult to convert your code to work with dynamic branching in the future.

さらに、#pragma require および #pragma target ディレクティブは、パラメーターとしてキーワードを取ることができます。これにより、与えられたキーワードが有効になっているバリアントにのみ適用されます。詳細については、HLSLの適用シェーダーモデルと GPU 機能 を参照してください。

multi_compile ショートカット

Unity では、シェーダーのキーワードを宣言するために、いくつかの “ショートカット” 表記が用意されています。

以下のショートカットは、ビルトインレンダーパイプラインのライト、影、ライトマッピングに関するものです。

  • multi_compile_fwdbase は、以下のキーワード群を追加します。DIRECTIONAL LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON SHADOWS_SCREEN SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING LIGHTPROBE_SH。これらのバリアントは、PassType.ForwardBase で必要となります。
  • multi_compile_fwdbasealpha は、以下のキーワード群を追加します。DIRECTIONAL LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING VERTEXLIGHT_ON LIGHTPROBE_SH。これらのバリアントは、PassType.ForwardBase で必要となります。
  • multi_compile_fwdadd は、以下のキーワード群を追加します。POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE。これらのバリアントは、PassType.ForwardAdd で必要となります。
  • multi_compile_fwdadd_fullshadows は、以下のキーワード群を追加します。POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE SHADOWS_DEPTH SHADOWS_SCREEN SHADOWS_CUBE SHADOWS_SOFT SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING。これは multi_compile_fwdadd と同じですが、ライトがリアルタイムの影を作れるようになります。
  • multi_compile_lightpass は、以下のキーワード群を追加します。POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE SHADOWS_DEPTH SHADOWS_SCREEN SHADOWS_CUBE SHADOWS_SOFT SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING。これは事実上、ライトプローブ以外に、リアルタイムのライトと影に関連するすべての機能の包括的なショートカットです。
  • multi_compile_shadowcaster は、以下のキーワード群を追加します。SHADOWS_DEPTH SHADOWS_CUBE。これらのバリアントは、PassType.ShadowCaster に必要です。
  • multi_compile_shadowcollector は、以下のキーワード群を追加します。SHADOWS_SPLIT_SPHERES SHADOWS_SINGLE_CASCADE。multi_compile_shadowcollector は、これらのキーワードをまったく含まないバリアントもコンパイルします。 これらのバリアントは、スクリーンスペースシャドウに必要です。
  • multi_compile_prepassfinal は、以下のキーワード群を追加します。LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON UNITY_HDR_ON SHADOWS_SHADOWMASK LIGHTPROBE_SH。multi_compile_prepassfinal は、これらのキーワードをまったく含まないバリアントもコンパイルします。 これらのバリアントは PassType.LightPrePassFinalPassType.Deferred に必要です。

以下のショートカットは、他の設定と関連しています。

  • multi_compile_particles は、ビルトインのパーティクルシステムに関連する以下のキーワードを追加します: SOFTPARTICLES_ON。multi_compile_particles は、このキーワードを含まないバリアントもコンパイルします。詳しくは、Built-in Particle System を参照してください。
  • multi_compile_fog は、フォグに関連する以下のキーワードを追加します: FOG_LINEAR, FOG_EXP, FOG_EXP2。multi_compile_fog は、このキーワードを含まないバリアントもコンパイルします。この動作は、Graphics 設定 ウィンドウ で制御できます。
  • multi_compile_instancing は、インスタンシングに関連するキーワードを追加します。シェーダーがプロシージャルなインスタンシングを使用する場合、以下の一連のキーワードを追加します: INSTANCING_ON PROCEDURAL_ON。そうでない場合は、INSTANCING_ON を追加します。また、multi_compile_instancing は、これらのキーワードを含まないバリアントもコンパイルします。この動作は Graphics 設定 ウィンドウ で制御できます。

これらのショートカットのほとんどは、複数のキーワードを含んでいます。プロジェクトに必要がないことがわかっている場合は、#pragma skip_variants を使って、一部のキーワードを削除することができます。例えば、以下のようになります。

# pragma multi_compile_fwdadd
# pragma skip_variants POINT POINT_COOKIE

これは、キーワード POINT または POINT_COOKIE を他のディレクティブから削除するようにコンパイラーに指示します。

HLSLで特定のグラフィックス API とプラットフォームを対象にする方法
シェーダーセマンティクス
Copyright © 2020 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961