立即注册找回密码

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

手机动态码快速登录

手机号快速注册登录

搜索

图文播报

查看: 83|回复: 0

[分享] 游戏中的实时水体模拟技术

[复制链接]
发表于 2024-9-27 18:11 | 显示全部楼层 |阅读模式

登陆有奖并可浏览互动!

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录 手机动态码快速登录

×
写在前面
这篇文章其实早就写好了,一直放在草稿箱没发。因为上一篇被各位看官老爷嫌看不懂,这次拿出来就删了n多公式,加了很多图示,大家没事就当看个热闹吧。麻烦多点赞。

海洋,溪流,湖泊等水体的模拟在游戏中是十分常见的技术,每个开发人员或多或少都听说过几种制作水体的方法。不过想要把水体模拟做好,做出高质量,其中还是有很多值得注意的地方。这篇文章就是总结一下个人制作水体模拟的心得,以及一些平时阅读技术论文和开发中容易忽略的细节。
首先要说一下,游戏中使用的“水体模拟”技术并不是真正的流体动力学计算,出于运行效率的考量,实际上使用技术的大多是用数学公式复现水体的视觉效果。从这点来说下面提到的公式基本都很简单,而且也不是金科玉律,可以根据每个人的理解进行改写。
游戏中使用的水体模拟技术大体可以分为三类

第一类是叠加不同的随机周期函数构成水体表面,多用来表现波涛起伏海面,暂且称为波形叠加法。


第二类是使用波动方程或者近似公式来表现局部的水波,多用于表现物体与水面互动产生的涟漪。


第三类是使用预渲染的Flow Map表现复杂的水流运动,多用于模拟涡流等难于实时计算的非线性运动。


第一部分 波形叠加
Gerstner波

波形叠加故名思义就是将很多个不同周期,不同振幅的周期函数叠加在一起。但在水体模拟中我们使用的基础波形并不是正弦和余弦波,而是一种叫做Gerstner波的特殊波形。Gerstner波和余弦波的差别,用一幅简单的图就能说明了。



与红色的余弦波相比Gerstner波在两侧有收紧的趋势,和真实海洋表面更加接近。


真实海洋中比较尖锐的波形
Gerstner波构造起来非常容易,用2d的波形作说明,只要在y轴上取cos(t),再在x轴上添加一个相对应的sin(2t)位移就能得到。Gerstner波的"收紧"部分就是绿色箭头所指的sin(2t)。



斜切波形
Gerstner波还有一种很多人不知道的变换,就是斜切波形。大家一定知道cos(x)如果把x换成x^i,波形会向一个方向倾斜。图中的波形是cos(2*pi*x^2),可以看出波形明显向右边“倾斜”。




如果Gerstner的x和y坐标都加上这种倾斜,就能得到斜切Gerstner波,用来模拟涌向海岸边的潮水。


将很多个不同波长,不同振幅的Gerstner波叠加在一起,加上一些随机值,就能得到下图这种看起来很复杂的海面效果。



FFT叠加
如果需要更为复杂的波形叠加,可以使用逆向fft算法。因为fft的效率还不错,一幅512x512的频谱图对应262144个波形,同时叠加这么多波形,能给海面带来非常高的复杂度。


fft频谱图和叠加出来的位移图
计算白浪
这里再补充一个一般人不太知道的技术。用雅可比绝对值计算白浪出现的位置。
白浪是水面激烈碰撞涌起的白色泡沫。在水面模拟的时候可以认为在Gerstner波最尖锐的部分会产生白浪。这个尖锐的部分可以用雅可比绝对值来计算。



可以设定一个阀值,当雅可比绝对值小余阀值的时候产生白浪。



我们制作的实时海面白浪,看起来还算自然

第二部分 波动方程
我想学理科的同学一定对波动方程不会陌生的。估计写的第一个matlab程序十之八九都是波动方程。实在不知道请查查wiki百科。这里不写一堆推倒公式了,免得大家看得头痛。
https://zh.wikipedia.org/wiki/%E6%B3%A2%E5%8A%A8%E6%96%B9%E7%A8%8B
https://zh.wikipedia.org/wiki/File:Wave_equation_1D_fixed_endpoints.gif

这里讲一个波动方程的变形wave particles。
这是07年的一片siggraph论文,虽然老了点,但效果很好。神秘海域4的水面模拟就是用的这个技术。
Wave Particles

wave particles的想法其实很直接。作者认为波动方程太简单了,波动方程的波之间不会相互影响 ,只会在碰到边界的时候反弹一下。那干脆别算波动方程了,把波都看成一个粒子,遇到边界会反弹,在移动的时候能量会衰减。再按照Gerstner波的样子变形出来,就是一个小鼓包。



如果你要制造一个扇面形状的波,发射一扇小鼓包。如果想制造一圈的波纹,就发射一圈小鼓包,随便你。


但是随着小鼓包的移动,他们本来是团结在一起的,却渐渐散开了。这也好办,小鼓包可以随着移动而增殖,如果跑的距离太远了,就一个变三个。


到这里就可以看出wave particles的最大优点是直观易懂,容易控制,想要生成什么样的波纹都可以控制。这也是神秘海域4开发时使用这个技术的主要原因。

不过wave particles对于开发人员来说还是挺有难度的,尤其是作者在论文中很多细节地方都没写清楚,我在做的时候遇到了不少麻烦。这里就随便提两点吧。
第一是上面提到的斜切波形的问题,论文中能实现出漂亮的浪头形状。但文章中只用了普通的Gerstner波。基本不可能做出来这种效果。




另一个问题是怎么把粒子渲染成位移图,文章中根本就没提。只提到以每个粒子为中心,渲染出一个Gerstner波形状。难道要每个粒子都向位移图渲染一个圆的范围吗,这个大的计算量怎么可能做到实时啊。


实际的做法是先渲染出粒子的位置,然后分别在x方向和y方向做一次模糊filter,filter的核就是Gerstner波的公式,这样比起双向filter的消耗还要小,真是个值得记住的小技巧。
当然wave particles比起波动方程还是有局限性的,比如像From Dust那种上帝游戏,会增加和减少水量,还是用波动方程计算水的流动比较容易。



第三类用Flow Map模拟水体比较偏美术,所以变种非常多,不太好讲。等以后有机会再说吧。(逃)

原文地址:https://zhuanlan.zhihu.com/p/21573239
楼主热帖
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册 微信登录 手机动态码快速登录

本版积分规则

关闭

官方推荐 上一条 /3 下一条

快速回复 返回列表 客服中心 搜索 官方QQ群 洽谈合作
快速回复返回顶部 返回列表