问答 3Dmax 材质贴图

法线贴图

cmi9
回答3 浏览5,602
NormalMapping 法线贴图 转载了一篇法线贴图   NormalMapping在游戏领域中的实践是一个非常值得记住的时期--Geforce3上市,GPU概念出现,硬件可编程流水线的出现(Shaders),NormalMapping是一种凹凸贴图技术,它的另外一个名字叫做Dot3bump mapping。   用于实现它的控制纹理是一张叫做NormalMap的纹理,也是目前大家在讨论如何之作的那种。我们先说说这张叫做NormalMap的图。这张图中存储的东西是每个原始表面法线的迭代,说起来有点复杂,但是不难理解。举例说我们的说面,一般在游戏的3D模型上,表面法线就像是一根站立于桌面的钢笔,垂直向上。而NormalMap中存储的东西就是我们这支表示表面法线方向的钢笔所“应该”指向的方向--比如说朝左边倾斜15度。   NormalMap有两种主要形式,一种叫做世界空间的NormalMap,一种叫做切空间的NormalMap。第一种在游戏中没有实用价值,我们说第二种,也就是大家最常见的一种。   那么,为什么我们看到的NormalMap会有这么奇怪的颜色呢?其实NormalMap和BumpMap一样,即它显示出来的颜色和它所起的作用是没有直接联系的。大家一定对空间坐标的概念非常熟悉了。在NormalMap的定义中,有一个事先的约定,这个约定就是--原本表面的垂直方向,我们称为Z轴;而表面的UV坐标两个方向,分别对应X轴和Y轴。(确切的说,应该是称作切线和负法线,但是这两个东西和大家熟悉的UV坐标刚好重叠,所以就用大家更习惯的说法了)然后我们知道如果我们在XYZ轴上各取一个点,这个点的取值位置在-1到1之间,那么我们就可以得到一个指向任何方向的法线方向(不用多解释,大家知道法线是一个向量,向量有方向和长度两个概念,但是对法线来说,长度是不需要的)。但是,请大家注意,我们在描述色彩的时候,RGB三个通道的取值范围都是从零开始的。可是当我们尝试把一个任意的法线保存在一张纹理中的时候,会面临取负值的问题。因此我们要把法线做压缩。方法很简单,把XYZ每个轴上的法线投影长度进行N+1/2的运算。这样就把所有的法线压缩到了0和1的范围里。然后我们把XYZ的方向分别存储在RGB三个通道中。似乎我们还没有说到关于为什么NormalMap会是蓝兮兮的原因是吧。那么现在就是公布结果的时候了!首先,我们知道如果在一个物体表面,法线垂直向上,那么它的 XYZ坐标是多少?是0,0,1对不对?然后我们把这个数字按照我们前面所说的压缩方法进行压缩,每个数字加1然后再除以2,那么我们得到的是 0.5,0.5,1对不对?好我们把它代入到RGB中,那么我们会得到128,128,255对不对?好了,试试看在调色板里的颜色吧!   P.S.现在FXCarl和你猜个谜,看看FXCarl说的对不对。现在我们在NormalMap上看见一个颜色,这个颜色是219,128,219。那么这个表面的法线方向是垂直向右偏45度。大家用MAX做一个NormalMap看看FXCarl说的对不对?   如果你还没有理解NormalMap的意思,或者说你有兴趣再深入了解一些,那么FXCarl再和你说的深入一些。不知道大家对于切空间的理解是什么?我们来个实验,找三支笔。然后其中两只笔在桌面放成互相成90度,笔尾接笔尾。最后我们把第三支笔,笔尖向上,笔尾和那两只桌面上的笔的笔尾叠在一个点上。注意看我们的三支笔!这三支笔就是这张桌面上这个点的切空间坐标了!大家一定想到了原来我们的NormalMap中存储的表面法线方向原来就是一个切空间向量啊,恩没错,就是切空间向量。但是似乎看起来切空间没什么作用是不是?呵呵,我们不妨把桌面换成一个篮球。记住,保持三支笔的互相关系,然后用三支笔并在一起的笔尾去接触篮球的表面。呵呵,发现了没有?切空间的优势在于,在任意表面上,切空间中的坐标都是有效的!也就是说始用切空间中的数据就可以做到和 3D模型的复杂度无关!你可以用在任意的表面,甚至这个表面一直在动也不会影响到NormalMap发挥作用,你说这个切空间是不是很有用
呢?   让我们回到开头,大家就会发现,如果使用世界空间的NormalMap会有什么样的结果呢?嘿嘿那样会造成一个很尴尬的结果,比如说我们做了一个人物身上的 NormalMap,可是我们的场景中有两个一样的人物,但是他们的姿势和面对的角度都不一样。那么……My God ~肯定有一个人物的NormalMap是没法适用的!而用切空间的NormalMap就没有问题了。恩,不过这个大家可以放心,MAX或者Maya做出来的NormalMap都是切空间的NormalMap,证明的方法很简单……看看这张贴图是不是主要由蓝色构成的……
OK,下面是重头戏,告诉大家NormalMap是如何发生作用的。
使用NormalMap的先决条件--逐像素着色。先来说一下传统着色,传统游戏使用的是一个Phong光照模型的简化版,甚至有游戏使用Ground模型。这两种算法的方式都是只对物体3D模型的顶点计算光照,而3D表面上的大面积区域则使用差值填充。逐像素着色是到了Shaders出现之后才有的,因此NormalMapping也是一个Shaders必须的算法。计算一个物体表面漫反射光照的公式是很简单的NdotL--什么是NdotL,就是物体表面的法线和光照方向的点积。点积是一个线性代数的问题,美术朋友们可以不用深究,写成程序也很容易:Diffuse = saturate(Mul(Normal,Light));。想要简单的理解就是--光线的方向矢量在法线矢量上的投影,然后这个投影的结果变成黑白中间的一个值。我们同样举个简单的例子,用两支笔放在桌面上,然后一支笔不动,令一支笔笔尾和第一支笔的笔尾相连,不动,然后以共同的笔尾做为圆心,移动笔。这时如果我们从一支笔尖往另外一支笔的笔杆上垂直拉一条线(一条垂线)就会看到这时移动后的一支笔在原本的笔杆所投影的长度(就是一支笔的笔尖连垂线到另一支笔的笔杆上的位置,这个位置沿着笔杆到共同笔尾的长度)会越来越短,当两支笔垂直的时候,投影的结果就是零--没有光照贡献了。这个容易理解,当光线的方向和一个表面绝对平行的时候,这个表面就会再也接受不到光线了。现在我们引入NormalMap。这时我们的光照计算和以往有点不同,我们把表面的法线用NormalMap中存储的法线来替代。这样当我们在计算表面光照情况的时候,就会因为法线不断的变化而产生比原来丰富的多的明暗变化。 至于为什么会感觉出凹凸来这个就是人的眼睛自己骗自己了……其实那里本没有凹凸的,但是我们人眼睛太多管闲事了。就像Windows的按钮哪个纯平面的东西我们还以为是凸出来的呢。
法线贴图是凸凹贴图(Bump mapping)的一种常见应用,简单说就是在不增加模型多边形数量的前提下,通过渲染暗部和亮部的不同颜色深度,来为原来的贴图和模型增加视觉细节和真实效果。简单原理是在普通的贴图的基础上,再另外提供一张对应原来贴图的,可以表示渲染浓淡的贴图。通过将这张附加的表示表面凸凹的贴图的因素于实际的原贴图进行运算后,可以得到新的细节更加丰富富有立体感的渲染效果
关于法线贴图的效果图,可以对比看看下面。模型面数为500,左侧只使用了简单的Diffuse着色,右侧使用了法线贴图。比较两张图片不难发现,使用了法线贴图的石头在暗部和亮部都有着更好的表现。整体来说,凸凹感比Diffuse的结果增强许多,石头看起来更真实也更具有质感
大多数法线图一般都和下面的图类似,是一张以蓝紫色为主的图。这张法线图其实是一张RGB贴图,其中红,绿,蓝三个通道分别表示由高度图转换而来的该点的法线指向:Nx、Ny、Nz。在其中绝大部分点的法线都指向z方向,因此图更偏向于蓝色。在shader进行处理时,我们将光照与该点的法线值进行点积后即可得到在该光线下应有的明暗特性,再将其应用到原图上,即可反应在一定光照环境下物体的凹凸关系了
NormalMap 看来可以增加细节,但是它的缺点也很明显。不过在说缺点之前,要提前说一句--NormalMap带来的优势是远远大于它的缺点的。因此仍然是个极好的东西,不要对它有偏见,特别是在我们后面介绍的更牛的技术前面,千万不要。最大的也是最明显的缺点应该就是它的视角问题。因为NormalMap只是改变的表面上的光照结果,并没有改变表面上的形状。因此,表面上看来,似乎只要是不接近水平,NormalMap就不会有视角问题。其实不然,NormalMap因为不能实现自身内部的遮挡,因此不能表现平面上凹凸起伏比较大的场合。比如说我们一个桌面上突出一块,然后在突出的这块东西边上放一支牙签。如果用NormalMap表现,会发现。根据经验,这个凸起会很轻易的挡住我们的视线,让我们看不见那支牙签。可是NormalMap却不会这么做。因此我们一直能看见障碍物背后的东西,这一点是个问题--也就是说只有在垂直于平面的时候NormalMap才会发挥最好的作用。这样一来,NormalMap只能用在大家对遮挡关系不敏感的场合,比如场景等,不是不能用于人物,而是用NormalMap的人物不太经得起特写,放大了,角度刁钻了都容易穿帮
虽然NormalMap有个不能平视的巨大问题,但是依然是好处远大于小障碍,因此还是非常值得推广的。后面的几种新兴算法其实都是由NormalMapping发展起来的,因此做为基础的东西,也还是最有理解价值的
P.S. 关于NormalMap的一点秘籍。注意理解……NormalMap其实并不是从低模的表面凸出高模的细节的,而是把高模中比最高点的位置低的地方凹进去的!因此低模要比高模大一点点才会很准。大家可以想像成我们是用一个比高模稍微大一点点尺寸的低模石膏模型来把高模雕刻出来的
P.S.2.关于NormalMap的做法,其实早期发明NormalMap的时候还没有MAX这种这么方便生成NormalMap的方法,NormalMap都是从 BumpMap计算得到的,因此其实通过很简单的算法就可以从BumpMap算出NormalMap的,甚至可以On The Fly(就是让游戏引擎直接读BumpMap然后转换成NormalMap)。因此对于一些建起模来效率很低,但是又能明显增加表面细节的东西,例如水泥表面的颗粒,用画Bump的方式来做是个更好的主意,然后交给技术美工去搞定好了--当然你会用Z-Bursh那就当我什么都没说了,呵呵。说来FXCarl估计MAX生成法线图的方式也是比较高低模上每个点的高度偏移,然后生成每个UV图素上的高度差来得到一个BumpMap,然后再从 BumpMap变成NormalMap。

105046y3559gtxyacbff6z.jpg
105047yoffzp4k2lo1lskn.jpg
105047j65edlnk66grl5al.jpg
我来帮他解答
大神,别默默的看啦,快登录帮我点评一下吧!
已有3条回答
 
我要提问
全部 课程推荐
主讲:水镜
73人在学
主讲:纯粹设计-罗肖雯
1455人在学
主讲:纯粹设计-黄恺
420人在学
学习进阶图
相似问题
1回答
5回答
1回答
6回答
签到
客服

已有943,949设计师加入了扮家家

约可免费渲染10张图 img 5秒注册领取
img