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:
要实现凹凸的效果就必须改变每个Vertex的Normal,
而最常见的方程如下:
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来使简单的物体显示更复杂表面。而和Bump Mapping不一样的是,normal mapping是用了RGB三个pixel通道,可以看出对细节的体现,Normal mapping更胜一筹。而且Normal mapping更多的应用在于对细节的表现而不仅仅是一个凹凸表面的显示。
现在我发向的实现的方法有两种:1,通过一个复杂的模型(又叫参照模型)和一个工作模型(低精度模型)进行Render to Texture的操作,使用的工具可以是Autodesk的Maya和3Ds Max或者NVIDIA的Melody。具体的使用方法不赘,大家可以Google一下。
2,可以使用例如Sobel的边缘检测算法(Edge Detect Filter)来生成带RGB的Normal 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
待续....
浙公网安备 33010602011771号