作为一款号称跨平台性最好的游戏开发引擎,Unity3D使用Mono这个开源的.NET来实现。对于要适应不同GPU的Shader来说,Unity使用自定义ShaderLab来组织Shader的内容,并将针对不同的平台进行编译。
2.1.1 关键字Shader
Unity的Shader文件是通过Shader这个关键字开始的,用户可以像目录一样组织Shader的命名。Shader的文件名和引用名不必一样,举例如下:
Shader "Tut/NewBie/FirstShader" Properties{ _MainTex ("Base (RGB)”,2D)="white"{} } Subshader{ ...} Subshader{ ...} FallBack "Diffuse" }
真正用于呈现渲染物体的内容是在SubShader中实现的。之所以用SubShader,是为了能让开发者针对不同性能的显卡编写不同的Shader,因为现实中并不是每个人都用相同的显卡。由于显卡千差万别,为了能让用户编写的游戏最大化地在各种各样的GPU上运行,尽可能地呈现最好的效果,就用SubShader来组织具体的实现,使Unity在运行时会针对实际的运行环境,从上到下选出最优的SubShader实现来呈现开发者的作品。从理论上来说,SubShader的数量是没有限制的,但实际操作中为了减少文件的大小,一般写两只个SubShader就行了,即针对目前最流行的一代显卡写一个,针对老旧的显卡写一个。
2.1.3SubShader的重要标签
给SubShader添加标签(Tags{}块),其实就是一系列指示牌,这些标签可以告诉Unity演染引擎或者其他用户如何认证这个SubShader。下面的代码是适应于SubShader的BuildIn类Tags:
SubShader{ Tags{"Queue"="Geometry""RenderType"="Opaque""IgnoreProjector"="True"} ... }
Queue就是队列的意思,在这里就是渲染队列的意思,表示希望Unity渲染引擎在什么时候渲染自己。Queue有5个可选值,它们是Background、Geometry、 AIphaTest、Transparent和Overlay,分别对应数字1000, 2000, 2450, 3000和4000。既然可以对应成数字,当然也可以把这些单词当作整型变量来看待,例如:
<span style="font-size:14px;">Tags{"Queue"="Geometry+1314”}</span>当你混合使用自定义的Shader和Unity的内置Shader时,一定要尊重上面的单词和字母的对应关系,因为Unity的内置Shader就是按照这个顺序来渲染的。
<span style="font-size:14px;">Tags{"MyTag"="Lucifer"}</span>
2.1.4SubShader中的Pass块
SubShader包装了一个渲染方案,而这个方案是由一个个Pass块来执行的。SubShader可以包括多个Pass块,每一个Pass块都包含了渲染一个几何体的具体代码。我们如果写Shader,大部分费神费力且能体现每位读者的劳动价值的地方就在Pass块中。
2.1.5 Pass块的标签及其名字的意义
Pass块内置的那些标签都是针对渲染路径的,告诉渲染引擎这个Pass应该在什么渲染路径下被渲染,这个内容会在后面相应的章节一一讲到。
Pass块的Name一般用来引用此Pass。这种引用意味着你可以定义一个Pass块,然后在其他Shader的Pass块中多次引用它。这是一种减少重复劳动的技巧。下面是这种技巧的一个演示:
<span style="font-size:14px;">Shader "Tut/NewBie/SecondShader"{ SubShader{ Pass{ Name ”HYC“ Material{ Diffuse(1, 0.7,0.4,1) Ambient(1,0.7, 0.9,1) } Lighting On SetTexture[ _ ] {combine primary} } } }</span>
这个Shader命名了一个Pass块,由于Unity的原因,命名时必须使用大写。下面这个Shader则通过这个名字引用了此Pass块:
<span style="font-size:14px;">Shader "Tut/NewBie/ThirdShader"{ SubShader{ UsePass "Tut/NewBie/SecondShader/HYC" } }</span>
2.1.6 使用FaIIBack保证Shader的广泛适应性
如果用户所有的SubShader都失败了,为了在用户的计算机上呈现设定的机制,一般会使用FallBack。 FallBack是Unity自己预制的Shader实现,一般能够在所有显卡上运行。我们在开发Shader的时候一般不使用FallBack,只有在实际发布时才会为了追求平台的最大适用性而加上。