
虽然有很多大佬已经实现了其中的效果,但是大佬们的文章太过于深奥,萌新只能简单的尝试下模拟效果了。
首先整个内容大体可以分为两个部分,材质液面模拟,裁切和运动简单模拟。我们先实现下材质液面的模拟。1.液面模拟
液面模拟我用的是印度大佬的方法,整个物体需要三层的模型,第一层模型用来模拟外面的玻璃容器,第二层模型用来模拟液面,第三层模型则是用来当裁切的MASK。
我们新建一个pawn或者actor,然后放入三层模型。我这边用的是一个酒瓶,glass_label_beer和glass_label_mask使用的是同一个酒瓶模型,cylinder用的则是一个和酒瓶差不多体积的柱子,因为柱子的面比较平液面是靠把顶面压平实现的,所以我选择了柱子,然而为什么是skeletal mesh呢,如果只是静态的话用staticmesh就可以,想要动起来的话我这边采取的方法需要skeletalmesh。

模型准备好后接下来就是材质的部分了,玻璃的材质很普通,大家可以做的更好一些

接下来就是液面的材质,液面需要将模型上半部分压扁,所以我先用世界位置减去物体位置得出一个基于自身的黑白mask,然后通过减去的height值来定义这个mask的上下移动,接着我们对其输出结果和1进行MAX运算以限制其最小值为1然后乘以负一将上半部分的位移反向,但是由于有max的关系,结果就会出现上半部分会被压成一个平面,(需连接到worlddisplacement或者worldpositionoffset)当然会有多余的部分,我们接下来就开始如何将其进行裁剪。



2.裁切
裁切的话我们是用custom depth进行裁切,需要准备一个瓶子模型然后给个简单的黑色材质就行了,将其添加到pawn中的glass_label_mask上,取消勾选Render in Depth Pass和Render in main pass,这样他就不会渲染了,然后勾选Render CustomDepthPass,就可以在液面材质中调用到这个自定义深度做成一个瓶子的mask对超出mask的液面进行不显示。

然后我们需要在液面材质中加入裁切判断,将场景深度减去自定义深度,就是刚才的瓶子mask,然后让超出的部分为0,未超过的设置为1,将结果连接到opacity通道上,并将材质的设置为translucent模式,勾选details面板的allow custom depth writes(允许自定义深度写入),这样我们就可以得到一个完整的裁切过的半透液面。最好将最外层玻璃瓶放大为1.2倍,用于裁切的mask放大为1.1倍用于提升裁切效果。



接下来我们需要在液面表面加一层泡沫,原理很简单,在第一步的时候我们得到了基于自身坐标的黑白蒙版,我们只需要将height值再减去一个数,作为mask进行颜色区分就可以了


有了泡沫以后我们需要在液体表面模拟一下基本的运动,基本方法是在表面用sine函数进行顶点偏移。将第一步worldposition减去objectposition的R轴提取出来(G轴也可以),然后加上时间偏移经过sine之后叠加到被压平的液面上乘以0,0,1取Z轴就可以得到基本的效果,然后可以自己控制sine的频率和强度,可以得到下面的运动效果。法线的话可以不加,如果想要静态的话这边已经可以基本满足你的需求了。


2.液面运动模拟
液面的运动模拟的话我采用的是spring bone的方法,我看到有些大佬是基于顶点算的效果,但是由于本人技术有限,只能做些简化的模拟了。
首先我们需要一个带绑定蒙皮的skeletalmesh,由于本人只会简单的绑定,绑的不是很好,权重都是自动的,当时的思路是由上面四个bone控制液面的运动,后来发现其实效果一般,相信各位大佬有更好的解决方法。由于需要液面运动,所以我给了比较多的点。


这步完成以后导入UE4并给上材质,然后这时候我们需要以圆柱的骨架创建一个动画蓝图,在动画蓝图里给每个bone加入spring controller,然后设置其对应的参数。最底层的骨骼我是用来模拟整体运动的,我让其只在Z轴运动并调整了SpringStiffness(刚度,越大弹性越好)和SpringDamping(阻尼,越大,回弹越慢)。然后给各个骨骼都调整参数(比较耗费时间,但是参数调的好可以模拟出大多数的流动质感)。


初始的动画我们直接双击圆柱的skeletalmesh,点击CreateAsset下的CreateAnimation然后创建个静态的动画就行了(或者你可以从建模软件中导出)。

最后我们将保存好的动画蓝图放在我们创建的pawn中的cylinder上就行了

现在我们可以点击play然后肆意的移动她,你会发现在旋转的过程中其实体积偏差有些大,这时候就需要把上面提到的height值用参数集代替然后用actor的rotation来关联调整height并且传回到液面的材质里。

然后我们基本就已经得到了我们所需要的结果,下面是我基本做好的液面,虽然运动轨迹不是很好,但是基本实现了我们所需要的效果,想要完善则需要更好的rig和更合适的参数设定了。我们也可以把参数和UI绑定一下,用UI控制更加直观一些。



总结:
这个效果前前后后也做了不少的时间,其中还存在着很多的问题,比如透明穿插,比如表面怎么模拟的更真实,运动如何更好,甚至泡沫如何形成消散等(本人也在努力学习raymarch,争取能在后面完善)。希望大佬们能多多指出我文章中的错误和不足,斧正。
最后感谢下孙同学提供的啤酒瓶 @孙大胖 。
附上原视频链接:https://www.youtube.com/watch?v=VIz80hrCNd4
给我思路的一篇文章:https://80.lv/articles/simulating-liquids-in-a-bottle-with-a-shader/