最近终于在U3D上自己实现了Gerstner波,其中参考了他人文章,也自己踩了坑,写一篇博客记录下问题。
一 Gerstner波
在水面模拟中我们常会使用到正弦函数叠加来模拟波的形状,这可能是绘制一个平静的,田园诗般的池塘所需的。对于粗狂的海洋,需要形成比较尖的浪头和比较宽的浪槽,这时候我们需要使用Gerstner波。简单来说Gestner波是将顶点向波峰聚集,从而形成尖的浪头。其算式如下:
GPU精粹一 中的Gerstner波函数
上式中不难发现输入的参数为x,y,t在我们写的代码中应该是x,z,t所以我们将y替换成z,并交换算式中二三行位置得到算式如下:
在U3D实现时用的Gerstner波函数
其中变量与其意义 :
- A:振幅
- D:波的方向
- ω:2*Pi/L 其中L为波长
- ψ:S*ω其中S为波速
- Q:控制波的陡度 值(0,1)为0时则波形为正弦波,为1时最陡。(PS:超过1时会看见波在波峰上形成环)
这时我们有了波函数在代码中实现过后我们可以的到一个通过顶点动画实现的Gerstner波,然而我们并不能只管的看见这个波,因为我们只修改了顶点位置,并没有修改法线的值,如果只有简单的光照渲染我们将会看见一个纯色的平面,为了获得更加真实的效果我们需要试试计算法线的值, 我们可以通过对波形函数分别求对x、z的偏导函数得到切线T与副切线B的算式:
N=B*T;
与波形函数一样,我们的算式与CPU精粹一书中并不一样。需要注意的是在u3d 中我们是在左手坐标系进行计算,为了符和左手法则我们使用对z的偏导来表示B,对x的偏导来表示T。