咱们可使用multi_compile来为shader建立多个稍微有点区别的shader变体。这个Shader被称为宏着色器(mega shader)或者超着色器(uber shader)。实现原理:根据不一样的状况,使用不一样的预处理器指令,来屡次编译Shader代码。html
在Unity里面,可使用:cookie
#pragma multi_compile #pragma shader_feature
两个指令来实现。适用于VF着色器和表面着色器。编辑器
运行时,会根据材质(Material)的关键字(Material的对象方法EnableKeyword和DisableKeyword)或者全局着色器关键字(Shader的类方法EnableKeyword和DisableKeyword)。ide
注:以前在Shader山下(十二)材质属性绘制器里,咱们已经介绍了多重编译的运用性能
使用multi_compile指令:测试
#pragma multi_compile TEST_OFF TEST_ON
这样会编译两个Shader变体,一个是TEST_OFF的版本,一个是TEST_ON的版本。运行的时候会根据材质关键之或者Shader全局关键字判断应该使用哪一个,若是两个关键字都为false,那么会使用第一个(TEST_OFF)变体。优化
咱们也能够建立多个关键字:spa
#pragma multi_compile TEST_A TEST_B TEST_C TEST_D
或者只建立一个关键字,这时候就须要使用__来代替另外一个:.net
#pragma __ TEST_KEY_ON
这样依然会生成两个shader变体,一个啥都没定义,另一个定义了TEST_KEY_ON。3d
咱们还能够经过多行指令来组合关键字:
#pragma multi_compile A B C #pragma multi_compile D E
这样就会生成六个shader变体(A+D、B+D、C+D、A+E、B+E、C+E)。可是这样shader变体的数量就可能会变得不少,10行multi_compile,每行有两个关键字,那么就会有1024个shader变体。
除了multi_compile以外,还有另一个相似的指令shader_feature,惟一的区别在于shader_feature不会将不用的shader变体添加到程序中去。shader_feature更适用于材质的关键字,而multi_compile更适用于代码设置的全局关键字。
示例:
#pragma shader_feature TEST_STUFF
这是下面这种写法的简写形式:
#pragma shader_feature __ TEST_STUFF
注:Unity中最多能够有128个关键字,可是Unity本身已经定义了一部分了,因此实际上会更少。因此使用multi_compile和shader_feature的时候,就须要特别注意不要超过这个限制。
Unity自身还内建一些multi_compile的快捷写法:
multi_compile_fwdbase:为基本前向渲染通道编译多个变体,不一样的变体可能须要处理不一样的光照贴图类型,或者一些使用了主平行光的阴影,而另外一些禁用了。(参考Unity渲染管线)
multi_compile_fwdadd:为附加前向渲染通道编译多个变体,不一样的变体可能须要处理不一样类型的光源——平行光、聚光灯或者点光源,亦或者它们附带cookie纹理的版本。
multi_compile_fwdadd_fullshadows:同上,不过包含了可让光源拥有实时阴影的功能。
multi_complie_fog:为处理不一样的雾效类型(off/linear/exp/exp2)扩展了多个变体。
大部份内建快捷写法会致使许多shader变体,若是某些不须要使用,那么可使用#pragma skip_variants来忽略它们。
#pragma multi_compile_fwdadd // will make all variants containing // "POINT" or "POINT_COOKIE" be skipped #pragma skip_variants POINT POINT_COOKIE
使用multi_compile的目的通常是为了建立一些fallback或者简化shader,它们在同一个目标平台(例如OpenGL ES)的高端硬件和低端硬件上均可以高效地运行。这种时候,咱们可使用shader硬件变体来为不一样性能等级的硬件建立一个特殊优化的变体集合。
为了生成shader硬件变体,须要添加#pragma hardware_tier_variantsrenderer,这里renderer表示某个可运行的渲染平台。使用这个指令,Unity会对每一个shader生成3个shader变体(其余关键字会不起做用),而对应的关键字是:
UNITY_HARDWARE_TIER1
UNITY_HARDWARE_TIER2
UNITY_HARDWARE_TIER3
在编辑器里,能够经过Graphics Emulation菜单来测试他们。
注:这些shader并不受Quality Setting的影响,它们纯粹是经过检测GPU的相关性能来决定的。