このページでは、HLSL コードでシェーダーキーワードを使用する際の情報を提供します。シェーダーキーワードの一般的な導入は、シェーダーキーワード を参照してください。Shader Graph でのシェーダーキーワードの宣言と使用については、Keywords を参照してください。
HLSL コードでは、#pragma
ディレクティブを使って、シェーダーキーワードと #if
ディレクティブを宣言し、コードがシェーダーキーワードの状態に依存することを示します。シェーダーキーワードは、通常のグラフィックシェーダー (サーフェスシェーダー を含む) と コンピュートシェーダー で使用できます。
シェーダーキーワードを宣言するには、HLSL コードの中で次の #pragma
ディレクティブのいずれかを使用します。
ディレクティブ | 説明 |
---|---|
#pragma multi_compile |
一群のキーワードを宣言します。 デフォルトでは、これらのキーワードはグローバルスコープを持ち、すべてのシェーダーステージに影響を与えます。 ビルドプロセスは、このセットのすべてのキーワードを含みます。 |
#pragma shader_feature |
一群のキーワードを宣言します。また、これらのキーワードのがひとつも有効になっていないバリアントをコンパイルするようにコンパイラーに指示します。 デフォルトでは、これらのキーワードはグローバルスコープを持ち、すべてのシェーダーステージに影響を与えます。 ビルドプロセスは、ビルド時に使用されているこの一群のキーワードを含みます。 |
#pragma multi_compile
と #pragma shader_feature
の違いと、いつどちらを使うべきかのガイダンスについては、シェーダーキーワード を参照してください。
また、これらのディレクティブにサフィックスを追加して、その動作を変更することもできます。
_vertex
、_fragment
、_hull
、_domain
、_geometry
、_raytracing
を加えて、この一群のキーワードが特定のシェーダーステージにのみ影響することを示します。これにより、必要のないシェーダーバリアントの数を減らすことができます。詳細については、シェーダーキーワード: ステージ固有のキーワード を参照してください。#pragma multi_compile
または #pragma shader_feature
ディレクティブに加えることができます。例えば、#pragma multi_compile_vertex
と #pragma shader_feature fragment
はどちらも有効です。_ local
を追加して、このキーワードのセットがローカルスコープであることを示します。キーワードのローカルスコープとグローバルスコープの詳細については、シェーダーキーワード: ローカルまたはグローバルスコープ を参照してください。#pragma multi_compile
や #pragma shader_feature
ディレクティブや、すでにステージ固有のサフィックスを持っているすべてのバリエーションに加えることができます。例えば、#pragma multi_compile_local
、#pragma multi_compile_vertex_local
、#pragma shader_feature_local
、#pragma shader_feature_fragment_local
はすべて有効です。さらに、#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
Unity では、通常の #if
ディレクティブは、標準の HLSL 内にあるときと同じように動作します。通常の #if
ディレクティブの詳細については、HLSL のドキュメント if、elif、else、endif ディレクティブ を参照してください。
さらに、#pragma require
および #pragma target
ディレクティブは、パラメーターとしてキーワードを取ることができます。これにより、与えられたキーワードが有効になっているバリアントにのみ適用されます。詳細については、HLSLの適用シェーダーモデルと GPU 機能 を参照してください。
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.LightPrePassFinal と PassType.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
を他のディレクティブから削除するようにコンパイラーに指示します。