Shader中采样器的使用(Using sampler states)
合并的贴图和采样器(Coupled textures and samplers)
大部分时候我们在Shader里采样贴图的时候,都是像下面这样子声明
sampler2D _MainTex;
......
half4 color = tex2D(_MainTex, uv);
这样采样贴图的具体方式来自贴图上的设置,实际上这是贴图和采样器合并在一起了(我们是可以单独声明采样器的)。我们可以使用sampler2D, sampler3D, samplerCUBE 这些HLSL的关键字来声明不同类型的贴图和采样器。
这种声明方式是旧的图形API唯一支持的一种设置(OpenGL ES)
独立的贴图和采样器(Separate textures and samplers)
上述的合并的贴图和采样器无法支持更复杂的情形,而现在许多图形API和GPU都允许采样器数量少于贴图数量,例如,Direct3D 11允许在一个shader中最多使用128张贴图,但是最多只允许使用16个采样器。
Unity支持使用DX11的HLSL语法来声明不同的贴图和采样器,采样器设置是"sampler"+贴图名称的组合,这样子获取到的是这张贴图的采样设置,如下所示,我们重写上面的那段代码
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)
但是,这种语法是DX11的HLSL语法,一些老的平台无法支持(比如OpenGL ES 2.0),我们可能需要指定#pragma target 3.5 来避免老平台的问题。
Unity提供了几个宏定义来帮助我们定义贴图和采样器,并且能够兼容所有平台
UNITY_DECLARE_TEX2D(_MainTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_SeconedTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_ThirdTex);
//...
half4 color = UNITY_SAMPLE_TEX2D(_MainTex, uv);
color