在这个关于 Blender 4.5 中使用 Fluid 模拟器制作火焰与烟雾系列教程的第三课中,我们将讨论 Blender 如何执行和存储 Bake,也就是火焰与烟雾的物理模拟计算。
本教程是关于 Blender 4.5 中火焰与烟雾基础的 10 集迷你系列的一部分。要查看完整的剧集列表,请点击这里。
本教程的视频版本目前尚未提供该语言版本,但可在页面顶部选择英文查看。
视频文字稿
大家好。在这个关于 Blender 4.5 中使用 Fluid 模拟器制作火焰与烟雾系列教程的第三课中,我们将讨论 Blender 如何执行和存储 Bake,也就是火焰与烟雾的物理模拟计算。我们还会讲解如何为一个 Domain 只计算一次模拟,然后将其复制并放置到场景的其他位置,而无需为所有副本重新计算模拟。最后,我们会学习如何为模拟设置 Offset,使动画一开始就呈现已经在燃烧的火焰,而不是从点燃瞬间开始。
本教程的初始场景包含一个装有木柴的火盆。
这些是两个独立的网格对象,其中木柴组成一个单一网格。
火盆放置在一个矩形 Plane 上,作为地面,稍后我们会在上面放置其他火盆。虚拟世界的 Strength 设置为 0,并且没有光源,因此在 Rendered 模式下场景会完全呈现为黑色。
根据前几课的内容,我们知道,要让一个物体产生火焰,需要为其添加一个类型为 Fire And Smoke Flow 的 Fluid 组件。因此,我为木柴添加一个 Physics Fluid 组件,并将 Behavior 设置为 Inflow,这意味着木柴将在每一帧持续生成火焰。

接着我创建一个 Cube,为其添加一个 Flow 组件并将类型设置为 Domain,然后让它最初包围整个场景。我们立刻会发现一个问题:默认分辨率过低,生成的 Voxels 过大,导致火焰相对于发射它们的物体显得过于巨大。
将分辨率提高到 64 后情况并没有明显改善,而且模拟时间也开始变长。我甚至不打算再继续提高分辨率,因为很明显这并不是正确的解决方案。

最直接的解决方法是缩小 Domain,使其只包围火盆,并在上方保留一定空间供火焰和烟雾发展。现在分辨率甚至表现得有些过高。实际上可能有些过度,我们可以将其降低回 32,同时仍然获得清晰的火焰效果。真正的问题是木柴产生的火焰过于强烈。

要减少火焰的生成量,可以调整 Inflow 对象的 Fuel 参数。直观来说,Fuel 值越高,每一帧燃烧的燃料就越多。因此,只需降低该值,直到火焰大小合适为止。
正如前几课提到的,与 Baking 相关的数据,也就是物理模拟的计算结果,会存储在一个专用文件夹中,其路径在 Domain 对象的 Cache 面板中指定。在创建 Domain 之前,我已经将文件保存到磁盘,因此缓存文件夹位于 Blender 项目文件所在的同一目录。
在 Domain 的 Cache 面板中,可以设置用于计算模拟的帧范围。这个范围不一定必须与场景动画的帧范围一致。这在只想 Bake 少量帧以预览火焰效果时非常有用,然后再运行完整的 Bake。另一个使用场景是,当某些 Fluid 对象不在相机视野内时,可以避免在那些帧中计算物理模拟。
在进一步查看 Cache 面板的其他参数之前,我们先来看一下,如果复制包含 Domain、火盆和木柴的整个组合,其中木柴作为 Inflow 对象,并将这些副本分布在场景中,会发生什么。正如之前所见,如果使用一个覆盖整个场景的单一 Domain,就需要极高的分辨率才能得到良好的火焰效果,同时还会浪费大量未使用空间。因此,要添加多个火盆,唯一的方法就是复制整套结构。
问题在于,当在 Timeline 中按下 Play 时,Blender 会为所有 Domain 使用同一个缓存文件夹,这意味着它们会共享相同的模拟数据。如果你确定所有模拟都使用相同参数,或许可以通过轻微旋转各个 Domain,或为每个 Domain 使用不同的 Materials,在渲染时让火焰看起来有所不同,从而在视觉上制造差异。
真正的问题出现在你更改某个 Domain 的分辨率或其他参数后再次执行 Bake。例如,我降低了远处 Domain 的分辨率,因为背景对象不需要高分辨率。此时 Blender 会混淆数据,因为具有不同特性的对象共享同一组体积数据。

如果希望每个 Domain 的数据彼此独立,就必须在运行模拟之前,为每个 Domain 指定不同的缓存文件夹。不用说,这会显著增加磁盘空间占用。应根据自身需求决定采用哪种策略:使用一个或多个非常大的 Domain 并复制同一模拟,还是为不同 Domain 创建独立缓存。
到目前为止,每当我们在 Timeline 中按下 Play,Blender 都会实时计算模拟的 Bake。但这并不是唯一模式。实际上,还有另一种模式可以使用一个非常实用的工具。为简单起见,我只保留场景中的一个火盆及其 Domain,并删除其他对象。不过要注意,删除 Domain 并不会删除磁盘上的数据。这其实是件好事,因为意味着我们可以保存并在以后重用模拟数据。但在本例中我不再需要这些数据,因此会手动将其删除。
在 Domain 的 Cache 面板中,可以看到 Type 菜单,默认设置为 Replay。这就是我们一直在使用的模式:每次回到第 1 帧并按下 Play 时,Blender 都会重新计算 Bake,并覆盖之前的数据。

Modular 模式允许对模拟的不同方面分别进行 Bake。在某些情况下,这很有用,可以单独检查或替换某些部分,而无需重新计算整个模拟。
All 模式则允许对整个模拟进行 Bake,并在后台计算,而不是在 Timeline 中进行。要开始 Bake,需要点击面板中的 Bake All 按钮。Blender 会显示进度条。计算完成后,可以在 Timeline 中按下 Play 流畅查看结果,因为模拟已经预先计算完成。
若要修改模拟设置,必须先点击 Free All 按钮清除现有数据。此时参数会重新变为可编辑状态,可以进行修改。随后需要再次点击 Bake All,让 Blender 重新计算模拟。
查看正在使用的文件夹,可以了解在使用 Modular 和 All 模式时,各个模块或 Bake 步骤是如何分别计算并存储的。

All 模式还会启用 Offset 参数,这可以解决一个你可能已经注意到的问题。到目前为止,所有火焰模拟都从动画第一帧开始点燃。
但这并不总是理想的,因为有时我们希望动画开始时火焰已经在燃烧。
为了解决这个问题,可以在 Offset 字段中输入一个负数。
提示说明,这并不意味着 Baking 会提前开始,而是模拟在动画第一帧播放时,会被视为已经向前推进了相应的帧数。
动画总帧数仍然由 Frame Start 和 Frame End 指定。
在本例中,Timeline 的最后 25 帧没有模拟,因为通过 Offset,我们告诉 Blender 在 Timeline 的第一帧播放模拟的第 25 帧。

要解决这个问题,只需让 Bake 计算更多帧,使模拟覆盖整个 Timeline。因此,我在 Domain 的 Cache 面板中将 Frame End 设置为 275,点击 Free All,然后点击 Bake All 重新执行 Bake。