使用光照贴图全局照明

Baked lightmaps are a workflow for adding indirect (or fully baked) lighting to a scene. Unlike the VoxelGI and SDFGI approaches, baked lightmaps work fine on low-end PCs and mobile devices, as they consume almost no resources at run-time. Also unlike VoxelGI and SDFGI, baked lightmaps can optionally be used to store direct lighting, which provides even further performance gains.

Unlike VoxelGI and SDFGI, baked lightmaps are completely static. Once baked, they can’t be modified at all. They also don’t provide the scene with reflections, so using 反射探针 together with it on interiors (or using a Sky on exteriors) is a requirement to get good quality.

As they are baked, they have fewer problems than VoxelGI and SDFGI regarding light bleeding, and indirect light will often look better. The downside is that baking lightmaps takes longer compared to baking VoxelGI. While baking VoxelGI can be done in a matter of seconds, baking lightmaps can take several minutes if not more. This can slow down iteration speed significantly, so it is recommended to bake lightmaps only when you actually need to see changes in lighting. Since Godot 4.0, lightmaps are baked on the GPU, making light baking faster if you have a mid-range or high-end dedicated GPU.

Baking lightmaps will also reserve baked materials’ UV2 slot, which means you can no longer use it for other purposes in materials (either in the built-in 标准 3D 材质与 ORM 3D 材质 or in custom shaders).

尽管缺乏灵活性,但烘焙光照贴图通常在(大多数)静态场景中同时提供最佳质量和性能。这使得光照贴图在游戏开发中仍然很受欢迎,尽管光照贴图是视频游戏中最古老的全局光照技术。

参见

不确定 LightmapGI 是否适合你的需求?Godot 4 中可用的 GI 技术的比较见 我应该使用哪种全局光照技术?

视觉比较

LightmapGI 已禁用。

LightmapGI 已禁用。

LightmapGI 已启用(仅烘焙间接光照)。

LightmapGI 已启用(仅烘焙间接光照)。直射光仍然是实时的,允许在游戏过程中进行细微的修改。

LightmapGI 已启用(直接和间接烘焙光照)。

LightmapGI 已启用(直接和间接烘焙光照)。最佳性能,但视觉效果质量较低。请注意右上角较模糊的太阳阴影。

视觉比较

Here are some comparisons of how LightmapGI vs. VoxelGI look. Notice that lightmaps are more accurate, but also suffer from the fact that lighting is on an unwrapped texture, so transitions and resolution may not be that good. VoxelGI looks less accurate (as it’s an approximation), but smoother overall.

../../../_images/lightmap_gi_comparison.png

与 LightmapGI 相比,SDFGI 的准确性也较低。但是,SDFGI 可以支持大型开放世界,而无需烘焙。

设置

首先,在光照贴图器可以执行任何操作之前,要烘焙的对象需要 UV2 图层和纹理大小。UV2 图层是一组辅助纹理坐标,可确保对象中的任何面在 UV 贴图中都有自己的位置。面与面之间不得共享纹理中的像素。

这里有几种方法可以确保你的对象具有唯一的 UV2 层和纹理大小:

场景导入时展开(推荐)

大多数情况下,这可能是最好的方法。唯一的缺点是,在大型模型上,导入时展开可能需要一段时间。不过 Godot 会在重新导入时缓存 UV2 ,所以只会在需要时重新生成。

在文件系统面板中选择被导入的场景,然后切换到导入面板。这里可以修改以下选项:

../../../_images/lightmap_gi_import.webp

The Meshes > Light Baking option must be set to Static Lightmaps (VoxelGI/SDFGI/LightmapGI):

../../../_images/lightmap_gi_mesh_import_meshes.webp

在导入并展开时,可以使用 网格 > 光照贴图纹素大小 选项调整纹理大小。较低的值将产生更详细的光照贴图,可能会以更长的烘焙时间和更大的光照贴图文件大小为代价获得更高的视觉质量。默认值 0.2 适用于中小型场景,但对于较大的场景,你可能希望将其增加到 0.5 甚至更多。如果你仅烘焙间接照明,则尤其如此,因为间接光是低频数据(这意味着它不需要高分辨率纹理即可准确表示)。

设置此选项的效果是场景中的所有网格都将正确生成其 UV2 贴图.

警告

