Stable Fluids · 实时烟雾仿真
拖鼠标在 GPU 上跑 Navier-Stokes —— 烟雾被你的速度场卷起,演化出涡和湍流。看流体力学最劝退的方程"活"在屏幕上。
Navier-Stokes 方程长什么样
不可压缩牛顿流体的运动方程:
每一项都”讲故事”:
- :速度随时间变化
- :对流——流体被自己的速度带走(这一项是非线性的,所有混沌都来自它)
- :压力梯度让流体从高压区流向低压区
- :粘性——动量在空间扩散
- :外力(鼠标拖拽就在这里加入)
- :不可压缩约束(流出去多少必须流回来)
这个方程系是非线性的、有约束的、二阶的偏微分方程组。在 21 世纪初被列为千禧年七大数学难题之一(解的存在性与光滑性问题至今未解 → 100 万美元奖金等你拿)。
但数值仿真它?1999 年 Jos Stam 发明了”Stable Fluids”算法,让你的 GPU 实时跑 Navier-Stokes。这个 demo 就是它的现代 WebGL 版本。
算法:把方程拆成 5 步
每帧时间步 dt,对速度场 u 做 5 件事:
1. 涡度增强(vorticity confinement)
数值耗散会让涡随时间衰减得过快。涡度增强人为强化已有的涡,让烟雾看起来”活生生”。这不在原始 Navier-Stokes 里,是图形学的工程技巧。
2. 对流(advection)
这一项。Stam 的巧招:半拉格朗日逆向追踪 —— 对每个网格点 x,问”上一时刻位于 x - dt·u(x) 的流体粒子,现在带着什么速度过来了?” 双线性插值即可。永远稳定,dt 想多大都行(精度差一些但不爆)。
3. 散度(divergence)计算
—— 当前速度场的局部”外流量”。理想情况这应该是 0。
4. 压力(pressure)求解
解一个泊松方程 找到能”修正”散度的压力场。用 Jacobi 迭代 20-40 次足够(每次让每个像素 = 4 个邻居的平均减去散度的 1/4)。
5. 投影(projection)
。减去压力梯度,得到无散度的速度场。这一步保证质量守恒。
每个步骤都是一个 GPU 片元着色器 + 一对 ping-pong 纹理交换 read/write。整个 Navier-Stokes 仿真在现代 GPU 上 5-10 毫秒一帧,60 fps 完全 hold 得住。
染料(dye)的角色
烟雾不是流体本身 —— 它是被流体携带的染料。每帧:
- 鼠标拖动 → 在那个位置注入染料(颜色)+ 一股速度
- 流体按 5 步演化
- 染料按 advection 公式 被流场卷走
染料纯被动,不影响流场。所以你看到的”烟”其实是给透明流场上色的可视化。
真实物理 vs 你看到的
这个仿真做了几个工程上的妥协:
- 不可压缩约束 用单次 Jacobi 投影近似(高精度需要预条件共轭梯度,慢得多)
- 粘性扩散 没有显式扩散步 —— 数值耗散提供”假”粘性
- 对流耗散 半拉格朗日方法本身有 numerical diffusion,所以小涡涨大了就模糊
- 网格分辨率 192×192 / 768×768 —— 真实湍流应该有 Kolmogorov 尺度下的精细结构,这里被网格平均掉了
但视觉上的现象——涡街、湍流混合、向上烟柱、缠绕的麻花——和真实流体几乎一模一样。视觉感性 ≠ 数值精度,但对教学和审美都够好。
试这些
- 快速直线拖动:注入一股很快的速度,看流速最快处的”流头”卷起来形成蘑菇云
- 慢速画 8 字:染料缠绕成精细花纹 —— 这就是混沌混合(Lagrangian chaos)
- 同一位置反复戳:每次注入新的颜色叠加,看染料如何被局部涡 mixing 成新色
- 拉高”涡度增强”:涡变得更剧烈,烟雾”更活”
- 拉低”染料衰减”:染料不消失,看长期混合后的画面
- 拉高”压力迭代”次数:得到更精确的不可压缩约束,烟雾不会”突然冒出来”
真实世界
- 电影特效:CGI 烟、火、水、爆炸 —— 几乎全是这套算法的升级版(FLIP、APIC、PIC)
- 天气预报:求解尺度更大的 Navier-Stokes,加上热力学和湿度
- 风洞模拟:飞机设计、F1 赛车空气动力学、建筑风阻
- 海洋模型:全球洋流、厄尔尼诺
- 聚变反应堆:等离子体在磁场约束下的流动(磁流体力学 MHD)
- 血管 / 心脏建模:医学手术规划
- 航天器再入:高超音速气动加热
Navier-Stokes 的离散化方法 —— 有限差分、有限体积、有限元、谱方法、晶格玻尔兹曼 —— 是现代科学计算的核心,养活了 计算流体力学 (CFD) 这个完整学科。
致谢与协议
这个 demo 的算法和着色器结构基于 Pavel Dobryakov 的 WebGL-Fluid-Simulation(MIT 协议)做精简移植,重新适配了:
- 站点的米色/朱砂/青绿/紫的调色板
- 站点的 UI 控件风格
- 移除了 bloom / sunrays 等装饰效果
- 加上了教学正文 + 算法解释
Pavel 的原版有更多视觉特效和参数 —— 如果想体验”完整版”可以去原仓库的 在线 demo 玩一下。
一个深刻的观察
Navier-Stokes 方程写出来很短(两行),但解析求解几乎不可能 —— 即使是几何最简单的”球绕流”也没有闭式解。
但数值上,5 个步骤 + 一些 GPU 纹理就够了。这就是计算性思维的力量:放弃”找公式”的执念,承认”可以快速迭代算出来”也是一种理解。
数学物理被这个思路接管的程度,比 20 世纪初的人能想象的要彻底得多。