使用预计算实时全局光照优化照明-优化实时光照贴图

本文地址:https://blog.csdn.net/t163361/article/details/123994783
翻译说明:
教程翻译主要用谷歌翻译后,对特别不通顺的地方进行了微调。同时针对一些比较重要的地方保留了英语或英语和汉语同时存在的方式。

教程目录

优化实时光照贴图

中级 1 小时

摘要

在本教程中,您将改进由 Unity 的预计算实时 GI 生成的自动展开 UVs功能。

1.概述

现在您已经从光照预计算中排除了合适的对象,您可以开始通过优化 UV 展开来减少剩余图表(Charts)的数量。
图表被创建来包含一个静态网格渲染器的UV光照贴图坐标。 因此,对象所需的图表数量在很大程度上取决于展开相关对象所需的 UV 壳(块)的数量。 展开始终是几何面上纹理像素分布失真与足够纹理覆盖所需的壳数之间的权衡。

2.了解 Unity 的展开算法

Unity 复杂的展开算法通常无需您的干预即可获得良好的结果;但是,有时您需要提供一些指导。因此,了解自动展开背后的理论和过程非常重要。
让我们回顾一下如何投影或展开对象上的 UV 的三个不同示例:
示例 1
未失真但需要多个 UV 壳的展开示例图像
在第一个示例中,结果基本上没有失真。用作纹理的方格图案的映射方式是,纹理的每个图块在纵横比上保持正方形。如果你想象这个棋盘是一个光照贴图(一张应用在物体上的灯光的“图像”),你会得到一个看起来正确且没有失真的结果。
但是,您需要使用六个 UV 壳来获得这种覆盖。结果,您将使用 Unity 的预计算实时 GI 系统获得六个图表。无论对象的大小如何,每个图表都需要至少 4x4 纹素,这意味着该对象将使用至少 96 纹素,而与分辨率无关。
示例 2
生成单个 UV 壳但会产生不可接受的纹理扭曲的 UV 坐标示例图像。
在第二张图片中,有一个不同的问题。 对象的 UV 纹理坐标已被投影,因此有一个完整的 UV 壳覆盖所有面。
虽然这在覆盖对象所需的图表数量方面是最佳的,但视觉结果会出现不可接受的失真。 您可能会看到应用在对象表面上的纹理“涂抹”。 对象的面也在 UV 纹理空间中重叠——这意味着如果您引用光照贴图,来自对象一侧的光照将显示在相对的面上。 这种展开对象的方法不会给您可接受的结果。
示例 3
示例图像显示了理想的结果,没有纹理扭曲和单个 UV 壳。
第三张图片显示了理想展开的示例。结果没有失真:棋盘纹理的瓷砖在纵横比上保持正方形。我们还成功地覆盖了对象的所有面,同时仅输出一个 UV 壳。这是通过连接或缝合与模型上的连续几何边缘相对应的 UV 边缘来实现的。
如果您以编程方式考虑这一点,我们做了什么来实现理想的展开?
首先,我们将 UV 投影正交投影到对象上,以创建单独的壳。
然后,我们评估这些壳的边缘,这些边缘在相应对象的几何形状中共享。
在找到共享边的地方,我们将这些壳移动并缝合到它们相邻壳的伙伴边缘。
这就是 Unity 的展开算法尝试对静态几何体自动执行的操作。

3.可视化图表

