Hotdry.

Article

Godot引擎中的纳维-斯托克斯流体模拟:从有限差分到实时渲染

基于Jos Stam经典算法,在Godot中实现实时流体模拟的完整技术路径,涵盖平流、扩散、压力投影与边界处理的可调参数。

2026-05-30game-dev

在游戏开发中实现逼真的流体效果一直是技术挑战与视觉回报并存的任务。纳维 - 斯托克斯方程作为描述流体运动的基础数学模型,其实时求解通常需要大量计算资源。本文基于 Godot 引擎的完整实现案例,探讨如何在保持可交互帧率的前提下,构建一个视觉上令人信服的二维流体模拟系统。

核心设计权衡:精度与性能

实时游戏场景下的流体模拟必须在物理准确性与计算开销之间做出取舍。该实现采用三个关键策略来降低计算成本:首先,使用相对较小的网格(默认 16×16)配合较大的单元格尺寸(32 像素),显著减少需要更新的单元数量;其次,采用任意时间步长推进模拟,而非严格遵循物理时间;最后,在求解压力场等计算密集型环节使用近似方法 ——Gauss-Seidel 松弛迭代,以可接受的精度损失换取更快的收敛速度。

这种设计哲学直接反映在数据结构的选择上。模拟使用一维数组存储标量密度场和二维速度场(分别用 uv 数组表示水平与垂直分量),通过 IX(i, j) = i + (N+2) * j 索引函数实现二维到一维的映射。网格四周预留一圈边界单元(因此实际尺寸为 (N+2) × (N+2)),为边界条件处理提供缓冲。

平流与扩散:物质的运动与传播

流体模拟的核心循环围绕两个物理现象展开:平流(advection)与扩散(diffusion)。平流描述物质随速度场的运动,其实现采用反向追踪策略 —— 对于每个目标单元,不是向前推算物质去向,而是反向追溯该单元内的物质可能来自何处。具体而言,根据当前单元的速度向量 (-u, -v) 乘以时间步长 dt0,计算出源位置坐标 (x, y),然后使用双线性插值从周围四个单元采样密度值。

扩散则模拟物质从高浓度区域向低浓度区域的自发传播。数学上这需要求解泊松方程,但实时场景下采用 Gauss-Seidel 松弛进行近似。算法迭代 20 次,每次更新单元值为自身原始值与四邻居平均值的加权混合:

density[idx] = (density_prev[idx] + a * Σneighbors) / (1.0 + 4.0 * a)

其中 a = delta * diffuse_rate * N² 控制扩散强度。迭代次数与扩散率是可调参数:默认密度扩散率为 0.006,速度扩散率为 0.001,均在 20 次迭代下达到视觉上的平滑效果。

不可压缩性约束:压力投影

单纯的平流与扩散会导致流体出现不自然的压缩或稀疏现象。为保持不可压缩性,需要引入压力投影步骤。该过程首先计算速度场的散度(divergence),衡量每个单元净流入 / 流出的量:

divergence = -0.5 * h * ((u[i+1] - u[i-1]) + (v[j+1] - v[j-1]))

然后通过求解压力泊松方程(同样使用 20 次 Gauss-Seidel 迭代)获得压力场,最后从速度场中减去压力梯度,消除压缩性误差。这一步骤在每次速度扩散和平流之后执行,确保流体体积守恒。

边界条件处理

边界单元的处理直接影响模拟的物理可信度。对于密度场,边界单元直接复制最近内部单元的值,确保物质不会凭空产生或消失。对于速度场,采用反射边界策略:垂直边界反转水平速度分量,水平边界反转垂直速度分量,模拟流体碰到墙壁反弹的效果。角落单元则取相邻边界单元的平均值,避免数值奇点。

可落地的参数配置

基于上述实现,以下参数配置可作为起点,根据具体需求调整:

参数 默认值 调整建议
网格尺寸 N 16 增大提升精度,但计算量按 O (N²) 增长
单元格大小 32px 与视觉表现相关,不影响物理计算
密度扩散率 0.006 增大使流体更易扩散,减小更集中
速度扩散率 0.001 控制涡流衰减速度,影响 "粘稠感"
松弛迭代次数 20 减小提升性能,增大改善收敛稳定性
密度淡出率 0.1 防止网格填满,可按场景关闭

性能优化路径

当前实现完全基于 CPU 计算,适合教学与原型验证,但在高分辨率网格或复杂场景下可能成为瓶颈。向 GPU 迁移是自然的优化方向:Godot 4.x 提供的 Compute Shader 可将密度场、速度场、散度场和压力场存储为纹理(RGBA 浮点纹理),利用 GPU 的并行计算能力同时更新所有单元。每个模拟步骤(扩散、平流、投影)对应一个计算着色器 Pass,通过纹理采样实现邻居访问,避免 CPU 实现中的复杂索引计算。

此外,可考虑引入涡量约束(vorticity confinement)增强小尺度涡流的视觉表现,或结合粒子系统实现混合式流体渲染 —— 用网格模拟大尺度流动,粒子表现飞溅、泡沫等细节。

资料来源

  • Myzopotamia.dev: "Navier-Stokes fluid simulation explained with Godot game engine" (2026)
  • Jos Stam: "Real-Time Fluid Dynamics for Games" (2003)
  • Mike Ash: "Fluid Simulation for Dummies"

game-dev

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com