Version: Unity 6.0 (6000.0)
语言 : 中文
着色器关键字基础知识
声明着色器关键字

选择要在着色器中使用的关键字类型

声明一组关键字时,可以选择将它们与着色器变体结合使用还是与动态分支结合使用。

  • “dynamic branch”:使用此属性可创建一组关键字以用于动态分支。Unity 在内部使用这些关键字来创建一致变量。
  • “multi compile”或“shader feature”:使用此属性可创建一组关键字以用于着色器变体。Unity 在内部使用这些关键字来创建 #define 预处理器指令。
    • “multi compile”声明一组用于着色器变体的关键字。

      Unity 为集合中的所有关键字编译着色器变体。
    • “shader feature”声明一组用于着色器变体的关键字,还指示编译器在未启用这些关键字的情况下编译变体。

      Unity 在构建时检查项目的状态,并仅为正在使用的关键字编译变体。如果构建中包含的材质启用了该关键字,则使用该关键字。

选择“multi compile”还是“shader feature”取决于如何使用关键字。如果使用关键字在项目中配置材质,并且在运行时没有从 C# 脚本中更改其值,则应使用“shader feature”来减少项目中着色器关键字和变体的数量。如果在运行时使用 C# 脚本启用和禁用关键字,则应使用“multi compile”来防止错误剥离变体。有关着色器剥离的更多信息,请参阅着色器变体剥离

对于着色器中的条件,不存在“一刀切”的方法,因此应考虑特定项目中特定着色器的每种方法的优缺点。

使用哪个条件取决于什么时候需要将着色器切换成其他代码分支:

编辑时切换代码分支

如果不需要着色器在运行时切换到其他代码分支,则可以使用 Unity 仅在编辑时才评估的条件。

例如,可以在材质的检视面板 (Inspector) 窗口中设置属性,使着色器执行以下操作:

  • 将镜面反射添加到材质的某些实例中,而不是其他实例中。
  • 为某些对象(例如水下场景中出现的对象)添加不同的外观。

如果使用此方法,着色器代码的编写和维护会更简单,并且不太会影响构建时间、文件大小和性能。

要执行此操作,请使用以下方法之一:

如果使用 shader_feature 关键字定义,Unity 会在构建中保留材质使用的着色器变体,并删除(“剥离”)其他着色器变体。这样可以缩短构建时间并减小文件大小。

避免使用 C# 脚本在运行时启用或禁用 shader_feature 关键字,因为如果材质使用缺失的着色器变体,Unity 会选择其他可用的变体。如果您确实需要在运行时启用或禁用关键字,请使用以下方法之一来确保构建中包含所需的所有变体:

在运行时切换代码分支

如果需要使用 C# 脚本使着色器在运行时切换到不同的代码分支,可以使用 Unity 在编辑时和运行时评估的条件。

例如,您可以使用 C# 脚本使着色器执行以下操作:

  • 动态更改材质,使其在特定时间有雪。
  • 当用户更改质量设置时更改材质,例如让用户动态控制是否出现雾效。

要执行此操作,请使用以下方法之一:

如果使用 multi_compile 关键字定义,Unity 会为着色器代码分支的每个可能组合(包括构建中的材质未使用的组合)构建一个着色器变体。这意味着可以在运行时启用和禁用关键字,但也可能会大大增加构建时间、文件大小、加载时间和内存使用量。请参阅着色器变体

动态分支不会产生着色器变体,但可能意味着着色器在 GPU 上的运行速度变慢,尤其是在以下任何情况下:

  • 着色器在性能较低的 GPU 上运行。
  • 条件代码具有“不对称分支”,其中一个分支比另一个分支更长或更复杂。

您可以检查有多少着色器变体,看看是否可以使用动态分支而不会对 GPU 性能产生太大影响。有关动态分支的优缺点,请参阅着色器分支

其他资源

着色器关键字基础知识
声明着色器关键字