Fluid Flux2.0海浪原理拆解

news/2024/10/18 18:14:08

【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!


大概一年前,在油管上看到这个视频:

Fluid Flux 2.0 - Coastline [Unreal Engine 5]

 

 

除了效果很好,更重要的是看到简介中写着:“并非实时模拟”、“预烘焙”:

 

这意味着不会有太大性能开销,于是顿觉价值大大的。

但当时事情多,就只收藏了一下,没细研究。后来还看到有人移植《戴子玲:Fluid Flux 2.0 的近岸海浪》。

虽然我们本来就是UE项目,移植更方便,但是想仔细看下原理。

通过删除次要内容,拆出来核心逻辑如下:

 

 

其中WorldCoastlineMap用于生成海岸线,WavePofileMap用于单个海浪动画和置换,WaveProfileDistance控制海浪离岸的距离,WaveProfileTime为动画时间。

效果:(将区域范围缩小到了100,手动拖动WaveProfileTime)

 视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/4.mp4

可以看到海浪的翻滚效果。

下面来分析原理,主要是搞懂:

  1. WorldCoastlineMap和WavePofileMap这两个图的含义。
  2. 由WorldCoastlineMap生成海岸线的原理。
  3. 由WavePofileMap生成单个动画的原理。

一、WorldCoastlineMap含义

WorldCoastlineMap:


R通道明显是SDF,表示“到水的距离”,在材质中,R先被0.5减,然后连到Distance,所以Distance含义为“到岸的距离”。

 

再看G、B通道,在材质中,它们也是先被0.5减,然后连到Direction:

 

即Direction=(0.5,0.5)-(G,B),我们看它表示哪个方向,如下图:
(因为G通道看起来像从左往右打光,所以我们用左亮右暗的球代表它,因为B通道看起来像从上往下打光,所以我们用上亮下暗的球代表它)

 

即当我们把岛看成球时,得到的Direction呈放射状(图中是(G,B)-(0.5,0.5),箭头向外,如果是Direction=(0.5,0.5)-(G,B),则箭头向里),所以Direction表示的是“指向海岸的方向”。

至此Distance和Direction的含义都清楚了,一个是(从陆地)“到海岸的距离”,一个是(从陆地)“指向海岸的方向”。

二、海岸线UV计算

由Distance和Direction计算海岸线UV,虽然连线摆在那儿,但默认的WorldCoastlineMap较复杂,难看清所以然。于是有必要自己弄一个简单的WorldCoastlineMap,就一个如图所示左高右低的简单斜面,Distance值左大右小,Direction=(-1,0,0):

 

则只需将材质中的Distance和Direction输入改一下:

 

结果:

 

可见,和预期是一致的。这样就有了一个更简单的例子可以观察。

为了方便做各种试验,在Houdini中复现了一下(为了代码简洁,参数随手写死的,与UE中的并不一致):

 

注意几点:

  1. 用Colormap采样出来的贴图(我用的TGA格式)颜色要做Gamma矫正Pow 0.45。
  2. UE中WaveProfileMap的Wrap模式U是设置为Wrap,V设置为Clamp:

 

 

但Houdini中Colormap的Wrap模式不能U和B分开控制:

 

所以只能把UV都设置成Clamp(Houdini中叫Streak),然后通过对U加Frac,人为实现U向的Tiling。也就是如下图所示,将代码从左边改成右边:

 

这样改是不影响最终结果的,而且由于U不再超出0到1,所以更便于可视化。

U这样改写以后,V就可以直接写成:
v=u-dis+offset;
其中offset就相当于UE里的WaveProfileDistance,用于控制浪到海岸的距离。

这样一来,公式比UE里连的更简洁了,下面就基于此来理解原理。

V可视化长这样:

 

以下为其演变过程:

 

可见:

  1. 加P.y是为让条纹倾斜。
  2. 加noise有两个效应:
  • 效应1:条纹产生扭曲。
  • 效应2:条纹V方向上渐变产生交错。

最右一行是将WaveProfileMap换成了如下自定义贴图(为了观察UV):

 

当time变化时,效果如下:

视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/18.mp4

如果不加noise,则如下:

视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/19.mp4

至此海岸线UV计算原理已看清楚。

三、海浪翻滚动画实现

从上面自定义贴图的视频中可以看到,如果不加noise的话,看起来就是贴图在沿着条纹平移。把自定义贴图换回WaveProfileMap,并加上Vector Disp,加noise与不加noise效果对比如下:

视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/20.mp4 

