シェーダーでテクスチャをサンプリングするほとんどの場合、テクスチャサンプリングの状態は テクスチャ設定 に基づきます。基本的に、テクスチャとサンプラーは組み合わせて使用されます。これは、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);
ただし、DX11 スタイルの HLSL シンタックスは、いくつかの古いプラット フォーム (例えば、OpenGL ES 2.0) では使用できないことに注意してください。詳細は Unity の HLSL を参照してください。#pragma target 3.5
(HLSL でシェーダーモデルと GPU 機能を特定する を参照) を指定して、シェーダーが古いプラットフォームを使用することをスキップすることもできます。
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” は、テクスチャラップモードを設定します (必須)。
“Compare” は深度比較のためにサンプラーを設定します (任意)。HLSL SamplerComparisonState 型と SampleCmp/SampleCmpLevelZero 関数で使用します。
以下は、それぞれ sampler_linear_repeat
と sampler_point_repeat
のサンプラー状態でテクスチャをサンプリングした例です。名前によってどのようにフィルタリングモードが制御されるかを示しています。
以下は、それぞれ SmpClampPoint
、SmpRepeatPoint
、SmpMirrorPoint
、SmpMirrorOncePoint
、Smp_ClampU_RepeatV_Point
SamplerStates の例です。名前がラッピングモードを制御する方法を示しています。最後の例では、水平軸 (U) と垂直軸 (V) に異なるラップモードが設定されています。すべての例のテクスチャ座標は –2.0 から +2.0 の範囲です。
独立したテクスチャ + サンプラーの構文のように、インラインサンプラーの状態は一部のプラットフォームではサポートされていません。現在、インラインサンプラーは Direct3D 11/12、PS4、XboxOne、Metal で実装されています。
“MirrorOnce” テクスチャラッピングモードは、ほとんどのモバイル GPU/API でサポートされていません。そのため、サポートされない場合は Mirror モードに代替されます。
2017–06–01 公開ページ
2017.1 の新機能NewIn20171