像素画纹理过滤:为什么必须用 Nearest

像素画游戏在放大渲染时,必须使用 Nearest(最近邻)过滤而非 Bilinear(双线性插值),原因涉及 GPU 纹理采样管线、像素画的离散美学特征、以及双线性插值的数学本质。

GPU 纹理采样底层原理

Nearest(最近邻)— 1 次采样

texel_x = floor(u * width)
texel_y = floor(v * height)
return texture[texel_x][texel_y]

将 normalized UV 坐标映射到纹素范围并选取最近的纹素,读取 1 个纹素直接返回。若用 texel-center 坐标描述,也可写作 x = u * width - 0.5 后选择最近的整数中心。结果永远是原始纹理中存在的颜色值,绝不创造新颜色

Bilinear(双线性插值)— 4 次采样

1. 转换到 texel-center 坐标: x = u * width - 0.5, y = v * height - 0.5
2. floor 得到左上角纹素索引: i = floor(x), j = floor(y)
3. 计算小数偏移: fx = fract(x), fy = fract(y)
4. 读取 2×2 纹素四元组: c00, c10, c01, c11
5. 两次线性插值:
   top    = lerp(c00, c10, fx)
   bottom = lerp(c01, c11, fx)
   result = lerp(top, bottom, fy)

读取 4 个纹素,通过加权平均在颜色边界处通常会产生原始纹理中不存在的新颜色

来源:Vulkan 1.3 规范 §16.8、《Real-Time Rendering》4th Ed. §13.4-13.5

为什么双线性插值摧毁像素画

像素画的视觉灵魂建立在三个原则上:

  1. 锐利的颜色边界 — 每个像素的颜色是精心选择的,边界处无渐变
  2. 严格的颜色调色板 — 通常只有 4~32 种颜色
  3. 轮廓由像素边界定义 — 形状辨识度依赖像素网格

双线性插值对每一条原则都是致命的:

  • 在颜色边界创造不存在的中间色(如黑色/白色边界处产生灰色”幽灵像素”)
  • 软化轮廓,使形状变得模糊
  • 在非整数缩放时(如 2.5×),让边界落在屏幕像素之间,从而产生混色和非像素精确的模糊边缘

开发者社区的经典描述:

“当你不小心对像素画用了双线性过滤,看起来就像有人在屏幕上涂了凡士林。每个锐利的像素边缘都变成了模糊的渐变。“

纹理游走(Texture Swimming)

双线性插值在动态场景中最致命的问题:

当摄像机以亚纹素精度(sub-texel)移动时,小数偏移 (fx, fy) 持续变化,导致:

  1. 相邻屏幕像素采样到略有不同的混合比例
  2. 产生微妙的闪烁/游走/扭曲效果
  3. 对只有 4-32 种颜色的像素画,这种色彩污染会被立刻感知

Nearest 是阶跃函数 — 在一定范围的坐标内始终选中同一个整数纹素,边界是硬切换,没有中间混色状态。因此它不会产生 Bilinear 那种连续混色的 texture swimming;但在亚像素移动或非 pixel-perfect 摄像机下,仍可能出现离散跳变、抖动或闪烁。

GPU 硬件管线完整流程

UV 坐标 → [地址模式] → [Mip 级别选择] → [过滤模式] → 输出颜色

Mip 级别选择机制(quad 执行模型,简化表达):

  • GPU 2×2 像素 quad 中,水平和垂直相邻片元用于估计 UV 对屏幕坐标的导数
  • 常见近似可写作:ρx = sqrt((du/dx * width)^2 + (dv/dx * height)^2)ρy = sqrt((du/dy * width)^2 + (dv/dy * height)^2)λ = log₂(max(ρx, ρy))
  • 实际实现还会受到显式 LOD、LOD bias、clamp、各向异性过滤和 GPU 实现细节影响
  • Nearest + Mip = 选 1 个 mip 级别 + 取 1 个纹素
  • Linear + Mip(三线性)= 选 2 个 mip 级别 × 每级 4 个纹素 = 8 次采样

来源:SPIR-V 规范 §3.23(Derivative Instructions)、NVIDIA Ada 架构白皮书

根本权衡

维度NearestBilinear
采样次数14
创造新颜色绝不在颜色边界处通常会
边缘外观锐利精确模糊抗锯齿
非整数缩放可能出现不均匀像素宽度 / snapping边界模糊、混色、非像素精确
时间稳定性阶跃切换平滑但有游走
最适合像素画、UI、文字照片、3D 纹理、渐变

各向异性过滤(AF)与像素画

AF 对像素画无帮助

  • AF 解决的是透视角度下的各向异性投影问题(如远处的地板)
  • 像素画通常使用正交投影(各向异性比接近 1:1),AF 的收益很小
  • AF 通常仍依赖线性/多点采样,无法保留像素画的硬边界;具体采样次数和 mip 参与方式取决于 GPU 与采样器实现

各种过滤模式对比

过滤类型纹素采样数Mip 级别数最适合场景
Nearest11像素画、复古图形
Bilinear413D 放大
Trilinear823D + Mipmaps
Anisotropic (16×)实现相关,可能显著多于 Bilinear实现相关透视角度表面

业界实践

所有顶级像素画游戏都使用 Nearest 过滤:

  • Celeste — 内部分辨率 320×180,Nearest 放大到屏幕
  • Stardew Valley — 16×16 瓦片,固定虚拟分辨率 + Nearest 缩放
  • Shovel Knight — NES 风格 400×240,严格 Nearest
  • Undertale — 简洁像素画,锐利渲染
  • Dead Cells — 像素精灵 + 流畅动画,严格 Nearest

结论

像素画的每一个像素都是艺术决策。双线性插值在颜色边界处通常会创造不存在的中间色,摧毁这种精心设计的离散性。Nearest 是唯一能在放大时保持原始像素 1:1 忠实还原的基础过滤方式。这不只是”好看不好看”的问题,而是正确性问题 — 线性插值从数学上就不是为离散的、像素级精确的美术资源设计的。

参考来源

相关页面