当前位置:   article > 正文

Unity | Shader基础知识(第十一集:什么是Normal Map法线贴图)_法线贴图格式

法线贴图格式

目录

前言

一、图片是否有法线贴图的视觉区别

二、有视觉区别的原因

三、法线贴图的作用

四、信息是如何存进去的

五、自己写一个Shader用到法线贴图

六、注意事项

七、作者的话


前言

本小节会给大家解释,什么是法线贴图?为什么法线贴图会产生深度?我们怎么自己写一个shader,用上法线贴图

一、图片是否有法线贴图的视觉区别

(如图1所示)我们本来有一张普通的图,看上去非常明显是平面的,如果加了法线贴图就会变成立体的感觉(如图2所示)。

图1 普通图片
图2 加了法线贴图的图片

二、有视觉区别的原因

平面和立体最重要的区别是有深度,多了一个维度,

但是多的这个维度是怎么在2D图片中显示出来的?

答:有了不同的深度,光线照射的情况会不一样。

例:如果我画了一座山,放在桌面上,那么这个画上面会接收到相同的光线。(如图3所示)

图3 平面的山

哪里都能照到,随便照,因为不存在遮挡关系,都是亮的。


但是如果是3D的山,光线就会存在遮挡问题,有些地方就照不到,有些地方能照到,照不到的地方接收到的就是黑色的光线,或者只能接到左边来的光线,右边来的光线只能接到一半。(如图4所示)

图4 看起来立体的山

因为有光线的加入,我们才会感觉东西立体了。

三、法线贴图的作用

我们把是否能接收到光的信息提前存进去,让该亮的地方亮,该暗的地方暗。

四、信息是如何存进去的

光线射过来的时候,都是一样的,遇到物体以后会改变他的方向。

我们把物体每一个点反射的光线方向存起来,最后再画出来就可以了。

由于每一个点都会有不同方向的反射光线(如图5所示),我们把光线的方向都用向量表示,但,全部用数字记录有点麻烦,比如(0.5,0.6,-0.2)

图5 反射光线向量

法线贴图就解决了这个问题:

图片刚好有rgb
r(0-255)→x(-1,1)

g(0-255)→y(-1,1)

b(0-255)→z(-1,1)

例如:图一中的法线贴图(如图6所示)

图6 图1的法线贴图

图7 选取了一个点

此时,这里的rgb为(84,128,247),换成向量就为(-0.34,0.008,0.97)

同样(-0.34,0.008,0.97)换成rgb就是(84,128,247),正反都成立。

那么就可以把一大堆信息,变成一个图片,想知道这点的光线信息,就去读它的颜色。

以前我们想看立体视角,必须要模型,现在,我们只需要法线贴图,就很省性能。但是,有个缺点,就是如果看影子,它还是正圆的,毕竟是贴图造出来的幻觉,并不是真凹进去了。

图8 法线贴图的影子

PS:为什么法线贴图都是蓝色的?

如图5所示,决定光线是否会穿出纸面,被人眼看见的是z向量,z向量对应的是b(0-255)蓝色,大部分颜色都需要被我们看见,所以法线贴图大多是蓝色的。

五、自己写一个Shader用到法线贴图

  1. Shader "Custom/006_nomalMap"
  2. {
  3. Properties
  4. {
  5. //首先先放两个图片进来
  6. //正常图片
  7. _MainTexture ("Texture", 2D) = "white" {}
  8. //法线图片
  9. _MainNormal ("NormalTexture",2D) = "bump" {}
  10. }
  11. SubShader
  12. {
  13. CGPROGRAM
  14. //引入已有的脚本
  15. #pragma surface surf Lambert
  16. //把上面资源里的图,接收到shader语法里
  17. //注意事项:名字必须和上面一样
  18. sampler2D _MainTexture;
  19. sampler2D _MainNormal;
  20. //待会我们需要把 图片数据 转换成 坐标数据
  21. struct Input
  22. {
  23. //准备接受主图的坐标数据
  24. float2 uv_MainTexture;
  25. //准备接收法线图片的坐标数据
  26. float2 uv_MainNormal;
  27. //注意事项:名字只能是上面的名字前面加uv
  28. };
  29. //写了一个方法,把shader原有的数据引入进来 把输出的接口也拿过来
  30. void surf(Input IN, inout SurfaceOutput o )
  31. {
  32. //改反射的内容 获取图片上的rgba改成坐标信息,但我们只要rgb的数据
  33. o.Albedo = tex2D(_MainTexture,IN.uv_MainTexture).rgb;
  34. //改法线信息 //这里因为rgb的数据是(0,1),但法线数据是(-1,1),所以需要二次转换一下
  35. o.Normal = UnpackNormal(tex2D(_MainNormal,IN.uv_MainNormal));
  36. //备注:这里的unpackNormal的全称是UnpackNormalFromTexture,
  37. // 意思是,从texture恢复(解压)成Normal
  38. }
  39. ENDCG
  40. }
  41. FallBack "Diffuse"
  42. }

六、注意事项

在使用法线贴图的时候,注意图片格式必须是法线格式。(如图9所示)

图9 贴图格式

七、作者的话

鸽了大家这么久,真对不住,主要是最近一直997,现在稍微闲一点点了,作者立马接上了。非常感谢大家的支持,爱你们哟~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/649753
推荐阅读
相关标签
  

闽ICP备14008679号