Version: 2019.4
动态光照
专家指南

在 Unity 中设置渲染管线和光照

本指南是以下 Unity 博客文章的更新版本:聚光灯团队最佳实践:设置光照管线 (Spotlight Team Best Practices: Setting up the Lighting Pipeline) - Pierre Yves Donzallaz

定义

首先,让我们来看看在本文中经常遇到的几个重要图形渲染术语的定义。

  • 渲染管线确定场景中对象的显示方式,分为三个主要阶段。
    • 第一步是剔除;它列出了需要渲染的对象,最好是那些对摄像机可见的对象(视锥体剔除)和其他对象不遮挡的对象(遮挡剔除)。
    • 第二个阶段渲染是指将这些对象绘制到基于像素的缓冲区中(通过正确的光照以及它们的一些属性)。
    • 最后,可以在这些缓冲区上执行后期处理操作,例如,应用颜色分级、泛光和景深,从而生成发送到显示设备的最终输出帧。

根据帧率,这些操作每秒钟重复很多次。

  • 着色器是在图形处理单元 (GPU) 上运行的程序或程序集合的通用名称。例如,在剔除阶段完成后,顶点着色器用于将可见对象的顶点坐标从“对象空间”转换为称为“裁剪空间”的不同空间;然后 GPU 使用这些新的坐标对场景进行光栅化,也就是将场景的矢量表示转换为实际像素。在稍后阶段,这些像素将由像素(或片元)着色器进行着色;像素颜色通常将取决于各自表面的材质属性以及周围的光照。现代硬件上另一种常见的着色器是计算着色器:计算着色器允许程序员利用 GPU 的大量并行处理能力,用于任何类型的数学运算,如光照剔除、粒子物理或体积模拟。
  • 直接光照指的是从自发光光源(如灯泡)发出的光照,而不是光从表面反射的结果。根据光源的大小及其与接收者的距离,这种光照通常会产生清晰的不同阴影。
    • 请勿将直接光照与方向光照混淆,后者是指是由无限远的光源(例如计算机模拟的太阳)发出的光。方向光的显著特性是能够用平行光线覆盖整个场景,并且不存在距离衰减(或光衰减);也就是说,接收到的光照量不会随着与光源距离的增加而衰减。
    • 在现实中,太阳光也会像任何其他光源一样,光照会按照距离的平方反比定律而衰减。简单来说,当接收者与光源之间的距离增加时,收到光照量会迅速降低。例如,水星上的太阳光照度几乎是地球上的 7 倍,火星上的太阳光照度是地球的近一半,而冥王星仅仅为 0.06%。然而,对于海拔高度范围非常有限的大多数实时应用程序来说,太阳光的衰减微不足道。因此,方向光完全足以模拟大多数 Unity 场景(包括以行星为中心的大型空旷空间)中的太阳光。
  • 间接光照是由于光从表面反射并通过介质(如大气或半透明物质)传播和散射而形成的结果。在这种状况下,遮挡物通常投射出柔和或难以看清的阴影。
  • 全局光照 (GI) 是对直接和间接光照进行建模以提供逼真光照效果的一组技术。GI 有几种方法,如烘焙/动态光照贴图、辐照度体积、光传播体积、烘焙/动态光照探针、基于体素的 GI 和基于距离场的 GI。Unity 支持开箱即用的烘焙/动态光照贴图和光照探针。
  • 光照贴图程序是一个基础系统,它通过发射光线、计算光线反弹并将产生的光线应用到纹理来生成光照贴图和光照探针的数据。因此,不同的光照贴图程序通常会产生不同的光照外观,因为它们可能依赖不同的技术来生成光照数据。

概述

下面的流程图从内容创建者的角度,大致显示了 Unity 中的整个光照管线。

首先要选择一个渲染管线。然后决定如何产生间接光照,并相应地选择一个全局光照系统。确保为您的项目适当地调整了所有全局光照设置之后,您可以继续添加光源发光表面反射探针光照探针光照探针代理体 (LPPV)。所有这些光照对象的用法和特性的详细介绍超出了本文的范围,因此,建议您阅读手册中的“光照”部分,以学习如何在项目中正确地使用光照。

