Chango的数学Shader世界(十二)流体模拟-丑陋的现实之平流,投影算子

23 篇文章 10 订阅
21 篇文章 5 订阅

目的:

参考《GPU Gems》,尝试重现2D流体模拟。

本节用UE4实现平流和投影算子部分。并对实际碰到的问题与论文的差距作分析。

 

参考:

《GPU Gems》

 

观察:

经过实践观察,我发现两个问题:

1.速度场的复杂度决定了模拟的流动有多好看,但复杂又无散的速度场我不知道怎么搞。

2.对染料浓度进行无散处理(上节的投影算子)没有任何意义,结果也很奇怪。但对速度场进行无散化,可以模拟水面波动后慢慢平静(匀速)下来的效果。

于是初步实践,我决定对浓度场在速度场中平流;简单生成一个速度场,并利用投影算子将速度场无散化。

 

分析与步骤:

1.对浓度场进行平流

利用文章九所得结论即可,两张RT相互更新,没啥说的。

d1(x,t+\delta t)=d1(x-u1(x)*\delta t,t)

2.构造速度场

缺乏想象力的我只能将每点uv-坐标(0,0.5),再归一化。这样整个速度场就像是从左边中点出发,均一的发散场。在GPU中编程最难受的就是不能在RT中存储负数,所以我只能用RG通道为xy,B通道分4部分存储符号(++,+-,-+,--)。公式为(1-m)/4+(1-n)/8,mn为2D矢量符号,如+-为(m=1,n=-1)。

初始速度场如下:

以后可以考虑复杂的速度场用mathematica处理可视化,会更清楚。

利用文章十中的离散公式,计算此速度场的散度。散度倒是一目了然,印证了那句散度体现“有源程度”

在计算这些场的过程中我都没有注意边界问题,从结果来看无大碍,但是其实速度场等已经有些不对了,之后会看到。

3.解Poission压力方程

接下来我准备对速度场进行无散处理(应用上节的P算子),回忆方程:

\boldsymbol{u}=\boldsymbol{w}-\nabla p

要应用它,就得求p。回忆Poission压力方程:

\nabla^{2}p=\nabla\cdot \boldsymbol{w}

对于这个方程,进行Jacobi迭代法解,网上也有很多资料,这里不说了。

而且把文章十的离散形式分别代入两边,也能推导出,有:

p_{i,j}^{k+1}=\frac{1}{4}(p_{i-1,j}^{k}+p_{i+1,j}^{k}+p_{i,j-1}^{k}+p_{i,j+1}^{k}-(\delta x)^{2}\nabla\cdot w)

其中p场是数值场,从全0场开始,对整个场多次计算。CPU控制迭代次数,GPU进行一次迭代的计算,有点像多次Glow或者是高斯模糊的操作:

如果迭代少了,那么p基本就像是负的散度:

但是再从其中计算得的梯度又不会像原来的速度场那么大了。(只有散度场和旋度场都存在才能唯一决定原场)。

(蓝色决定矢量符号,红绿决定x,y分量大小)

Poission方程相当于没解。原速度场减去这种\nabla p,几乎相当于没变,它还是一个有散场,因此染料行为就严格按照“圆形”速度场流动。相比开头有种更像缩放的感觉。

我把循环改成书上建议的40,结果就是开头的样子,其p场和\nabla p也变成了这样:

随着时间的流逝,速度场逐渐变成无散场,其散度RT也几乎变成了全黑。

在迭代更新压力场的时候,我发现其对边界处理很敏感,我现在的做法是,若寻址到uv以外的点,则取对应边界点的负数。即如果i<0,p(i,j)=-p(0,j)。具体我还未深入研究。目前发现除此以外的做法都会得到很奇怪的结果。

对于扩散项,目前没有加上,因为文中说由于计算误差,无论如何染料都会扩散,但从结果看来并不明显。染料面积增加只是因为我们的初始速度场是有散场。

结论

1.对文

    尽管此文拓展了我的数学?方向,但不足处很多。没有完整实现,代码都是伪代码和片段,对于算子行为意义,模糊不清。总得来说,没有一个按图索骥的感觉,让人感觉陷入毫无意义的研究当中。文中的图片效果很大程度来自其涡流状的速度场。

2.对实践结果

    目前缺陷有若干:

1.无扩散项:下节添加

2.边界计算,误差问题。希望弄清原理。

期间错误得到了很多奇怪的速度场,倒也蛮好看的。

3.反省

    在研究过程中,陷入了数学推导中,没有紧密结合实际。对于研究的前因后果没有顾及就开始一头扎入。对于物理知识的匮乏其实是研究此类Shader最大的拦路虎。下次在选择研究课题时,要么得做好充足的物理知识储备,要么就选择那种纯数学的Shader类型。

    在下节添加完扩散项后,流体模拟就得告一段落了。菜是原罪啊。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值