Unity Shaders and Effects Cookbook (2-5) 如何使用法线贴图

2019-04-13 15:22发布

法线贴图,是用来给 低模 模拟 高模 的效果,这里说的 低模 高模 ,指的是模型的三角形数量。 转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
在游戏中所看到的模型,都是一个一个三角形拼起来的,看起来越 圆润 的模型,就用了更多的三角形。

第二张图用了 16 个三角形来模拟 一个 园,但是仍然 不是很圆润。
更直观的,在Unity 中新建一个 球,来看看有多少个三角形。
真是惊人,那我想在这个球上面,做一些凹凸的效果,可以想象,需要的三角形可能会翻倍,或许还不止。
这里注意,模型的凹凸效果,是在有光照的情况下才能提现的。因为不同的顶点,受光照的强弱影响不同,所以有的地方暗,有的地方亮,这种不规则的明暗效果,就体现出凹凸感。 如果要在模型中制作一些凹凸效果,传统的方法就是要增加更多的顶点,更多的三角形。然后计算出每个顶点的法线,然后计算光强,最后就有了明暗 凹凸效果。 这就是我们所说的高模了,高数量顶点的模型。 这样做可以的,但是这样模型的顶点数急剧增加,然后因为法线数据要在顶点着 {MOD}器中进行一次坐标转换计算,所以会导致性能急剧下降。 所以前辈了找到了法线贴图这个方法。
法线贴图是在 设计的时候,用高模,收集所有的顶点的法线并且进行 坐标转换计算之后,把法线数据 ( x,y,z ) 存入到 纹理的 R、G、B 通道中。 然后在游戏中,使用低模就可以了。在 Fragment Shader中,从法线贴图中读取出来法线数据,进行光照计算。
下图是这一节的最终效果转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
可以看到,在球上 有很多凹凸不平,但是顶点数量并没有改变,这就是法线贴图的应用。
不过想起来,法线贴图也有缺点。就是多了一张法线贴图文件,加大了游戏安装包大小……
还是来看看整个Shader 文件吧。 Shader "CookBookShaders/Normal mapping" { Properties { _NormalTex ("Base (RGB)", 2D) = "white" {} _MainTint ("Diffuse Tint",Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _NormalTex; float4 _MainTint; struct Input { float2 uv_NormalTex; }; void surf (Input IN, inout SurfaceOutput o) { float3 normalMap=UnpackNormal(tex2D(_NormalTex,IN.uv_NormalTex)); //normalMap=float3(normalMap.x * 10,normalMap.y * 10,normalMap.z); o.Albedo = _MainTint.rgb; o.Alpha = _MainTint.a; o.Normal = normalMap.rgb; } ENDCG } FallBack "Diffuse" }
使用到了一个 UnpackNormal 函数,这个函数是从 法线贴图中读取法线数据的。读取数据之后我们把法线数据给了 SurfaceOutput,然后去进行光照计算了。 可以在 Unity 安装目录下的 UnityCG.cginc 中找到这个函数 inline fixed3 UnpackNormal(fixed4 packednormal) { #if defined(UNITY_NO_DXT5nm) return packednormal.xyz * 2 - 1; #else return UnpackNormalDXT5nm(packednormal); #endif }
packednormal.xyz * 2 - 1;
因为颜 {MOD}数据的范围是 ( 0,1 ),所以这里进行了 *2-1 操作,将范围转换到 ( -1,1 )。
要注意的是,法线贴图导入Unity之后,纹理类型要选择 Normal Map才行哦。

示例项目下载: http://pan.baidu.com/s/1bIpZ6Q