Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

使用光照贴图全局照明

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

烘焙光照贴图和 VoxelGI、SDFGI 不同,是完全静态的。一旦烘焙就完全不能被修改。它也无法为场景提供反射,因此要在室内场景(或使用 Sky 的室外场景)中获得较好的画质,就需要搭配反射探针使用。

因为是烘焙出来的,所以光照贴图在光线渗透方面的问题会比 VoxelGI 和 SDFGI少很多,且间接光照看起来往往更好。缺点是在烘焙时间上,烘焙光照贴图比烘焙 VoxelGI 要长得多。烘焙 VoxelGI 只需几秒钟,而烘焙光照贴图则可能需要几分钟甚至更久。这可能会严重拖慢迭代速度,因此建议只在真正需要查看光照变化时才烘焙光照贴图。光照贴图在 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 可以支持大型开放世界,无需任何烘焙。

设置

警告

由于图形 API 限制,网页版编辑器不支持烘焙光照贴图。在网页平台上,仅支持 渲染 在其他平台上烘焙的光照贴图。

备注

LightmapGI 节点只会烘焙与其处于同一层级(兄弟节点)或作为其子节点的节点。这允许你使用多个 LightmapGI 节点来分别烘焙场景的不同部分,彼此互不干扰。

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

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

在 Godot 内展开

警告

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

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

../../../_images/lightmap_gi_mesh_menu.webp

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

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

最后一种方法是在你喜欢的 3D 应用程序中进行操作。通常不推荐这种做法,但为了让你知道它的存在,这里还是解释一下。主要优点是,对于可能需要大量重新导入的复杂对象,在 Godot 中进行的纹理生成过程可能相当昂贵,因此在导入之前将其解包可以更快。

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

../../../_images/lightmap_gi_blender.webp

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

../../../_images/lightmap_gi_lmsize.webp

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

为图元网格生成 UV2

备注

此选项仅适用于图元网格,例如 BoxMesh、CylinderMesh、PlaneMesh 等。

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

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

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

为 CSG 节点生成 UV2

自 Godot 4.4 起,你可以 将 CSG 节点及其子节点转换为 MeshInstance3D。通过以下步骤,你可以将其用于在 CSG 节点上烘焙光照贴图:

  • 选择根 CSG 节点并在 3D 编辑器视口顶部选择 CSG > 烘焙网格实例。

  • 隐藏刚刚烘焙的根 CSG 节点(它不会自动隐藏)。

  • 选择新创建的 MeshInstance3D 节点,然后选择 网格 > 为光照映射或环境光遮蔽展开 UV2。

  • 烘焙光照贴图。

小技巧

别忘了在场景树中保留原始的 CSG 节点,这样你就可以在需要时对几何体进行修改。如果要修改几何体,请移除 MeshInstance3D 节点并重新使根 CSG 节点可见。

检查 UV2

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

../../../_images/lightmap_gi_uvchannel.webp

设置场景

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

../../../_images/lightmap_gi_scene.webp

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

设置网格

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

../../../_images/lightmap_gi_use.webp

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

设置灯光

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

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

../../../_images/lightmap_gi_bake_mode.webp

模式有:

Disabled(禁用)

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

警告

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

Dynamic

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

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

根据 Shadowmask Mode 的取值,你仍然可以为 DirectionalLight3D 获取远处的烘焙阴影。这使得近处的阴影可以实时渲染并显示动态物体,同时允许远处的静态物体仍然投射阴影。

Static

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

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

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

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

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

烘焙

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

../../../_images/lightmap_gi_bake.webp

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

警告

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

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

调整

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

  • 超采样:以更高分辨率生成光照贴图后降采样,可减少噪点与漏光现象,并提升小尺度细节的阴影质量。但会延长烘焙时间并增加内存占用。超采样系数决定降采样前光照贴图的渲染尺寸。

  • Bounces:间接光照的反弹次数。默认值(3)是烘焙时间和质量之间的一个平衡点。取值越高,光线在停止之前反弹的次数越多,间接光照的效果也就越平滑(但同时也可能越亮,取决于材质和几何)。

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

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

  • Shadowmask 模式:如果设置为除 None 以外的其他模式,场景中第一个使用 Dynamic 全局光照模式的 DirectionalLight3D 的静态阴影将被烘焙到一个称为 shadowmask 的单独纹理中。这可以用于让远处的静态物体在其他静态物体上投射阴影,而不管距离摄像机有多远。有关更多详细信息,请参阅 shadowmasking 部分。

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

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

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

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

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

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

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

  • Gen Probes > Subdiv:见 动态对象。

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