渲染管线

在 2018 年初之前,Unity 中只有一个渲染管线:内置渲染管线 (Built-In Render Pipeline)。此渲染管线提供了可选择的渲染路径:前向渲染路径和延迟渲染路径。

  • 在使用(多通道)前向渲染路径时,场景中的所有对象都是按顺序渲染,根据影响每个对象的光源数量,可能在多个通道中渲染,因此当对象被多个光源照亮时,渲染成本会急剧增加。这种类型的渲染器通常提供各种各样的着色器,并且可以很轻松地处理透明度。
  • 在使用延迟渲染路径时,所有(不透明)几何体首先渲染到缓冲区中,在其中存储有关材质的信息(颜色、镜面反射、光滑度等等)。在后一种通道(也就是“延迟”)中,每个像素按顺序着色:渲染时间将主要取决于影响每个像素的光源数量。对于透明对象以及某些包含复杂着色器的对象,仍然需要额外的前向渲染通道。当处理包含许多动态光源的场景时(例如具有人工光照的内部空间,或室外与室内光照相结合的项目),通常建议使用延迟渲染。

2018 年 1 月,Unity 推出了可编程渲染管线 (SRP),允许通过 C# 脚本来自定义渲染循环。这实际上是游戏引擎领域的一次小革命:用户终于无需使用像 C++ 这样的低级编程语言便可以个性化设置对象剔除、绘制和帧后期处理。

Unity 当前提供两个预先构建的 SRP:

  • 高清渲染管线 (HDRP) 是一种混合延迟/前向瓦片/聚类渲染器。它提供了先进的渲染和着色功能,是专为要求逼真视觉的 PC 和高端游戏主机项目而设计。

瓦片是帧的一个小型二维方形像素部分,而聚类则是摄像机视锥体中的一个三维体积。瓦片和聚类渲染技术都依赖于影响每个瓦片和聚类的光源的列表,然后可以用相应的已知光源列表在一个通道中计算其光照。不透明对象很可能使用瓦片系统进行着色,而透明对象则依赖于聚类系统。该渲染器的主要优点是,与内置渲染管线(延迟)相比,光照处理速度更快,带宽消耗也大大减少,因为内置渲染管线依赖于更慢的多通道光照积累。

  • 通用渲染管线 (URP) 是一种快速的单通道前向渲染器;它主要设计用于不支持计算着色器技术的低端设备,例如较早的智能手机、平板电脑和 XR 设备。但是,URP 还可为中端设备(如游戏主机和 PC)提供更高质量的图形性能,有时其性能成本低于内置渲染管线。URP 根据每个对象来剔除光线,并允许在单个通道中计算光照,与内置渲染管线相比,这会降低绘制调用次数。最后,URP 还提供 2D 渲染器,并规划了延迟渲染器。

您可以使用下面的决策图表来快速确认您应该根据几个关键标准选择哪一种渲染管线。

设置

可以通过 Unity Package Manager (Window > Package Manager) 来下载最新版本的 HDRP 和 URP。要使用这些 SRP 的其中之一,最简单的方法是使用 Unity Hub 来创建一个新项目并使用其中一个对应的模板。

如果要为项目设置 HDRP,请确保安装了所需的包。然后,使用 HD Render Pipeline Wizard (Window > Render Pipeline > HD Render Pipeline Wizard) 来一键设置您的项目。

可扩展性

如果您略懂渲染方面的知识,熟悉 C#,并需要为项目完全定制渲染器,您可以试着使用 SRP 概念来创建您自己的自定义可编程渲染管线。因为通用渲染管线的着色器库较小并且能够快速注入、删除和交换渲染通道,因此可以对通用渲染管线进行轻松扩展。

兼容性

