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

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

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

このページには以下の情報が含まれています。

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

In your HLSL code, use #pragma directives to declare shader keywords. You can declare shader keywords in regular graphics shaders (including Surface Shaders) and compute shaders.

pragma directives for declaring shader keywords

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

ディレクティブ 説明
#pragma dynamic_branch Declares a set of keywords for use with dynamic branching.
#pragma multi_compile Declares a set of keywords for use with shader variants.

By default, these keywords have global scope and affect all shader stages.

The build process includes all keywords from this set.
#pragma shader_feature Declares a set of keywords for use with shader variants, and also instructs the compiler to compile variants where none of these keywords are enabled.

By default, these keywords have global scope and affect all shader stages.

The build process includes keywords from this set that are in use at build time.

For more information on the difference between these options, and guidance on when to use which one, see Shader keywords.

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.

    You can add this suffix to #pragma dynamic_branch, #pragma multi_compile, or #pragma shader_feature directives; for example, #pragma dynamic_branch_local, #pragma multi_compile_local, or #pragma shader_feature_local.
  • 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 or #pragma shader_feature_local_fragment. This does not work with #pragma dynamic_branch.

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

キーワード群の宣言

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

To declare a set of keywords, use the appropriate #pragma directive, followed by a space-delimited list of keywords.

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

# pragma multi_compile QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_ULTRA

What happens internally depends on whether you declare these keywords for use with shader variants or with dynamic branching.

When you use #pragma multi_compile or #pragma shader_feature to use the keywords with shader variants, Unity uses the keywords to create #define directives. In the above example, when Unity compiles the shader, it generates four variants: one where QUALITY_LOW is defined, one where QUALITY_MEDIUM is defined, one where QUALITY_HIGH is defined, and one where QUALITY_ULTRA is defined.

When you use #pragma dynamic_branch to use the keywords with dynamic branching, Unity uses the keywords to create uniform variables. If the above example used #pragma dynamic_branch, when Unity compiles the shader, it would create four uniform variables with boolean state: one called QUALITY_LOW, one called QUALITY_MEDIUM, and so on.

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

You can declare multiple sets of keywords to represent different features. To do this, use multiple #pragma directives.

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

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

Creating variants where none of the keywords are defined

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

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

# pragma shader_feature EXAMPLE_ON

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

# pragma multi_compile __ EXAMPLE_ON

制限

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

  • If you declare the same keyword for use with dynamic branching and shader variants, Unity prioritizes dynamic branching and the shader keyword will not work with variants.
  • 同じ群に同じキーワードを複数回入れることはできませんが、同じキーワードを異なる群で宣言することは可能です。
  • シェーダープログラムでは、同じキーワードから成る群を複数回宣言することはできません。
  • シェーダーが使用できるキーワードの数には制限があります。シェーダーのソースファイルで宣言されたすべてのキーワードとその依存関係は、この制限に数えられます。詳細については、シェーダーキーワードの制限 を参照してください。

Making behavior conditional with shader keywords

To mark parts of your shader code as conditional based on whether a given shader keyword is enabled or disabled, use an HLSL if statement.

This works for both variant keywords and dynamic branching keywords, and means that you can use the same syntax for both. This makes it easy to maintain your code, and also easy to change the way that you use keywords if required. For example, if you find that you need to reduce the number of variants in your application, you can convert a set of keywords to use dynamic branching simply by changing the declaration; you don’t need to also change the conditionals.

// Declare a set of keywords
#pragma multi_compile QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_ULTRA


if (QUALITY_ULTRA)
{
// If the keywords work with shader variants, the shader compiler recognises this code as a static branch and compiles it only for the needed variants
// If the keywords work with dynamic branching, the shader compiler compiles this code as a regular dynamic branch
}

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 provides several “shortcut” notations for declaring shader keywords that result in certain shader variants.

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

  • 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