Unity Shaders and Effects Cookbook (2-5) 如何使用法线贴图
2016-03-27 01:00
405 查看
法线贴图,是用来给 低模 模拟 高模 的效果,这里说的 低模 高模 ,指的是模型的三角形数量。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
在游戏中所看到的模型,都是一个一个三角形拼起来的,看起来越 圆润 的模型,就用了更多的三角形。
第二张图用了 16 个三角形来模拟 一个 园,但是仍然 不是很圆润。
更直观的,在Unity 中新建一个 球,来看看有多少个三角形。
真是惊人,那我想在这个球上面,做一些凹凸的效果,可以想象,需要的三角形可能会翻倍,或许还不止。
这里注意,模型的凹凸效果,是在有光照的情况下才能提现的。因为不同的顶点,受光照的强弱影响不同,所以有的地方暗,有的地方亮,这种不规则的明暗效果,就体现出凹凸感。
如果要在模型中制作一些凹凸效果,传统的方法就是要增加更多的顶点,更多的三角形。然后计算出每个顶点的法线,然后计算光强,最后就有了明暗 凹凸效果。
这就是我们所说的高模了,高数量顶点的模型。
这样做可以的,但是这样模型的顶点数急剧增加,然后因为法线数据要在顶点着色器中进行一次坐标转换计算,所以会导致性能急剧下降。
所以前辈了找到了法线贴图这个方法。
法线贴图是在 设计的时候,用高模,收集所有的顶点的法线并且进行 坐标转换计算之后,把法线数据 ( x,y,z ) 存入到 纹理的 R、G、B 通道中。
然后在游戏中,使用低模就可以了。在 Fragment Shader中,从法线贴图中读取出来法线数据,进行光照计算。
下图是这一节的最终效果转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
可以看到,在球上 有很多凹凸不平,但是顶点数量并没有改变,这就是法线贴图的应用。
不过想起来,法线贴图也有缺点。就是多了一张法线贴图文件,加大了游戏安装包大小……
还是来看看整个Shader 文件吧。
使用到了一个 UnpackNormal 函数,这个函数是从 法线贴图中读取法线数据的。读取数据之后我们把法线数据给了 SurfaceOutput,然后去进行光照计算了。
可以在 Unity 安装目录下的 UnityCG.cginc 中找到这个函数
因为颜色数据的范围是 ( 0,1 ),所以这里进行了 *2-1 操作,将范围转换到 ( -1,1 )。
要注意的是,法线贴图导入Unity之后,纹理类型要选择 Normal Map才行哦。
示例项目下载:
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
在游戏中所看到的模型,都是一个一个三角形拼起来的,看起来越 圆润 的模型,就用了更多的三角形。
第二张图用了 16 个三角形来模拟 一个 园,但是仍然 不是很圆润。
更直观的,在Unity 中新建一个 球,来看看有多少个三角形。
真是惊人,那我想在这个球上面,做一些凹凸的效果,可以想象,需要的三角形可能会翻倍,或许还不止。
这里注意,模型的凹凸效果,是在有光照的情况下才能提现的。因为不同的顶点,受光照的强弱影响不同,所以有的地方暗,有的地方亮,这种不规则的明暗效果,就体现出凹凸感。
如果要在模型中制作一些凹凸效果,传统的方法就是要增加更多的顶点,更多的三角形。然后计算出每个顶点的法线,然后计算光强,最后就有了明暗 凹凸效果。
这就是我们所说的高模了,高数量顶点的模型。
这样做可以的,但是这样模型的顶点数急剧增加,然后因为法线数据要在顶点着色器中进行一次坐标转换计算,所以会导致性能急剧下降。
所以前辈了找到了法线贴图这个方法。
法线贴图是在 设计的时候,用高模,收集所有的顶点的法线并且进行 坐标转换计算之后,把法线数据 ( 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才行哦。
示例项目下载:
http://pan.baidu.com/s/1bIpZ6Q
相关文章推荐
- Unity 用简单工厂模式创建对象
- ubuntu14.04 LTS 安装 Unity Tweak Tool
- Community Detection (社区发现)算法
- 我的Unity Shader 学习心路历程
- Oculus Rift & Unity 开发配置和注意事项
- 在OSX上开发UNITY本地插件的经验分享
- [Unity官方文档翻译]2D or 3D Projects Unity中2D和3D项目的区别
- [Unity官方文档翻译]Downloading and Installing Unity下载和安装unity教程
- Unity3D热更新<一> 学习Lua
- Unity从HelloWord开始
- Unity中ScrollRect锁定元素详述(二)
- Unity 通过计算定点绘制图形
- Unity 问题汇总
- Unit3D--人机交互入门
- Unity3D学习1——鼠标点击效果显示
- 【Unity】2.2 Unity编辑器中的常用菜单项
- 【Unity】2.1 初识Unity编辑器
- 【Unity】2.0 第2章 Unity编辑器和基本操作
- Unity 随机函数的应用
- Unity中ScrollRect锁定元素详述(一)