第九章 Normal Mapping and Displacement Mapping
本章主要讲述两种图形学技术,支持在不增加objects的poly primitive的情况下,在场景中增加更多的细节。第一种是normal mapping,通过创建一些“fake” geometry(虚设的多边形图元)模拟光照作用。第二种是displacement mapping,根据纹理数据moving vertices actually(与“fake”相对应,这里指真实的移动)来创建凹凸不平的表面。
Normal Mapping(法线贴图)
前面几章,已经讨论了specualr maps,environment maps以及transparency maps,这些texture maps都提供了附加的数据信息。Specular maps中的数据用于限制specular highlight,environment maps则包含了用于reflective surfaces的colors,transparency maps用于控制output-merge阶段的alpha blending。这些额外的信息由每一个pixel提供,比仅由每一个vertex提供,具有更高的精度。同样 ,一个normal map也是对每一个pixel都提供表面的法向量数量,该额外的数据可以应用于多种技术上。
Normal maps的其中一个应用是虚构一个凹凸表面的细节,比如石墙。可以使用足够的geometry来模拟这中凹凸不平的墙面,使用的vertices越多,得到的细节也越多。这样就可以在场景中更好的处理光照,远离光源的石块就会显示为较暗的区域。但是,增加geometry会导致计算成本也增大。相反,对于一个含有少量poly geometry的object(即使是一个flat plane),使用normal map方法,也可以模拟与大量增加geometry情况下同样的光照效果。这种应用就称为normal mapping。
Normal Maps
图9.1中显示了用于一面石墙的color map(左图)和normal map(右图)。相对于color map,normal map看起来有点奇怪。虽然可以把norml map显示出来,但是normal map中存储的是3D directions vectors(3维的方向向量)。对normal map进行采样时,从RGB通道中得到的结果表示方向向量的x,y,z分量。这些法向量可用于一些效果的计算,比如diffuse lighting。
图9.1 A color map (left) and normal map (right) for a stone wall. (Textures by Nick
Zuccarello, Florida Interactive Entertainment Academy.)
RGB texture的每一个channels都存储一个unsigned 8-bit值(unsigned char),该类型的数值范围为[0, 255]。但是一个规范化的方向向量,对应的xyz各个分量值范围是[-1, 1]。因此,法线向量存储到texture之前必须先转换到范围[0, 255],对texture进行采样的时候必须再转换到范围[-1, 1]。可以使用如下的公式,把浮点型向量从范围[-1, 1]转换到范围[0, 255]:
f(x) = (0.5x + 0.5) * 255 再使用下面的方程式变换回来:
实际工作中,一般会使用图像处理软件(比如Adobe Photoshop)把一个normal map编码成RGB texture格式。但是采样texture时需要在shader中手动计算,把数据从范围[0, 255]转换回[-1, 1]。在采样过程中已经执行了浮点除法(除以255)操作,所以得到的采样结果在范围[0, 1]之间。因此,只需要使用下面的方程函数把范围[0, 1]转换到范围[1, 1]:
f(x) = 2x 1 或者,也可以使用16位或32位浮点型数值作为normal maps的texture格式,这样可以产生更好的细节效果,但会牺牲一些性能。
Tangent Space(切空间)
一般使用每一个vertex的法线来计算diffuse,同样也可以使用每一个pixel的法线。但是法线必须与light处于同一个坐标空间。对于per-vertex法线,由object space提供。但是normal maps的法线值处于tangent space。
Tangent space(或者texture space)是一个相对于纹理的坐标系,由三个相互正交的向量确定:surface normal向量,tangent向量以及binormal向量。图9.2描述了这三个向量。
图9.2 An illustration of tangent space. (Texture by Nick Zuccarello, Florida Interactive Entertainment Academy.)
其中normal向量,N,是一个vertex的表面法向量。Tangent向量,T,与表面的法线垂直,与指向texture的u轴方向。Binormal向量,B,则指向texture的v轴方向。
可以使用这三个向量创建一个TBN(tangent, binormal, normal)变换矩阵,如下所示:
可以使用这个矩阵把向量由tangent space变换到object space中。但是,由于light vector通常是在world space中,因此需要把从normal map中采样得到的noraml从tangent space变换到world space。或者换一种方式,直接使用已经处于world space中的向量创建TBN矩阵。