为什么我们需要纹理过滤(双线性、三线性、各向异性……)

Why do we need texture filtering (bi-linear, trilinear, anisotropy...)

也许我对纹理映射的实现方式的理解是错误的。我最近在 Java 中构建了一个纯粹的 3D 引擎(我知道我手上有很多时间)并且我完成了纹理映射部分。我这样做的方法是,当我将像素绘制到屏幕上时,我会在该位置查找纹理的颜色。我知道纹理过滤有助于减少以更倾斜的角度观看的高距离纹理的模糊度。但是为什么这个问题一开始就出现了呢?它没有在我的实施中。为什么我们缩小图像时会丢失分辨率?

这是我的引擎的图像。

两个词:奈奎斯特定理。

您的纹理是一个信号,屏幕像素是采样位置(因此术语采样器用于将纹理采样到屏幕像素的单元)。奈奎斯特定理指出,要忠实地表示具有样本的信号,该信号不得包含高于平均采样频率一半的频率。如果不满足该约束,就会出现混叠。因此,当您缩小纹理时,您实际上是在对其进行子采样,如果纹理信号中的采样距离变得比最高分辨率纹理特征之间的距离的两倍大(即采样频率较低),这将导致混叠。

因此,在每个离散采样系统中,在采样器之前都有一个所谓的 "antialiasing filter"。

您很容易理解,当您显示的像素少于原始图像中的像素时,您会丢失信息并产生令人不快的伪像。细节太多,有些乱扔。

考虑一个序列或 red/green/blue 个像素。如果您每隔三个像素采样一次,您将获得纯红色、纯绿色或纯蓝色行,具体取决于您从哪里开始。如果采样率接近三,您将观察到一系列依次为红色、绿色和蓝色的像素。这称为别名。 (就像在过去,当你通过直接抽取来缩小精灵时,效果是灾难性的。)

解决方法是让目标像素是它覆盖的源像素的混合,这相当于平均滤波器的效果。实际上,通过降低振幅,您可以更均匀地抛出精细细节。当 X 和 Y 的缩放因子不同时,过滤器将是各向异性的。

另请注意,插值没有帮助,因为当您需要超像素分辨率时,它会创建亚像素分辨率。 (在前面的示例中,您会在 RGB 运行之间进行缓慢混合。)

两个字:云纹

参见:https://en.wikipedia.org/wiki/Moir%C3%A9_pattern

如果你的纹理中有规则的重复图案,那么当它被采样的频率接近纹理中图案的频率时,这些大面积明暗区域的图案就会出现。

这就是为什么经常使用棋盘来显示双线性过滤的好处的原因。

用棋盘纹理试试你的引擎。

请注意,一种频率混叠效应,如"Nyquist theorem"答案中所述,但这种特殊的混叠效应无需任何复杂的数学运算即可轻松理解.