When reusing a mesh within a scene, keep in mind that UVs will be generated for the first instance found. If the mesh is re-used with different scales (and the scales are wildly different, more than half or twice), this will result in inefficient lightmaps. To avoid this, adjust the Lightmap Scale property in the GeometryInstance3D section of a MeshInstance3D node. This lets you increase the level of lightmap detail for specific MeshInstance3D nodes (but not decrease it).

另外,请不要在版本控制系统中忽略 *.unwrap_cache 文件,这些文件可以用来保证不同平台、不同版本的引擎在重新导入 UV2 时的一致性。

使用 Godot 进行展开

警告

如果在导入的 3D 场景上使用此 Mesh 菜单操作,则重新加载场景时生成的 UV2 将丢失。

Godot 可以选择展开网格并可视化 UV 通道。 选择 MeshInstance3D 节点后,可以在 3D 编辑器视口顶部的 Mesh 菜单中找到它:

../../../_images/lightmap_gi_mesh_menu.png

这将生成第二组 UV2 坐标, 可用于烘焙, 并且还将自动设置纹理大小.

使用你自己的 3D 建模软件展开

The last option is to do it from your favorite 3D app. This approach is generally not recommended, but it’s explained so that you know it exists. The main advantage is that, on complex objects that you may want to re-import a lot, the texture generation process can be quite costly within Godot, so having it unwrapped before import can be faster.

只需在第二个UV2层上进行展开即可。

../../../_images/lightmap_gi_blender.png

然后正常导入 3D 场景。记得在导入后为网格设置纹理大小。

../../../_images/lightmap_gi_lmsize.png

If you use external meshes on import, the size will be kept. Be wary that most unwrappers in 3D modeling software are not quality-oriented, as they are meant to work quickly. You will mostly need to use seams or other techniques to create better unwrapping.

为图元网格生成 UV2

备注

此选项仅适用于图元网格,例如 BoxMeshCylinderMeshPlaneMesh 等。

在图元网格上启用 UV2 可以使它们接收烘焙照明并做出贡献。这可用于某些照明设置。例如,你可以在烘焙光照贴图后隐藏具有自发光材质的圆环,以创建遵循圆环形状的区域光。

默认情况下,图元网格不会生成 UV2 以节省资源(因为这些网格可以在游戏过程中创建)。你可以在检查器中编辑基元网格并启用添加 UV2,以使引擎按程序为图元网格生成 UV2。默认的 UV2 填充值经过调整,以避免大多数光照贴图渗色,而不会在边缘浪费太多空间。如果你注意到光照贴图仅在特定基元网格上渗色,则可能需要增加 UV2 填充

Lightmap Size Hint(光照贴图大小提示)表示光照贴图纹理上的单个网格所采用的大小,该大小因网格的大小属性和 UV2 Padding 值而异。Lightmap Size Hint 不应手动更改,因为重新加载场景时任何修改都将丢失。

检查 UV2

在前面提到的网格菜单中, 可以显示 UV2 纹理坐标。如果出现问题,请仔细检查网格是否具有以下 UV2 坐标:

../../../_images/lightmap_gi_uvchannel.png

设置场景

首先需要在场景中添加一个 LightmapGI 节点。这将在该场景中的所有节点(和子节点)上启用光照烘焙,甚至在实例化场景中也是如此。

../../../_images/lightmap_gi_scene.png

烘焙器支持同一子场景存在多个实例,它们会有各自独立的光照贴图(前提是你得遵守之前提过的关于缩放的规则)。

设置网格

对于要参与烘焙过程的 MeshInstance3D 节点,需要将其光照烘焙模式设置为 Static 。光照烘焙模式设置为 DisabledDynamic 的网格体将被光照贴图器忽略。

../../../_images/lightmap_gi_use.png

在场景导入时自动生成光照贴图时, 会自动启用此功能.

设置灯光

默认情况下,灯光采用间接灯光烘焙。这意味着阴影贴图和光照仍然是动态的并影响移动的物体,但从该光反射的光将被烘焙。

灯可以禁用(不烘焙)或完全烘焙(直接和间接). 这可以通过灯光中的 烘焙模式 菜单进行控制:

../../../_images/lightmap_gi_bake_mode.png

模式有:

Disabled(禁用)

烘焙光照贴图时,光线会被忽略。这个模式可以用于动态光照效果,例如爆炸和武器特效。

