天天看点

游戏中的实时水体模拟技术分享:波形叠加法与波动方程 游戏中的实时水体模拟技术分享:波形叠加法与波动方程

http://www.gameres.com/694945.html

游戏中的实时水体模拟技术分享:波形叠加法与波动方程

发布者: 小篱 | 发布时间: 2016-12-6 16:09| 评论数: 0

游戏程序
平台类型:
程序设计: 3D图形 
编程语言:
引擎/SDK: 其它 
游戏中的实时水体模拟技术分享:波形叠加法与波动方程 游戏中的实时水体模拟技术分享:波形叠加法与波动方程

  文/FOXhunt

  海洋,溪流,湖泊等水体的模拟在游戏中是十分常见的技术,每个开发人员或多或少都听说过几种制作水体的方法。不过想要把水体模拟做好,做出高质量,其中还是有很多值得注意的地方。这篇文章就是总结一下个人制作水体模拟的心得,以及一些平时阅读技术论文和开发中容易忽略的细节。

  首先要说一下,游戏中使用的“水体模拟”技术并不是真正的流体动力学计算,出于运行效率的考量,实际上使用技术的大多是用数学公式复现水体的视觉效果。从这点来说下面提到的公式基本都很简单,而且也不是金科玉律,可以根据每个人的理解进行改写。

  游戏中使用的水体模拟技术大体可以分为三类

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

游戏中的实时水体模拟技术分享:波形叠加法与波动方程 游戏中的实时水体模拟技术分享:波形叠加法与波动方程
  第二类是使用波动方程或者近似公式来表现局部的水波,多用于表现物体与水面互动产生的涟漪。
游戏中的实时水体模拟技术分享:波形叠加法与波动方程 游戏中的实时水体模拟技术分享:波形叠加法与波动方程
  第三类是使用预渲染的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百科。这里不写一堆推倒公式了,免得大家看得头痛。

  这里讲一个波动方程的变形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模拟水体比较偏美术,所以变种非常多,不太好讲。等以后有机会再说吧。(逃)

继续阅读