Shader山下(二十一)多重变体(Multiple Variants)

Shader山下(二十)编译指令(Compilation Directives)介绍了如何使用编译指令,本文就专文介绍一下多重编译(multi_compile)指令。

咱们可使用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的相关性能来决定的。

相关文章
相关标签/搜索