在优化展开图表和光照贴图图表之前,您需要一种在编辑器中可视化它们的方法。图表是在网格导入管线的展开阶段生成的。对于预计算实时 GI,这些图表随后在预计算过程的几何阶段被打包到图集中。这是为了确保它们不会重叠。
只有在预计算的几何阶段完成并保存可视化数据后,您才能看到图表的预览。
重要提示:如果您作为团队的一部分使用版本控制,请注意此信息在本地缓存。这意味着在各种诊断绘制模式可用之前,必须在本地计算机上执行预计算。
您可以采用两种不同的方法来可视化图表。
选项 1:使用 UV 图表绘制模式
快速可视化图表的一种方法是使用场景视图中的 UV Charts绘制模式。使用此模式,图表可以被视为不同颜色的面板,上面覆盖着代表相应光照贴图分辨率的棋盘纹理。要使用此模式:

  1. 在 Scene 视图的左上角,使用 Draw Mode 下拉菜单选择 UV Charts
  2. 如果您启用了自动生成模式(Window > Rendering > Lighting Settings > Auto Generate),将自动计算展开参数的更改,并且Scene视图将使用结果更新。
    UV 图表模式下的场景视图,将场景中使用的不同图表表示为彩色区域,将光照贴图分辨率表示为棋盘覆盖。

选项 2:使用照明窗口预览窗格
处理复杂对象时,很容易错过场景视图中的图表。通过使用 Lighting 窗口中的 Preview 窗格,您可以查看单个对象使用的所有图表。这可以帮助您更准确地评估这些对象的展开,这将帮助您减少场景中的图表计数。
要使用预览窗格:

  1. 在Hierarchy中,选择您要查看的对象。
  2. 打开 Lighting 窗口(Window > Lighting)并选择 Object 选项卡。
  3. 在 Inspector 窗口(Window > General > Inspector)中展开 Lightmapping 标题。
  4. 展开Realtime Lightmap折叠,双击光照贴图缩略图(lightmap thumbnail)。
  5. 在 Preview 窗格的右上角,从下拉菜单中选择 UV Charts
    该对象使用的图表数量将由彩色方块表示,上面覆盖有相应的浅蓝色 UV 坐标。
    对象预览窗口的 UV 图表模式,将 UV 图表显示为彩色方块,将光照贴图 UV 显示为浅蓝色线框。

4.展开参数:Optimize Realtime UVs

您可以调整许多设置以优化 UV 展开。所有这些设置都是针对每个对象的。您可以在“照明”窗口中访问这些设置:

  1. 选择您希望在Hierarchy窗口中查看的对象。
  2. 在 Inspector 窗口(Window > General > Inspector)中,展开 Lightmapping 折页。

Optimize Realtime UVs
Unity 的自动展开算法允许用户在编辑器中创作光照贴图 UV。您可以使用 Optimize Realtime UVs 选项来访问这些控件,这些控件可以在 Mesh Renderer 组件的 Lightmapping 折叠下找到。
启用此选项会公开两个属性:Max DistanceMax Angle。您将在本教程的后面部分查看这些属性。
优化实时 UV 位于 Mesh Renderer 组件内的 Lightmapping 折页中。
在某些情况下,使用自动展开器可能无法获得理想的展开。最终可能会在光照贴图中出现太多图表或不可接受的失真(在 GI 图表绘制模式下显示为拉伸棋盘格)。在这些情况下,可能需要在模型文件的 UV01 通道中手动创作 UV。这是在您选择的内容创建包中需要完成的工作。
如果是这种情况,请禁用 Optimize Realtime UVs 设置,以强制 Unity 的展开算法保留定义在模型的 UV01 通道中的 UV 壳的形状。
需要注意的是,这些外壳将始终重新打包以节省光照贴图空间。这是单独展开外壳的方式,它将被保留,而不是使用在光照贴图中的位置(此句翻译可能有误,后面是原句:It is the manner in which the shells are unwrapped, individually, which will be preserved rather than the shell’s position within the lightmap)。
重要提示:使用此方法时必须小心。 在光照贴图 UV 包含大量 UV 壳的情况下,此选项实际上会增加预计算时间。 这是因为绕过了Unity 的自动展开器提供的 UV 合并步骤,并且保留了手动 UV 布局。 请记住,期望的结果是尽可能少的 UV 壳 - 因此尽可能少的图表 - 同时保持可接受的失真水平。

5.展开参数:Max Distance

