ARM 在Unity3D 中的美术优化解决方案 5.光照

(注意:虽然我们选择了渐进 CPU 光照贴图,但我们鼓励你试用渐进 GPU 光照贴图并进行性能分析。根据系统 GPU 的不同,性能可能会有所差异。)

Unity 引擎提供了三个生成光照贴图的选项 - Enlighten、Progressive CPU lightmapper 和 Progressive GPU lightmapper。在本项目中,我们选择使用渐进 CPU 光照贴图,因为 Enlighten 即将弃用,而渐进 GPU 光照贴图还处于预览阶段。

使用渐进 CPU 光照贴图实现烘焙光照时,可在处理光照信息时节省 CPU 周期。因此,你可能会发现每秒帧数 (FPS) 大幅增加,而 CPU 使用率却出现下降。在测量两个场景的 FPS 时,你应会在 Statistics 窗口中看到明显的差异。

移动设备能够真正体现这种差异。将示例场景构建到你选择的手机上,对两个场景进行性能分析,同时在性能分析器的 Global Illumination 部分中观察 Total CPU 图。根据手机的规格,你应会看到 CPU 使用率存在巨大差异。

可以看到,更高的分辨率会增加所需的工作量。应从较低的 Lightmap Resolution(5 - 10 之间)开始,然后根据场景需要进行放大或缩小。增加 Lightmap Resolution 会导致每次迭代时大小大幅增加。

例如,将 Lightmap Resolution 从 15 降低到 12,可将所需的光照贴图数量从 7 个减少到 4 个,如下面的屏幕截图所示。

2.光照贴图和全局光照

在为移动设备开发应用程序时,使用静态光照至关重要。静态光照在移动设备上的运行速度更快,可为用户带来更好的体验。可以通过称为烘焙的过程(在该过程中,Unity 在运行时之前执行光照计算并保存结果)保存非移动对象上的静态光照信息。

相比之下,非静态光照(如动态或实时光照)是在每一帧中计算和更新的。虽然这可以增加场景的逼真度和增强沉浸感,但其成本要高得多。因此,在使用非静态光照时,要注意在美学目标与性能之间取得平衡。2.烘焙光照光照是实时 3D 视觉效果最重要的方面之一。它可以营造气氛、引导交互、确定目标和目的。在本项目中,我们将介绍并比较可在 3D 移动应用程序中使用的各种光照和光照模式之间的差异。

光照 - 概述

在本教程中,我们将简要讨论为什么良好的光照在 3D 移动应用程序中很重要以及本项目的学习目标。

1.概述

光照是实时 3D 视觉效果最重要的方面之一。它可以营造气氛、引导交互、确定目标和目的。光照也能营造或破坏用户体验。好的光照技术可让简单模型焕发生机,而差的光照技术可令精细模型神采尽失。在本项目中,你将:

  • 了解并比较静态光照与动态光照的区别。

  • 了解如何在保持最佳性能的同时表现你想要的视觉效果,例如伪造光照/阴影。

  • 比较不同的光照模式和光源类型,以便为你的 3D 场景实现最高效、最准确的光照。

2.关于渲染管线的说明

在创建移动应用程序时,要确保你的最终产品在尽可能多的设备上流畅运行,这一点非常重要。Unity 的通用渲染管线 (URP)(一种针对移动性能进行了调整的预先构建的可编程渲染管线)拥有多种功能,可帮助你的移动应用程序发挥出最佳性能。有关 URP 的更多信息,请参阅 Unity 文档

在下一个教程中,我们将介绍 Unity 中可用的不同光源类型和模式。

光照模式和类型

在本教程中,我们将比较 Unity 中可用的光照模式和类型以及它们的优缺点。

1.光照模式

在 Unity 中,有几种不同的光照模式可供选择。这些模式与光源的移动性及其在场景中的使用方式有关。各种模式在性能方面存在差异,因此在实现光照时,这是一个重要的考虑因素。在本教程中,我们将探讨三种不同光照模式(baked、mixed 和 real-time)的优缺点。

2.烘焙光照

