Unity3D开发移动平台游戏的常用Shader
Shader介绍
3D计算机图像技术的发展使得在数字游戏和动画中模拟真实世界成为可能,材质和灯光技术是其中两种重要的模拟技术。材质(Material)用来表现真实世界里物体的材料和质地。
材质的制作大致上分为两个方面:着色器(Shader)和纹理贴图(texture mapping)。纹理贴图很好理解。而Shader则是描述纹理贴图如何绘制到屏幕的关键。相同的贴图在不同的Shader渲染下,能在屏幕中产生完全不同的效果。通过以下链接可以看到这种变化:
http://game.ceeger.com/Components/SL-SurfaceShaderExamples.html
Shader是GPU中的可编程计算单元,包括顶点着色器和像素着色器。作为一个可编程单元,自然有编程语言,现在主流的高级Shader语言包括了三种:
OpenGL Shader Language (glsl)
Microsoft High-Level Shader Language (HLSL)
NVIDIA Cg Shader Language (cg)
要学好这三种语言的任何一个,都需要一个长时间的过程,需要专业的图形程序。幸好Unity编辑器已经内置了数十个Shader的Shader库供开发者使用,并且Unity引擎支持一种叫做ShaderLab的编程语言,对以上三种高级shader语言进行了封装,使得编写shader的门槛大大降低。
在之前的开发过程中我们自己开发了一些shader,用于表现不同的渲染效果。不建议直接使用Unity内置shader库,因为有两个原因:Unity内置shader大多面向PC平台,对于手机平台有些shader效率太低;只使用自创的若干几个shader,方便管理,有利于控制整体渲染效率。
那究竟是什么在影响shader渲染效率?
Shader性能
在Unity中,Shader的性能和两件事情直接有关,Shader本身和被项目或者特定摄像机的渲染路径。使用顶点光照路径,或使用顶点光照Shader,总是要比像素Shader来的廉价。而像素Shader能使光照效果更加真实细腻,但是物体会因为每一个额外的光源而多绘制一次,其带来的性能消耗在iPhone4上有时都不可以接受。因此项目中要尽量不使用像素shader,减少额外光源。
一般来说,Shader的复杂度随下面的因素而依次增加:
l 纯纹理绘制,无光照(Unlit),这是最简单的Shader
l 顶点光照(VetexLit)
l 漫反射(Diffuse)
l 法线贴图(Normal mapped)。这要比漫反射昂贵得多,多了一张法线贴图,还有一系列指令
l 高光(Specular)。增加了高光计算。
l 高光发现贴图(Normal Mapped Specular)。这要比高光又昂贵很多
l 视差法线贴图(Parallax Normal mapped)。增加了视差法线贴图计算。
l 视差高光法线贴图(Parallax Normal Mapped Specular)。这增加了视差法线贴图和镜面高光计算
另外在Shader自身的编写上,也需要注意一些细节:
l 只进行必要的计算,不要因为方便扩展而增加额外计算。这一点与计算机编程不同,能写的简单尽量简单,要斤斤计较到每一步计算操作。
l 能使用低精度计算,尽量使用低精度。对于手机平台,这一点尤为重要。在像素 Shader上使用高精度浮点计算会消耗大量性能。
l 考虑到Shader的计算频率,尽量将计算从像素Shader中移到顶点Shader中,从顶点Shader中移到外部程序中。
l 手机平台使用AlphaTest以及Clip()是非常昂贵的,只在必要时使用。
手机平台使用ColorMask是非常昂贵的,只在必要时使用。
Shader库
在移动平台3D游戏开发过程中,需要各种专为移动终端使用的Shader,在反复调试中,使得这些Shader达到了性价比较高的状态,适用于手机平台的开发。
下面介绍一下移动终端平台的一些常用Shader。
Shader "FX/Additive"
效果材质,实现带alpha叠加效果。背景色与贴图相加,颜色更加明亮。
半透渲染效果。
渲染次序:3000 (渲染次序决定半透渲染先后顺序,效果Shader的次序都放在3000)
同 Shader "Mobile/Particles/Additive"
Shader "FX/Soft Additive"
效果材质,实现部分叠加效果,并非完全叠加,没有Addtive明亮,颜色更加接近贴图自身的颜色。
半透渲染效果。
渲染次序:3000
Shader "FX/AlphaBlend"
效果材质,实现颜色混合效果。背景色与贴图按Alpha进行混合。
半透渲染效果。
渲染次序:3000
贴图需要Alpha通道,用于混合计算。
同 Shader "Mobile/Particles/Alpha Blended"
Shader "FX/Multiply"
效果材质,实现相乘效果。背景色与贴图相乘,颜色相比两者更暗。
半透渲染效果。
渲染次序:3000
贴图不用Alpha通道。
Shader "FX/Water (Two Layers)"
用于海面绘制的材质。双层水面效果,速度分别由Wave Speed的(x,y)和(z,w)控制。顶点色实现与背景色的Alpha混合。
半透渲染效果。
渲染次序:2980
Shader "Mobile/Particles/Multiply"
效果材质,实现相乘效果。背景色与贴图相乘,颜色相比两者更暗。
半透渲染效果。
渲染次序:3000
贴图需要Alpha通道,贴图的RGB将先按照Alpha进行插值,Alpha为1时,取贴图本身颜色;Alpha为0时,取白色。然后再与背景色相乘。
此方法不如Shader ”FX/Multiply”高效,Shader ”FX/Multiply”中要求贴图中的RGB已经按照Alpha的变化填充好,省去插值计算。
Shader "Mobile/VertexLit"
仅按顶点光照进行渲染,用于人物绘制。
非半透渲染效果。
没有其他额外光源时,可以使用更加快速的
Shader "Mobile/VertexLit (Only Directional Lights)"
Shader "Mobile/Diffuse"
用于人物绘制,漫反射渲染仅对方向光,其他光源按照顶点光照来处理。相比Shader “Mobile/VertexLit”光照渲染会相对细腻一些。
非半透渲染效果。
Shader "Terrain/TwoLayer VertexColor LightMap"
用于建造大地图地面渲染。使用两张地面贴图,按照顶点色进行混合,再结合LightMap实现阴影效果。这样使得地面显得更加自然,衔接更加平滑。
非半透渲染效果。
Shader "Custom/Build/Transparent VertexColor"
用于大地图上半透物体的材质,使用顶点色进行阴影层次的效果。
半透渲染效果。
渲染次序:2998
贴图需要Alpha通道,与背景色进行混色计算。
Shader "Custom/Opaque Lightmap"
用于建筑的贴图材质,使用Lightmap实现阴影层次的效果。
非半透渲染效果。
Shader "Custom/Build/Shadow Lightmap"
用于建筑基址的贴图材质,使用Lightmap实现阴影层次的效果。
半透渲染效果。
渲染次序:2990
贴图需要Alpha通道,与背景色进行混色计算。
Shader "Custom/Build/Shadow"
用于树木阴影的贴图材质。
半透渲染效果。
渲染次序:2991
贴图需要Alpha通道,与背景色进行混色计算。
Shader "Custom/Transparent Texture"
用于某些个别的半透明的贴图材质。
半透渲染效果。
渲染次序:3000
贴图需要Alpha通道,与背景色进行混色计算。
此Shader只适用于个别少数的半透材质,如果有大量的半透材质物体出现,可能会大大增加drawcall次数,需要考虑额外增加一个次序的Shader。
Shader "PandaUI/2DBackfaceCulled"
用于UI界面绘制的材质。
半透渲染效果。
渲染次序:4000
贴图需要Alpha通道,与背景色进行混色计算。
Shader "PandaUI/3D Text Shader"
用于UI界面字体绘制的材质。
半透渲染。
渲染次序:4000
贴图需要Alpha通道。
Shader "Outlined/Silhouetted Diffuse"
用于人物勾边渲染的材质。绘制进行两遍,一遍绘制勾边颜色,一遍绘制本体。
这是一种比较昂贵的渲染,只在必要的地方使用。