Unity 的展开算法试图通过移动外壳并将 UV 边缘缝合在一起来简化光照贴图 UV。仅当壳在 Max Distance 定义的距离内时,这些UV壳才会被此操作考虑。此范围以 Unity 的世界空间单位定义。请记住,在示例场景中,我们假设单位为 1 米。
在 Mesh Renderer 组件的 Lightmapping 标题下找到的 Max Distance 设置。
在许多情况下,0.5 个单位的默认值将给出可接受的结果。对于具有很多面的特别大的对象,可能需要增加此值。这是为了防止合适的候选 UV 被拼接算法排除在选择之外。
增加最大距离通常会减少所选对象所需的图表数量。减小这个值在光照贴图纹素可见拉伸的情况下很有用,我们实际上可能需要更多图表来获得所需的纹素覆盖。使用 UV Charts Scene视图绘图模式中的棋盘覆盖可以轻松评估这些更改的结果。找到正确的平衡通常需要一些实验。

6.展开参数:Max Angle

照明 UV 壳也会根据相应网格的相邻面之间的角度进行缝合评估。Max Angle定义共享 UV 边的面之间允许的最大角度,并使用内角进行计算。如果背面之间的角度大于此值,则不会考虑缝合这些 UV 壳。
在 Mesh Renderer 组件的 Lightmapping 标题下找到的 Max Angle 设置。
增加此值将使光照 UV 更有可能通过 Unity 的展开算法进行组合。因此,最大角度是减少选定对象所需图表数量的好方法。但是,有时当此容差过于宽松时,可能会出现拉伸光照贴图。减小最大角度将使展开器不太可能合并 UV 边缘,这将导致更多图表但更少失真。
同样,在 UV Charts Scene 视图渲染模式中使用棋盘叠加是评估您正在使用的值的适用性的好方法。

7.展开参数:Ignore Normals

在某些情况下,网格导入器可能会决定分割几何体。这也会影响图表。例如,如果网格具有极高的三角形数,则 Unity 将其拆分为单独的子网格可能会更高效。通常这是针对硬件特定要求,例如减少每次绘制调用中的三角形数量。这些分裂发生的位置是根据相邻网格面之间的法线角度存在较大差异的区域(例如硬边)来确定的。
在模型的网格导入过程中以这种方式拆分网格。在此过程中,图表可能会被拆分,因为图表中的边可能会被分离,从而导致多个外壳,这反过来又需要额外的图表。
在 Mesh Renderer 组件的 Lightmapping 标题下找到的 Ignore Normals 设置。
有时不希望以这种方式拆分图表。图表数量的增加可能不利于预计算时间,并且光照接缝可能会导致生成的光照贴图中出现不需要的视觉伪影。在这些情况下,启用 Ignore Normals 属性将防止图表被拆分以用于预计算实时 GI 照明。
注意:只有预计算实时 GI 受此选项影响。选定网格中的分割仍保留用于 Unity 中的其他用途。

8.优化预计算时间:隔离感兴趣的对象

复杂的场景可以包含数百甚至数千个静态对象。为所有这些对象生成图表图集可能会导致缓慢的照明预计算,这会对您在场景上迭代的速度产生负面影响。
在尝试对象的展开设置时,有时将感兴趣的对象隔离在空场景中会很有用,您可以在其中以最少的预计算时间快速迭代。然后可以取回您确定的展开设置并将其应用于原始场景中该类型的其他对象。在准备照明场景时,以这种方式工作可以节省大量时间。
让我们将房屋对象隔离为感兴趣的对象:

  1. 打开示例项目中包含的 LightingTutorialStart 场景。
  2. 在层次结构中,选择名为 HouseBig02 的游戏对象之一。这些被分组在环境 > 结构 > 房屋下。
  3. 通过选择 Ctrl+C(在 macOS 上为 Cmd+C)将此对象复制到剪贴板。
  4. 通过选择 Ctrl+N(在 macOS 上为 Cmd+N)创建一个新场景。
  5. 如果提示保存您的更改,如果您对当前场景进度感到满意,请选择“Yes”,如果您想放弃它,请选择“No”。
  6. 在新创建的场景中,通过选择 Ctrl+V(在 macOS 上为 Cmd+V)从剪贴板粘贴 HouseBig02。
  7. 打开 Lighting 窗口(Window > Rendering > Lighting Settings),然后选择 Scene 选项卡。
  8. 启用 Auto Generate 属性以打开自动预计算模式。