烘焙光照模式提供静态光照,也就是说,它在运行期间不会发生改变。烘焙是指在运行游戏前将光照数据存储在纹理贴图中的过程。关于烘焙光照模式,有以下重要注意事项:

  • 光照和阴影被烘焙到了光照贴图中,因此在运行时无法修改。这项处理是在 Unity 中创建光照时完成的,因此不影响运行时性能。

  • 阴影是静态的,如果在游戏过程中有动态或移动对象,阴影可能会显得很奇怪。

  • 烘焙光照模式是我们在本指南中讨论的计算成本最低的方法。

3.实时光照

实时光照模式提供动态或可移动的光照。实时光照模式的主要特点如下:

  • 动态光照和阴影未烘焙到光照贴图中,可在运行时进行修改。

  • 实时光照模式是我们在本指南中讨论的计算成本最高的光照模式。

4.混合光照

混合光照模式将静态光源与移动对象结合在一起。可以将其视为其他两种方法的混合体。混合光照模式的主要特点如下:

  • 提供动态的直接光照和阴影。

  • 混合光照类型的光源可以参与静态物体的光照贴图烘焙过程。

  • 光源会影响动态对象,包括为这些对象生成阴影。

  • 可在运行时更改强度,并且仅更新直接光照。

  • 混合光照模式是一种代价高昂的计算方法。

5.实时光源和光源类型

在构建 3D 移动应用程序时,应尝试使用烘焙光照、光照探针和材质效果处理所有的光照。当需要使用实时光源时,必须考虑要使用的实时光源类型。各种类型的计算成本存在差异:

  • 方向光:方向光朝所有方向发射、无衰减,是成本最低的实时光照。通常只需要一个方向光,因为它可以照亮整个场景。这意味着,在进行前向渲染时,Unity 将始终渲染一个方向光。即使场景中没有方向光,也是如此。

  • 点光源:点光源位于空间中的一个点,并在所有方向上均匀发光。

  • 聚光灯:相比球形点光源,聚光灯能剔除更多对象,因此它是成本第二低的实时光照类型。限制锥体宽度,只让它照亮选定对象,以获得最佳性能。

使用聚光灯和点光源看似时尚,但也会影响性能。相比之下,方向光计算成本较低,并可照亮所有区域。小区域应使用聚光灯,大区域应使用点光源,同时还应考虑它们对性能的影响。阴影计算可能是光照计算中开销最大的部分,向各个方向投射光线会增加阴影计算所花费的计算能力。动态光源的渲染成本很高,最好不要在移动游戏中使用。有时,3D 引擎会根据所用的设备和图形 API 限制其使用。例如,在 Unity 通用渲染管线前向渲染器中,每个对象最多只能使用 8 个光源(使用 OpenGL ES 2.0 时,限制为 4 个光源)。

6.总结

光照是 3D 可视化的重要组成部分,但在场景中放置光源之前,需要考虑性能影响。在下一个教程中,我们将介绍在静态对象上生成光照的最佳实践。

静态对象的光照

在本教程中,我们将讨论光照对于静态对象的重要性,以及光照贴图和全局光照的应用。

1.概述

在为移动设备开发应用程序时,使用静态光照至关重要。静态光照在移动设备上的运行速度更快,可为用户带来更好的体验。可以通过称为烘焙的过程(在该过程中,Unity 在运行时之前执行光照计算并保存结果)保存非移动对象上的静态光照信息。

相比之下,非静态光照(如动态或实时光照)是在每一帧中计算和更新的。虽然这可以增加场景的逼真度和增强沉浸感,但其成本要高得多。因此,在使用非静态光照时,要注意在美学目标与性能之间取得平衡。

2.光照贴图和全局光照

烘焙会生成称为光照贴图的单独纹理,它存储了有关光照效果的信息。该信息已缓存,因而不会在运行时产生额外的性能成本。在为移动平台构建应用时,应将尽可能多的信息烘焙到光照贴图中。

预烘焙的光照无法根据场景的动态方面进行调整。但是,烘焙光照包括场景中所有静态元素的全局光照,这让每个静态元素可以发出和接收间接反射光,使得光照更加逼真。

下图显示了一个完全烘焙的场景:

