UnityShader 浮雕凹凸贴图BumpMap与法线贴图NormalMap的原理及其区别

效果图:

     

                         浮雕凹凸贴图效果 ====》 高度图

    

                    法线贴图凹凸效果    ====>  法线贴图

简介

法线贴图是目前游戏开发中最常见的贴图之一。我们知道,一般情况下,模型面数越高,可以表现的细节越多,效果也越好。但是,由于面数多了,顶点数多了,计算量也就上去了,效果永远是和性能成反比的。怎么样用尽可能简单模型来做出更好的效果就成了大家研究的方向之一。纹理映射是最早的一种,通过纹理直接贴在模型表面,提供了一些细节,但是普通的纹理贴图只是影响最终像素阶段输出的颜色值,不能让模型有一些凹凸之类的细节表现。而法线贴图就是为了解决上面的问题,给我们提供了通过低面数模型来模拟高面数模型的效果,增加细节层次感,效果与高模相差不多,但是大大降低了模型的面数。

凹凸映射和纹理映射非常相似。然而,纹理映射是把颜色加到多边形上,而凹凸映射是把粗糙信息加到多边形上。这在多边形的视觉上会产生很吸引人的效果。我们只需要添加一点信息到本来需要使用大量多边形的物体上。需要注意的是这个物体是平的,但是它看起来却是粗糙不平的。“凹凸映射和纹理映射有什么不同?”它们的不同之处在于——凹凸映射是一种负责光方向的纹理映射。
 

法线贴图原理

要模拟一个圆球,要想越平滑,就需要更多的面数,否则会很容易地发现面和面之间的明显边界。最早时的GPU是没有fragement编程能力的,也就是说在这种情况下,在计算时需要逐顶点计算光照,然后每个像素的颜色在各个顶点的颜色之间插值,也就是高洛德着色,这种情况下,面数决定一切效果,没有什么好办法。而当像素着色器出现之后,我们可以逐像素来计算光照效果,这时候,在计算每个像素的光照时,会计算这个像素所在的面的法向量,而这个面的法向量也是由这个面周围的顶点法线(也就是我们之前vertex shader中出现的normal)插值得来的,当然,如果面数很低,那么效果也好不到哪里去。但是,逐像素计算光照时,我们每一个像素都会根据该点的法向量来计算最终该点的光照结果,那么,我们如果能够改变这个法线的方向,不是就可以改变这个点的光照结果了呢!那么,把纹理采样的思想用在这里,我们直接用一张图来存储法线(或者法线偏移值,见下文),逐像素计算时,在采样diffuse贴图的时候,再采样一张法线的贴图,就可以修改法线了,进而修改最终的效果。

 

为什么法线贴图会让我们感觉有凹凸感呢?看下面一张图,在现实世界中,你要相信你的眼睛,眼见为实还有点道理,在计算机世界中,一切以忽悠你为目的。在平面的情况下,我们感觉物体是凹陷还是凸起,很大一部分取决于这个面的亮度,像下面这张图,有了这种亮度的对比,我们就很容易感觉这个按钮有周围的一圈凸起。

 

如果还是没理解,再看一套图片,同样一张图片,旋转180度后的结果完全相反。

从远处看,你判断这个物体是粗糙的的唯一证据是在它表面上下的亮度有改变。你的大脑能够获得这些亮暗不一的图案信息,然后判断出它们是表面中有凹凸的部位。左边的一幅图就说明了这一点。你可以发现它是一个浮雕式的表面。一些矩型和字母被印入表面,但是它们摸上去就像是一个隐藏的监控器的玻璃。如果这个图像是在适当的位置上,那么它除了改变亮度,不需要再做任何其他的工作。 
那么你也许会问:我是怎么知道哪些点要亮,哪些点要暗呢?这不难。绝大多数人生活在这样一种环境下——这个环境的大多数光源来自上方(译者注:比如白天主要的光来自太阳,夜晚主要的光来自天花板上的日光灯)。所以向上倾的地方就会更亮,而向下倾的地方就会更暗。所以这种现象使你的眼睛看到一个物体上亮暗区域时,可以判断出它的凹凸情况。相对亮的块被判断是面向上的,相对暗的块被判断是面向下的。所以我只需要给物体上的线条简单得上色。 
如果你想要更多的证据,这里还有一幅几乎相同的图,不同于前的是它旋转了180度。所以它是前一幅图倒转的图像。那些先前看起来是凹进去的区域,现在看起来是凸出来的了。