警告

隐藏灯光对生成的光照贴图烘焙没有影响。这意味着你必须使用禁用烘焙模式,而不是通过禁用其 Visible 属性来隐藏 Light 节点。

Dynamic

这是默认的模式,是性能与实时友好性的折衷。只会烘焙间接光照。直接灯光和阴影仍旧是实时的,就像没有 LightmapGI 时一样。

这个模式可以在保持显示效果相对正确的同时,允许进行灯光颜色、能量、以及位置的 微调 。例如,你可以借此实现静态火把的闪烁,它的间接光照仍然是烘焙的。

Static

间接和直接光照都将被烘焙。 由于静态表面可以完全跳过照明和阴影计算,因此此模式提供了最佳性能,并且实现永远不会根据距离而衰退的平滑阴影。 实时光将不再影响烘焙表面,但仍会影响动态对象。 在灯光上使用 All (全部) 烘焙模式时,动态对象不会将实时阴影投射到烘焙表面上,因此你需要使用别的方法,例如斑点阴影。 斑点阴影可以使用 Decal 节点来实现。

游戏过程中无法调整灯光。灯光的移动、改变颜色(或者调整能量)都不会对静态表面产生影响。

由于烘焙模式可以根据每个光源进行调整,所以可以创建混合烘焙光源设置。 一种比较流行的选择是使用实时 DirectionalLight,并将其烘焙模式设置为 Dynamic ,并使用 OmniLights 和 SpotLights 的 Static 烘焙模式。 这样做能有良好的性能,同时仍然允许动态对象在室外区域投射实时阴影。

完全烘焙的灯光还可以利用灯光节点的 大小 (全向/聚光)或 角度距离 (方向)属性。 这允许阴影具有真实的半影,随着阴影投射者和阴影之间距离的增加,半影的尺寸也会增加。 与实时 PCSS 阴影相比,这也具有较低的性能成本,因为只有动态对象才会在其上渲染实时阴影。

../../../_images/lightmap_gi_omnilight_size.png

烘焙

要开始烘焙过程,请在选择 LightmapGI 节点时,单击 3D 编辑器视口顶部的 烘焙光照贴图 按钮:

../../../_images/lightmap_gi_bake.png

根据场景大小、所选烘焙方法以及质量的不同,其过程可能花费几秒钟到几分钟不等(也可能是几小时)。

警告

烘焙光照贴图是一个可能需要大量视频内存(即显存)的过程,尤其是当生成的纹理很大时。 由于内部限制,如果生成的纹理尺寸太大(即使在具有大量视频内存的系统上),引擎也可能崩溃。

为了避免崩溃,请在导入面板上确保光照贴图的纹素大小设置到了足够高的值。

