← ALL ARTICLES
纹理技术5 MIN READ

纹理采样与过滤

全库目录221
本文目录23

相机斜着看一条路,纹理开始模糊或闪烁,单纯提高图片分辨率未必改善。一个像素覆盖的Texel范围发生了变化,采样器必须选择Mip和过滤方式。我们从这个采样足迹出发,看邻域过滤怎样保留信息,以及法线、Alpha和距离场为何不能都按普通颜色缩小。

专题阅读

  • 纹理压缩格式:纹理块压缩降低存储和采样带宽,但改变精度、格式支持和数据语义。

纹素坐标与单级过滤

Texel 是纹理中的离散元素。像素是屏幕输出元素。一个像素可能读取多个 Texel,一个 Texel 也可能影响多个像素。

二维 UV 通常使用归一化坐标。(0,0)(0,0) 和 (1,1)(1,1) 对应纹理边界,但 API、图片格式和引擎可能有不同的 V 轴方向。

点采样

选择离采样位置最近的一个 Texel。它保留硬边,适合像素风、索引贴图和不允许混合的离散数据。

缩放时会明显跳变和闪烁。

双线性过滤

归一化UV先换成以纹素中心为整数的坐标:q=uv*size-0.5。令i=floor(q)、f=q-i,取i周围2×2纹素,沿X按fx插值,再沿Y按fy插值。每次取值先按地址模式处理整数索引。这样uv=(0.5/W,0.5/H)正好读到首个纹素中心。

例如2×2标量纹理的两行为[0,2]和[4,6],中心UV=(0.5,0.5)得到3。该结果在单级内部连续,但过滤颜色应在线性空间进行;材质ID等离散数据不应参与这个平均。

它不能解决纹理缩小时一个像素覆盖很多 Texel 的问题,只是在当前 Mip 内取四个邻居。

Mipmap

Mipmap 保存逐级缩小的纹理:

text
L0: W × H
L1: W/2 × H/2
L2: W/4 × H/4
...

对长宽同时减半的较大二维纹理,完整Mip链的额外纹素量约为基级的三分之一。极细长纹理不满足这个近似,例如8×1各级为8、4、2、1,共15纹素。它换来更稳定的缩小采样和更好的缓存/带宽使用。

LOD估计

GPU 根据 UV 在屏幕相邻像素间的变化估计纹理 Footprint。简化理解:

ρ=max⁡(∥∂u∂x∥,∥∂u∂y∥),LOD≈log⁡2ρ\rho=\max\left( \left\lVert\frac{\partial \mathbf u}{\partial x}\right\rVert, \left\lVert\frac{\partial \mathbf u}{\partial y}\right\rVert \right), \qquad LOD\approx\log_2\rho

上式的u必须采用纹素单位。若输入是归一化UV,先逐分量乘(W,H):dx = ddx(uv)*float2(W,H),dy = ddy(uv)*float2(W,H),再用二者长度的最大值求log2。1024×512纹理的导数分别为(1/256,0)、(0,1/128),两个方向均覆盖4纹素,LOD为2。零足迹需要数值下界,最终LOD还受可用mip范围、Sampler偏置及最小/最大值限制。

这估计的是近似各向同性尺度;各向异性过滤还需要足迹的长短轴。先在连续UV上求导,再由采样器执行Wrap。若先做frac,跨整数处的导数会把平滑平铺误判成巨大足迹。

SampleLevel 显式指定 LOD,SampleGrad 显式提供导数。顶点阶段通常使用显式LOD;计算阶段能否使用导数由着色模型与线程布局决定。HLSL SM6.6支持满足quad布局要求的Compute导数,不能把所有Compute环境都归为不支持。

三线性过滤

分别在两个相邻 Mip 做 Bilinear,再在 Mip 之间插值。它减少 Mip 切换带状边界,但采样和带宽比单级 Bilinear 更高。

各向异性过滤

倾斜表面的 Footprint 不是正方形,而是细长椭圆。普通 Mipmap 只按最大范围选一个方形尺度,会让某个方向过度模糊。