这个时候你的大脑并没有被完全欺骗,你脑中存留的视觉印象使你仍然有能力判断出这是前一幅图,只是它的光源变了,是从下往上照的,你的大脑可能强迫性地判断出它是第一幅图。事实上,你只要始终盯着它,并且努力地想像着光是从右下方向照射的,你就会理解它是凹的(译者注:因为日常生活的习惯,你会很容易把这些图形判断成凸出的图形,但是因为有了上一幅对照图的印象,你可能才会特别注意到这些图块其实还是凹入的,只是判断方法不符合我们日常生活习惯,因为这时大多数光不是从上方照射,而是从下往上照射)。

既然一个面的光照条件(亮度)的改变,就可以让我们感觉这个面有凹凸感,那么上面说的,通过改变法线来改变面上某点的光照条件,进而忽悠观察者,让他们感觉这个面有凹凸感的方法就行得通了。

 

假如下面是我们的低面数模型,上面是我们的高面数模型,上面的模型在计算光照时,由于面数多,每个面的法线方向不同,所以各个面的光照计算结果都不同,就有凹凸的感觉了,而下面的低模,只有一个面,整个面的光照条件都是一致的,就没有凹凸的感觉了。我们如果把上面的高模的法线信息保存下来,类似纹理贴图那样,存在一张图里,再给低模使用,低模就可以有跟高模一样的法线,进而在计算光照时达到和高模类似的效果,这也就是常说的烘法线的原理。

凹凸映射的目的是使用一张纹理来修改模型表面的法线,以便为模型提供更多的细节。这种万法不会真的改变模型的顶点位置,
只是让模型看起来好像是“凹凸不平”的,但可以从模型的轮廓处看出“破绽”。
有两种主要的方法可以用来进行凹凸映射: 一种方法是使用一张高度纹理(height map)来模拟表面位移( displacement ), 然后得到一个修改后的法线值,这种方法也被称为高度映射(height mapping);另一种方法则是使用一张法线纹理(normal map )来直接存储表面法线,这种方法又被称为法线映射( normal mapping )。

凹凸贴图(Bump Map)

既然说了要研究法线贴图,所以肯定要从老一辈的开始,首先来看一下凹凸贴图(Bump Map)。Bump Map是最早的法线贴图实现方式,这也是制作上最容易的一种模式,可以直接通过一张灰度图,默认为黑色,越凸起的地方颜色越亮,这种就是可以直接在PhotoShop中画的法线,但是这种法线贴图的原理理解起来比较难,我只说一下我的理解,然后附上unity中的shader实现。这种技术现在貌似已经过时了,但是思想还是流传下来了,而且这种画灰度图,或者通过灰度图生成法线贴图的方式现在仍然在使用,Unity就支持这种直接通过灰度图生成法线贴图。

BumpMap一种是Emboss Bump Map(浮雕凹凸贴图),它使用的是Height map,原理是在原始图像的基础上,对高度场图像进行复制、轻微平移、差操作。但它存在很多严重的局限性,它只能用于漫反射表面,对于镜面高光来说是不可能的。当光源直接照射在物体表面时,如果没有偏移,那么物体表面就不会出现任何凹凸现象。

工作原理:

凹凸映射是补色渲染技术(Phong Shading Technique)的一项扩展,只是在补色渲染里,多边形表面上的法线将被改变这个向量用来计算该点的亮度。当你加入了凹凸映射,法线向量会略微地改变,怎么改变则基于凹凸图。改变法线向量就会改变多边形的点的颜色值。就这么简单。 
现在,有几种方法来达到这个目的(译者注:这个目的指改变法线向量)。我并没有实际编写补色渲染和凹凸映射的程序,但是我在这里将介绍一种我喜欢的方法来实现! 
现在我们需要将凹凸图中的高度信息转换成补色渲染用到的法线的调节信息。这个做起来不难,但是解释起来比较费劲。

好的,我们现在将凹凸位图的信息转换成一些小向量——一个向量对应于一个点。请看上面一副放大的凹凸图。相对亮的点比相对暗的点更为凸出。看清楚了吗?现在计算每个点的向量,这些向量表征了每个点的倾斜情况,请看下图的描绘。图中红色小圆点表示向量是向下的:

有很多计算向量的方法,不同

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值