Version: 2023.1
言語: 日本語
HLSL の include と include_with_pragmas ディレクティブ
HLSL でシェーダーモデルと GPU 機能を特定する

Provide information to the shader compiler in HLSL

In HLSL, you can use the following types of preprocessor directive to provide information to the shader compiler:

  • #pragma
  • #define_for_platform_compiler

Pragma directives

#pragma directives provide additional information to the shader compiler that isn’t covered by other types of preprocessor directive.

You can put #pragma directives anywhere in your HLSL code, but it is a common convention to put them at the start, like this:

# pragma target 3.0
# pragma exclude_renderers vulkan
# pragma vertex vert
# pragma fragment frag

// 残りの HLSL コードをここに記述

制限

#pragma ディレクティブの使用については、いくつかの制限があります。

  • 式が以下のものだけに依存している場合は、#pragma ディレクティブを条件 (#if) ディレクティブの中で使用することができます。
    • 独自コードのカスタムの #define ディレクティブ
    • 以下のプラットフォームキーワード: SHADER_API_MOBILE, SHADER_API_DESKTOP, UNITY_NO_RGBM, UNITY_USE_NATIVE_HDR, UNITY_FRAMEBUFFER_FETCH_AVAILABLE, UNITY_NO_CUBEMAP_ARRAY
    • UNITY_VERSION マクロ
  • Unity 固有の #pragma ディレクティブは、 .shader ファイルと、 #include_with_pragmas ディレクティブでインクルードしたファイルでのみ使用できます。Unityは、#include ディレクティブでインクルードするファイルではサポートしていません。コンパイラーはこれらを無視します。
  • #include ディレクティブでインクルードするファイルでは、標準の HLSL #pragma ディレクティブのみを使用できます。Unity は .shader ファイルや #include_with_pragmas ディレクティブでインクルードするファイルではそれらをサポートしません。コンパイラーはこれらを無視します。

Standard pragma directives

Unity は、標準的な HLSL の一部である #pragma ディレクティブが通常のインクルードファイルに含まれている限り、すべてサポートします。これらのディレクティブの詳細については、HLSL のドキュメント [#pragma ディレクティブ](https://docs.microsoft.com/ja-jp/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-pre-pragma) を参照してください。

サーフェスシェーダー

サーフェスシェーダー を書く場合は、このディレクティブを使って サーフェス関数 として使用する関数をコンパイラーに指示し、その関数にデータを渡します。

ステートメント 機能
#pragma surface <surface function> <lighting model> <optional parameters> 関数を与えられた名前でサーフェスシェーダーとしてコンパイルすると、与えられたライティングモデルで動作します。詳細は、サーフェスシェーダー を参照してください。

シェーダーステージ

通常のグラフィックスシェーダーを書いている場合は、これらのディレクティブを使って、シェーダーの各ステージで使用する関数をコンパイラーに伝えます。#pragma vertex#pragma fragment ディレクティブは必須ですが、その他のステージは任意です。

ステートメント 機能
#pragma vertex <name> 指定された名前の関数を頂点シェーダーとしてコンパイルします。<name> を関数名に置き換えてください。このディレクティブは、通常のグラフィックスシェーダーでは必須です。
#pragma fragment <name> 指定された名前の関数をフラグメントシェーダーとしてコンパイルします。<name> を関数名に置き換えてください。このディレクティブは、通常のグラフィックスシェーダーでは必須です。
#pragma geometry <name> 指定された名前の関数をジオメトリシェーダーとしてコンパイルします。<name> を関数名に置き換えてください。このオプションは、自動的に #pragma require geometry をオンにします。詳細は、HLSL の適用シェーダーモデルと GPU 機能 を参照してください。

ノート: Metal はジオメトリシェーダーをサポートしていません。
#pragma hull <name> 指定された名前の関数を DirectX 11 ハルシェーダーとしてコンパイルします。<name> を関数名に置き換えてください。このオプションは、自動的に #pragma require tessellation を加えます。詳細は、HLSL の適用シェーダーモデルと GPU 機能 を参照してください。
#pragma domain <name> 指定された名前の関数を DirectX 11 ドメインシェーダーとしてコンパイルします。<name> を関数名に置き換えてください。このオプションは、自動的に #pragma require tessellation をオンにします。詳細は、HLSL の適用シェーダーモデルと GPU 機能 を参照してください。

シェーダーのバリアントとキーワード

これらのディレクティブを使用して、シェーダーコンパイラーに [シェーダーのバリアントとキーワード] の扱い方を伝えます。詳細は HLSL でのシェーダーキーワードの宣言と使用 を参照してください。

ディレクティブ 説明 
#pragma multi_compile <keywords> キーワード群を宣言します。コンパイラーには、ビルドのすべてのキーワードが含まれています。

_local などのサフィックスを使用して、追加のオプションを設定することができます。

詳細および対応するサフィックスのリストについては、HLSL のシェーダーキーワードの宣言と使用 を参照してください。
#pragma shader_feature <keywords> キーワード群を宣言します。コンパイラーは、ビルドから使用していないキーワードを除きます。

