纹理滤波

为何需要纹理滤波

在应用纹理贴图时，需要对于每一个像素中心所在的位置进行查询纹理值的操作。但是由于被渲染的目标表面相对于视角，可能处于任意距离或者角度，一个像素不一定有一个纹素对应。所以需要应用某种滤波方式来决定其纹理值，缺少滤波或使用不当都会造成最终的图像存在例如锯齿和闪烁之类的瑕疵。
由于应用纹理贴图的表面相对于视角的距离和角度不同，在表面之上的一个像素和对应的纹理之上一个或多个纹素之间可能存在多种对应关系，这也导致需要应用不同的滤波方式。如果把一个正方形的纹理映射到一个正方形的表面上，在离视角的某一个距离上，屏幕上的一个像素和一个纹素几乎等尺寸。如果比这个距离近，纹素就会比像素尺寸大，这是就需要将纹素相应地放大，这就是所谓的纹理放大。同理，如果比这个距离远，纹素将比像素尺寸小，一个像素最终的纹理值就会从其覆盖的多个纹素的值计算出，这也就是通常所说的纹理缩小。常见的图像应用程序接口，例如OpenGL，提供了多种的缩小和放大滤波方式。
值得注意的是，即使在像素和纹素尺寸相等的情况下，其之间也不一定就存在一一对应的关系。例如可能存在错位而导致一个像素覆盖了相邻四个纹素的各一部分。所以仍然需要某种滤波方式。

Mipmapping

Mipmapping是一种常见的通过预计算减小渲染时所需滤波工作的方法。在纹理放大中，所参与计算一个像素的纹理值的纹素一般是四个或更少；而在纹理缩小中，随着目标表面远离视点，整个纹理尺寸可能最终将比一个像素还小，这将造成需要其上的所有纹素进行计算，这样造成的计算量和带宽在实时渲染中是不现实的。Mipmapping通过进行预计算，并将结果存储在一系列更小尺寸的纹理中，避免了这种情况的发生。当目标表面逐渐远离时，更小尺寸的纹理将自动被选用参与计算。

滤波方式

以下列举了常见的纹理滤波方式，以计算成本从少到多排序。

最近邻插值

最近邻插值是最快速，也是最粗糙的滤波方式。最邻近像素中心的纹素颜色将被作为像素的颜色。在纹理放大时，这种方式会导致色块；而在纹理缩小时，则会导致闪烁和锯齿。

最近邻Mipmapping

这种方式先根据距离选择最近的mipmap层级，再从其中选择最靠近像素中心的纹素。这对闪烁和锯齿很有效，但不能减少色块。

双线性滤波

双线性滤波会从最近的mipmap层次上，选择最靠近像素中心的四个纹素，再根据他们靠近像素中心的具体进行权重插值。这时如果进行纹理放大，当像素相对于纹素移动时，像素颜色会从逐渐从一个纹素颜色变化到相邻的纹素颜色，而不是像最近邻插值那样，在穿过两个纹素的边界时发生突变，这样就消除色块。双线性滤波经常与mipmapping一起使用，但也可以单独使用，但这时会出现闪烁和锯齿化的问题。

三线性滤波

在使用mipmapping双线性滤波时，当目标表面的距离变化时，会从一个mipmap层次突变到相邻的层次。三线性滤波被用来解决这个问题，方法是在最相邻的两个mipmap层次上分别进行双线性滤波，再用得到的两个值进行线性插值。值得注意的是，当距离小于mipmap的零层次时（即纹素大小超过像素大小时），三线性插值退化为双线性插值。

各向异性滤波

各向异性过滤是现有消费级显卡所提供的图像质量最佳的滤波方式。传统的各项同性滤波中只是在正方形的mipmap层次间进行双线性或三线性插值，但是当一个目标表面和摄像机之间角度较大时，纹理的填充面积并不是正方形，这样便引入了模糊和闪烁等瑕疵。 于是，各向异性滤波需要对一个非方形纹理进行采样。在一些简单的实现中，显卡使用长方形的纹理取代方形纹理，达到了较好的近似效果。但是这种方式在处理边界时效果依然不理想，原因是在倾斜的表面上，近端边界比远端边界拥有更多的像素。于是一些高端显卡使用了梯形纹理，当然这也要求更大的运算量。