调整

  • Quality:提供了四种烘焙质量模式:Low(低级)、Medium(中级)、High(高级)、Ultra(超级)。质量越高所需的时间越长,但最终光照贴图的显示效果越好、噪点也越少。针对自发光材质或者几乎没有直接光照的地方,不同质量模式之间的区别尤为显著。每个烘焙质量模式都可以在项目设置中进一步调整。

  • Bounces :(反弹)间接光照的反弹次数。默认值( 3 )是烘焙时间和质量之间的一个平衡点。取值越高,光线在停止之前反弹的次数越多,间接光照的效果也就越好(同时也越亮)。在做最初的光照迭代工作时,建议把反弹次数减小到 1 以加快烘焙速度。请注意,降低反弹次数会让场景变暗。

  • Bounce Indirect Energy: (反弹间接能量)烘焙灯光间接能量时使用的全局乘数。这会乘以每个灯自己的 Indirect Energy 值。不是 1.0 的值在物理上并不准确,但可以用于艺术效果。

  • Directional: (定向)如果启用,则存储光照贴图的方向信息。 这改善了烘焙表面的法线贴图材质的外观,尤其是在完全烘焙的灯光下(因为它们也有直接光线烘焙)。 缺点是定向光照贴图的渲染成本稍高。 它们还需要更多的时间来烘焙,从而导致文件大小更大。

  • Interior: (内部)如果启用,将不会获取环境照明。 将其用于纯室内场景以避免漏光。

  • Use Texture for Bounces: (使用纹理进行反弹)如果启用,将生成带有照明信息的纹理,以加快间接照明的生成速度,但会牺牲一定的精度。当使用低分辨率光照贴图或在表面上明显地拉伸光照贴图的 UV 时,几何体可能会出现额外的漏光伪影。如果不确定,请默认启用此功能。

  • Use Denoiser: (使用降噪器)如果启用,则使用去噪算法使光照贴图的噪点明显减少。这个设置开启会增加烘烤时间,并且偶尔会引入伪影,但结果通常是值得的。请参阅 降噪 了解更多信息。

  • Denoiser Strength: (降噪器强度)应用于生成的光照贴图的去噪步骤的强度。值越高,消除噪点越有效,但会减少静态阴影的阴影细节。仅当启用降噪且降噪方法为 JNLM 没有降噪强度设置)。

  • Bias :(偏置)用于 3D 单位阴影的偏移值。 通常不需要更改此值,除非烘焙后光照贴图中遇到光渗色(light bleeding)或黑点问题(dark spots)。 此设置不会影响烘焙表面上投射的实时阴影(对于具有 Dynamic 光照烘焙模式的灯光)。

  • Max Texture Size: (最大纹理尺寸)生成的纹理图集的最大纹理尺寸。 较高的值将导致生成的切片较少,但由于硬件对纹理大小的限制,可能无法在所有硬件上工作。 如果不确定,请将其保留为默认值 16384

  • Environment > Mode: (环境 > 模式)控制烘焙光照贴图时环境光照的来源方式。 Scene 的默认值适用于具有可见外部部件的关卡。 对于纯室内场景,将其设置为 Disabled 以避免漏光并加快烘焙速度。 也可以将其设置为 自定义天空自定义颜色 以使用与实际场景的环境天空不同的环境照明。

  • Gen Probes > Subdiv: (生成探针 > 细分)详见 动态对象

  • Data > Light Data: (数据 > 光照数据)详见 光照贴图数据

平衡烘焙时间和质量

因为高质量的烘焙可能花费非常长的时间(大型复杂场景可能需要数十分钟),推荐首先设置成较低质量。 之后,场景的照明设置到了让你非常满意的程度,就可以提高质量设置,并在导出项目之前执行“最终”烘焙。

通过增加导入的 3D 场景上的 光照贴图纹素尺寸 来降低光照贴图分辨率,也会显着地加快烘焙速度。 但是,这将要求你重新导入所有有光照贴图的 3D 场景,然后才能再次烘焙光照贴图。

降噪

由于烘焙光照贴图依赖于光线追踪,因此“原始的”烘焙光照贴图中始终会存在可见的噪点。在反射光难以到达的区域(例如阳光可以进入的开口较小的室内区域),噪点尤其明显。提高烘焙质量可以减少噪点,但这样做会显着增加烘焙时间。

禁用降噪和启用降噪之间的比较

禁用降噪和启用降噪之间的比较(使用默认的 JNLM 降噪器)。

为了消除噪点而不过多增加烘焙时间,可以使用降噪器。降噪器是一种在最终烘焙光照贴图上运行的算法,检测噪声模式并软化它们,同时尝试最好地保留细节。 Godot 提供了两种降噪算法:

JNLM(Non-Local Means with Joint Filtering,联合过滤的非局部均值)

JNLM 是 Godot 自带的默认的降噪方法。它使用一种简单但有效的降噪算法,称为 非局部均值 (non-local means)。 JNLM 使用计算着色器在 GPU 上运行,并且与任何可以运行 Godot 4 的基于 Vulkan 的渲染方法的 GPU 相兼容。该方法无需额外设置。

JNLM 的降噪可以使用 Denoiser Strength 属性进行调整,该属性在启用 Use Denoiser 后可见。较高的 Denoiser Strength 值可以更有效地消除噪声,但代价是会抑制静态阴影的阴影细节。

不同 JNLM 降噪强度值之间的对比

不同 JNLM 降噪强度值之间的对比。较高的值将会减少阴影细节。

OIDN (Open Image Denoise)

与 JNLM 不同,OIDN 使用机器学习方法对光照贴图进行降噪。与 JNLM 相比,ODIN 具有经过专门训练的模型,可消除光照贴图的噪点,同时在大多数场景中保留更多阴影细节。

