1. 主页
  2. 文档
  3. 从零开始的计算机图形_程序员的3D渲染介绍教程
  4. 从零开始的计算机图形_程序员的3D渲染介绍 纹理
  5. 双线性插值

双线性插值

假设我们把相机放在非常靠近其中一个立方体的地方。我们会看到类似图14-7的东西。

图14-7: 从近处渲染的纹理物体

图像看起来非常块状。为什么会发生这种情况?屏幕上的三角形拥有比纹理拥有更多的像素,所以每个纹理都被映射到许多连续的像素上。

我们正在对纹理坐标u和v进行插值,它们是0.0和1.0之间的实值。之后,给定纹理尺寸w和h,我们将u和v坐标分别乘以w和h,映射为tx和ty的纹理坐标。但是,由于纹理是一个具有整数索引的像素阵列,我们要把tx和ty四舍五入到最近的整数。由于这个原因,这种基本技术被称为近邻过滤。

即使(u, v)在三角形的表面上平滑地变化,产生的纹理坐标也会从一个像素“跳跃”到下一个像素,导致我们在图14-7中看到的块状外观。

我们可以做得更好。与舍入tx和ty向下不同,我们可以将分数纹理坐标(tx, ty)解释为描述四个整数纹理坐标之间的位置(通过舍入tx和ty向上和向下的组合获得)。我们可以取周围整数纹理的四种颜色,并为分数纹理计算线性插值的颜色。这将产生一个明显更平滑的结果(图14-8)。

图14-8: 使用插值颜色从近处渲染一个有纹理的物体

我们把周围的四个像素称为TL、TR、BL和BR(分别代表左上、右上、左下和右下)。让我们把tx和ty的小数部分称为fx和fy。图14-9显示了C,即由(tx,ty)描述的确切位置,被整数坐标的纹理所包围,以及它与它们的距离。

图14-9。我们将C处的一个颜色从它周围的四个纹理中线性插值出来。

首先,我们对CT处的颜色进行线性插值,它位于TL和TR之间。

CT = (1 – fx) · TL + fx · TR

注意,TR的权重是fx,而不是(1-fx)。这是因为当fx变得更接近于1.0时,我们希望CT变得更接近于TR。事实上,如果fx=0.0,那么CT=TL,如果fx=1.0,那么CT=TR。

我们可以用类似的方法来计算TL和TR之间的CB:

CB = (1 – fx) · BL + fx · BR

最后,我们计算C,在CT和CB之间进行线性插值:

C = (1 – fy) · BT + fy · CB

在伪代码中,我们可以写一个函数来获得对应于小数点的内插颜色:

GetTexel(texture, tx, ty) {
fx = frac(tx)
fy = frac(ty)
tx = floor(tx)
ty = floor(ty)
TL = texture[tx][ty]
TR = texture[tx+1][ty]
BL = texture[tx][ty+1]
BR = texture[tx+1][ty+1]
CT = fx * TR + (1 - fx) * TL
CB = fx * BR + (1 - fx) * BL
return fy * CB + (1 - fy) * CT
} 

这个函数使用floor()和frac(),前者将一个数字向下舍入到最接近的整数,后者返回一个数字的小数部分,可以定义为x-floor(x)。

这种技术被称为双线性插值(因为我们要做两次线性插值,在每个维度上一次)。

这篇文章对您有用吗?