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

HLSL のプラグマディレクティブ

HLSL では、#pragma ディレクティブは プリプロセッサーディレクティブ の一種です。他のタイプのプリプロセッサーディレクティブではカバーされていない追加情報をシェーダーコンパイラーに提供します。

pragma ディレクティブの使用

#pragma ディレクティブは HLSL コードのどこにでも入れることができますが、以下のように先頭に入れるのが一般的です。

# 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 ディレクティブでインクルードするファイルではそれらをサポートしません。コンパイラーはこれらを無視します。

キャッシングシェーダープリプロセッサーが無効の場合

  • Unity は、条件 (#if) ディレクティブの中の #pragma ディレクティブをサポートしていません。コンパイラはこれらを無視します。
  • .shader ファイルの Unity 固有の #pragma ディレクティブのみ使用できます。Unity は、#include ディレクティブでインクルードするファイルではサポートしていません。コンパイラーはこれらを無視します。
  • #include ディレクティブでインクルードするファイルの標準の HLSL #pragma ディレクティブのみ使用できます。Unity は、.shader ファイルではサポートしていません。コンパイラーはこれらを無視します。

サポートされているプラグマディレクティブのリスト

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

さらに、Unity は以下の Unity 固有の #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 などのサフィックスを使用して、追加のオプションを設定することができます。

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

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

詳細および対応するサフィックスのリストについては、シェーダバリアントとキーワード を参照してください。
#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) を放出します。
HLSL の include と include_with_pragmas ディレクティブ
HLSL でシェーダーモデルと GPU 機能を特定する