在 Unity Shader 中,tex2D 是最常用的纹理采样函数,用于从 2D 纹理中读取颜色值。它是实现纹理映射、法线贴图、遮罩效果等的核心工具。


1. 基本语法

fixed4 tex2D(sampler2D sampler, float2 uv);
  • sampler:纹理采样器(如 _MainTex),需与 Properties 块中声明的纹理关联。
  • uv:纹理坐标,通常是范围为 [0, 1] 的二维向量。
  • 返回值:采样到的颜色值(fixed4float4,包含 RGBA 四个通道)。

2. 工作原理

  • 纹理坐标uv(0,0) 对应纹理左下角,(1,1) 对应右上角。
  • 采样方式:根据纹理的 Filter Mode(过滤模式)和 Wrap Mode(环绕模式)自动处理插值和边界行为。

3. 核心参数详解

3.1 纹理采样器 (sampler2D)

sampler2D _MainTex;  // 声明采样器

需在 Properties 块中关联纹理:

Properties {
    _MainTex ("Texture", 2D) = "white" {}  // 默认白色纹理
}

3.2 纹理坐标 (uv)

  • 范围:默认 [0, 1],超出范围的行为由纹理的 Wrap Mode 决定。
  • 常见处理
    // 应用材质面板中的缩放和偏移
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    
    // 手动缩放纹理(例如重复4次)
    o.uv = v.uv * 4.0;
    
    // 镜像效果
    o.uv = 1.0 - abs(o.uv * 2.0 - 1.0);
    

4. 纹理参数对采样的影响

4.1 Filter Mode(过滤模式)

控制纹理在缩放时的表现:

  • Point:最近邻采样(像素风,硬边缘)。
  • Bilinear:双线性插值(平滑过渡,默认)。
  • Trilinear:三线性插值(考虑 mipmap,更平滑)。

4.2 Wrap Mode(环绕模式)

控制纹理坐标超出 [0, 1] 时的行为:

  • Repeat:重复纹理(需配合 fractmod 使用)。
  • Clamp:边缘像素延伸。
  • Mirror:镜像重复。

5. 代码示例

5.1 基础纹理采样

fixed4 frag (v2f i) : SV_Target {
    fixed4 col = tex2D(_MainTex, i.uv);  // 采样纹理
    return col;
}

5.2 纹理重复(4x4 平铺)

fixed4 frag (v2f i) : SV_Target {
    float2 tiledUV = fract(i.uv * 4.0);  // 使用fract确保坐标在[0,1]内
    fixed4 col = tex2D(_MainTex, tiledUV);
    return col;
}

5.3 带遮罩的纹理混合

sampler2D _MaskTex;  // 遮罩纹理

fixed4 frag (v2f i) : SV_Target {
    fixed4 baseCol = tex2D(_MainTex, i.uv);      // 基础纹理
    fixed4 maskCol = tex2D(_MaskTex, i.uv);       // 遮罩纹理
    fixed4 finalCol = lerp(baseCol, _Highlight, maskCol.r);  // 根据遮罩值混合
    return finalCol;
}

5.4 法线贴图采样

sampler2D _NormalMap;  // 法线贴图

fixed4 frag (v2f i) : SV_Target {
    fixed4 normalCol = tex2D(_NormalMap, i.uv);    // 采样法线贴图
    float3 normal = UnpackNormal(normalCol);       // 解压法线向量
    // 后续光照计算...
}

6. 高级变体函数

6.1 带 Mipmap 级别控制的采样

fixed4 tex2Dlod(sampler2D sampler, float4 uv_and_lod);
  • uv_and_lod.xy:纹理坐标。
  • uv_and_lod.w:Mipmap 级别(0 表示最高精度)。

6.2 带导数计算的采样(用于抗锯齿)

fixed4 tex2Dgrad(sampler2D sampler, float2 uv, float2 ddx, float2 ddy);
  • ddx/ddy:纹理坐标在屏幕空间的导数。

7. 性能与优化

  • 减少采样次数:多次 tex2D 会显著降低性能。
  • 使用压缩纹理:如 DXT、ETC 格式可减少内存占用。
  • 合理设置 Mipmap:远距离物体启用 Mipmap 可提升性能。

总结

tex2D 是 Unity Shader 中纹理采样的核心函数,通过组合不同的纹理坐标处理和参数设置,你可以实现:

  • 基础纹理映射
  • 纹理重复与镜像
  • 遮罩与混合效果
  • 法线贴图与光照
  • 高级渲染技术(如环境映射、后处理)

