一、定义
在unity中我们可以通过使用#pragma multi_compile或#pragma shader_feature指令来为shader创建多个稍微有点区别的shader变体。这个Shader被称为宏着色器(mega shader)或者超着色器(uber shader)。实现原理:根据不同的情况,使用不同的预处理器指令,来多次编译Shader代码。
在运行时,Unity从Material宏Material.EnableKeyword和Shader.DisableKeyword或全局着色器宏Shader.EnableKeyword和Shader.DisableKeyword中选择适当的着色器变体。如果这两个宏都未启用,则Unity使用第一个宏。
二、使用
//定义两个TEST_1,TEST_2两个宏
#pragma multi_compile TEST_1 TEST_2
//在shader中使用
#ifdef TEST_1
//Todo
#endif
#ifdef TEST_2
//Todo
#endif
上面这个命令会产生2种着色器变种:TEST_1,TEST_2。
要生成未定义预处理器宏的着色器变体,请添加一个仅为下划线(__
)的名称。这是避免使用两个宏的常用技术,因为对项目中可以使用的宏数量有限制,例如:
#pragma multi_compile __ TEST_1
在脚本中控制使用:
//使用TEST_1变种
Shader.EnableKeyword ("TEST_1");
Shader.DisableKeyword ("TEST_2");
三、组合
#pragma multi_compile TEST_1 TEST_2
#pragma multi_compile TEST_3 TEST_4 TEST_5
它产生总共六个着色器变体(TEST_1_TEST_3,TEST_1_TEST_4,TEST_1_TEST_5,TEST_2_TEST_3,TEST_2_TEST_4,TEST_2_TEST_5)。
所以如果有10行multi_compile,每行2个选项,那么将一共产生1024个着色器变体。
请记住,着色器变体数量将以这种方式疯狂增长。
四、pragma shader_feature
shader_feature非常相似multi_compile。唯一的区别是Unity shader_feature在最终版本中不包含未使用的着色器变体。所以shader_feature适用于在我们在编辑器中,选中材质,设置它使用的shader的宏,如果在程序中动态的去设置可能无效(原因下面说明)。而对于multi_compile,会把所有的变体都编译进程序里,所以适合需要在程序运行中动态改变状态的宏,适合全局设置 。
材质中设置位置截图:
五、宏限制
在unity中限制了全局的宏个数为265个,而unity内部使用了大约60个,所以在多个不同的着色器中定义全局宏时需要注意宏数量不要超过限制。
使用本地宏替代一部分全局宏: