Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

使用光照贴图全局照明

烘焙的光照贴图也是一种为场景添加间接光照(也叫全烘焙光照)的工作流程。与 VoxelGI 的方法不同,烘焙光照贴图在低端 PC 和移动设备上运行良好,因为它们在运行时几乎不消耗资源。与 VoxelGI 和 SDFGI 的另一个不同点是,烘焙光照贴图还能够用来保存直接光照,从而进一步提升性能。

烘焙光照贴图与 VoxelGI 和 SDFGI 不同,是完全静态的,一旦被烘焙就完全不能被修改。它也不能为场景提供反射,所以如果要达到较好的画质,在室内场景(或者是使用 Sky 的室外场景)中就需要和 反射探针 搭配使用。

因为是烘焙出来的,所以在光线渗透方面的问题就比 VoxelGI 和 SDFGI 少很多,并且间接光照也会看上去更漂亮。烘焙光照贴图的缺点是烘焙所需的时间比 VoxelGI 长很多,VoxelGI 几秒钟就能搞定的烘焙,换成烘焙光照贴图就可能至少得花上几分钟。这会严重拖慢迭代速度,所以推荐只在确实有查看光照变化的需求时进行光照贴图的烘焙。从 Godot 4.0 开始,光照贴图烘焙在 GPU 上运行,如果你有中端或高端专用 GPU,则光照烘焙的速度会更快。

烘焙光照贴图还会占用被烘焙材质的 UV2 栏位,也就是说你无法再把 UV2 用于该材质的其它用途(无论是内置的 标准 3D 材质与 ORM 3D 材质 还是自定义着色器)。

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

参见

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

视觉比较

LightmapGI 已禁用。

LightmapGI 已禁用。

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

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

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

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

视觉比较

以下是 LightmapGI 和 VoxelGI 的一些显示效果比较。可以看到光照贴图更精确,但也由于光照事实上是位于展开纹理上的影响,所以过渡以及分辨率可能就没有那么理想。VoxelGI 看上去没有那么精确(因为是近似估算),但总体上更平滑。

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

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

设置

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

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

使用 Godot 进行展开

警告

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

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

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

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

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

最后一种方法是在你喜欢的 3D 应用程序中进行操作。通常不推荐这种做法,但为了让你知道它的存在,这里还是解释一下。这种做法的主要优势在于,针对可能要经常重新导入的复杂对象,在 Godot 中进行纹理生成的代价可能相当高,所以在导入前展开可以提高速度。

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

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

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

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

如果在导入时使用外部网格,则将保留大小。请注意,3D 建模软件中的大多数解包器都不是以质量为导向的,因为它们的目的是快速工作。你通常需要使用接缝或其他技术来创建更好的展开效果。

为图元网格生成 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 文件的修改。

Reducing LightmapGI artifacts

If you notice LightmapGI nodes popping in and out of existence as the camera moves, this is most likely because the engine is rendering too many LightmapGI instances at once. Godot is limited to rendering 8 LightmapGI nodes at once, which means up to 8 instances can be in the camera view before some of them will start flickering.