在 Unity 中将项目的材质从内置渲染管线移植到 HDRP 或 URP 相对比较容易,这要归功于 Edit > Render Pipeline > Upgrade… 下的一键材质转换器。请注意,这种操作是不可逆的。强烈建议提前备份您的项目!

尽管如此,必须手动移植自定义着色器,因此在生产过程中从内置渲染管线过渡到 HDRP 或 URP 可能会耗费时间,具体时间取决于必须重新编写的自定义着色器数量。

此外,由于 HDRP 在物理上比内置渲染管线更正确,特别是在光衰减和分布方面,因此在切换到 HDRP 之后,项目应该会有所不同。

此外,HDRP 和 URP 并不是交叉兼容的,因为它们没有共同的渲染特征。可以将项目从 HDRP 移植到 URP,反过来也可以,但并不是一键操作,而是需要手动重新制作光照、材质和着色器!

全局光照系统

如果要在场景中添加间接光照,必须使用 Unity 的两个全局光照系统之一,或者使用您自己的烘焙解决方案生成这种光照。在 Unity 的 Window > Rendering > Lighting Settings 下提供的这两个系统是:

1.实时全局光照:这个系统完全依赖于第三方光照中间件 Enlighten。在 Unity 中的预计算期间,Enlighten 经历两个漫长的阶段:聚类和光线传输。第一个阶段是将场景简化为一组称为聚类的面片,第二个阶段是计算这些聚类之间的可见性。在运行时,这些预计算的数据用于以交互方式生成间接光照。Enlighten 的强大功能依赖于实时编辑光照的能力,因为预计算的数据依赖于聚类间的关系。然而,与其他传统的光照贴图技术一样,编辑场景中的静态几何体将触发新的预计算。目前正在从 Unity 中移除 Enlighten,并在研究一种新的解决方案。 * HDRP 对于 Unity 2019.3 及更高版本中的新项目不支持实时全局光照。尽管如此,在 Unity 2019.3 之前创建的项目仍可以升级到 2019.3 或 2019 LTS。 * URP 从未支持使用 Enlighten 提供实时全局光照。 * 内置渲染管线将支持使用 Enlighten 提供实时全局光照,直到 Unity 2020 LTS(2020 年底或 2021 年初)为止。这意味着该版本的重大错误修复将继续到 2022 年底或 2023 年初。

总而言之,如果您要在 Unity 2019.3 或更高版本中创建新项目,则在使用 URP 或 HDRP 的情况下将不可使用 Enlighten。如果选择内置渲染管线,则 Enlighten 将保持可用状态,直到 2020 年底或 2021 年初。

2.烘焙全局光照:光照被烘焙成称为光照贴图的纹理以及光照探针。烘焙 GI 系统可以使用下列其中一个光照贴图程序: * 渐进光照贴图程序 (Progressive Lightmapper) * Enlighten

渐进光照贴图程序可以优先计算摄像机视野内对象的光照,并大大加快光照的迭代速度,而代价是增加整个场景的整体烘焙时间。渐进光照贴图程序使用 CPU 根据路径追踪来计算间接光照。一种新的 GPU 渐进光照贴图程序目前处于预览版,将极大降低场景的烘焙时间。

因为 Enlighten 和渐进光照贴图程序使用不同的方法产生烘焙光照,因此在比较这两者时,不应该期望得到完全匹配的光照效果。

请查看下面的图表,确定项目适合使用哪种全局光照系统,以及该系统的主要优点和缺点。

静态与动态对比

无论使用哪种全局光照系统,在烘焙/预计算光照过程中,Unity 只会考虑标记为“Contribute GI”的对象。动态(即非静态)对象必须依赖于放置在整个场景中的光照探针来获得间接光照。

由于光照的烘焙/预计算是一个相对缓慢的过程,所以只有具有不同光照变化(例如凹度和自我阴影)的大型和复杂资源才应被标记为“Contribute GI”。获得均匀光照的较小和凸面网格不应进行这样的标记,因此它们应该从光照探针获得间接光照;光照探针中存储了更简单的光照近似值。较大的动态对象可以依赖 LPPV,以便获得更好的本地化间接光照。要最大程度减少烘焙时间并同时保持足够的光照质量,最重要的就是限制场景中标记为“Contribute GI”的对象数量。可在本教程中详细了解这个优化过程和探针光照的重要性。