9.优化预计算时间:查看对象的 UV 展开设置

配置展开参数时,理想的结果是找到导致图表数量最少光照贴图失真最小的值的组合。请记住,当启用UV图表绘制模式时,扭曲将可视化为应用于场景视图中的对象的棋盘纹理的拉伸。
棋盘图案可用于可视化光照贴图纹理分布。请注意,在下面的示例中,整个模型中的棋盘格相对一致——这意味着光照贴图失真很小。
带有棋盘格的 UV 展开示例图像 棋盘格显示几乎没有失真。
在第二个示例中,这个示例棋盘的拉伸和扭曲表明光照贴图纹素的分布存在一些不一致。
UV 展开的示例图像,其中棋盘被拉伸和扭曲。
让我们应用您学到的关于 UV 展开的知识来优化教程项目中对象的预计算时间:

  1. 在 Hierarchy 中,选择 HouseBig02游戏对象。
  2. 在 Inspector 窗口(Window > General > Inspector)中展开 Lightmapping 标头。
  3. 展开Realtime Lightmap折叠,双击光照贴图缩略图。
  4. 在 Preview 窗格的右上角,从下拉菜单中选择 UV Charts 以查看对象是如何展开的。
    显示具有默认展开设置的 HouseBig02 对象的图表预览的图像。

HouseBig02 在我们的场景中是一个相当复杂的对象,这可能证明使用多个图表是合理的。但是,我们仍然可以通过修改我们的展开设置来减少这个数字。
对象展开设置面板

10.优化预计算时间:调整最大距离

没有一种万能的解决方案来展开对象。 Unity 的展开算法试图根据适当的默认值做出明智的决定,但在一些用户指导下,它可能能够获得更优化的结果。
减小最大距离
让我们从减小最大距离开始:

  1. 在 Hierarchy 中,选择 HouseBig02游戏对象。
  2. 在 Inspector 窗口(Window > General > Inspector)中展开 Lightmapping标头。
  3. 启用Optimize Realtime UVs
  4. Max Distance 设置为其最小值 0.1

预计算过程将开始。经过简单的计算,您会在 Lighting 窗口的 Preview 区域中看到 Charts 的数量明显增加。检查场景视图似乎没有什么失真,这很好。然而不幸的是,此类复杂的对象具有这么多图表是不可接受的。请记住,更多图表意味着更长的预计算时间并降低运行时的性能。
增加最大距离
让我们尝试增加 Max Distance 值:

  1. 在 Hierarchy 中,如果尚未选择 HouseBig02游戏对象,请选择它。
  2. 在 Inspector 窗口(Window > General > Inspector)中展开 Lightmapping标头。
  3. Max Distance值设置为 10
    显示 HouseBig02 游戏对象的光照贴图 UV 失真的图像

你现在有相反的问题。图表的数量有所减少,但代价是给光照贴图带来了不可接受的失真。您可以在 UV Charts场景视图渲染模式中观察到这种失真。失真显示为棋盘覆盖的条纹或拉伸。
您现在知道 Unity 的展开算法试图通过将 UV 壳合并在一起来最小化图表的数量。最大距离设置指定考虑合并时 UV 壳之间允许的最大距离(在世界空间中)。如果壳之间的距离超过此值,则它们不会被合并。
在您的实验中:

  • 当您减小最大距离时,符合合并条件的 UV 壳会减少。这意味着在流程结束时会保留更多单独的图表。
  • 当您增加最大距离时,在世界空间中相距很远的 UV 壳随后能够被合并。这导致图表更少,但这种激进的合并也导致光照贴图 UV 扭曲,因此光照贴图输出出现更多失真。

