包含此页的版本:
不含此页的版本:
大多数情况下,在着色器在 GPU 上运行的程序。更多信息
请参阅术语表,纹理采样状态应来自纹理设置——本质上,纹理和采样器耦合在一起。这是使用 DX9 样式着色器语法时的默认行为:
sampler2D _MainTex;
// ...
half4 color = tex2D(_MainTex, uv);
使用 sampler2D、sampler3D、samplerCUBE HLSL 关键字声明纹理和采样器。
大多数时候,这是您想要的,并且是较旧的图形 API (OpenGL ES) 上唯一支持的选项。
许多图形 API 和 GPU 允许使用比纹理更少的采样器,并且耦合纹理 + 采样器语法可能不允许编写更复杂的着色器。例如,Direct3D 11 允许在单个着色器中使用多达 128 个纹理,但最多只能使用 16 个采样器。
Unity 允许使用 DX11 样式的 HLSL 语法声明纹理和采样器,并使用特殊的命名约定来匹配它们:名称为“sampler”+TextureName 形式的采样器将从该纹理中获取采样状态。
上一节中的着色器片段可以用 DX11 样式的 HLSL 语法重写,它将执行相同的作:
Texture2D _MainTex;
SamplerState sampler_MainTex; // "sampler" + “_MainTex”
// ...
half4 color = _MainTex.Sample(sampler_MainTex, uv);
但是,这样可以编写着色器来“重用”其他纹理的采样器,同时采样多个纹理。在下面的示例中,对三个纹理进行采样,但所有纹理只使用一个采样器:
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 等旧平台上使用三个采样器。
除了识别名为“sampler”+TextureName 的 HLSL SamplerState 对象外,Unity 还可以识别采样器名称中的其他一些模式。这对于直接在着色器中声明简单的硬编码采样状态非常有用。一个例子:
Texture2D _MainTex;
SamplerState my_point_clamp_sampler;
// ...
half4 color = _MainTex.Sample(my_point_clamp_sampler, uv);
名称“my_point_clamp_sampler”将被识别为应使用点(最近)纹理筛选和钳制纹理包装模式的采样器。
被识别为“内联”采样器状态的采样器名称(所有不区分大小写):
“点”、“线性”或“三线性”(必填)设置纹理过滤模式。
“Clamp”、“Repeat”、“Mirror”或“MirrorOnce”(必填)设置纹理包裹模式。
“比较”(可选)设置采样器进行深度比较;与 HLSL SamplerComparisonState 类型和 SampleCmp / SampleCmpLevelZero 函数一起使用。
“AnisoX”(其中 X 可以是 2/4/8 或 16,例如Aniso8)可以添加来请求各向异性滤波。
下面是使用sampler_linear_repeat和sampler_point_repeatSamplerStates,说明名称如何控制筛选模式:
sampler_linear_repeat.右图:对纹理进行采样sampler_point_repeat.这是一个示例SmpClampPoint,SmpRepeatPoint,SmpMirrorPoint,SmpMirrorOncePoint,Smp_ClampU_RepeatV_PointSamplerStates,说明名称如何控制包装模式。在最后一个示例中,为水平 (U) 和垂直 (V) 轴设置了不同的环绕模式。在所有情况下,纹理坐标都从 –2.0 到 +2.0。
SmpClampPoint,SmpRepeatPoint,SmpMirrorPoint,SmpMirrorOncePoint,Smp_ClampU_RepeatV_Point.就像单独的纹理 + 采样器语法一样,某些平台不支持内联采样器状态。目前,它们在 Direct3D 11/12 和 Metal 上实现。
请注意,大多数移动 GPU/API 不支持“MirrorOnce”纹理包装模式,当不支持时,它将回退到镜像模式。
请注意,“AnisoX”过滤模式是基于平台功能和所选 API 的最佳选择。实际值将根据支持的最大各向异性水平进行限制(包括在不支持各向异性过滤的情况下禁用)。
| 宏观: | 用: |
|---|---|
UNITY_DECLARE_TEX2D(name) |
声明纹理和采样器对。 |
UNITY_DECLARE_TEX2D_NOSAMPLER(name) |
声明不带采样器的纹理。 |
UNITY_DECLARE_TEX2DARRAY(name) |
声明纹理数组采样器变量。 |
UNITY_SAMPLE_TEX2D(name,uv) |
使用给定的纹理坐标从 Texture 和 Sampler 对中采样。 |
UNITY_SAMPLE_TEX2D_SAMPLER( name,samplername,uv) |
从纹理(名称)采样,使用另一个纹理(采样器名称)中的采样器。 |
UNITY_SAMPLE_TEX2DARRAY(name,uv) |
从具有float3 UV的纹理数组中采样;坐标的 z 分量是数组元素索引。 |
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod) |
从具有显式 mipmap 级别的纹理数组中采样。 |