可见,浪前沿的不规则形状是靠noise的效应1“条纹产生扭曲”实现的,浪前沿顿锐交错是靠noise的效应2“条纹V方向上渐变产生交错”实现的。在未加noise之前,浪只感觉是在沿着条纹走,丝毫感觉不到垂直于条纹向前推的感觉,但加上noise之后,浪沿条纹走的感觉就削弱了,开始有了垂直于条纹推进的错觉。

在浪垂直于条纹向前推进的过程中,还会有翻滚效果,拉近可以看得比较清楚:

视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/21.mp4

所以最后一个问题就是:浪的翻滚是靠什么实现的。

这涉及到WaveProfileMap的含义。

打开UE工程的WaveProfileMap关卡,可以看到制作WaveProfileMap的方式,是用一排样条线做出了一个卷曲的海浪形状:

 

这可以理解为一个完整的3D海浪,也可以理解为一套2D序列(每个切片为一帧2D剪影)。

后一种理解更符合此方法的本意。

在Houdini用一个移动立面进行截取,可以直观看到2D海浪动画的样子:

视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/23.mp4

所以它就是在条纹上每个点处播放这个2D动画:

 

由于条纹V方向上有均匀渐变(不加noise的情况下),所以V方向上各处2D动画存在均匀的相位差,整体看上去就像一个完整3D海浪在沿着条纹平移一样。然后通过加noise使条纹扭曲,并在V方向上产生相位产生交错,从而打破平移感。

四、不规则海岸

上面通过构造最简的直线形海岸,大致看清了原理。依此原理,容易生成其它形状海岸,比如(为了方便,仍然在Houdini里验证):

(1)圆形:

 

 视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/26.mp4

 

(2)自定义形状:

 

 视频:https://uwa-ducument-img.oss-cn-beijing.aliyuncs.com/Blog/USparkle_FluidFlux2/28.mp4

 

五、不足(个人观点)

我觉得海岸线UV计算的方法很巧妙,但也有不足,最主要的不足是公式不对称,从而不同方向得到的UV品质不一致,导致某些方向上海浪的形不够好,比如:拉伸过于严重、移动速度沿条纹方向过快等。

是否可以考虑不用通过DIS和DIR简单的数学运算生成UV,而是用离线方法生成更好的UV,从而得到更好的效果,或许是一个改进方向。


这是侑虎科技第1689篇文章,感谢作者杨超wantnon供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

作者主页:https://www.zhihu.com/people/wantnon

再次感谢杨超wantnon的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73156.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

PHP将整形数字转为Excel下标

1、背景 这两天在接到一个需求,需要导出一个班级所有学员的所有成绩,在最后excel表处理的时候发现导出的列超过了26列,后面会出现AA之类的下标,所以写了一个函数把数字整型转为Excel对应的下标。 2、转换函数/*** @Notes:将整数转为excel对应的列标* @Function int_to_chr*…

18. 模块

一、什么是模块模块化 指将一个完成的程序分解为一个一个小的模块。通过将模块组合,来搭建一个完整的程序。如果不采用模块化,那么所有的代码将统一保存到一个文件中。采用模块化后,将程序分别编写到多个文件中。使用模块化后,我们可以把代码进行复用,这方面后序的开发和维…

csp-s模拟12

csp-s模拟12\(T1\) T2918. 小 h 的几何 \(100pts\)对于任意三角形,均有其三条边的中点、三条高的垂足、三个顶点与垂心连线的中点,这九个点在一个圆上。观察样例可知,对于单位圆上 \(\triangle ABC\) 的三个顶点 \(A(x_{a},y_{a}),B(x_{b},y_{b}),C(x_{c},y_{c})\) ,其九点…

Android8,reactnative中webView传的token,vue中获取不到是怎么回事?

rn代码是这样的,要在vue页面获取到tokenvue中是这样写的,安卓9以上都能得到,就是8获取不到有没有大佬帮忙看看,跪谢!!!!

实时同步服务

1 实时同步应用场景通过rsync+定时任务实现定时备份/同步 对于NFS我们需要进行实时同步2 实时同步工具选型实时同步工具 特点 选型inotify工具+脚本inotify监控指定的目录,监控 目录下是否有变化,显示变化了的文件. 通过rsync服务端与客户端传送,书写脚本.不推荐,有性能问题.se…

DevExpress隐藏列表中显示的加号+

GridView1.OptionsDetail.EnableMasterViewMode = False

人大金仓kingbase部署

环境准备: 系统版本:CentOS Linux release 7.9.2009 (Core) 硬件配置:4C4G200G 安装包准备:KingbaseES_V008R006C008B0020_Lin64_install.iso https://www.kingbase.com.cn/xzzx/index.htmlicense准备:license_企业版.zip https://www.kingbase.com.cn/xzzx/index.htm计划…