Real time fluid
虽然不是什么新的东西, 但是因为觉得很好玩, 所以还是自己抽空实现了一下, 顺便也是要分享一些自己的学习心得.
1. 什么是流体?
自然界中有很多东西是流体, 包括占据了将近半个地球体积的空气, 覆盖了70%地表的水体, 还有那在太阳系的中央, 永恒地燃烧着的火焰.
2. 流体的行为?
在上个世纪的早些年代,Navier和Stokes共同发现了流体运动的规律, 从而写下了著名的Navier-Stokes流体动力学方程,当然它假设流体是不可压缩(体积不变)和均匀(密度不变)的:
其中, u是指速度场, ∇, ∇^2, ∇•分别是梯度算子, 拉普拉斯算子和散度算子.其对应的运算如下:
值得注意标量场的梯度是矢量, 而矢量场的散度是标量.上表中拉普拉斯算子的微分形式的v改成u
Navier-stokes方程的实际意义是速度场在单位时间里的改变量=加速度∂u/∂t=F/m;
所以, 速度的即时改变量主要由该方程式的右边项决定
推导如下,
求解像这样的偏微分方程, 通常不可能获得解析解, 所以要使用数值方法
首先, 让我介绍求解中最重要的概念之一Splitting:
所以, 求解上式被拆解成以下几个步骤:
来看其中的最后一个步骤:
写成离散形式, 有:
所以 求解压力的伯松方程, 再从散度速度场中减去压力的梯度, 就得到了新的divergince free的速度场
注意上图有个加号错了.
方程的求解:
已经被证明, 对于矩阵表示的线性方程, jacobi迭代也照样可行Ax=b, 而伯松压力方程, 就正好是这样的一类方程.
by run the iteration times, we can get the pressure field.
at last, let's look at the advection term.
Implementation:
所有的东西都是2维数组, 所有的运算都是数据运算, 所以, 数组就是2D texture, 运算就是画屏幕大小的quad.
以下是一个实现
done by..zxx
挂个友链: