版本:Unity 6 (6000.0)
语言:English
着色器关键字作用域基础
声明着色器关键字

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

当您声明一组关键字时,您选择是否将其与着色器变体根据着色器关键字及其状态的特定组合,Unity 生成的着色器程序的版本。一个着色器对象可以包含多个着色器变体。更多信息
参见 术语表
或与 动态分支 一起使用。

  • “动态分支”:使用此方法创建一组用于动态分支的关键字。在内部,Unity 使用这些关键字创建统一变量。
  • “多编译”或“着色器在 GPU 上运行的程序。更多信息
    参见 术语表
    功能”:使用此方法创建一组用于着色器变体的关键字。在内部,Unity 使用这些关键字创建#define预处理器指令。
    • “多编译”声明一组用于着色器变体的关键字。

      Unity 为该集中所有关键字编译着色器变体。
    • “着色器功能”声明一组用于着色器变体的关键字,并指示编译器编译其中未启用任何这些关键字的变体。

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

是否选择“多编译”或“着色器功能”取决于您如何使用关键字。如果您使用关键字配置项目中的材质并且不从 C# 脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间推移修改组件属性以及以任何您喜欢的方式响应用户输入。更多信息
参见 术语表
在运行时更改其值,则应使用“着色器功能”来减少项目中着色器关键字和变体的数量。如果您在运行时使用 C# 脚本启用和禁用关键字,则应使用“多编译”以防止错误地删除变体。有关着色器删除的更多信息,请参见 着色器变体删除

着色器中的条件语句没有“一刀切”的方法,您应该考虑每种方法在给定着色器、给定项目中的优缺点。

使用哪种条件语句取决于您何时需要着色器切换到不同的代码分支

在您编辑时切换代码分支

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

例如,您可以在材质的 检查器一个 Unity 窗口,显示有关当前选定的游戏对象、资源或项目设置的信息,允许您检查和编辑值。更多信息
参见 术语表
窗口中设置一个属性,以使着色器执行以下操作

  • 向某些材质实例添加镜面反射,但对其他实例不添加。
  • 为某些对象添加不同的外观,例如出现在水下 场景场景包含游戏环境和菜单。可以将每个唯一的场景文件视为一个唯一的关卡。在每个场景中,您放置环境、障碍物和装饰,基本上是分段设计和构建游戏。更多信息
    参见 术语表
    中的对象。

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

为此,请使用以下方法之一

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

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

  • 预加载着色器 列表中包含一个包含您需要的着色器变体的 着色器变体集合
  • 在您的构建中包含一个材质,用于您想要使用的shader_feature关键字的每种组合。

在运行时切换代码分支

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

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

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

为此,请使用以下方法之一

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

动态分支不会创建着色器变体,但可能意味着您的着色器在 GPU 上运行速度较慢,尤其是在以下任一情况为真时

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

您可以 检查您有多少个着色器变体,以查看您是否可以在不影响 GPU 性能的情况下使用动态分支。有关动态分支的优缺点的更多信息,请参见 着色器分支

其他资源

着色器关键字作用域基础
声明着色器关键字