版本:Unity 6 (6000.0)
语言:英语
着色器中的分支
着色器中的静态和动态分支

静态和动态分支介绍

静态分支

着色器在 GPU 上运行的程序。 更多信息
参见 词汇表
程序包含在编译时评估的条件语句时,它使用静态分支。编译器将排除来自未使用分支的代码,因此它不会出现在已编译的着色器程序中。

在内部,Unity 在创建着色器变体时使用静态分支。静态分支本身不会带来着色器变体任何性能上的缺点。

静态分支的优点和缺点

静态分支的主要优点是它不会对运行时性能造成负面影响。静态分支的主要缺点是您只能在编译时使用它。

静态分支意味着编译器会从着色器程序中排除不需要的代码。它会生成小型、专门的着色器程序,其中只包含必要的代码。静态分支不会产生运行时性能成本;事实上,更小的程序可能会导致更快的加载时间和更低的运行时内存使用量。

要使用静态分支,条件必须在编译时保持不变。这意味着您不能使用它在运行时为不同的条件执行代码。

动态分支

当着色器程序包含在运行时评估的条件语句时,它使用动态分支。

动态分支有两种类型:基于统一变量的动态分支和基于任何其他运行时值的动态分支。基于统一变量的分支通常效率更高,因为统一变量值对于整个绘制调用保持不变。

您可以使用着色器关键字进行动态分支。这使您可以使用 C# 脚本一段代码,使您能够创建自己的组件、触发游戏事件、随时间推移修改组件属性以及以任何您喜欢的方式响应用户输入。 更多信息
参见 词汇表
和材质 检查器Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。 更多信息
参见 词汇表
来配置着色器的运行时分支行为。这会导致基于统一变量的分支;当您执行此操作时,Unity 会将着色器关键字编译为统一变量。

动态分支的优点和缺点

动态分支的主要优点是它允许您在运行时使用条件语句,而不会增加项目中着色器变体的数量。动态分支的主要缺点是它会影响 GPU 性能。

GPU 性能影响会因硬件和着色器代码而异。原因如下

  • 基于非统一变量的分支意味着 GPU 必须要么同时执行不同的操作(从而破坏并行性),要么“扁平化分支”并通过执行两个分支的操作然后丢弃一个结果来保持并行性。基于统一变量的分支意味着 GPU 必须扁平化分支。这两种方法都会导致 GPU 性能下降。
  • 对于任何类型的动态分支,GPU 必须为最坏情况分配寄存器空间。如果一个分支比另一个分支的成本高得多,这意味着 GPU 会浪费寄存器空间。这可能导致并行执行的着色器程序调用次数减少,从而降低性能。

一般来说,如果您的代码分支基于统一值并且两个分支的工作量大致相似,那么对 GPU 性能的影响很可能很小。但是,您应该始终分析应用程序并逐案考虑优点和缺点。

注意:动态分支也可能导致较大的着色器程序,因为所有条件的代码都被编译到同一个着色器程序中。但是,这些较大的文件对加载时间和内存使用量的影响通常比着色器变体的影响小。

有关在着色器中使用条件语句的其他方法以及如何确定哪种技术适合您的用例的信息,请参阅着色器中的条件语句

着色器中的分支
着色器中的静态和动态分支