Bump Map的基本原理很简单,就是使用纹理图像中的数据修改光照方程中的法线.
造成Bump Map变得复杂的原因,是实际应用中的纹理的具体数据表达以及它们如何修改法线值的方式.
1.3字节RGB法线图,以我的观点,法线图就是一个Bump Map(这里的法线它就不垂直于表面),用它们直接替换光照方程中的法线值.当然大多数人不这么想,起了个深奥的名词:dot3_bump_map,丫得不就一法线图吗.在Shader语言中用的通常是这种直接可寻纹理的数据,因为它最快.但在固定流水线中也可以实现这些,结果差不多等于实现了一遍光照方程,相当麻烦.根据法线图内法线的定义空间,可分模型空间和正切空间,这个概念也相当复杂,游戏编程精粹1里有专门论述,总之,很麻烦,最好写 Shader
2.Offset vector bump map,似乎是Blinn提出这种奇怪的修改方式,因为他老人家是泰斗,所以大部分文章讲述凹凸贴图时引用的都是这个标准方法,但实际应用中却有很多的变种,有时甚至面目全非.此中纹理图的每Texel存储的是2个带符号单字节数值(A8L8),经过/127,得到浮点数bu,bv.
设原某法线为N,先求N的2个分别延u,v方向的垂直标准向量Nu,Nv,分别乘以bu,bv,累加到N上,得到:
N' = N + Nu * bu + Nv * bv;
为了节省空间,在Shader中也使用这种方法,计算上比1慢.
3.使用高度图修改法线值,根据相邻行列间的高度差计算出2中偏移值.这种方法最节省空间,但最慢,通常用于在Shader中通过3次纹理查找完成.
从魔兽世界的流体数据上分析,它应该采用的是这种方式,节省数据量为主,即通过Shader实现(在BLS文件内),所以在不支持Pixel Shader的显卡机器上是没有水面凹凸,地面闪光效果的.
三种方法使用的Texel分别是3,2,1字节,但实际使用中会有其他附加的字节集成到Texel,如Specular color map,Specular exponent (shininess),Parallax bump mapping.
Bump Map是一个最能体现理论与实际之间差距的技术,它的概念建立在Phong逐象素光照模型基础之上.
Reference:
http://freespace.virgin.net/hugo.elias/graphics/x_polybm.htm
http://download.nvidia.com/developer/Papers/2004/Bump_Map_Compression/Bump_Map_Compression.pdf
http://www.codesampler.com/oglsrc/oglsrc_4.htm#ogl_dot3_bump_mapping
http://www.r3.nu/~cass/thesis/thesis/