使用阴影遮罩实现远距离平行光阴影

当使用 DirectionalLight3D 时,其实时阴影的绘制距离受到 Shadow Max Distance 属性的限制。在大型场景中,这可能会成为一个问题,因为远处的物体将不会显示来自 DirectionalLight3D 的照射下的阴影。虽然可以通过在 DirectionalLight3D 上使用 Static 全局光照模式来解决这个问题,但这有几个缺点:

  • 由于直接光和间接光都是烘焙的,动态物体无法以逼真的方式在静态表面上投射阴影。在这种情况下,Godot 会完全跳过阴影采样,以避免“双重光照”的伪影问题。

  • 近距离的静态阴影缺乏细节,因为它们只依赖于光照贴图纹理,而不是实时的阴影级联。

我们可以通过使用 shadowmasking(阴影遮罩)来避免这些缺点,同时仍然受益于远处阴影。虽然动态物体不会接收到来自阴影遮罩的阴影,但由于大多数场景主要由静态物体组成,它仍然能极大地改善视觉效果。

由于光照贴图本身不包含阴影信息,我们可以将这些阴影信息烘焙到一个单独的纹理中,称为 shadowmask。

阴影遮罩(shadowmasking)仅影响场景中第一个(由树顺序决定)使用 Dynamic(动态)全局光照模式的 DirectionalLight3D。由于 Static(静态)全局光照模式会完全跳过对静态物体的阴影采样,因此无法在该模式下使用阴影遮罩。这是因为静态全局光照模式会烘焙直接光和间接光。

有三种阴影遮罩模式可用:

  • None(默认): 不烘焙阴影遮罩纹理。方向光阴影在 DirectionalLight3D 的 Shadow Max Distance(阴影最大距离)属性指定的范围之外将不可见。

  • 替换:烘焙一个 shadowmask 纹理,并在超出 DirectionalLight3D 的 Shadow Max Distance 属性指定范围时使用它来绘制方向光阴影。在此范围内的阴影保持完全实时。这个选项通常对大多数场景最有意义,因为它可以很好地处理表现出微妙运动的静态对象(例如植被阴影)。

  • Overlay:烘焙阴影遮罩纹理,并使用它来绘制方向光阴影,无论与摄像机的距离如何。在 DirectionalLight3D 的 Shadow Max Distance 属性范围内的阴影将叠加实时阴影。这可以使实时阴影和烘焙阴影之间的过渡不那么突兀,但代价是静态物体阴影会出现“涂抹”效果,具体取决于光照贴图的纹素密度。此外,这种模式无法很好地处理表现出细微运动的静态物体(如植被),因为烘焙阴影无法随时间变化而动画化。不过,对于摄像机快速移动的场景,这可能是比 Replace 是更好的选择。

这是一张不同 shadowmask 模式的视觉对比图,其中 Shadow Max Distance 被设置得非常低以便于比较。蓝色方块是动态物体,而场景的其余部分是静态物体。场景中只有一个 DirectionalLight3D,并且启用了动态全局光照模式:

阴影遮罩模式之间的比较

阴影遮罩模式之间的比较

备注

你可以在替换(Replace) 和叠加(Overlay) 两种 shadowmask 模式之间切换,而无需重新烘焙光照贴图。

平衡烘焙时间和质量

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

通过增加导入的 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 后可见。较高的值可以更有效地消除噪声,但代价是会抑制静态阴影的阴影细节。

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

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

OIDN(Open Image Denoise)

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

如果配置了硬件加速,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 编辑器的顶部切换 视图 > 小工具 > LightmapGI(“闭眼”图标表示这个 Gizmo 已隐藏)。

光照贴图数据

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

小技巧

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

减少 LightmapGI 的伪影

如果你发现 LightmapGI 节点在摄像机移动时忽隐忽现,这很可能是因为引擎一次渲染了太多 LightmapGI 实例。Godot 的限制是一次只能渲染 8 个 LightmapGI 节点,这意味着摄像机视图中最多可以出现 8 个实例,超过这个数量它们就会开始闪烁。