警告

Unity 允许烘焙和实时 GI 系统同时有效,因此可以访问所有光照功能。但是,务必注意,同时启用这两个系统会大大增加运行时的烘焙时间和内存使用量,因为这些系统不依赖相同的数据集。此外,在运行时对间接光照的交互式更新将给 CPU 带来更大的压力,而且在视觉上比较烘焙和实时 GI 系统提供的间接光照时,应该会看到差异,因为它们依赖不同的技术来模拟间接光照,并且通常以明显不同的分辨率运行。

同时使用这两个 GI 系统应仅限于高端平台和/或以可预测的成本对场景进行严格控制的项目。这种方法只应由非常了解所有光照设置的专家用户使用,因为同时管理这两个系统会增加很大的复杂性。所以,对大多数项目来说,选择两个 GI 系统的其中一个通常是更安全的策略。很少推荐同时使用这两个系统!

光照模式

Light 组件的 Mode 属性是一种常常让人混淆的属性。

Light Inspector 中提供了三种光照模式

1.烘焙:从这些光源产生的直接和间接光照被烘焙成光照贴图,这可能是一个耗时的过程。处理这些光源不需要运行时成本,但是将所产生的光照贴图应用到场景中确实需要很小的成本。 2.实时:来自这些光源的直接光照和阴影是实时的,因此不会被烘焙成光照贴图。它们的运行成本可能很高,具体取决于场景的复杂性、阴影投射光源的数量、重叠光源的数量等。此外,如果启用实时全局光照,则会在运行时更新间接光照,从而产生性能成本。 3.混合:这种混合模式提供烘焙和实时功能(如烘焙间接光照和实时直接光照)的混合。场景中所有混合光源的行为及其性能影响取决于该场景的光照模式

必须注意的是,只有启用了烘焙全局光照系统时,光源的模式才有意义。如果不使用任何 GI 系统或只使用实时 GI 系统,那么所有烘焙光源和混合光源的行为就好像它们的 Mode 属性设置为 Realtime 一样。

下面的图表结合了一个决策流程图和一个比较表;可以帮助您决定每次在场景中添加新光源时哪种光源模式合适。

光照模式

如前面的图表中所示,场景中的所有混合光源具有特定的烘焙和实时功能,具体取决于您在 Lighting 窗口中选择的光照模式 (Lighting Mode)。

有三种模式可供选择:

1.Subtractive 2.Baked Indirect 3.Shadowmask

Shadowmask 光照模式有两个质量设置:

1.Shadowmask 2.Distance Shadowmask

使用 HDRP 的阴影遮罩光照模式 (Shadowmask Lighting Mode) 时,在 Graphics 设置中分配的 HDRP 资源中会启用阴影遮罩功能;然后必须通过 Frame Settings 专门为您的摄像机激活该功能。

渲染管线比较表

下表概述了 Unity 2019.3 中每个渲染管线支持的功能。

光照情形

我们已经介绍了渲染管线和主要光照功能,现在让我们看看几个项目的例子,看看可以使用哪些设置来提供光照。由于每个项目都是独一无二的,因此您可能会根据自己的需求使用稍微不同的选项。

1.原型构建或快速预先可视化

如果您严重依赖 Asset Store 来构建原型,则内置渲染管线可能是唯一合适的渲染管线,因为 Asset Store 中的大多数资源并不完全兼容 HDRP 和 URP;尽管如此,资源兼容性将随着时间推移而改善。如果您要从头开始构建所有资源,并且已经清楚了解了自己项目的需求,那么您可以从这两个 SRP(即 URP 或 HDRP)中选择一个,甚至创建一个自定义 SRP。