如果配置了硬件加速,OIDN 可以在 GPU 上运行。借助现代高端 GPU,与基于 CPU 的降噪相比,这个配置可以提供超过 50 倍的加速:

  • 在 AMD GPU 上,必须安装和配置 HIP。

  • 在 NVIDIA GPU 上,必须安装并配置 CUDA。CUDA的安装配置可能由 NVIDIA 安装程序自动完成,但在 Linux 上,默认情况下可能不会安装 CUDA 库。仔细检查你的 Linux 发行版中的 CUDA 软件包是否已安装。

  • 在 Intel GPU 上,必须安装和配置 SYCL。

如果硬件加速不可用,OIDN 将回退到基于多线程 CPU 的降噪。要确认基于 GPU 的降噪是否有效,请在烘焙光照贴图时使用 GPU 利用率监视器,并在 Godot 编辑器中显示去噪步骤时查看 GPU 利用率和 VRAM 利用率。 对此, nvidia-smi 命令行工具很有用。

由于 OIDN 的下载包相对较大,所以它不包含在 Godot 中。你可以从其`网站<https://www.openimagedenoise.org/downloads.html>`__ 下载预编译的 OIDN 二进制包。将包解压到 PC 上的某个位置,然后在编辑器设置中指定 oidnDenoise 可执行文件的路径( 文件系统 > 工具 > OIDN > OIDN 降噪器路径 )。该可执行文件位于你提取的二进制包的 bin 文件夹中。

指定 OIDN 降噪可执行文件的路径后,通过将 渲染 > 光照贴图 > 降噪器 设置为 OIDN 来更改项目设置中的降噪方法。设置更改后,这将影响该项目上的所有光照贴图烘焙。

备注

降噪方法需要在项目设置中配置,而不是在编辑器设置中。这样做是为了确保同一项目的不同团队成员使用相同的降噪方法,以最终获得一致的表现。

JNLM 和 OIDN 降噪器的比较

JNLM 和 OIDN 降噪器之间的比较。请注意 OIDN 如何更好地保留细节并减少不同对象之间的接缝。

动态对象

与 VoxelGI 和 SDFGI 不同,动态对象接收间接光照的方式与静态对象不同。 这是因为光照贴图仅在静态对象上执行。

为了显示动态对象上的间接照明,使用了 3D 探针系统,其中光照探针遍布整个场景。 烘焙光照贴图时,光照贴图器将计算探针接收到的 间接 光量。 直射光不会存储在光照探针中,即使对于将烘焙模式设置为 Static 的光源也是如此(因为动态对象继续会实时点亮)。

有两种方法可以向场景中添加光照探针:

  • Automatic(自动):Gen Probes > Subdiv 设置为 Disabled 以外的值,然后烘焙光照贴图。 默认值为 8,不过你可以选择更大的值来提高精度,但代价是烘焙时间会更长且输出文件大小会更大。

  • Manual(手动): 作为除自动生成探针之外,或者作为自动生成探针的替代方案,你可以通过向场景添加 LightmapProbe 节点来手动添加光照探针。 这可用于改善动态物体经常经过的区域的照明细节。 在场景中放置 LightmapProbe 节点后,必须再次烘焙光照贴图才能使其生效。

备注

烘焙光照贴图后,你会注意到 3D 场景中的白色球体,它们表现了烘焙光照将如何影响动态对象。 这些球体 不会 出现在正在运行的项目中。

如果要在编辑器中隐藏这些球体,请在3D编辑器的顶部切换 View > Gizmos > LightmapGI (“闭眼”图标表示这个 Gizmo 已隐藏)。

光照贴图数据

LightmapGI 节点中的 Data > Light Data 属性包含烘焙后的光照贴图数据。纹理会被保存到磁盘上,但这里还会包含动态对象的捕获数据,数据量可能非常大。如果你使用的是 .tscn 格式的场景,应该将此资源保存成外部的二进制 .lmbake 文件,否则 .tscn 场景可能因为使用 Base64 编码二进制数据而变得巨大。

小技巧

如果有后期处理的需要,可以使用图像编辑器查看并编辑所生成的 EXR 文件。不过请注意,重新烘焙贴图会覆盖你对 EXR 文件的修改。

Previous Next


© 版权所有 2014-present Juan Linietsky, Ariel Manzur and the Godot community (CC BY 3.0). Revision b1c660f7.

Built with Sphinx using a theme provided by Read the Docs.