凹凸映射(bump mapping)
凹凸映射的目的是使用一张纹理来修改模型表面的法线,以便为模型提供更多的细节。这种方式不会真的改变模型的顶点位置,只是让模型看起来凹凸不平。
一般有两种方法进行凹凸映射:一种是使用一张高度纹理(height map),来模拟表面位移(displacement),然后得到一个修改后的法线值,这种方法也被称为高度映射(height mapping)。另一种是使用一张法线纹理(normal map)来直接存储表面法线,这种方法又被称为法线映射(normal mapping)。
法线纹理
1、法线的映射
法线纹理存储的就是表面的法线方向,法线一般都是[-1,1]之间,而颜色都是[0,1]之间,因此需要做一个映射,让法线在[0,1]之间:
法线映射
当从片元着色器中采样得到颜色之后,需要进行一次反映射,以得到正确的法线:
反映射
2、模型空间的法线纹理(object-space normal map)
对于模型顶点自带的法线,它们是定义在模型空间中的,将修改后的模型空间中的表面法线存储在一张纹理中,这种纹理被称为模型空间的法线纹理。
模型空间的法线纹理
可以看到模型空间的法线纹理色彩各式各样,这是因为顶点的法线是各向异性,都处于模型空间,各个方向的都有,经过映射之后就是各种各样的颜色。
3、切线空间的法线纹理(tangent-space mapping)
在实际的制作过程中,往往会使用切线空间的法线纹理,即用模型顶点的切线空间来存储法线。对于模型的每个顶点,它都有一个属于自己的切线空间,这个切线空间的原点就是顶点本身,z轴是法线方向,x轴是切线方向,y轴是副切线(binormal),由法线和切线叉乘得到,这种纹理就被称为切线空间的法线纹理。
切线空间
切线空间的法线纹理
可以看到切线空间的纹理颜色大都是偏蓝色,这是因为在切线空间下,所有的法线都是(0,0,1),经过映射之后变为(0.5,0.5,1)淡蓝色 。
模型空间的法线纹理优点:
(1)实现简单,直观。因为原模型的顶点法线都直接存储在一张图片中,在使用时直接采样即可。生成也简单,而如果要生成切线空间下的法线纹理,由于模型的切线一般和UV方向相同,因此如果想要得到效果比较好的法线映射就要要求纹理映射也是连续的。
(2)在纹理坐标的缝合处和尖锐的边角部分,可见的突变(缝隙)较少,可以提供平滑边界效果。这是因为模型空间下的法线纹理存储的是同一坐标系下的法线信息,因此在边界通过插值得到的法线可以平滑变换。而在切线空间下法线纹理中的法线信息是依靠纹理坐标的方向得到的结果,可能会在边缘或是尖锐处在成更多可见的缝合迹象。
切线空间的法线纹理优点:
(1)自由度很高,模型空间的法线纹理记录的都是绝对法线信息,只能用于与之对应的模型上,放在其他模型就是错误的。而切线空间的法线纹理记录的是相对法线,这样把它用在不同的模型上也可以得到差不多的结果。
(2)可以进行UV动画,我们可以移动UV坐标让纹理“动起来”形成凹凸移动的效果,而模型空间的法线纹理,动起来就是错误的结果。在水和火山熔岩这种类型的物体上经常用到UV动画。
(3)可以重用法线纹理。把同一张法线纹理用于同一个物体不同的面。
(4)可压缩,由于切线空间的法线纹理中法线的Z方向总是正方向,只要存储XY,就能算出Z方向。而模型空间的法线纹理需要存储3个方向的值。