Direct3D 9 (双向纹理筛选)

纹理始终以线性方式从左上角的 (0.0、0.0) 到右上角的 (1.0、1.0) ,如下图所示。

illustration of 4x4 texture with solid blocks of color

纹理通常看似由固态色块构成,但实际上应将纹理视为等同于光栅显像才更为准确:每个纹素均定义为位于网格单元的正中心,如下图所示。

illustration of 4x4 texture with texels defined at the center of the grid cells

如果你要求纹理采样器在 UV 坐标 (0.375, 0.375) 处获得这种纹理的颜色,那么将得到纯红色 (255, 0, 0)。 这很有意义,因为红色纹素单元格的确切中心位于 UV (0.375,0.375) 。 如果你要求采样器在 UV (0.25, 0.25) 处获得这种纹理的颜色,会怎么样? 这并不容易,因为 UV (0.25, 0.25) 位于 4 个纹素的确切角落。

最简单的方案只是让采样器返回最接近的纹素的颜色:这称为点筛选 (看到 最接近的点采样 (Direct3D 9) ) ,并且通常是由于粒度或块状结果而不需要的。 在 UV (0.25, 0.25) 处对纹理进行点采样显示出最近点筛选的另一个微妙问题:存在与采样点等距离的四个纹素,因此不存在单个最近的纹素。 这四个纹素之一将被选择作为返回的颜色,但是选择取决于坐标是如何舍入的,这可能引入撕裂伪影(参见 SDK 中的“最近点采样”文章)。

稍微准确和更常见的筛选方案是计算离采样点最近的 4 个纹素的加权平均值:这称为双线性筛选,而且额外的计算成本通常可以忽略不计,因为此例程是在现代图形硬件中实现的。 以下是我们使用双线性筛选在几个不同的采样点处获得的颜色:

UV: (0.5, 0.5)

此点正好位于红色、绿色、蓝色和白色纹素之间的边界处。 采样器返回的颜色是灰色:

  0.25 * (255, 0, 0)
  0.25 * (0, 255, 0) 
  0.25 * (0, 0, 255) 
## + 0.25 * (255, 255, 255) 
------------------------
= (128, 128, 128)
UV: (0.5, 0.375)

此点位于红色纹素和绿色纹素之间的边界的中点。 采样器返回的颜色是黄灰色(注意,蓝色纹素和白色纹素的贡献被缩放为 0):

  0.5 * (255, 0, 0)
  0.5 * (0, 255, 0) 
  0.0 * (0, 0, 255) 
## + 0.0 * (255, 255, 255) 
------------------------
= (128, 128, 0)
UV: (0.375, 0.375)

这是红色纹素的地址,它是返回的颜色(筛选计算中的所有其他纹素的权重都被设置为 0):

  1.0 * (255, 0, 0)
  0.0 * (0, 255, 0) 
  0.0 * (0, 0, 255) 
## + 0.0 * (255, 255, 255) 
------------------------
= (255, 0, 0)

将这些计算与下图进行比较,可以看到如果在跨越 4×4 纹素的每个纹理地址处执行双线性筛选计算,会发生什么。

illustration of 4x4 texture with bilinear filtering performed at every texture address

纹理筛选