1、         What`s Bump Mapping?

Bump Mapping通过改变几何体表面各点的法线,使本来是平的东西看起来有凹凸的效果,是一种欺骗眼睛的技术:)。

我们知道,如果几何体表面有高低不平的凹凸,那么表面上各点的法线方向就会不同, 那么当光照射到这些点上时,各点光照产生效果就不一样,那么我们最终看到的各点就是凹凸不平的。如果几何体表面是平的,但是各点的法线方向各不相同,当用光照模型进行光照计算后,我们看到最终渲染出来的图会是什么样呢?会看到高低不平的凹凸效果。

Bump Mapping把各象素法线相关的信息存于一张Texture中,各象素的法线就是通过从这张TextureSample得到的信息,进行一定的计算得到。根据Sample的方法和计算的方法不同,分为了Bump MappingNormal Mapping,Parallax Mapping,Parallax Occulision Mapping,Relief Mapping等等。

Bump Mapping这种思想最早是由图形学届大牛中的大牛Jim Blinn提出的,后来的Normal Mapping, Parallax Mapping,Parallax Occulision Mapping,Relief Mapping等等,均是基于同样的思想,只是考虑得越来越全面,产生的效果越来越好。

2、         Why Bump Mapping?

如果要在几何体表面表现出凹凸不平的细节,那么在建模的时候就会需要很多的三角面,如果用这样的模型去实时渲染,出来的效果是非常好,只是性能上很有可能无法忍受。Bump Mapping不需要增加额外的几何信息,就可以达到增强被渲染物体的表面细节的效果,可以大大地提高渲染速度,因此得到了广泛的应用。

3、         Bump Mapping

Jim Blinn在1978发表了一篇名为:“Simulation of Wrinkled Surfaces”,提出了Bump Mapping这个东东。Bump Mapping通过一张Height Map记录各象素点的高度信息,有了高度信息,就可以计算HeightMap中当前象素与周围象素的高度差,这个高度差就代表了各象素的坡度,用这个坡度信息去绕动法向量,得到最终法向量,用于光照计算。坡度越陡,绕动就越大。那么,根据HeighMap如何计算Normal呢?

设当前象素纹理坐标为(u,v),切线空间中切向量为T(对应纹理空间U方向),负法线为B(对应纹理空间V方向),Height(u,v)表示纹理坐标(u,v)处的高度值。   

du=1/HightmapWidth,dv = 1/Hightmap Height所有计算均是在切线空间,计算公式如下:

u_gradient = Height(u-du, v) - Height (u+du, v) U方向的坡度)

v_gradient = Height(u, v-dv) - Height (u, v+dv) (V方向的坡度)

New_Normal = Normal + (T * u_gradient) + (B * v_gradient)Normal是当前象素切线空间的Normal)。用shader片断如下:

float u_gradient = tex2D(HeightMap,texcoord+float2(-du,0) )-

                    tex2D(HeightMap,texcoord+float2(+du,0));

     float v_gradient = tex2D(HeightMap,texcoord+float2(-dv,0))-

                    tex2D(HeightMap,texcoord+float2(dv,0));

     float normal = normal + Tangent*u_gradient+Binormal*v_gradient;

 

4、         Normal Mapping

Normal Mapping也叫做Dot3 Bump Mapping,它也是Bump Mapping的一种,区别在于Normal Mapping技术直接把Normal存到一张NormalMap里面,从NormalMap里面采回来的值就是Normal,不需要像HeightMap那样再经过额外的计算。

NormalMap一般都是由HeightMap离线生成,建模工具(Max,Maya)一般都支持导出模型的NormalMap,一般都是由高模导出NormalMap,在渲染的时候用低模+高模导出的NormalMap,在PixelShader采样出Normal值,中运用某种光照模型,运行逐象素光照。

值得注意的是,NormalMap存的Normal是基于切线空间的,因此要进行光照计算时,需要把Normal,Light Direction,View direction统一到同一坐标空间中。一般的做法是在VS中把Light DirectionView Direction变换到Tangent Space,通过硬件Rasterrize后,在PS中便统一到切线空间,可以直接计算。Normal MapShader网上可以搜出一堆,这里就不贴啦。

5、         Parallax Mapping

当使用Normal Mapping技术时,并没有把视线方向考滤进去。在真实世界中,如果物体表面高低不平,当视线方向不同时,看到的效果也不相同。Parallax Mapping就是为了解决此问题而提出的。

Parallax Mapping首先在一篇名为“Detailed Shape Representation with Parallax Mapping”的文章中提出。它的基本思想如下图示(本图来自Parallax Mapping with Offset Limiting: A PerPixel Approximation of Uneven Surfaces)。在图示的视线方向,如果表面是真正的凹凸不平的,如real surfacer所示,那么能看到的是B点,因此用于采样法线的正确纹理坐是TB而不是TA

因此,我们需要对纹理坐标作偏移,为了满足实时渲染的要求,采用了取近似偏移的方法(如下图示),这种近似的算法已经可以达到比较好的效果。具体的offset计算可以参考:“Parallax Mapping with Offset Limiting: A PerPixel Approximation of Uneven Surface”,里面有详细的讲解。

 

6、         Parallax Occlusion Mapping

Parallax Occlusion Mapping是对Parallax Mapping的改进,DirectX SDK中有个Sample专门讲这个,相关细节可以参看此Sample. Parallax Occlusion Mapping中实现了Self Shadow,还计算了比较精确的offset,复杂度比Parallax Mapping大,但是实现效果更好。

 

7各种Mapping的比较。

 

 

高度图

法线图

随视点变化

自阴影

性能

Bump Mapping

需要

不需要

Normal Mapping

 

需要

Parallax Mapping

需要

需要

较快

Parallax Occlusion Mapping

需要

需要

 

posted on 2009-11-22 15:35  Just a Programer  阅读(5666)  评论(2编辑  收藏  举报