这是FluidFlux插件文档链接:
http://imaginaryblend.com/2021/09/26/fluid-flux/
FluidFlux插件原本可以在编辑器模式下,通过右键SimulationDomain保存模拟状态,这个模拟状态保存后是一个资产文件以及三张纹理图Ground,Height,Velocity。
SimulationDomain中有一个俯视的场景捕获相机,三张纹理图就是根据场景捕获得来的。Ground是在模拟过程中一直不变的,代表地面捕获结果,是模拟过程的基础高度图。Height中保存了水位高度信息,Velocity中保存了水流速信息。通过纹理图每个像素保存的信息对这片捕获的区域进行水体模拟还原,实际上也就是划分了栅格,栅格大小和多少是在domain中自行调节的。最高尝试过包围4096*4096大小的区域,每个像素代表2平方米,实际也就是8平方公里多一点。
接入外部已经生成好的洪水水位数据,可以将其映射到该区域对应的栅格内,反向手动生成高度图,如果有流速信息,亦可反向生成速度图。插件生成的Height纹理是PF_R16F格式,float数据需要转换到uint16格式进行逐像素的数据操作。Velocity纹理是RGBA8格式,通过材质看,似乎RG通道分别代表了xy流向速度,B通道存储了高度值,A通道存储的是和水面泡沫相关的数值。我只尝试手动生成了Height纹理,Velocity并不十分确定。
生成后,可根据Domain的Load方法,加载生成好的高度图,即可生成对应的水位模拟情况。
有几个点可能要注意:
①整个过程可以改造成运行时而不紧紧是编辑器态下可用,可实现在线的数据接入。如果只需要预制好一系列贴图,编辑器态下就够了。
②如果纹理过大,生成时间还是比较长的,还需要考虑显存占用问题。数据读入和纹理生成可以全都放到子线程中进行没有问题。会有较大的性能提升。
③如果数据不太丝滑,会导致直接生成的水面有尖峰,且相邻间水填充初始状态有问题,可以考虑先提前Load进去,模拟一小会,再把Domain中的Current State中的高度图与速度图做保存使用,这样保证在实际场景中的表现效果。
④水位高度图中每像素数据应该不是纯粹的相对于地面的水位高度数据,最终采用的一个方法是,在完全没有水的情况下捕获场景区域,存储一个基础Height,在此Height图逐像素值基础上加上水位高度。
⑤如果每像素栅格数值较大,则捕获场景会不够精细,有些凹凸不平的地面,会初始带有奇怪的水迹,在做数据映射时,可以考虑把这些没用的数据点额外减一个值,让他们的水位别凸出来。
最终方案已经基本完成,因为贴图较大,所以还是有一点卡顿情况,还有就是如③所说,平滑数据需要一些时间,实际运行时需要在后台跑挺长时间,但基本不影响主线程,不会造成大片的卡顿。
方案仅供参考,欢迎交流。