请注意,对于大型对象,有时可能需要增加最大距离以适应网格内面的大小。相反,随着较小的对象减小最大距离可能会产生更好的结果。
优化最大距离
对于这个示例对象 HouseBig02,Max Distance 值为 0.8 可以很好地平衡图表计数和失真:

  1. 在 Hierarchy 中,如果尚未选择 HouseBig02游戏对象,请选择它。
  2. 在 Inspector 窗口(Window > General > Inspector)中,展开 Lightmapping标头。
  3. Max Distance值设置为 0.8
    图像显示了 HouseBig02 游戏对象的改进光照贴图 UV
    但是,仍然可以进行一些进一步的改进。

11.优化预计算时间:调整最大角度

现在让我们回顾一下 Max Angle 参数。与 Max Distance 一样,此值会影响 Unity 展开算法的 UV 合并步骤。除了在合并 UV 壳之前测试距离外,展开器还测试相邻网格面之间的角度。只有角度低于此值的边才会被考虑合并。
较小的最大角度意味着较少的边缘将通过测试。结果,将合并更少的 UV 壳,并且图表的数量将增加。相反,更大的 Max Angle 意味着合并算法将更能容忍面之间的角度。可能会合并更多的 UV 壳,其结果可能是更少的 UV 壳,因此图表也更少。与 Max Distance 一样,如果由于公差过大而组合了不合适的边缘,最终光照贴图 UV 中可能会出现失真。
减小最大角度
让我们尝试减小最大角度:

  1. 在 Hierarchy 中,如果尚未选择 HouseBig02 游戏对象,请选择它。
  2. 在 Inspector 窗口(Window > General > Inspector)中,展开 Lightmapping 标头。
  3. Max Angle值设置为 0
    显示具有过多图表的 HouseBig02 游戏对象的图像

当您回顾 Lighting 窗口的 Preview 区域时,我们会注意到创建的图表数量高得无法接受。这是因为在考虑合并之前,您只允许面之间的偏差为 0 度或更小。这几乎可以肯定意味着没有 UV 外壳将通过测试,因此许多图表将在合并过程之后依然被保留。
增加最大角度
接下来,让我们尝试增加最大角度:

  1. 在 Hierarchy 中,如果尚未选择 HouseBig02 游戏对象,请选择它。
  2. 在 Inspector 窗口(Window > General > Inspector)中,展开 Lightmapping 标头。
  3. 慢慢增加Max Angle值,在Lighting窗口的Preview窗格中观察每次变化的效果。

显示具有减少图表数量的 HouseBig02 游戏对象的图像
您应该注意到图表的数量随着值的增加而减少。这是因为考虑合并的网格面之间允许的角度更宽容。更多的 UV 壳通过测试并将被合并。因此,光照贴图 UV 壳的数量减少了,相应的图表数量也减少了。这种方法对于减少具有圆形表面的对象上的图表特别有用。
优化最大角度
对于此示例对象 HouseBig02,Max Angle93 可提供良好的结果:

  1. 在 Hierarchy 中,如果尚未选择 HouseBig02 游戏对象,请选择它。
  2. 在 Inspector 窗口(Window > General > Inspector)中,展开 Lightmapping 标头。
  3. Max Angle值设置为 93
    在对其展开设置进行了一些优化之后,HouseBig02 的图表预览。
    请注意,在进行简短的预计算后,Lighting 窗口的 Preview 区域中的图表数量是如何减少的。

12.优化预计算时间:返回工作场景

在这个阶段,您优化的展开设置可以带回工作场景:

  1. 在 Hierarchy 中,如果尚未选择 HouseBig02 游戏对象,请选择它。
  2. 在 Inspector 窗口中,找到 Mesh Renderer 组件,然后选择组件右上角的 More options (⋮)。
  3. 选择Copy Component
    菜单中突出显示的复制组件选项
  4. 打开 LightingTutorialStart 场景。
  5. 在Hierarchy中,找到所有名为 HouseBig02 的对象。
  6. 按住 Ctrl(macOS 上为 Cmd)并在 Hierarchy 窗口中选择每个 HouseBig02 游戏对象。
  7. 在 Inspector 中,找到 Mesh Renderer 组件。
  8. 选择组件右上角的More options (⋮)。
  9. 选择Paste Component Values以应用您之前复制的设置。

