Stable Fluids / Real-Time Fluid Dynamics for Games 笔记

这篇博客详细介绍了Stable Fluids算法在游戏中的应用,用于实现实时流体动力学。文章分析了论文的代码实现,包括网格系统、密度步骤、速度步骤、边界条件和完整过程。作者使用欧氏方法建立网格,采用高斯-赛德尔迭代解决线性方程组,处理扩散、对流和速度场的投影,以确保流体的不可压缩性。同时,文章提供了一个基于Web的实现示例,展示了流体模拟的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Stam J. Real-Time Fluid Dynamics for Games[J]. Journal of Graphics Tools, 2003, 6.

感谢朱老师的指导..本文对论文的实现代码进行分析,并试图补全论文中说得不够详细的部分,侧重于对solver的分析,opengl的部分比较简单,附件为已添加注释的代码。

我使用canvas api实现了一个基于web的版本,限于浏览器性能,在帧率上不如原文。可以在此链接中浏览效果:http://pigcage.tech/MyProjects/stablefluid/

 

一、系统的建立

1、网格系统

这里使用的是欧氏方法,代码中创建了一个N*N的网格(其中N=64,越大的N值意味着越高的性能开销)。在网格的四周有一层边界(0与N+1),亦即实际网格的大小为size=(N+2)*(N+2)。对于网格中的每一个单元格(cell),假定N*N网格的边长为1,那么每个单元格的边长为h=1/N。

基于此网格系统,程序使用一些全局变量来储存流体的基本属性,见附件中demo.c的注释如图:

时间步长为dt,一般来说,应满足dt < h * |u|,以保证模拟的精度。

每个单元格对应有密度(density)与速度(velocity)两个属性。其中速度为矢量,此处为二维模拟,故分为u、v两个方向表示,此处u指上下方,v指左右方。对于这些属性,分别使用形如dens、dens_prev形式的两个数组, 表示网格该属性的当前状态和前一状态。使用SWAP(x0,x)来交替这两个数组以达到状态的更新,其中x0为上一状态。这些数组均为一维数组,程序中使用形如dens[IX(i , j)]的形式,表示第j行i列的单元格属性。

2、准备知识

1.为了便于求解,使用到了Splitting方法,大体来说是这样的,感觉比较显然就不具体描述了吧..

2.N-S方程

3.顺便贴一下物质导数D

二、密度步骤

由于这里是处理烟雾,密度的高低等价于烟雾的浓度。使用密度数据即可绘制对应的烟雾视图。对密度的处理分为上图几个步骤,在每一帧中,依次添加力、处理扩散和移动。

1、力和源的添加

这一步比较简单,使用add_source函数。

void add_source ( int N, float * x, float * s, float dt )
{
    int i, size=(N+2)*(N+2);
    for ( i=0 ; i<size ; i++ ) x[i] += dt*s[i];
}

用户输入的源(source)或力(force)被储存在 s[ ] 中,那么把这些状态直接加到新一帧的对应属性 x[ ] 即可。至于乘以dt也就是因为使用了splitting的方法,并不是冲量..下同。

2、扩散(diffusion)

上面已经处理了外部输入源的情况。对于接下来的扩散步骤(烟雾的自发扩散)。根据N-S方程,我们知道扩散项为 k · ∇^2 u

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值