The compare between different mapping

要了解类似事物的方法最好就是对比,通过对比我们可以记住相同也会留意差异。
最近在学习HLSL,自然Mapping也少不了,google了一下,现在的mapping大概分五种:
1,Bump mapping(凹凸贴图)
2,Normal mapping (法线贴图)
3,Displacement mapping (位移贴图)
4,Relief mapping
5,Parallax mapping

详细介绍

1, Bump mapping

这里的Bump mapping是狭义的Bump mapping,并不包含Normal mapping

又叫Height Map。主要通过灰度(RBG相同)pixel值(0-255)代表对应Vertex的高度,所以叫着张贴图为Height Map。举个简单的例子:

Earth Texture map:


Earth Height Map:

要实现凹凸的效果就必须改变每个VertexNormal

而最常见的方程如下:

x_gradient = pixel(x-1, y) - pixel(x+1, y)
y_gradient = pixel(x, y-1) - pixel(x, y+1)
New_Normal = Normal + (U * x_gradient) + (V * y_gradient)
Shader的实现:
 (之后补上,;))


 
 

2, Normal mapping

通过改变物体表面的Normal来使简单的物体显示更复杂表面。而和Bump Mapping不一样的是,normal mapping是用了RGB三个pixel通道,可以看出对细节的体现,Normal mapping更胜一筹。而且Normal mapping更多的应用在于对细节的表现而不仅仅是一个凹凸表面的显示。

现在我发向的实现的方法有两种:1,通过一个复杂的模型(又叫参照模型)和一个工作模型(低精度模型)进行Render to Texture的操作,使用的工具可以是AutodeskMaya3Ds Max或者NVIDIAMelody。具体的使用方法不赘,大家可以Google一下。

2,可以使用例如Sobel的边缘检测算法(Edge Detect Filter)来生成带RGBNormal Map

1,Rough soccer and High resolution soccer



2,
Generated normal map


3,
Final Result

 

Shader例子:

 (之后补上,;))

 



3, Displacement mapping

Displacement mapping和normal,bump,parallax不一样,它是并不是通过贴图来达到真实的视觉效果的,而是根据Displacement map对Vertex进行Translate,这样会产生大量的Vertex,但这样可以容易做到自身遮挡,自身投影和获得精确的外轮廓线(用于Stencil Shadow Volume)。
问题是由于大量的Geometry的增加,整个渲染性能会大幅度下降,个人认为Displacement并不适合在Realtime API(OpenGL和DirectX)中实现,即使使用VertexShader,其性能还是比较低。

计算公式:

float4 pn; //new position
float4 po; //old position
float4 normal; //read from the normal map
float4 distance; //read from the displacement map
pn = po + normal * distance;
问题是,仅仅用这个简单的公式并不能得到满意的效果,你需要对Displace的表面进行适当的Subdivide来增加vertex,不然Displace出来的精度会非常低。

Wikipedia的例子:



4, Parallax mapping(翻译ShaderX3中关于Parallax Mapping部分)

   纵使Bump mapping可以使平坦的表面增加不少细节,但效果依然不尽人意。而造成这样失真的原因是视线的偏差,参考下图:

Figure2.1.3中 Pixel Ta,Tb分别和Vertex A,B对应。由于Eye Vector和Ta,B相交,所以实际进入眼中的Pixel是Ta但高度却是B。
所以造成视差失真,而修正的方法是计算出AB点的UV纹理的offset,重新令AB分别与Ta,Tb对应。

数学公式:



过A作平行polygon平面的平行线和Eye vector相交,交点和A之间的距离叫做视差距离,也就是我们需要平移的Texture coordinate的距离。由于对每一个Pixel的调整运算都在法线空间上计算(即normal,tagent和binoraml组成的线形空间),我们需要把世界坐标空间和法线空间进行做换再作运算。

由于eye vector在线形空间中可分解成xy,z的向量, Vxy 和 Vz

在Remapped的Heightmap中对应的高度等于:hsb = (h.s) + b  ( h is the height, s stands for the scale, b is bais)

对应新的Texture坐标为:Tnew = Ta + Vxy.Hsb / Vz

为了避免Vz接近0时Tnew增加的太大的问题,可以令Vz = 1

其实,更容易理解的变形公式是:(Tnew - Ta)/ Vxy = Hsb / Vz 




 待续....



posted on 2007-04-10 22:49  SigEric  阅读(1117)  评论(3)    收藏  举报

导航