Version: 2023.1
言語: 日本語
Provide information to the shader compiler in HLSL
HLSLで特定のグラフィックス API とプラットフォームを対象にする方法

HLSL でシェーダーモデルと GPU 機能を特定する

#pragma ディレクティブ を使うと、シェーダーが特定の GPU 機能を必要とすることを示すことができます。ランタイムに、Unity はこの情報を使ってシェーダープログラムが使用中のハードウェアと互換性があるかどうかを判断します。

#pragma require ディレクティブで個々の GPU 機能を指定したり、シェーダーモデル を指定したりすることができます。シェーダーモデルとは、一群の GPU 機能のことです。これは内部的には、同じ機能を持つ #pragma require ディレクティブのようなものです。

シェーダーが必要とする GPU 機能を正しく記述することが重要です。シェーダーが要件リストに含まれていない機能を使用すると、 コンパイル時にエラーが発生したり、デバイスが実行時にシェーダーをサポートできなくなる可能性があります。

デフォルトの動作

デフォルトでは、Unity はシェーダーを #pragma require derivatives でコンパイルします。これは #pragma target 2.5 に相当します。

シェーダーステージの特別な要件

シェーダーが特定のシェーダーステージを定義する場合、Unity は自動的に要件リストに項目を追加します。

  • シェーダーが (#pragma geometryによって) ジオメトリステージを定義する場合、Unity は自動的に geometry を要件リストに追加します。
  • シェーダーが (#pragma hull または #pragma domainによって) テッセレーションのステージを定義する場合、Unity は自動的に tessellation を要件リストに追加します。

要件のリスト (または同等のターゲット値) にこれらの値がまだ含まれていない場合、Unity はシェーダーのコンパイル時に、これらの要件を追加したことを示す警告メッセージを表示します。この警告メッセージが表示されないようにするには、明示的に要件を追加するか、コードで適切なターゲット値を使用してください。

GPU 機能かシェーダーモデルの指定

必須の機能を指定するには、#pragma require ディレクティブの後に、スペースで区切られた値のリストを使用します。例えば、以下のようになります。

# pragma require integers mrt8

#pragma require ディレクティブの後に、コロンとスペースで区切られた シェーダーキーワードのリスト を表記して使用することもできます。これは、指定されたキーワードのいずれかが有効になっているときに使用されるバリアントにのみ要件が適用されることを意味します。

例:

# pragma require integers mrt8 : EXAMPLE_KEYWORD OTHER_EXAMPLE_KEYWORD

複数の #pragma require 行を使用することができます。この例では、シェーダーはすべての場合に 整数 を要求し、EXAMPLE_KEYWORD が有効な場合には mrt8 を要求します。

# pragma require integers
# pragma require integers mrt8 : EXAMPLE_KEYWORD

シェーダーモデルを指定するには、#pragma target ディレクティブを使用します。例えば、以下のようになります。

# pragma target 4.0

#pragma target ディレクティブの後に、スペースで区切られた シェーダーキーワードのリスト を表記して使用することもできます。これは、指定されたキーワードのいずれかが有効になっているときに使用されるバリアントにのみ要件が適用されることを意味します。

例:

# pragma target 4.0 EXAMPLE_KEYWORD OTHER_EXAMPLE_KEYWORD

ノート: #pragma require#pragma target のキーワードを指定する構文は若干異なります。#pragma require のキーワードを指定する場合は、コロンを使用します。#pragma target のキーワードを指定する場合は、コロンを使用しません。

‘#pragma target’ 値のリスト

以下は、Unity が使用するシェーダーモデルのリストと、それぞれが対応する #pragma require の値の組み合わせです。

ノート: Unity のシェーダーモデルは、DirectX のシェーダーモデルや OpenGL のバージョン要件と似ていますが、完全に対応しているわけではありません。説明をよく読んで、違いを確実に理解してください。

  説明  サポート 相当する #pragma require
2.0 DirectX シェーダーモデル 2.0 に相当。

制限された計算とテクスチャの指示。Interpolator 8 個、頂点テクスチャサンプリング無し、フラグメントシェーダーの派生無し、明示的 LOD テクスチャサンプリング無し。
Unity がサポートするすべてのプラットフォームで動作します。 該当なし
2.5 3.0 とほぼ同じですが、Interpolator が 8 個しかなく、明示的な LOD テクスチャサンプリングもありません。 DirectX 11 feature level 9+
OpenGL 3.2+
Vulkan
Metal
derivatives
3.0 DirectX シェーダーモデル 3.0 に相当。

DirectX 11 feature level 10 +
OpenGL 3.2+
OpenGL ES 3.0+
Vulkan
Metal
2.5 のすべてに加えて、
interpolators10 samplelod fragcoord
3.5 OpenGL ES 3.0 に相当。

DirectX 11 機能レベル 10 以降
OpenGL 3.2 以降
OpenGL ES 3 以降
Vulkan
Metal
3.0 のすべての機能に加えて、
interpolators15 mrt4 integers 2darray instancing
4.0 DirectX shader model 4.0 に相当します。ただし、8 つの MRT をサポートする必要はありません。 DirectX 11 機能レベル 10 以降
OpenGL ES 3.1+AEP
Vulkan
Metal (ジオメトリステージが定義されていない場合)
3.5 のすべてに加えて
geometry
4.5 OpenGL ES 3.1 に相当。 DirectX 11 機能レベル 11 以降
OpenGL 4.3 以降
OpenGL ES 3.1
Vulkan
Metal
3.5 のすべてに加えて、
compute randomwrite msaatex
4.6 OpenGL 4.1 に相当。

Mac でサポートされている OpenGL の最高レベルです。
DirectX 11 機能レベル 11 以降
OpenGL 4.1 以降
OpenGL ES 3.1+AEP
Vulkan
Metal (ジオメトリステージが定義されておらず、且つ、ハルまたはドメインステージが定義されていない場合)。
4.0 のすべてに加えて、
cubearray tesshw tessellation msaatex
5.0 DirectX shader model 5.0 に相当。ただし、32 の Interpolator かキューブマップ配列をサポートする必要はありません。 DirectX 11 機能レベル 11 以降
OpenGL 4.3 以降
OpenGL ES 3.1+AEP
Vulkan
Metal (ジオメトリステージが定義されておらず、且つ、ハルまたはドメインステージが定義されていない場合)。
4.0 のすべてに加えて、
compute randomwrite msaatex tesshw tessellation

コンソールプラットフォームでのシェーダーモデルのサポートについては、プラットフォーム別のドキュメントを参照してください。

ノート:

  • DirectX の定義では、シェーダーモデル 4.0 には mrt8 が、シェーダーモデル 5.0 には interpolators32cubearray が含まれています。Unity には、互換性を高めるために、これらの機能は含まれていません。これらの機能を必須にするには、明示的に #pragma require ディレクティブを使用してください。
  • geometry を必要とするターゲットを使用しているが、シェーダーがジオメトリステージを定義していない場合、Unity はコンパイル時に geometry を要件リストから削除します。
  • tessellation を必要とするターゲットを使用しているが、シェーダーがハルまたはドメインステージを定義していない場合、Unity はコンパイル時に tessellation を要件リストから削除します。

‘#pragma require’ 値のリスト

#pragma require ディレクティブに有効なすべての値配下の通りです。

  説明 
interpolators10 最低 10 個の頂点からフラグメントへの補間 (varying) が可能です。
interpolators15 最低 15 個の頂点からフラグメントへの補間 (“variing”) が利用可能です。

ノート: 内部的には、これは自動的に integers を要件リストに追加します。
interpolators32 最低 32 個の頂点からフラグメントへの補間 (“varying”) が可能です。
integers 整数は、ビット/シフト演算を含めてサポートされているデータ型です。

** 注意:** 内部的には、これは自動的に interpolators15 を要件リストに追加します。
mrt4 最低でも 4 つのレンダーターゲットに対応します。
mrt8 最低でも 8 つのレンダーターゲットに対応します。
derivatives ピクセルシェーダーの派生命令 (ddx/ddy) に対応します。
samplelod 明示的なテクスチャ LOD サンプリング (tex2Dlod / SampleLevel) がサポートされています。
fragcoord ピクセルシェーダーのピクセル位置 (画面の XY、クリップスペースの ZW 深度) の入力がサポートされます。
2darray 2D テクスチャ配列は、サポートされているデータタイプです。
cubearray キューブマップ配列は、サポートされているデータタイプです。
instancing SV_InstanceID の入力システムの値をサポートします。
geometry ジオメトリシェーダーのステージをサポートします。
compute コンピュートシェーダー、構造体バッファ、アトミックオペレーションをサポートします。
randomwrite または uav “Random write” (UAV) テクスチャをサポートします。
tesshw ハードウェアテッセレーションはサポートされていますが、必ずしもテッセレーション (ハル/ドメイン) シェーダーステージをサポートしているわけではありません。例えば、Metal はテッセレーションをサポートしていますが、ハルやドメインのステージはサポートしていません。
tessellation テッセレーション (ハル/ドメイン) シェーダーのステージをサポートします。
msaatex マルチサンプリングされたテクスチャにアクセスする機能 (HLSL の Texture2DMS) をサポートします。
sparsetex 常駐情報を持つスパーステクスチャ (DirectX 用語の “Tier2” サポート、CheckAccessFullyMapped HLSL 関数)。
framebufferfetch または fbfetch フレームバッファフェッチ (ピクセルシェーダーで入力ピクセルカラーを読み取る機能) をサポートします。
setrtarrayindexfromanyshader ジオメトリシェーダーステージだけでなく、どのシェーダーステージからでもレンダーターゲット配列のインデックスを設定することができます。

Use shader keywords to target GPU features

You can use a shader keyword to target the following GPU features:

  • Support for 16-bit data types.
  • Support for wave operations in compute shaders.

Use the following syntax:

#pragma multi_compile _ <keyword>

You don’t need to add a pragma require directive.

Unity then does the following:

  • Uses a compatible shader compiler and turns on compiler flags related to the feature.
  • Automatically compiles both a shader variant with the keyword on and a shader variant with the keyword off.
  • At runtime, automatically checks if the hardware supports the feature and selects the correct variant.

You can use an #if statement to make parts of your shader code conditional on whether the GPU supports the feature.

Keywords

multi-compile keyword GPU feature Keyword for conditional shader code
UNITY_DEVICE_SUPPORTS_NATIVE_16BIT Supports 16-bit data types. If you use this keyword, the layout of shader buffers might change, because data types such as half and min16float convert to 16-bit. UNITY_DEVICE_SUPPORTS_NATIVE_16BIT
UNITY_DEVICE_SUPPORTS_WAVE_ANY Supports wave operations of any size. Use this keyword only if you use wave operations where the size of the waves doesn’t matter. UNITY_HW_SUPPORTS_WAVE
UNITY_DEVICE_SUPPORTS_WAVE_8 Supports wave operations with a wave size of 8. UNITY_HW_SUPPORTS_WAVE
UNITY_DEVICE_SUPPORTS_WAVE_16 Supports wave operations with a wave size of 16. UNITY_HW_SUPPORTS_WAVE
UNITY_DEVICE_SUPPORTS_WAVE_32 Supports wave operations with a wave size of 32. UNITY_HW_SUPPORTS_WAVE
UNITY_DEVICE_SUPPORTS_WAVE_64 Supports wave operations with a wave size of 64. UNITY_HW_SUPPORTS_WAVE
UNITY_DEVICE_SUPPORTS_WAVE_128 Supports wave operations with a wave size of 128. UNITY_HW_SUPPORTS_WAVE

If you use a keyword that targets a specific wave size, Unity sets a UNITY_HW_WAVE_SIZE define to the same wave size so you can use it in shader code.

Refer to Declaring and using shader keywords in HLSL for more information.

Provide information to the shader compiler in HLSL
HLSLで特定のグラフィックス API とプラットフォームを対象にする方法