Unity 让烘焙光照变得极其简单。你必须事先执行以下两个步骤:

1.单击包含要切换的光源组件的游戏对象。将 Mode 设置为 Mixed 或 Baked。

对于移动平台,请尽可能选择 Baked 而不是 Mixed,因为 Baked 是代价最低廉的选项。

2.将接收烘焙光照的游戏对象标记为 Static:

可以向一个对象标记多个静态标记,但通常的做法是在设置中选择 Everything。当将一个对象标记为 Static 时,Unity 就知道要在烘焙过程中包括该对象。

(注意:如果为某个对象启用了 Batching Static,你将无法移动该对象或对其进行动画处理。这是另一种优化,应尽可能保持开启。)

请记住,在烘焙光照时,是基于开始烘焙时处于活动状态的场景保存数据的。将生成一个与活动场景同名的文件夹。烘焙光照的所有组件和数据都存储在该文件夹中。如果你的项目使用了多个同时加载的场景,则每个场景都需要单独烘焙光照。如果调整了场景中的光照或对象,则需要重新烘焙光照才能使更改生效。下图显示了一个包含主场景光照数据的文件夹的示例。

3.优化光照贴图

配置要烘焙的光照后,还应确保已优化烘焙光照贴图。

光照贴图的大小取决于烘焙时使用的设置。在移动平台上最好尽量减少内存使用,因此请密切注意光照贴图的大小。在下面的示例图像中,可以看到 7 个 1024x1024 像素的光照贴图。

在地图的预览中,可以看到其网格,其中突出显示了选定的网格。

Lightmapping Settings (Windows > Rendering > Lighting Settings) 中的以下选项和实际地图的大小决定了使用的内存量。

4.光照贴图

Unity 的 Lightmapper 提供了三种不同的方法来烘焙场景中的光照:

  • Enlighten(自 Unity 2019 LTS 起弃用,但仍可使用)

  • 渐进式光照烘焙(CPU)

  • 渐进式光照烘焙(GPU)

下图显示了这些选项:

你应该在任何项目中使用其中一个渐进式光照烘焙。渐进光照贴图以增量方式创建光照贴图,因此可以节省时间。如果选择了 Prioritize View,将优先处理 Scene 视图中的区域。为场景设置光照时,Prioritize View 可加快迭代速度。

CPU 与 GPU 渐进光照贴图的主要区别在于光照贴图是由 CPU 生成还是由 GPU 生成。结果是一样的,但如果你拥有性能强大的 GPU,则渐进 GPU 可能会快得多。可在此处找到更多关于 GPU 选项的要求和设置。

5.纹素

纹素(也称作纹理元素)是纹理贴图中的单个像素。纹素在光照贴图中光线命中某个对象的每个点处存储光照信息。可以通过计算纹素的数量来衡量烘焙光照所需的工作量。了解什么是纹素以及纹素如何影响光照质量、烘焙的计算时间、磁盘存储和 VRAM 成本非常重要。

为尽量减少所需的光照贴图数据量,应在 Lightmapping Settings 中调整每个烘焙单位的纹素数量。通过这些设置,你可以控制光照贴图,包括每个对象在烘焙中使用多少个纹素,如示例图像所示。

Lightmapping Settings 还包括一个名为 Lightmap Resolution 的选项。该选项决定了光照贴图中每个单位使用的纹素数量。要查看场景中纹素的布局,请执行以下操作:

  • 在 Scene 视图的左上角,单击 Shading Mode 下拉选单。

  • 找到并单击 Lightmap Indices。

已烘焙的对象将被置于棋盘格中。这就是烘焙光照时纹素的分布情况。下面的屏幕截图显示了一个立方体采用不同的 Lightmap Resolution 设置时的情况。左侧图像的设置为 1,中间图像的设置为 2,右侧图像的设置为 5。

可以看到,更高的分辨率会增加所需的工作量。应从较低的 Lightmap Resolution(5 - 10 之间)开始,然后根据场景需要进行放大或缩小。增加 Lightmap Resolution 会导致每次迭代时大小大幅增加。

例如,将 Lightmap Resolution 从 15 降低到 12,可将所需的光照贴图数量从 7 个减少到 4 个,如下面的屏幕截图所示。

