MIT 6.837:Texture Mapping 纹理映射

MIT 6.837:Texture Mapping 纹理映射

当遇到表面细节复杂的几何体时,利用几何(三角面)来表示这些细节需要巨大的计算开销,从而导致性能瓶颈。一种折中的办法是在平面的纹理上表示这些表面细节,而将纹理图片映射到几何体表面上,大大简化了几何的复杂程度。

二维纹理映射

透视投影后的插值

应用纹理到三角面上通常在投影完成后(fragment shader)进行,此时三角面不在具有空间中的坐标,而只保存了屏幕空间坐标与 Z 缓冲区(或 1/z 值)。因此,纹理的应用必须依赖屏幕空间坐标进行。如果直接对屏幕空间中的坐标进行线性插值,会得到怪异的结果,如下图所示。

50 1024x411 - MIT 6.837:Texture Mapping 纹理映射

在这个例子中,我们把一个方形的纹理映射到两个三角面上,这两个三角面拼成了一个斜的方形面。这两个三角面上的纹理的扭曲不相同。

一种解决此问题的方法是将大三角面细分为小三角面,以让三角形邻接处的扭曲程度接近,减少这种怪异的明显程度。但此方法的效果并不好,我们有其他办法从根本上解决此问题。

这种问题产生的原因是,在透视投影中,屏幕空间上的线性插值在空间中由于 z 坐标原因并不是线性分布的。这个问题在可见性中的 Z 缓冲区话题第一次被提及,而此次我们希望将插值运用在纹理映射中。

51 - MIT 6.837:Texture Mapping 纹理映射

我们可以通过比较在屏幕空间中的线性插值与世界空间中的线性插值,以得到两个插值之间的关系。假设只考虑 xOz 屏幕,则空间中的一条直线被投影到 z=1 上为 x 坐标的一段区间,屏幕空间中 x 坐标即可表达一个点,而世界空间中需要用一个有序对 (x, z) 来表达一个点。

$$
\begin{align}
& 屏幕空间: p(t)=p_1+t(p_2-p_1)=\frac{x_1}{z_1} + t \left( \frac{x_2}{z_2}-\frac{x_1}{z_1} \right) \\
& 世界空间: \begin{bmatrix} x\\z \end{bmatrix}=\begin{bmatrix} x_1\\z_1 \end{bmatrix} + s \left( \begin{bmatrix} x_2\\z_2 \end{bmatrix}-\begin{bmatrix} x_1\\z_1 \end{bmatrix} \right) \\
& 世界空间中点在屏幕空间的投影: p\left( \begin{bmatrix} x\\z \end{bmatrix} \right) = \frac{x_1+s(x_2-x_1)}{z_1+s(z_2-z_1)}
\end{align}
$$

联立屏幕空间与世界空间投影的插值表达式,可得 s 与 t 的关系如下

$$ s=\frac{tz_1}{z_2+t(z_1-z_2)} $$

如果 Z 缓冲区保存的是 1/z 或 w 值,则上式还可以写成

$$ s=\frac{tw_2}{w_1+t(w_2-w_1)} $$

因此,在插值参数为 t 的像素时,我们可以利用上式转换为空间中的插值参数 s,通过 s 的值来获取纹理中的颜色值,这样就可以得到正确的投影效果。

纹理的获取与使用

纹理的获取渠道很多,可以利用现实物体的照片生成纹理,也可自行绘制。如果使用照片生成纹理,直接将物体的三角面与照片中的一部分映射是有问题的,因照片本身也是一种投影结果,投影中会发生拉伸。因此,可以将照片再次投影到同一角度的几何体上,从而得到正常的纹理效果。

52 - MIT 6.837:Texture Mapping 纹理映射

如果使用自己绘制的纹理,则需要指定每一个三角面的纹理,如面数较多,纹理图片的数量也较多,不易管理。此时,可以将一些纹理拼成一张图片,并在模型中指定顶点与纹理图片坐标的对应关系。

52 1 - MIT 6.837:Texture Mapping 纹理映射
52 2 1024x714 - MIT 6.837:Texture Mapping 纹理映射

一种应用纹理颜色的方法是,将 Phong 模型中的漫反射系数替换为纹理图片中的采样值,从而将纹理与光照效果结合起来。

52 - MIT 6.837:Texture Mapping 纹理映射

特殊的纹理

程序化生成纹理

如果能够得到一个函数 $f(x,y,z)$,其输入为要渲染位置的坐标,而输出为颜色,这样的函数也可以看做是纹理。上面基于图片的纹理可以看做是函数值离散化的函数,而如果规定了连续的函数,则纹理可以做到无限大分辨率。

这种纹理通常与噪声算法结合,用于生成一些具有一定随机性同时有一定规律的纹理,如树干、瓷器、动物毛皮花纹等。

53 - MIT 6.837:Texture Mapping 纹理映射

法线贴图

实际的渲染中,我们经常遇到需要在较简单的几何体上实现表面细节的需求。除了常规的材质颜色外,还有光照阴影等效果,这可以通过修改表面的法线的来完成。

一种方法是 Gouraud 渲染,在计算顶点值时,它先计算顶点周围面的平均法向量,再计算颜色,最后在三角面上对顶点颜色进行插值,得到一种较平滑的颜色效果。

另一种方法是 Phong 法线插值,它的插值对象是法线本身,对于每一个渲染的像素插值其法线,再计算颜色值。

54 - MIT 6.837:Texture Mapping 纹理映射

还可以直接在纹理中指定法线方向,利用图片的 RGB 三个通道来表示世界空间中的三维方向向量坐标,直接用纹理中的向量来代替原本的法向量,这样的方法叫做法线贴图。

另一种与法线贴图类似的方法叫凹凸贴图,它指定顶点需要看起来凹凸的程度,通过在此贴图上计算梯度值来改变法向量,形成看起来凹凸的情况。但这种方法无法正确处理自遮挡产生的阴影,因此凹凸程度不宜设置过大。

55 - MIT 6.837:Texture Mapping 纹理映射

置换贴图

置换贴图是凹凸贴图的改进。为了解决凹凸贴图无法正确处理自遮挡的问题,置换贴图应用时将先移动几何体中点的位置,再将新的顶点坐标作为之后阶段渲染的输入。由于置换贴图需要在世界坐标系修改顶点位置,其与上面的方法的应用阶段不同,一种方法是在几何的曲面细分阶段中完成。

56 - MIT 6.837:Texture Mapping 纹理映射

环境贴图

在渲染包含反射项的物体时,反射光线的起点可看成一个新的相机。因此,我们可以预先根据反射光线得到周围环境的图像,再将其直接应用在物体的反射项中,物体较小时可以假设反射线从同一个点发出。

56 - MIT 6.837:Texture Mapping 纹理映射

光照贴图

全局光照的计算开销很大,而场景中的很多物体是静止的。光照贴图通过预先计算那些静止物体的光照强弱,暂时缓存这一部分的光照结果,只需要处理动态物体的光照并合并结果即可。

纹理的混叠

混叠(Aliasing)指的是采样导致频域上不同周期之间的信号叠在一起,导致采样结果发生畸变。

纹理图片的分辨率是有限的,每次获取颜色时要对纹理图片这一离散信号进行采样,如采样率太低则容易发生混叠现象。

57 1024x487 - MIT 6.837:Texture Mapping 纹理映射

对于纹理来说,一种减少混叠的方法是使用 mipmap。



发表回复

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据