_local などのサフィックスを使用して、追加のオプションを設定することができます。

詳細および対応するサフィックスのリストについては、HLSL のシェーダーキーワードの宣言と使用 を参照してください。
#pragma hardware_tier_variants <values> ビルトインレンダーパイプラインのみ。指定のグラフィックス API 用にコンパイルする際に、グラフィックスティア のキーワードを加えます。詳細は、グラフィックスティア を参照してください。
#pragma skip_variants <list of keywords> 指定したキーワードを削除します。

GPU 要件とシェーダーモデルサポート

以下のディレクティブを使用して、シェーダーが特定の GPU 機能を必要とすることをコンパイラーに伝えます。

ステートメント 機能
#pragma target <value> このシェーダープログラムが互換する最小のシェーダーモデルです。<value> を有効な値に置き換えてください。有効な値のリストについては、シェーダーコンパイル: HLSL の適応シェーダーモデルと GPU 機能 を参照してください。
#pragma require <value> このシェーダープログラムが互換する最小の GPU 機能です。<value> を有効な値、または、スペースで区切られた複数の有効な値に置き換えてください。有効な値のリストについては、シェーダーコンパイル: HLSL の適応シェーダーモデルと GPU 機能 を参照してください。

グラフィックス API

以下のディレクティブを使用して、特定のグラフィックス API 用のコードを含む、または除外するように指示します。

ステートメント 機能
#pragma only_renderers <value> 指定したグラフィックス API に対してのみ、このシェーダープログラムをコンパイルします。<values> をスペースで区切られた有効な値のリストに置き換えます。詳細と有効な値のリストについては、HLSL の適応グラフィックス API とプラットフォーム を参照してください。
#pragma exclude_renderers <value> 指定したグラフィックス API に対して、このシェーダープログラムをコンパイルしません。<values> をスペースで区切られた有効な値のリストに置き換えます。詳細と有効な値のリストについては、HLSL の適応グラフィックス API とプラットフォーム を参照してください。

その他の pragma ディレクティブ

ステートメント 機能
#pragma instancing_options <options> 指定したオプションを使って、このシェーダーで GPU インスタンシングを有効にします。詳細については、GPU インスタンシング を参照してください。
#pragma once このディレクティブをファイルに入れて、コンパイラーがシェーダープログラムでファイルを 1 回だけ加えるようにします。

ノート: Unity は、シェーダーキャッシングプリプロセッサー が有効な場合にのみ、このディレクティブをサポートします。
#pragma enable_d3d11_debug_symbols サポートされているグラフィックス API 用のシェーダーデバッグシンボルを生成し、すべてのグラフィックス API の最適化を無効にします。

Unity は、Vulkan、DirectX 11 と 12、およびサポートされているコンソールプラットフォーム用のデバッグシンボルを生成します。

注意: これを使用するとファイルサイズが大きくなり、シェーダーのパフォーマンスが低下します。シェーダーのデバッグが終わり、アプリケーションの最終ビルドを行う準備ができたら、シェーダーのソースコードからこの行を削除し、シェーダーを再コンパイルしてください。
#pragma skip_optimizations <value> 指定したグラフィックス API に対して、強制的に最適化をオフにします。<values> をスペースで区切られた有効な値のリストに置き換えます。詳細と有効な値のリストについては、HLSL の適応グラフィックス API とプラットフォーム を参照してください。
#pragma hlslcc_bytecode_disassembly 逆アセンブルされた HLSLcc バイトコードを変換したシェーダーに埋め込みます。
#pragma disable_fastmath NaN 処理を含む正確な IEEE 754 規則を有効にします。現在、これは Metal プラットフォームにのみ影響します。
#pragma editor_sync_compilation 同期コンパイルを強制します。これは Unity エディターにのみ影響します。詳細については、非同期シェーダーコンパイル を参照してください。
#pragma enable_cbuffer 現在のプラットフォームが定数バッファをサポートしていない場合でも、HLSLSupport から CBUFFER_START(name)CBUFFER_END マクロを使用する場合に cbuffer(name) を放出します。

Use a define_for_platform_compiler directive

Use a #define_for_platform_compiler directive in your shader code to send a #define directive to the shader compiler.

For example, #define_for_platform_compiler EXAMPLE_SYMBOL sends a #define EXAMPLE_SYMBOL directive to the shader compiler that defines a symbol called EXAMPLE_SYMBOL. Refer to external shader compiler documentation, for example Microsoft’s documentation on the FXC compiler, for more information about symbols that shader compilers use.

The Unity preprocessor doesn’t use symbols you define with #define_for_platform_compiler, so you can’t use the symbols in your own shader code. For example, in the above example, if you add shader code inside an #if (EXAMPLE_SYMBOL) statement, the code won’t run.

HLSL の include と include_with_pragmas ディレクティブ
HLSL でシェーダーモデルと GPU 機能を特定する