6.纹素使用量

虽然可以使用 Lightmapping Settings 设置场景中的纹素数量,但你可能还想减少某些对象的纹素数量。

通过 Unity,你可以控制每个对象可以使用的纹素数量。进入对象的 Mesh Renderer (Inspector > Mesh Renderer),可以看到一个名为 Scale In Lightmap 的参数。调整该设置可更改对象在光照贴图中使用的纹素数量。

在下面的屏幕截图中,左侧是一个为每个烘焙单位获取 5 个光照信息纹素(因为 Lightmap Resolution 设置为 5)的普通对象。右侧是一个 Scale In Lightmap 设置为 0.5 的盒体:

右侧盒体的光照贴图占用的空间要远小于左侧盒体。在下面的屏幕截图中,可以看到 Mesh Renderer 组件中可用的光照贴图设置。

请尽量避免在以下元素上使用纹素:

  • 用户看不到的表面和对象。这可避免浪费内存存储更大的光照贴图,换来的却是屏幕上看不到的细节。

  • 光照变化不大的表面,如阴影中的对象或单一光线命中的对象。

  • 小或薄的对象。小或薄的对象接收的光照量不会给场景的最终渲染增色多少。

7.LOD 和光照贴图

在模型上使用细节级别 (LOD) 会影响到烘焙光照。LOD 组中只有最详细的模型会获得光照,就像它是一个静态对象一样,而该组中的其他模型都将获得动态光照。对于直接/间接光照和实时全局光照,将使用不同的光照贴图。

使用 Enlighten 光照贴图时,系统将只烘焙直接光照。要对间接光照进行采样,必须在场景中使用光照探针。

以下图像是 LOD 模型的一些示例。请注意,由于未在场景周围放置光照探针,只有第一张图像中的 LOD 0 模型获得了正确的光照。第二张图像是使用 LOD 的模型的示例,它通过光照探针获得了正确的光照。

为确保正确地对 LOD 模型进行烘焙光照处理,必须在 Static 复选框旁边的下拉菜单中将 LOD GameObject 标记为 Contribute GI。

8.总结

使用光照贴图存储静态对象的光照数据是优化 3D 美术的重要组成部分。在下一个教程中,我们将讨论光照探针如何为移动对象和具有 LOD 的对象提供更逼真的烘焙光照条件。

光照探针

在本教程中,我们将讨论光照探针在 3D 移动应用程序中的最佳用例。

1.光照探针用例

光照探针有两个主要用途:

  • 第一个用途是为场景中的移动对象提供高质量的光照(包括间接反射光)。

  • 第二个用途是在静态景物使用 Unity 的细节级别 (LOD) 系统时提供该景物的光照信息。

光照探针与光照贴图具有很多相同的优点,因为它们都能用于存储在运行游戏前就计算好的光照数据。光照贴图对场景中的表面在给定纹素处接收到的光照进行编码时,光照探针会存储穿过空白空间的光。然后,该数据可用于照亮动态对象,这有助于在视觉上将它们与整个场景中的光照贴图对象融合在一起。光照探针仅存储静态场景的光源和阴影信息。这是因为光照探针是预先烘焙的。它们不是从动态对象、实时光源或自身阴影创建光照的解决方案。尽管如此,光照探针仍可为场景提供大部分光照下面的屏幕截图显示了一个使用光照探针的示例。

有关在场景中实现光照探针的更多信息,请参阅 Unity 文档。

2.总结

光照探针是一种捕获静态场景光照并在运行时将数据应用于移动对象的简单方法,它的成本要低于实时全局光照。在下一个教程中,我们将讨论在 3D 移动应用程序中渲染阴影的最佳实践。

阴影

在本教程中,我们将讨论实现和优化阴影的替代方法。

1.实现伪阴影

真实阴影的渲染计算成本很高。我们建议在动态对象上实现伪阴影,而不要使用动态光照。实时阴影通常通过阴影贴图技术生成。渲染到阴影贴图的场景几何体的成本与绘制到其上的顶点数量相当。考虑到成本,限制场景中的阴影投射几何体数量以及实时阴影投射光照的数量非常重要。下面是实现伪阴影的一些方法:

  • 使用放置在角色下方的 3D 网格、平面或四边形,并对其应用模糊的纹理。

  • 编写自定义着色器以创建更复杂的模糊阴影。

