Shader小常识之——模型法线和法线纹理是如何工作的

  • 写在前边:写这篇文章是因为我有一个爱学爱问的小学弟,他经常会问一些这样那样的问题,仔细想想,也许大多数人,包括我自己在内,在刚接触一门新的知识的时候,也会因不了解而产生各种“奇怪的”问题,也许过后觉得很是简单,但是隔行如隔山,不了解的时候感觉高大上的东西,其实并没有那么神秘,所以在这里纪录下来,帮助更多“后来者”,好让其早日“居上”。

  • 问题:为什么我们加了法线纹理后,模型就变得凹凸有致了,法线纹理和模型本身的法线信息是怎样一个关系?

    我们都知道,游戏中的模型都是由点连线,线练面构成的,对于一个平面来说,它的法线始终垂直于整个面的,如图所示,法线朝上。OK,这里我们做一个假设,假设太阳光从平面上方照射下来,那么此时这个面应该被照亮,接下来改变光线角度,让它从下方照射上来,结果整个平面就变暗。从这里我们可以看出,物体的法线跟光源之间的位置关系会直接影响到物体的明暗
    模型法线控制的光照效果
    这个自然规律如果用shader来实现,其实就是一句话:
    dot(normal, lightDir)
    其中normal是法线向量,lightDir是光源向量,两者做点乘,结果大于0,表示在面的同侧,小于0则表示在异侧。我们这里用的法线是模型本身的法线(始终朝上),那如果我想让这个平面有更多的明暗关系,那怎么办?站在模型师的角度上来说,增加点线是最直观的方法,但是通常游戏都会尽量避免不必要的顶点面数,这个时候我们就可以利用一张法线纹理来重新给normal进行赋值,在frag函数里添加以下代码:
    normal = UnpackNormal(tex2D(_BumpTex, i.uv))
    然后再进行点乘操作,这样面片上每个像素的法线信息都由新的法线纹理来控制,我们就完全不管模型原来的法线是什么样子了,效果如图:
    法线纹理控制后的光照效果与之对应的法线贴图
    这里我们改变了法线信息,也就改变其与光源位置的关系,物体表现出明暗不一的凹凸感。这样就实现了在顶点数不变的情况下,增加了模型的“凹凸”感。这种方法在游戏中非常常见,从人物到场景,从旗帜到流水……当然,这毕竟是利用了一种视觉差,如果你感兴趣,可以从某些角度看看游戏里的物件,你就会发现,其实都是“假”的。
    换个角度来看
    OK,我想到这里,大家应该已经冥冥之中感受到了答案。但这其实只是入门的开始,我们这里只是用了一个平面,所有顶点的法线都垂直向上,你有想过,其实一个面应该有两个方向向量与之垂直,一个朝上一个朝下,那究竟哪个是它的法线呢?你有想过,那么如果是一个立方体,它一个顶点对应3个面,那它的法线应该朝哪里呢?还有法线纹理为什么都是蓝色的?该如何制作法线贴图呢?OK,今天就到这里,每天一个小知识,如果你也有这么多的问题,欢迎留言讨论,我会考虑把它写出来,大家一起分享。

猜你喜欢

转载自blog.csdn.net/u013917120/article/details/78808501
今日推荐