如果处于(预)生产的早期阶段,并且需要快速周转时间和最大的光照灵活性,您可能更想要使用一种不需要任何预计算的完全实时方法,因此您可能希望同时关闭烘焙和实时 GI 系统。为了缓解缺少正确间接光照的问题,您可以启用屏幕空间环境光遮挡 (Screen Space Ambient Occlusion):该功能可以提供低成本的实时接触阴影,从而帮助场景中的对象上底色。

2.3D 手机策略游戏

如果目标平台是移动设备,URP 可能是很好的候选项,可确保策略游戏的扎实性能。如果需要自定义渲染管线以更好地适应游戏,图形开发程序员可能会发现,扩展 URP 会更加简单明了。如果选择 URP 并且使用烘焙全局光照,请注意,目前不支持阴影遮罩混合光照模式 (Shadowmask Mixed Lighting Mode)。

或者,如果您决定坚持使用内置渲染管线,例如,由于您依赖 Asset Store 中的许多资源,那么所有混合光照模式都受支持。在这种情况下,采用阴影遮罩光照模式 (Shadowmask Lighting Mode) 的方法将提供烘焙阴影,同时仍然允许动态对象投射实时阴影。如果阴影遮罩对您的项目来说成本过高,则可以回退到最低成本的 Subtractive 模式。最后一点,如果关卡中有非常少的光源,且目标平台采用旧硬件,那么前向渲染路径可能是最好的选择。

3.AAA 级走廊射击游戏(一天中的固定时间)

如果目标是在 PC 和游戏主机上实现线性第一人称射击游戏的 AAA 级质量视觉效果,HDRP 应该是首选的渲染管线。同样,还可以在图形开发程序员的帮助下开发自定义 SRP。

如果关卡包含许多投射实时阴影的光源(例如,可破坏的灯光道具和移动光源),那么应该将烘焙 GI 系统与 Baked Indirect 模式配合使用,这样可以确保混合方向光和静态灯光道具中的烘焙光源呈现出良好的间接光照效果。如果关卡中大部分都是投射固定阴影的光源,那么推荐使用阴影遮罩的方法,因为 HDRP 提供了一个很好的混合阴影遮罩模式,允许更精细地控制实时阴影和烘焙阴影之间的混合。

如果您还计划支持 Nintendo Switch,则建议您使用 URP,这样您就可以支持市场上的大多数游戏平台,而不必经历将项目从 HDRP 移植到 URP(或反之)的繁琐过程。

4.大逃杀游戏(昼夜周期)

如果您计划发布一款面向 PC 和游戏主机的大逃杀类型游戏(特征是包含大规模环境和完全动态光照),那么应该选择 HDRP,或者进行扩展以便为项目量身定制渲染管线。如果目标不是实现 AAA 级逼真视觉效果,而是面向低规格的移动设备或系统,那么可以考虑使用 URP。

为了适应昼夜周期,由于 HDRP 和 URP 不支持实时全局光照系统 (Enlighten),因此必须使用间接烘焙和自定义脚本来处理昼夜周期,例如,这样可以模拟一整天中的太阳光和间接光强度。

对于这个特定的场景,例如,如果您使用的是内置渲染管线,不建议同时激活实时 GI 系统和烘焙 GI 系统,因为对于庞大的关卡,性能和场景管理方面产生的开销可能至关重要。反对同时使用这两个 GI 系统的另一个理由是,这样大规模的多人游戏存在着不可预知性:例如,性能估算要远远难于高度可编程的线性关卡。

结束语

由于引入了可编程渲染管线,Unity 中的渲染架构在过去的几年中发生了翻天覆地的变化。因此,要弄清楚所有这些变化及其对光照管线的影响可能会令人筋疲力尽。

希望本指南和及其多个插图能让您更好地理解每个渲染管线的功能,从而能在 Unity 中满怀信心地使用合适的渲染和光照设置让您项目大放异彩!

可通过以下页面来详细了解 Unity 中的光照和渲染管线:

动态光照
专家指南