下面的屏幕截图显示了使用阴影网格的阴影实现。

将光照信息直接绘制到纹理上不失为一个好方法。这样做可减少实时光照所需的额外计算。当在场景中烘焙光照时,绘制的光照还可以节省内存,因为场景需要较少的纹理存储光照贴图。

尽可能使用着色器或材质模拟光照。可以使用自定义材质模拟不同类型的光照效果。例如,你可能希望角色具有边缘光照,以提高其可见性和视觉效果。对于这种情况,可以使用着色器营造光照错觉,而不是使用光源创造这种效果。

2.网格渲染器(Mesh Renderer)组件设置

不管场景使用何种光照,都必须确保正确设置网格渲染器。

一个良好的原则是关闭一切不打算使用的设置。例如,Cast Shadows 等设置可能会增加渲染场景的成本,即使对象没有光照也是如此。下面的屏幕截图显示了一个网格渲染器设置的示例:

屏幕截图中显示的选项设置为通过混合最近探针的光照信息来接收光照,但不接收反射。我们使用的是 Blob 方法,因而关闭了 Cast Shadows。场景是烘焙的,没有任何对象投射实时阴影,因此也没有选中 Receive Shadows。

3.总结

阴影可以为 3D 环境增加真实感,但在运行时的计算成本很高。在移动设备上,最好尝试使用着色器、纹理或其他不依赖阴影投射光照的方法伪造阴影。在下一个教程中,我们将深入剖析一个光照演示,以展示烘焙光源可能带来的性能提升。

演示:光照烘焙

最佳做法是尽可能确定 3D 移动应用程序中的静态对象,以便正确、有效地照亮它们。在本演示中,我们将比较烘焙和非烘焙光照的性能。

1.概述

在上一个教程中,你了解了在 3D 场景中实现烘焙光照的好处。在本演示中,你将剖析两个示例场景,并比较烘焙与非烘焙光照的性能差异。

2.开始之前

请在此处下载包含示例演示的课程项目。当弹出提示时,单击 Lighting Demo - Non-baked 或 Lighting Demo - Baked。

也可以在 Project 视图中打开示例场景(Assets > 4 Lighting > Scene > Lighting_Baked 或 Assets > 4 Lighting > Scene > Lighting_Unbaked)。下载并打开后,可以在编辑器中进入运行模式,也可以将该场景构建到移动设备上以在性能分析器中进行性能分析。

3.要观察的内容

如上一个教程中所述,Unity 引擎提供了三个生成光照贴图的选项 - Enlighten、Progressive CPU lightmapper 和 Progressive GPU lightmapper。在本项目中,我们选择使用渐进 CPU 光照贴图,因为 Enlighten 即将弃用,而渐进 GPU 光照贴图还处于预览阶段。

使用渐进 CPU 光照贴图实现烘焙光照时,可在处理光照信息时节省 CPU 周期。因此,你可能会发现每秒帧数 (FPS) 大幅增加,而 CPU 使用率却出现下降。在测量两个场景的 FPS 时,你应会在 Statistics 窗口中看到明显的差异。

移动设备能够真正体现这种差异。将示例场景构建到你选择的手机上,对两个场景进行性能分析,同时在性能分析器的 Global Illumination 部分中观察 Total CPU 图。根据手机的规格,你应会看到 CPU 使用率存在巨大差异。

(注意:虽然我们选择了渐进 CPU 光照贴图,但我们鼓励你试用渐进 GPU 光照贴图并进行性能分析。根据系统 GPU 的不同,性能可能会有所差异。)

4.总结

光照可以强调移动应用程序中可能会被忽略或不被重视的特征。在做出光照决策时,请明智地选择静态和非静态光照,该选择将决定你的应用程序能否达到预期以及能否在目标设备上有效执行。

猜你喜欢

转载自blog.csdn.net/Kaitiren/article/details/129683287