Version: 2022.1
言語: 日本語
シェーダーのデータ型と精度
Unity での GLSL

サンプラー状態の利用

テクスチャとサンプラーを組み合わせる

シェーダーでテクスチャをサンプリングする場合、大抵、テクスチャのサンプリング状態は、テクスチャ設定 に基づいています。基本的に、テクスチャとサンプラーは関連付けられています。これは、DX9 スタイルのシェーダー構文を使用する場合のデフォルトの動作です。

sampler2D _MainTex;
// ...
half4 color = tex2D(_MainTex, uv);

sampler2D、sampler3D、samplerCUBE HLSL キーワードは、テクスチャとサンプラーの両方を宣言します。

ほとんどの場合はこれで用が済みます。古いグラフィックス API (OpenGL ES) で唯一サポートされている選択肢です。

テクスチャとサンプラーを分ける

多くのグラフィックス API と GPU では、テクスチャよりもサンプラーの数を減らすことができます。さらに、テクスチャとサンプラーを組み合わせたシンタックスでは、複雑なシェーダーを記述できない場合があります。例えば、Direct3D 11 では、1 つのシェーダーで最大 128 のテクスチャを使用できますが、最大 16 サンプラーしか使用できません。

Unity では、DX11 形式の HLSL 構文のテクスチャとサンプラーを組み合わせる特別な命名規則を使用して、テクスチャとサンプラーを宣言することができます。“sampler” + TextureName という形式の名を持つサンプラーは、そのテクスチャからサンプリング状態を取得します。

上で述べたシェーダースニペットは、DX11 形式の HLSL 構文で書き直すことができ、同じことを行います。

Texture2D _MainTex;
SamplerState sampler_MainTex; // "sampler" + "_MainTex"
// ...
half4 color = _MainTex.Sample(sampler_MainTex, uv);

ただし、以下のようにすると、シェーダーが複数のテクスチャをサンプリングしながら、他のテクスチャのサンプラーを「再利用」するようできます。以下の例では、3 つのテクスチャをサンプリングするために 1 つのサンプラーしか使用していません。

Texture2D _MainTex;
Texture2D _SecondTex;
Texture2D _ThirdTex;
SamplerState sampler_MainTex; // "sampler" + "_MainTex"
// ...
half4 color = _MainTex.Sample(sampler_MainTex, uv);
color += _SecondTex.Sample(sampler_MainTex, uv);
color += _ThirdTex.Sample(sampler_MainTex, uv);

Unity は、この「サンプラーを分ける」アプローチを使用して、テクスチャの宣言とサンプリングを支援するシェーダーマクロをいくつか提供しています。詳細は、ビルトインマクロ を参照してください。ビルトインマクロを使うと、上の例を以下のように書き直すことができます。

UNITY_DECLARE_TEX2D(_MainTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_SecondTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_ThirdTex);
// ...
half4 color = UNITY_SAMPLE_TEX2D(_MainTex, uv);
color += UNITY_SAMPLE_TEX2D_SAMPLER(_SecondTex, _MainTex, uv);
color += UNITY_SAMPLE_TEX2D_SAMPLER(_ThirdTex, _MainTex, uv);

上のコードは Unity がサポートするすべてのプラットフォームでコンパイルできますが、DX9 のような古いプラットフォームでは 3 つのサンプラーを使用する方法で代替されます。

インラインサンプラーの状態

sampler + TextureName という名前の HLSL サンプラー状態のオブジェクトを認識することに加えて、Unity はサンプラー名の他のパターンもいくつか認識します。これは、単純なハードコーディングされたサンプリングステートをシェーダーで直接宣言するのに便利です。以下はその例です。

Texture2D _MainTex;
SamplerState my_point_clamp_sampler;
// ...
half4 color = _MainTex.Sample(my_point_clamp_sampler, uv);

“my_point_clamp_sampler” という名前は、Point (最も近い) テクスチャフィルタリングと、Clamp テクスチャラップモードを使用するサンプラーとして認識されます。

インラインのサンプラー状態として認識されるサンプラー名 (大文字と小文字は区別しません)

  • “Point”、“Linear”、“Trilinear” は、テクスチャフィルタリングモードを設定します (必須) 。

  • “Clamp”、“Repeat”、“Mirror”、“MirrorOnce” は、テクスチャラップモードを設定します (必須)。

    • ラップモードは 軸 (UVW) ごとに指定できます。例えば “ClampU_RepeatV”
  • “Compare” は深度比較のためにサンプラーを設定します (任意)。HLSL SamplerComparisonState 型と SampleCmp/SampleCmpLevelZero 関数で使用します。

  • “AnisoX” (where X can be 2/4/8 or 16, for example, Ansio8) can be added to request anisotropic filtering.

以下は、それぞれ sampler_linear_repeatsampler_point_repeat のサンプラー状態でテクスチャをサンプリングした例です。名前によってどのようにフィルタリングモードが制御されるかを示しています。

以下は、SmpClampPointSmpRepeatPointSmpMirrorPointSmpMirrorOncePointSmp_ClampU_RepeatV_Point の SamplerState をそれぞれ使用した例で、名前がラップモードをどのように制御するかを示しています。最後の例では、水平軸 (U) と垂直軸 (V) で異なるラップモードを設定しています。いずれの場合も、テクスチャ座標は –2.0 から +2.0 までです。

Just like separate texture + sampler syntax, inline sampler states are not supported on some platforms. Currently they are implemented on Direct3D 11/12 and Metal.

Note that “MirrorOnce” texture wrapping mode is not supported on most mobile GPUs/APIs, and will fallback to Mirror mode when support is not present.

Note that the “AnisoX” filtering modes are a best effort based on the platform capabilities and selected API. The actual value will be clamped based on the maximum supported anisotropic level (including disabled in cases where no anisotropic filtering is supported).


  • 2017–06–01 公開ページ

  • 2017.1 の新機能NewIn20171

シェーダーのデータ型と精度
Unity での GLSL