参考文章:
使用采样器状态 - Unity 手册docs.unity3d.comhttps://blog.csdn.net/chenjinxian_3D/article/details/51816918blog.csdn.net根据Unity的参考文档,Unity Shader使用采样器状态有三种方式,分别是:耦合的纹理和采样器;单独的纹理和采样器;内联纹理采样器状态。
耦合的纹理和采样器
第一种采样器状态来源于纹理设置,本质上纹理跟采样器会耦合在一起,使用DX9的语法风格,它的默认行为如下:
sampler2D _MainTex;
// ...
half4 color = tex2D(_MainTex, uv);
使用 HLSL 关键字 sampler2D、sampler3D 和 samplerCUBE 可声明纹理和采样器。在较旧的图形 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);
但是请注意,DX11 风格的 HLSL 语法在某些较旧的平台(例如,OpenGL ES 2.0)上无效,不过可以通过指定#pragma target 3.5
以避免较旧的平台使用着色器。
内联采样器状态
除了能识别名为“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”将被识别为应该使用点(距离最近)纹理过滤和钳制纹理包裹模式的采样器。
采样器名称被识别为“内联”采样器状态(全都不区分大小写):
*“Point”、“Linear”或“Trilinear”(必需)设置纹理过滤模式。
*“Clamp”、“Repeat”、“Mirror”或“MirrorOnce”(必需)设置纹理包裹模式。
下面罗列参见的内联采样器状态:
sampler_tex1 // 使用unity的texture setting的sampler
sampler_linear_clampu // filter:linear, wrap: clamp u
sampler_linear_clampv // filter:linear, wrap: clamp v
sampler_point_clamp // filter:point, wrap: clamp u & v
sampler_linear_clamp // filter:linear, wrap: clamp u & v
sampler_trilinear_clamp // filter:trilinear, wrap: clamp u & v
sampler_trilinear_mirroru // filter:trilinear, wrap: mirror u
sampler_trilinear_mirrorv // filter:trilinear, wrap: mirror v
sampler_trilinear_mirror // filter:trilinear, wrap: mirror v & v
sampler_trilinear_mirroronceu // filter:trilinear, wrap: mirror once u, 这个亲测法线mirror v也生成,不知道是否解析的BUG
sampler_trilinear_mirroroncev // filter:trilinear, wrap: mirror once v, 这个亲测法线mirror u也生成,不知道是否解析的BUG
sampler_trilinear_mirroroncev_mirroru // filter:trilinear, wrap: mirror once v & mirror u, 亲测两个一起设置,就没有BUG
sampler_trilinear_mirroru_repeat // filter:trilinear, wrap: mirror u & repeat v