着色器关键字可用于在着色器代码中使用条件行为。可以创建共享某些通用代码的着色器,但它们在启用或禁用特定关键字时具有不同功能。
着色器关键字可以与动态分支结合使用,也可以与着色器变体结合使用。在使用着色器关键字之前,了解这些技术的工作原理以及哪种技术适合您的项目非常重要。
注意:在 Shader Graph 中,术语有所不同:一组关键字被称为一个关键字集(Keyword),而一个关键字集中的各个关键字则被称为状态(states)。在内部,其功能是相同的:Unity 以相同的方式编译它们,使用 C# 脚本以相同的方式处理它们,依此类推。
以集合形式声明着色器关键字。一个集合包含互斥的关键字。
例如,以下集合包含三个关键字:
声明着色器关键字的方式会影响许多方面:
声明一组关键字时,可以选择将它们与着色器变体结合使用还是与动态分支结合使用。如果选择着色器变体,还必须选择 Unity 在内部定义关键字的方式;这会影响 Unity 编译的变体数量。
请参阅选择要在着色器中使用的条件类型以了解更多信息。
创作着色器时,以集合形式声明关键字。一个集合会包含互斥的关键字。
在运行时,Unity 没有这些集合的概念。它可用于独立启用或禁用任何关键字,启用或禁用关键字不会影响任何其他关键字的状态。这意味着可以启用同一集合中的多个关键字,或禁用一集合中的所有关键字。
如果将关键字与着色器变体结合使用,则当启用一个集合中的多个关键字或未启用一个集合中的任何关键字时,Unity 会选择它认为“足够好”的变体。但它无法保证具体会发生什么,这样可能导致意外结果。最好通过谨慎管理关键字状态来避免这种情况。
如果将关键字与动态分支结合使用,则当启用一个集合中的多个关键字或未启用一个集合中的任何关键字时,条件分支会相应执行。例如,如果同时启用了 KEYWORD_A 和 KEYWORD_B,则 if (KEYWORD_A) 和 if (KEYWORD_B) 的分支都将执行。
Unity 最多可以使用 4,294,967,294 个全局着色器关键字。单个着色器和计算着色器最多可以使用 65,534 个本地着色器关键字。上面的总数包括用于变体的关键字和用于动态分支的关键字。
着色器源文件中声明的每个关键字及其依赖项都计入此限制值。依赖项包括着色器通过 UsePass 包含的通道 (Passes) 以及通过 Fallbacks 包含的着色器。
如果 Unity 多次遇到具有相同名称的着色器关键字,则仅在限制中计算一次。
如果着色器总共使用超过 128 个关键字,则产生的运行时性能损失较小;因此,最好使用数量较低的关键字。Unity 始终为每个着色器保留 4 个关键字。