中年流体算法 和 模拟水墨特效


中年流体算法 和 模拟水墨特效
本文插图
本文介绍利用流体算法 , 模拟水墨特效 。
中年流体算法 和 模拟水墨特效
本文插图
参考
本文主要参考了 恬纳微晰 的 github 实现和 GPU Gems 第 38 章

  • https://github.com/TNWX-Z/EnhanceSmokeSimulationPro
  • https://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch38.html

中年流体算法 和 模拟水墨特效
本文插图
恬纳微晰的实现效果
中年流体算法 和 模拟水墨特效
本文插图
GPU Gems
之前在网上搜索流体算法的时候看到了 恬纳微晰 的实现 ,但是是通过 shader 在 image effect 里实现的 。 恰好中文的流体算法的看得懂的相关资料不多 。 于是我就做了一个 compute shader 的实现并学习了相关算法 。
算法实现
这个流体算法 ,大体上可以分为 平流模拟(advection)和 旋涡模拟(Vorticity) 。 使用的是网格的方式模拟每个网点的流速 , 压强和密度 。
中年流体算法 和 模拟水墨特效
本文插图
Compute Shader 入门可以看我之前的文章
  • https://zhuanlan.zhihu.com/p/33675797
计算的数据用了:
RWTexture2D Result//渲染结果RWTexture2D Flowmap//流速图RWStructuredBuffer VelocityW//流速 写入StructuredBuffer VelocityR//流速 读取RWStructuredBuffer Curled// 卷曲度RWStructuredBuffer Divergenced//发散度RWStructuredBuffer DensityW//密度 写入StructuredBuffer DensityR//密度 读取RWStructuredBuffer ColorW//颜色 写入StructuredBuffer ColorR//颜色 读取
主要计算步骤为:
Advection //平流计算Curl //卷曲计算Vorticity //旋涡Divergence //发散Pressure //压力GradientSubtract //梯度减法RenderTex //渲染Splat //笔刷绘制
Advection 平流的计算为, 根据当前的流速, 反推时间 deltaTime后流到这个位置的 网点的信息, 作为自己deltaTime后的信息.
比如当前流速是 v = 1m, 那么t = 0.1s后会流到这个位置的坐标c就是当前坐标 减去v * t
中年流体算法 和 模拟水墨特效
本文插图
Curl 卷曲计算 为根据当前格子周围格子的速度, 计算出当前网点的旋转速度 。 这个量是垂直于计算面的 。
蓝色为周围网格的流速 , 黄色箭头为卷曲度 , 即当前网点的 旋转速度 。
中年流体算法 和 模拟水墨特效
本文插图
Vorticity 旋涡计算的是当前网点附近的 卷曲值 对网点流速的影响 。 周围网点流速的不均衡导致当前网点的流速获得一个改变方向的力 。
Divergence 发散 和 Pressure 压力的迭代 , 模拟了压力在网点间的传播 。
大部分 2D 水面模拟会用 压强和密度来计算水波的传播 , 比如 奥日与黑森林

中年流体算法 和 模拟水墨特效
本文插图
【中年流体算法 和 模拟水墨特效】
蓝色为周围网点的流速 , 绿色箭头为压力 。 当周围向中心流动时 , 压强上升 , 反之则压强下降 。
中年流体算法 和 模拟水墨特效


推荐阅读