版本:Unity 6 (6000.0)
语言:English
检查您有多少着色器变体
解决 AssetBundle 中着色器重复的问题

剔除着色器变体

您可以阻止着色器变体Unity 根据着色器关键字及其状态的特定组合生成的着色器程序版本。一个着色器对象可以包含多个着色器变体。更多信息
参见 术语表
被编译。这称为 **剔除**。剔除不需要的变体可以大大减少构建时间、文件大小、着色器在 GPU 上运行的程序。更多信息
参见 术语表
加载时间和运行时内存使用量。在大型项目或具有复杂着色器的项目中,这是一个非常重要的考虑因素。

如果您剔除了材质在运行时所需的着色器变体,Unity 会尝试选择一个可用的类似着色器变体。为避免这种情况,请使用以下方法

  • 如果您使用 shader_feature 关键字,请不要使用该关键字来更改在运行时执行哪个代码分支。
  • 检查您有哪些着色器变体 以帮助您查看材质在运行时需要哪些着色器变体和关键字组合。
  • 将着色器添加到 图形设置 中的 **始终包含的着色器** 列表中。

在声明着色器关键字时限制着色器变体

声明着色器关键字的方式可以限制它们生成的变体数量

  • 尽可能使用 shader_feature 而不是 multi_compile - 请参阅 着色器中的条件语句
  • 确保您没有使用 multi_compile 定义未使用的关键字。

有关在手动编写的着色器中声明关键字的信息,请参阅 在 HLSL 中声明和使用着色器关键字。有关在 Shader Graph 中声明关键字的信息,请参阅 Shader Graph:黑板

指示哪些着色器关键字影响哪个着色器阶段

当您 声明一个关键字 时,Unity 假设着色器的所有阶段都包含该关键字的条件代码。

您可以添加以下后缀来指示只有某些阶段包含该关键字的条件代码,以便 Unity 不会生成不需要的着色器变体。

  • _vertex
  • _fragment
  • _hull
  • _domain
  • _geometry

例如,使用 #pragma shader_feature_fragment RED GREEN BLUE 来指示您仅在片段阶段使用这 3 个关键字创建条件代码。

您不能将这些后缀添加到 #pragma dynamic_branch,因为 dynamic_branch 不会创建变体。

这些后缀的行为可能会有所不同或没有效果,具体取决于 图形 API。例如

  • 这些后缀对 OpenGL、OpenGL ES 或 Vulkan 没有影响。
  • _geometry_raytracing 后缀对 Metal 没有影响。Metal 将 _vertex_hull_domain 视为单个阶段。

使用预处理器宏按平台限制变体

在 Unity 2021.3 及更高版本中,您可以使用 目标平台预处理器宏 创建条件着色器代码,以便您可以限制内存有限平台上的变体。

代码示例执行以下操作

  • 如果您为 SHADER_API_DESKTOP 平台 构建,Unity 将为每个可能的关键字组合构建变体。
  • 如果您为其他平台构建,Unity 将仅为构建中材质使用的关键字组合构建变体。
#ifdef SHADER_API_DESKTOP
   #pragma multi_compile _ RED GREEN BLUE WHITE
#else
   #pragma shader_feature RED GREEN BLUE WHITE
#endif

您可以使用目标平台预处理器宏在 shader_featuremulti_compiledynamic_branch 之间进行选择。有关何时使用每种类型的条件语句的更多信息,请参阅 着色器条件语句

创建用户控制的质量设置

当您为内存有限的控制台和移动平台构建时,可以通过仅允许用户在少量质量设置之间切换来限制着色器变体。

例如,如果您使用关键字 DYNAMIC_LIGHTINGSOFT_SHADOWSHIGH_QUALITY_LIGHTMAPS,您可以创建以下内容

  • 一个“低质量”设置,它启用 DYNAMIC_LIGHTING
  • 一个“高质量”设置,它启用 DYNAMIC_LIGHTINGSOFT_SHADOWSHIGH_QUALITY_LIGHTMAPS

这意味着当 DYNAMIC_LIGHTING 关闭或这 3 个关键字的各种开/关组合时,Unity 不会创建着色器变体。

您可以使用 目标平台预处理器宏 有条件地创建更少的质量设置和更少的变体,以用于内存有限的平台。例如,以下代码示例将允许用户在 SHADER_API_DESKTOP 平台上切换 8 个设置排列,但在 SHADER_API_MOBILE 平台上仅切换 2 个。

#if SHADER_API_DESKTOP
   #pragma multi_compile SHADOWS_LOW SHADOWS_HIGH
   #pragma multi_compile REFLECTIONS_LOW REFLECTIONS_HIGH
   #pragma multi_compile CAUSTICS_LOW CAUSTICS_HIGH
#elif SHADER_API_MOBILE
   #pragma multi_compile QUALITY_LOW QUALITY_HIGH
   #pragma shader_feature CAUSTICS // Uses shader_feature, so Unity strips variants that use CAUSTICS if there are no Materials that use the keyword at build time.
#endif

在编辑器 UI 中剔除着色器变体

在 Unity 编辑器 UI(用户界面) 允许用户与您的应用程序交互。Unity 目前支持三种 UI 系统。更多信息
参见 术语表
中有几个地方可以配置着色器剔除

  • 图形设置窗口 中,配置 **着色器剔除** 部分中的设置

  • 确保 **始终包含的着色器** 设置中不包含任何不需要的着色器。

  • 剔除与 GPU 实例化、光照贴图和雾相关的变体。

  • 在内置 渲染管线一系列操作,用于获取场景的内容并在屏幕上显示它们。Unity 允许您从预构建的渲染管线中选择,或编写您自己的渲染管线。更多信息
    参见 术语表
    中,如果您的层级设置不必不同,请确保它们彼此相同。有关更多信息,请参阅 图形层级

  • 在通用渲染管线 (URP) 中,禁用 URP 资源中未使用的功能。有关更多信息,请参阅 着色器剔除

如果您使用通用渲染管线,您还可以执行以下操作

如果您使用高清渲染管线,您还可以执行以下操作

使用编辑器脚本剔除着色器变体

对于无法通过其他方式剔除的着色器变体,您可以在编辑器脚本中使用以下 API 执行构建时剔除

有关此主题的更多信息,请参阅 剔除脚本化着色器变体

检查您有多少着色器变体
解决 AssetBundle 中着色器重复的问题