版本:Unity 6 (6000.0)
语言:English
减少着色器的大小或数量
减少着色器变体

着色器编译

每次构建项目时,Unity 编辑器都会编译构建所需的所有着色器:每个所需的着色器在 GPU 上运行的程序。 更多信息
请参阅 术语表
变体,以及每个所需的图形 API。

在 Unity 编辑器中工作时,编辑器不会预先编译所有内容。这是因为为每个图形 API 编译每个变体可能需要很长时间。

相反,Unity 编辑器执行以下操作

  • 当它导入着色器资源时,它会执行一些最小的处理(例如表面着色器生成)。
  • 当它需要显示着色器变体时,它会检查 Library/ShaderCache 文件夹。
  • 如果它找到一个以前编译的着色器变体,该变体使用相同的源代码,则它会使用该变体。
  • 如果找不到匹配项,它会编译所需的着色器变体并将结果保存到缓存中。
    • 注意:如果启用异步着色器编译,它会在后台执行此操作,并同时显示一个占位符着色器。

着色器编译是使用名为 UnityShaderCompiler 的进程进行的。可以启动多个 UnityShaderCompiler 进程(通常每个 CPU 内核一个),以便在播放器构建时可以并行进行着色器编译。当编辑器未编译着色器时,编译器进程不会执行任何操作,也不会消耗计算机资源。

如果有很多经常更改的着色器,则着色器缓存文件夹可能会变得非常大。可以安全地删除此文件夹;它只会导致 Unity 重新编译着色器变体。

在播放器构建时,所有“尚未编译”的着色器变体都会被编译,以便即使编辑器碰巧没有使用它们,它们也包含在游戏数据中。

不同的着色器编译器

不同的平台使用不同的着色器编译器进行着色器程序编译,如下所示

  • 使用 DirectX 的平台使用 Microsoft 的 FXC HLSL 编译器。
  • 使用 OpenGL(Core 和 ES)的平台使用 Microsoft 的 FXC HLSL 编译器,然后使用HLSLcc将字节码转换为 GLSL。
  • 使用 Metal 的平台使用 Microsoft 的 FXC HLSL 编译器,然后使用HLSLcc将字节码转换为 Metal。
  • 使用 Vulkan 的平台使用 Microsoft 的 FXC HLSL 编译器,然后使用HLSLcc将字节码转换为 SPIR-V。
  • 其他平台,例如游戏机平台,使用各自的编译器。
  • 表面着色器编写内置渲染管线着色器的一种简化方法。 更多信息
    请参阅 术语表
    使用 HLSL 和MojoShader进行代码生成分析步骤。

可以使用pragma 指令配置各种着色器编译器设置。

缓存着色器预处理器

着色器编译涉及多个步骤。第一步之一是预处理。在此步骤期间,一个称为预处理器的程序会为编译器准备着色器源代码。

在早期版本的 Unity 中,编辑器使用当前平台的着色器编译器提供的预处理器。现在,Unity 使用自己的预处理器,也称为缓存着色器预处理器。

缓存着色器预处理器针对更快的着色器导入和编译进行了优化。它的工作原理是缓存中间预处理数据,因此编辑器仅在包含文件的内容发生更改时才需要解析包含文件,这使得编译同一着色器的多个变体更加高效。

有关缓存着色器预处理器与先前行为之间差异的详细信息,请参阅 Unity 论坛:新的着色器预处理器

构建时剥离

在构建游戏时,Unity 可以检测到某些内部着色器变体未被游戏使用,并将其从构建数据中排除(“剥离”)。有关更多信息,请参阅着色器变体根据特定组合的着色器关键字及其状态而生成的着色器程序的版本。一个着色器对象可以包含多个着色器变体。 更多信息
请参阅 术语表

减少着色器的大小或数量
减少着色器变体