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

法线贴图,是用来给 低模 模拟 高模 的效果,这里说的 低模 高模 ,指的是模型的三角形数量。

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

在游戏中所看到的模型,都是一个一个三角形拼起来的,看起来越 圆润 的模型,就用了更多的三角形。

Unity Shaders and Effects Cookbook (2-5) 如何使用法线贴图_第1张图片


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


第二张图用了 16 个三角形来模拟 一个 园,但是仍然 不是很圆润。


更直观的,在Unity 中新建一个 球,来看看有多少个三角形。

Unity Shaders and Effects Cookbook (2-5) 如何使用法线贴图_第3张图片


真是惊人,那我想在这个球上面,做一些凹凸的效果,可以想象,需要的三角形可能会翻倍,或许还不止。


这里注意,模型的凹凸效果,是在有光照的情况下才能提现的。因为不同的顶点,受光照的强弱影响不同,所以有的地方暗,有的地方亮,这种不规则的明暗效果,就体现出凹凸感。

如果要在模型中制作一些凹凸效果,传统的方法就是要增加更多的顶点,更多的三角形。然后计算出每个顶点的法线,然后计算光强,最后就有了明暗 凹凸效果。

这就是我们所说的高模了,高数量顶点的模型。

这样做可以的,但是这样模型的顶点数急剧增加,然后因为法线数据要在顶点着色器中进行一次坐标转换计算,所以会导致性能急剧下降。

所以前辈了找到了法线贴图这个方法。


法线贴图是在 设计的时候,用高模,收集所有的顶点的法线并且进行 坐标转换计算之后,把法线数据 ( 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;

因为颜色数据的范围是 ( 0,1 ),所以这里进行了 *2-1 操作,将范围转换到 ( -1,1 )。

要注意的是,法线贴图导入Unity之后,纹理类型要选择 Normal Map才行哦。

Unity Shaders and Effects Cookbook (2-5) 如何使用法线贴图_第4张图片


示例项目下载:

http://pan.baidu.com/s/1bIpZ6Q





你可能感兴趣的:(unity3d,shader,法线贴图)