在 Unity Shader 中,除了基础的 tex2D 函数外,还有许多其他纹理采样函数,用于处理不同类型的纹理、实现特殊效果或优化性能。

1. 带 Mipmap 控制的采样

tex2Dlod

直接指定 Mipmap 级别,用于精细控制细节程度:

fixed4 tex2Dlod(sampler2D sampler, float4 uv_and_lod);
  • uv_and_lod.xy:纹理坐标。
  • uv_and_lod.w:Mipmap 级别(0 表示最高精度,值越大越模糊)。

应用场景:程序化纹理、地形 LOD 过渡。

2. 带导数计算的采样

tex2Dgrad

手动提供纹理坐标的导数(用于屏幕空间变化率),优化抗锯齿:

fixed4 tex2Dgrad(sampler2D sampler, float2 uv, float2 ddx, float2 ddy);
  • ddx/ddy:纹理坐标在屏幕空间 X/Y 方向的导数。

应用场景:快速移动对象的纹理采样、自定义过滤算法。

3. 3D 纹理采样

tex3D

用于采样体积纹理(如雾效、体积云):

fixed4 tex3D(sampler3D sampler, float3 uv);
  • uv:三维纹理坐标。

应用场景:体积渲染、流体模拟、环境雾。

4. 立方体纹理采样

texCUBE

用于采样立方体贴图(如反射探针、天空盒):

fixed4 texCUBE(samplerCUBE sampler, float3 direction);
  • direction:采样方向向量(从原点指向立方体表面)。

应用场景:反射、折射、环境光照。

5. 投影纹理采样

tex2Dproj

用于实现阴影映射或透视投影纹理:

fixed4 tex2Dproj(sampler2D sampler, float4 uv_proj);
  • uv_proj:投影纹理坐标(通常是齐次坐标 (u,v,w,q),采样时会自动执行 (u/q, v/q))。

应用场景:阴影贴图、投影广告牌。

6. 双线性过滤的点采样

tex2Dbias

在采样时应用 Mipmap 偏移,实现更精细的控制:

fixed4 tex2Dbias(sampler2D sampler, float4 uv_bias);
  • uv_bias.xy:纹理坐标。
  • uv_bias.w:Mipmap 偏移值(负值使纹理更清晰,正值使纹理更模糊)。

应用场景:选择性锐化或模糊特定区域。

7. 纹理数组采样

tex2Darray

用于采样纹理数组(一组相同尺寸的纹理):

fixed4 tex2Darray(sampler2DArray sampler, float3 uv);
  • uv.xy:纹理坐标。
  • uv.z:纹理数组索引。

应用场景:多材质渲染、纹理动画序列。

8. 采样并比较(用于阴影)

tex2Dcmp

用于阴影采样,将采样值与比较值进行深度比较:

fixed tex2Dcmp(sampler2D sampler, float4 uv_compare);
  • uv_compare.xy:纹理坐标。
  • uv_compare.z:用于比较的深度值。

应用场景:阴影贴图(与 UNITY_SAMPLE_TEXCUBE_COMPARE 配合使用)。

9. 特殊采样函数

UNITY_SAMPLE_TEXCUBE_LOD

Unity 专用的立方体贴图采样,带 LOD 控制:

fixed4 UNITY_SAMPLE_TEXCUBE_LOD(samplerCUBE sampler, float3 dir, float lod);

应用场景:带反射细节控制的 PBR 材质。

10. 内置宏与辅助函数

UNITY_SAMPLE_GI

采样全局光照(GI):

UNITY_SAMPLE_GI(lightColor, worldPos, worldNormal);

应用场景:间接光照计算。

总结

函数名 作用 应用场景
tex2Dlod 指定 Mipmap 级别采样 程序化纹理、地形 LOD
tex2Dgrad 手动提供导数 自定义过滤、抗锯齿
tex3D 采样 3D 体积纹理 体积雾、流体模拟
texCUBE 采样立方体贴图 反射、天空盒
tex2Dproj 投影纹理采样 阴影映射、投影广告牌
tex2Darray 采样纹理数组 多材质切换、纹理动画
tex2Dcmp 采样并比较(阴影专用) 阴影贴图
UNITY_SAMPLE_GI 采样全局光照 间接光照计算