Version: 2021.1
着色器简介
着色器资源

Shader 类

在 Unity 中,当您使用的着色器属于图形管线 的一部分,通常用到 Shader 类的实例。我们将一个 Shader 类的实例称为 Shader 对象

Shader 对象是 Unity 使用着色器程序的特定方式;它是着色器程序和其他信息的封装器。它允许您在同一个文件中定义多个着色器程序,并告诉 Unity 如何使用它们。

渲染管线兼容性

功能名称 内置渲染管线 通用渲染管线 (URP) 高清渲染管线 (HDRP) 自定义 SRP
Shader 对象

Shader 对象基础

Shader 对象包含着色器程序、更改 GPU 上设置的指令(统称为渲染状态)以及告诉 Unity 如何使用它们的信息。

您将 Shader 对象与材质共同使用来确定场景的外观。

资源

您可以通过两种方式创建 Shader 对象。分别具有各自类型的资源:

无论您以何种方式创建 Shader 对象,Unity 在内部都以相同的方式表示结果。

在 Shader 对象内部

Shader 对象具有嵌套结构。它将信息按照名为子着色器通道的结构进行组织。它将着色器程序组织成着色器变体

Shader 对象

Shader 对象包含:

  • 关于自身的信息,例如其名称 *一个可选的回退 Shader 对象,如果 Unity 不能使用这个对象,则会使用回退对象
  • 一个或多个子着色器。

您还可以定义附加信息,例如共享着色器代码,或是否使用自定义编辑器。有关定义 Shader 对象的信息,请参阅 ShaderLab:定义一个 Shader 对象

子着色器

子着色器用于将 Shader 对象分成多个部分,分别兼容不同的硬件、渲染管线和运行时设置。

一个子着色器包含:

  • 有关此子着色器与哪些硬件、渲染管线和运行时设置兼容的信息
  • 子着色器标签,这是提供有关子着色器的信息的键值对
  • 一个或多个通道

您还可以定义其他信息,例如对其所有通道通用的渲染状态。有关可在子着色器中定义的所有信息,请参阅 ShaderLab:定义一个子着色器

通道

通道包含:

  • 通道标签,这是提供有关通道的信息的键值对
  • 在运行着色器程序之前更新渲染状态的说明
  • 着色器程序,组织成一个或多个着色器变体

您还可以定义其他信息,例如名称。有关可在通道中定义的所有信息,请参阅 ShaderLab:定义一个通道

着色器变体

通道包含的着色器程序被组织成着色器变体。着色器变体共享通用代码,通过启用或禁用给定关键字,使其具有不同功能。

通道中的着色器变体的数量取决于您在着色器代码中定义的关键字数量以及目标平台。每个通道包含至少一个变体。

有关更多信息,请参阅着色器关键字和变体

渲染期间的操作顺序

这是 Unity 如何在所有渲染管线中使用 Shader 对象渲染几何体的高级描述。

在 Unity 使用 Shader 对象之前:

  1. Unity 为 Shader 对象创建一个子着色器列表。它添加 Shader 对象中定义的所有子着色器,然后按顺序添加任何回退 Shader 对象中的所有子着色器。

当 Unity 首次使用 Shader 对象渲染几何体时,或者当着色器 LOD 值或活动渲染管道更改时:

  1. Unity 遍历所有子着色器的列表并检查它们以确定它们是否:与设备硬件兼容;等于或低于当前着色器 LOD 值;并与活动渲染管道兼容。
  2. 如果列表包含一个或多个满足这些要求的子着色器,它会选择第一个子着色器。这是活动的子着色器。
  3. 如果列表不包含任何满足所有要求的子着色器:
    1. 如果列表包含一个或多个满足硬件要求(但不满足 LOD 或渲染管线要求)的子着色器,则 Unity 选择第一个子着色器。这是活动的子着色器。
    2. 如果列表不包含任何满足硬件要求的子着色器,则会显示错误材质。

Unity 可以识别使用相同着色器变体的几何体并将其组织成批次实现更高效的渲染。每帧一次,对于每批几何体:

  1. Unity 确定它应该渲染活动子着色器中的哪些通道,以及帧中的哪个点。此行为因渲染管道而异。
  2. 对于它渲染的每个通道:
    1. 如果当前渲染状态与通道中定义的渲染状态不匹配,Unity 会根据通道中的定义设置渲染状态。
    2. GPU 使用相关的着色器变体渲染几何体。
着色器简介
着色器资源