Unity3D:着色器关键字

推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生

着色器关键字

着色器关键字允许您在着色器代码中使用条件行为。您可以创建共享一些通用代码的着色器,但在启用或禁用给定关键字时具有不同的功能。您可以与着色器变体一起使用。

本页包含以下信息:

  • 使用着色器关键字
  • 声明着色器关键字
  • 使用着色器关键字使行为成为条件
  • 启用和禁用着色器关键字
  • Unity 的预定义着色器关键字
  • 着色器关键字限制

使用着色器关键字

声明着色器关键字

在集合中声明着色器关键字。集合包含互斥关键字。

例如,以下集合包含三个关键字:

  • COLOR_RED
  • COLOR_GREEN
  • COLOR_BLUE

注意:在着色器图中,术语是不同的:一组关键字称为关键字,一组关键字称为状态。在内部,功能是相同的:Unity 以相同的方式编译它们,您使用 C# 脚本的方式使用它们,依此类推。

声明着色器关键字的方式会影响许多因素:

  • 类型会影响 Unity 为关键字创建着色器变体的方式。
  • 范围会影响关键字是本地还是全局。这决定了它们在运行时的行为。
  • 阶段会影响关键字影响的着色器阶段(如果适用)。

定义类型:“多重编译”或“着色器功能”

声明一组关键字时,还必须选择 Unity 在内部定义关键字的方式;这会影响 Unity 编译的变体数量。

  • “多重编译”或“着色器功能”:使用它来创建一组用于着色器变体的关键字。在内部,Unity 使用这些关键字来创建预处理器指令。#define
  • “多重编译”声明了一组用于着色器变体的关键字。

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

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

选择“多重编译”还是“着色器功能”取决于您如何使用关键字。如果使用关键字在项目中配置材质,并且不会在运行时从 C# 脚本更改其值,则应使用“着色器功能”来减少项目中着色器关键字和变体的数量。如果在运行时使用 C# 脚本启用和禁用关键字,则应使用“多重编译”来防止错误地去除变体。有关着色器剥离的详细信息,请参阅着色器变体剥离。

注意:如果在“图形设置”窗口中将着色器添加到“始终包含着色器”列表中,Unity 将包含构建中所有集中的所有关键字,即使它们是使用“着色器功能”声明的。

若要设置此值,请参阅以下文档:

  • 在手动编码的着色器中,请参阅在 HLSL 中声明和使用着色器关键字
  • 在着色器图中,请参阅关键字。

本地或全球范围

声明一组关键字时,可以选择该集中的关键字是具有本地范围还是全局范围。这决定了是否可以在运行时使用全局着色器关键字重写此关键字的状态。

默认情况下,声明具有全局范围的关键字。这意味着您可以使用全局着色器关键字在运行时覆盖此关键字的状态。如果使用本地范围声明关键字,这意味着无法在运行时使用全局着色器关键字重写此关键字的状态。有关详细信息和代码示例,请参阅将着色器关键字与 C# 脚本配合使用。

注意:如果着色器源文件及其依赖项中存在同名关键字,则源文件中关键字的作用域将覆盖依赖项中的范围。依赖项包括通过回退命令包含的所有着色器,以及通过 UsePass 命令包含的通道。

若要设置此值,请参阅以下文档:

  • 在手动编码的着色器中,请参阅在 HLSL 中声明和使用着色器关键字
  • 在着色器图中,请参阅关键字

特定于阶段的关键字

默认情况下,Unity 会为着色器的每个阶段生成关键字变体。例如,如果您的着色器包含顶点阶段和片段阶段,Unity 会为顶点和片段着色器程序的每个关键字组合生成变体。如果一组关键字仅在其中一个阶段中使用,则会导致另一个阶段的变体相同。Unity 会自动识别相同的变体并删除重复数据,以便它们不会增加构建大小,但它们仍然会导致编译时间浪费、着色器加载时间增加和运行时内存使用量增加。

为避免此问题,在手动编码着色器中声明一组关键字时,可以指示 Unity 仅针对给定着色器阶段编译它们。然后,您负责确保关键字仅在指定的着色器阶段使用。

注意:以下图形 API 不完全支持特定于阶段的关键字。在 OpenGL 和 Vulkan 中,Unity 会在编译时自动将所有特定于阶段的关键字指令转换为常规关键字指令。在 Metal 中,任何定位顶点阶段的关键字也会影响细分阶段,反之亦然。

要设置此值,请执行以下操作:

  • 在手动编码的着色器中,请参阅在 HLSL 中声明和使用着色器关键字
  • 在着色器图中,不能设置此值。默认情况下,所有关键字都会影响所有阶段。

使用着色器关键字使行为成为条件

可以使用着色器关键字使着色器的某些部分具有条件,以便仅在给定关键字处于给定状态时执行某些行为。

为此需要执行以下操作:

  • 在手动编码的着色器中,请参阅定义和使用着色器关键字。
  • 在着色器图中,请参阅着色器图:关键字节点。

启用和禁用着色器关键字

您可以启用或禁用着色器关键字。启用或禁用着色器关键字时,Unity 会渲染相应的着色器变体,或者 GPU 会执行相应的分支。

有两种方法可以启用和禁用着色器关键字:

  • 在运行时或在 Unity 编辑器中使用脚本。有关更多信息,请参见将着色器关键字与 C# 脚本配合使用。
  • 使用 Unity 编辑器中的材质检查器。有关更多信息,请参阅在材质检查器中使用着色器关键字。

Unity 的预定义着色器关键字

Unity 使用预定义的着色器关键字集来生成启用通用功能的着色器变体。

Unity 在编译时添加以下着色器变体关键字集:

  • 默认情况下,Unity 会将这组关键字添加到所有图形着色器程序中:STEREO_INSTANCING_ON、STEREO_MULTIVIEW_ON、STEREO_CUBEMAP_RENDER_ON UNITY_SINGLE_PASS_STEREO。您可以使用编辑器脚本去除这些关键字。有关详细信息,请参阅着色器变体剥离。
  • 默认情况下,Unity 会将这组关键字添加到标准着色器中:LIGHTMAP_ON、DIRLIGHTMAP_COMBINED、DYNAMICLIGHTMAP_ON、LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK。您可以使用图形设置窗口去除这些关键字。
  • 在内置渲染管线中,如果您的项目使用彼此不同的层设置,Unity 会将这组关键字添加到所有图形着色器:UNITY_HARDWARE_TIER1、UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3。有关详细信息,请参阅图形层:图形层和着色器变体。

着色器关键字限制

Unity 最多可以使用 4,294,967,294 个全局着色器关键字。单个着色器和计算着色器最多可以使用 65,534 个本地着色器关键字。

着色器源文件中声明的每个关键字及其依赖项都计入此限制。依赖项包括着色器随 UsePass 一起包含的通道和回退。

如果 Unity 多次遇到同名着色器关键字,则只计入一次限制。

如果着色器总共使用 128 个以上的关键字,则会导致较小的运行时性能损失;因此,最好保持较低的关键字数量。Unity 始终为每个着色器保留 4 个关键字。

3D建模学习工作室整理翻译,转载请注明出处!

上一篇:Unity3D:检查您有多少个着色器变体 (mvrlink.com)

下一篇:Unity3D:将着色器关键字与 C# 脚本结合使用 (mvrlink.com)

NSDT场景编辑器 | NSDT 数字孪生 | GLTF在线编辑器 | 3D模型在线转换 | UnrealSynth虚幻合成数据生成器 | 3D模型自动纹理化工具
2023 power by nsdt©鄂ICP备2023000829号