当应用于包含数百个对象的场景时,这些设置为您带来的适度节约可以增加更显著的优化效果。

13.Unwrap设置和Prefabs

展开设置可以存储在 Prefab 中,方法是将它们应用到 Prefab 层次结构中的任何 Static MeshRenderer 组件。或者,也可以将展开设置应用于场景中的单个游戏对象。应用于场景中预制件实例的展开设置将覆盖存储在预制件中的设置。这种工作方式为您提供了一些设置场景照明的有用方法。
逐预制件设置
为预制件配置默认展开和照明设置通常很有用。如果要多次实例化预制件,则可以省力地预先配置该对象的展开,而不必在整个场景中重复指定。
逐预制变体设置
作为 Unity 2018.3 版本中引入的嵌套预制件功能的一部分,现在可以创建预制件变体。 Prefab Variant 从作为其变体的 Prefab 继承属性(称为基础 Prefab)。您可以为基于基础预制体创建的每个预制变体覆盖这些属性。这是一种非常有用的方式来配置适用于大多数场景的默认设置,然后在特殊情况下覆盖这些设置。
例如,如果在可播放区域内可以近距离看到 Prefab Variant,那么在该 Variant 上使用更高保真度设置是有意义的。如果 Prefab Variant 距离很远,那么使用照明预算来维持相同的资源密集型设置是没有意义的。在这种情况下,您可以采用的更好方法可能是降低光照贴图的质量并在展开时使用更积极的拼接参数。

14.在整个场景中应用展开设置

现在是时候开始将您学到的关于 Unity 自动展开算法的知识应用到 LightingTutorialStart 场景中剩余的静态几何体了。通过系统地工作,设置场景以显着改善预计算时间应该不需要很长时间:

  1. 打开示例项目中包含的 LightingTutorialStart 场景。
  2. 在 Hierarchy 窗口中,选择 Environment > Structures 下的顶部游戏对象。
  3. 将游戏对象复制到一个空场景。

此时,您应该应用您所学到的关于展开参数的知识,并随意尝试不同的值。请记住将 UV Charts Scene 视图 Draw Mode 与 Lighting 窗口的 Preview 区域的 Charting 模式结合使用。这将使您能够在光照贴图失真和所需图表数量之间找到适当的平衡。
训练指导
LightingTutorialOptimal 场景可以在您不确定的情况下用作参考。请注意,在某些情况下,甚至可能根本不需要更改默认展开值。默认值实际上可能提供最佳结果。
要完成此练习:

  1. 尝试不同的展开参数值,直到图表数量和光照贴图失真之间达到平衡。
  2. 复制设置,返回 LightingTutorialStart 场景并将它们粘贴到同一游戏对象的所有其他实例中。多选层次结构中的所有相应对象将使您能够使用Paste Component Values快速将设置应用于多个对象。
  3. 对 Hierarchy 视图中每个唯一命名的游戏对象重复此过程。
  4. 一旦Structures 组下的所有游戏对象都已优化,请转到Rocks组下剩余的静态几何体。

以这种方式有条不紊地工作,设置场景中所有静态几何体的展开值应该不会超过几分钟。这种手动准备的结果将是在照明场景时更快的迭代和更好的运行时性能。

15.下一步

在本教程中,您探索了展开在减少项目中图表数量方面的作用,这可能对照明优化产生重大影响。
接下来,您将通过微调 Unity 项目中的光照贴图参数来完成此学习体验。

下一篇 微调光照贴图参数

猜你喜欢

转载自blog.csdn.net/t163361/article/details/123994783