各种纹理贴图技术

凹凸贴图(bump mapping)概念


无论是程序员还是美工人员,几乎每个游戏开发者都知道一些3D图形学的知识,因此每个人都或多或少了解 一点bump mappingBump mapping是在像素级别扰动物体表面法向量的一种光照技术,它一般采用纹理映射作为输入表示扰动的大小。在光照 计算时考虑到扰动的法向量,不需要增加额外的几何信息就可以增强被渲染物体的表面细节



[原文链接
1. 浮雕贴图(Emboss bump mapping)
这种处理方式不用 lighting models,而直接使用贴图明暗度来产生凸凹效果.
玩过photoshop的都知道可以使用alpha通道对RGB图像进 行混合,这种透明度直接
混合出来的明暗看起来象平的,为了使用图像随灯光看起来有立体感的明暗度,
一种简单的办法就是使用 Emboss bumpmapping.

实现如下:
就是将原alpha通道值一分为二,一个是原alpha通道的亮度减 半, 另一个是反转alpha
通道并将uv偏移灯光一点点,最后将两个alpha通道加起来再与原RGB图像进行混合,
这样看起来明 暗度偏离灯光使看起来立体感较强.
另外这样的处理方式还可混合顶点色.

优缺点:
CPU使用较多,计算uv偏移 值,可以直接用固定管道实现. 完全用贴图渲染,只实现了diffuse.


参考:
dx8 sdk中的emboss源码


2. 環境凹凸貼圖(EMBM: Environment-mapped bump mapping)
这种贴图保存了du和dv两个偏差值,最常见的是用在水的反射渲染中对反射图进行干挠.
使水面看起来产生涟漪的效果. 就是说dv和dv将会加到顶点对应反射图的uv中. dx中可
以设置bump矩阵对它调整得以实时变化.

 优缺点:
CPU占用少,可以使用固定管道实现.效率问题主要是在反射图(也就是Environment map)的
渲染占用上,当然也可以采用假的静态反射图.

参见:
dx8 sdk中的BumpWaves源码

以及我的文章:
使用固定管道渲染反射和折射:
http://blog.csdn.net/flipcode/archive/2008/03/03/2143788.aspx  

  dx9反射图计算参见:
http://flipcode.spaces.live.com/blog/cns%218E578E7901A88369%21363.entry

    
3. 法线图(Normal mapping)
这种是比较流行的实时凹凸贴图方法,原理很简单,就是多边形上每一象素点如果用不同的
法向量进行光照模型运算,那么就可得到不同的凹凸明暗度. 

实现方法:
就是将多边形的法线保存在高位图的RGB中.然后程序读取来在ps中取出RGB作为法线
进行光照模型的计算即可.

法线图中的法线值一般是以贴图空间(也就是切线空间,U为tangent向量,V为binormal向量, n为normal向量)
来存放的,所以灯光到顶点的向量要先转到切线空间后再与法线进行光照运算即可.

优缺点:
CPU使用不多,用点光源效果较好, 需要硬件支持DotProduct, 光照实时变化.

参见:
dx8 sdk中的DotProduct3源码,使用固定管道来实现:
// Store the light vector, so it can be referenced in D3DTA_TFACTOR
DWORD dwFactor = VectortoRGBA( &m_vLight, 0.0f ); 
m_pd3dDevice->SetRenderState( D3DRS_TEXTUREFACTOR, dwFactor );

  // Modulate the texture (the normal map) with the light vector (stored
// above in the texture factor)
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_DOTPRODUCT3 );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );

  或者这里也有DotProduct3同上dx8的例子:
http://www.two-kings.de/tutorials/dxgraphics/dxgraphics16.html

切线空间的计算参见:
计算切线空间:
http://blog.csdn.net/flipcode/archive/2008/03/03/2143483.aspx 

  提示, NormalMap制作:
法线图制作的几种方法: 
1. 直接使用高位图(Height map), 再通过D3DXComputeNormalMap函数得到.
2. 使用PhotoShop加载高位图,然后再用NV的photoshop插件进行生成Normal Map图像, 详细
作法可参 见<怎样用PhotoShop创建Bump Map图像>:
http://phoenixzz.blogbus.com/logs/1597471.html
3. 通过高模表面采样得到(polybump),可以使用ATI的3DS Max插 件,参见:
<Normal Mapping Primer>by Gary Pate. http://www.ionization.net/tutsnorm2.htm

4. 置换贴图(Displacement mapping)
这种需要硬件支持,在vs中真正改变几何顶点的位置, 由此引起的几何细分需要处
理大量的多边形,一般不能实时应用到.

5. 自阴影(Self-shadowing bump maps)
法线图可以实现阴影动态变化,但实现不了自阴影,也就是说如果有凸块 遮挡了光线,它不能实现遮挡产生的阴影.

一种叫horizon map的技术可以实现自阴影.
这是一种从特定点向各方向记录可见水平高度(the elevation of the visible horizon)的纹理。
光源如果低于这个水平高度,就不会照亮对应的特定点。这可在切线空间对光源向量执行这种可见性检查,
就可以产生自阴影bump maps.

优缺点:
实现自阴影,占用过多纹理内存,计算量很大。

6. 视差映射(Parallax mapping)
Parallax mapping也被称为"offset mapping"或"virtual displacement mapping"
这种处理是将纹理的坐标向眼睛方向偏移一定的距离来实现立体视角感.

从渲染点出发到眼睛的斜射线上找到表面垂直距离等于渲染点对应的Parallax mapping高度值时,
那么眼睛斜射线上到表面垂直相交的那点就是要偏移到的地方.(可参见前面所附链接中的图示)

优缺点: 
视差映射跟EMBM一样也是调整贴图uv坐标的,不过它有两个约束条件:一是对应视差映射中的高度值
二是到眼睛的射线. 从而随视角变化而变化,效果效率都很好. 而EMBM一般用正/余弦波来改变du/dv
后再去影响贴图坐标从而达到水的涟渏效果(这在前面有说)

7. Z-correct bump mapping
这种是在ps中根据视线方向偏移Z值,使物体相交处会随着表面的凹凸情况发生变化而不仅仅表示为一条直线。

优缺点:
物体相交处通过z偏移表现凹凸变化,在pixel shader中修改Z值会禁止图形硬件的早期深度测试优化.

注意: 
本文参考了以下文章:
An Overview Of Bump Mapping Techniques
英文版:
http://www.delphi3d.net/articles/viewarticle.php?article=bumpmapping.htm
翻译版:
http://phoenixzz.blogbus.com/logs/1332892.html
如 果看不懂就看原文吧 


另外还可参考:
http://snowwin.bokee.com/4148760.html

你可能感兴趣的:(技术)