各向异性过滤沿长轴增加多个采样,保留道路、地面和斜面纹理细节。等级越高,最坏采样成本越高,但硬件会根据 Footprint 自适应。

放大与缩小

  • Magnification:一个 Texel 覆盖多个屏幕像素,主要靠 Point/Bilinear 决定放大外观。
  • Minification:一个屏幕像素覆盖多个 Texel,需要预过滤、Mipmap 和各向异性过滤减少混叠。

Address Mode

Repeat/Wrap

取坐标小数部分平铺纹理。适合 Tileable 材质。

Clamp

超出范围时使用边缘值。适合 Mask、Lookup Table 和屏幕纹理。

Mirror

每个重复区间翻转,可以减少平铺边界方向突变。

Border

范围外返回指定颜色。并非所有平台和 Sampler 类型都同样支持。

Atlas 子区域即使使用 Clamp,也可能在过滤和 Mip 中读到邻近图块,需要 Padding 和边缘扩展。

数据语义与mip生成

Normal Map

平均法线向量后长度会变短。生成 Mip 时需要按方向语义处理,并在采样后归一化。高频法线还会改变表面统计 Roughness,可使用 Toksvig、LEAN 等思路减少远处高光闪烁。

Alpha Test

平均 Alpha 会改变覆盖率,导致树叶远处变稀或变厚。可以在各 Mip 调整阈值或重映射 Alpha,尽量保持 Coverage。

SDF

距离场的零等值线和距离尺度需要保持。普通颜色平均可能让边界漂移。

ORM/Mask

不同通道可能需要不同缩小策略。通道打包前要确认它们是否适合共享分辨率和 Mip。

数据缩小的具体失效

两份单位法线(0.6,0,0.8)与(-0.6,0,0.8)平均成(0,0,0.8),重新归一化变成(0,0,1)。平均方向正确描述中心朝向,却丢失了两侧坡度的分布;用它配合原来的低粗糙度BRDF,会把本应展开的高光重新集中。Toksvig等方法借助未归一化平均向量长度估计方差,再影响高光宽度,完整算法需按采用的BRDF与法线编码匹配。

Alpha四个子纹素为[1,0,0,0]、裁剪阈值0.5时,原覆盖率为1/4。普通平均得到父值0.25,再裁剪则覆盖为0;若仅把父值乘2使其达到0.5,单个父纹素又会全部保留。覆盖保持是在更大统计区域内调分布,单个父纹素不能同时保存所有子像素形状,MSAA覆盖或远景专用表示提供额外自由度。

各向异性足迹若长轴16纹素、短轴2纹素,按最大轴选LOD4会把两个方向都压到16纹素尺度。以短轴对应的LOD1作为起点、沿长轴取若干样本再组合,可保留短轴细节;确切采样位置和数量属于硬件规则。达到各向异性上限后仍需更保守过滤,所以提高等级也不能保证任意斜视角保持清晰。

验证方法

  • 显示 Mip Level 和 Texture Streaming 状态。
  • 缓慢移动相机,观察远处闪烁和 Mip Band。
  • 对比 Point、Bilinear、Trilinear 和 Anisotropic。
  • 放大查看压缩 Block、渐变、Normal 高光和 Alpha 边缘。
  • 用引擎 Memory Profiler 检查运行时格式和完整 Mip 占用。
  • 检查平台 Override,避免编辑器格式与真机格式不一致。

相关主题

本机检查:reference.py中的texture_lod、bilinear与mip_bytes展开了纹素单位、中心位置、Clamp和细长mip尾部计算。运行 python -B 知识库/examples/revision_06_08/test_reference.py。模型未验证硬件过滤精度、各向异性采样分布或真实画面。

参考资料

  • OpenGL 4.6 Core规范:8.14.1缩放与LOD、8.14.2坐标寻址与纹素选择、8.14.3 mip及8.15放大过滤;UV、纹素中心和mip过滤规则。
  • Microsoft,SM6.6 Derivatives:2026-10-22核读Thread Groups and Quads与Texture Sample Methods,限定计算导数能力。
  • 采样与混叠维护采样定理与足迹积分推导。