笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
前端时间在CSDN开始了关于《算法与游戏技术实战》系列讲座,主要是讲解了一些游戏实战中常用的算法,在这里也是使用数学方程解决海水渲染问题,告诉开发者数学算法对游戏开发非常重要,我们可以使用数学运算解决很多问题:包括人工智能,深度学习,游戏开发,VR/AR等。
摘 要 针对目前海浪的研究都是基于PC端的问题,为了实现在移动端实时仿真模拟海洋,提出了一种可以在移动端运行的算法,利用快速傅里叶变换算法(FFT)建立海浪高度场,结合LOD(Levelof Detail)算法生成多块网格无缝拼接形成无限海水;采用GPU编程技术对海水表面实现海面光照,反射,折射效果以及海面颜色渲染处理;最后通过Perlin噪音在海面产生海浪泡沫效果,从而更加逼真的实现了海水模拟可以在移动端运行。实验结果表明,该算法满足了海水在移动端运行,并且达到了预期效果。
1 概述
海洋仿真的逼真度来源于海浪的波形及运动的真实性,海浪建模的方法有多种,Foumier和Reeves[1]提出一个基于深海小振幅波的海浪模型;Jensen[2]和Tessendorf[3]分别详细描述了采用统计模型和快速傅里叶变换(FFT)方法模拟海浪的方法。在合成过程中采用规则矩形来完成绘制,降低了图像的质量和真实感。徐迎庆[4]等提出了一个基于物理模型的模拟海浪的计算机动画方法。Mastern[5]等提出了一种利用Fourier变换来合成一块水波区域的方法;其结果显得非常自然。Chen[6]采用数值迭代方法求解二维的水力学方程组(Navier-Stokes)来模拟海浪。杨怀平[7]等利用海浪频谱和方向谱的相关公式,实现了基于海频谱的波浪造型及显示,能够快速的模拟海浪。以上的海水研究都是基于PC端的,随着移动端硬件的快速发展,提出了一种新的海洋模拟方法,该方法不仅局限于PC端和Web端仿真,可以同时运行在移动平台。通过快速傅立叶变换(FFT)建立海浪高度场,采用LOD技术实现多块网格无缝拼接形成无限海洋表面,而且实现了海浪随风起伏的效果,最后通过GPU编程实现了水面光照、反射以及折射效果。
2 建立海浪模型
由于海水的运动形式是在不断变化的,在统计模型中,海浪的高度方程是随着给定的位置 和时间t而生成的,通过傅里叶快速变换(FFT)将一个海浪谱从频率域转换到空间域,形成海浪高度场。下面求解高度方程,假设网格大小为M*N,水面面积为。表达式如下所示:
其中,
本文引入参数和,设定它们的范围分别是0,1,...,N-1和0,1,...,M-1。
因此有表达式:,,将其代入(4),(5)方程可得到n,m的表达式:
根据和的值将(2),(3)代入可以计算出的值,公式如下:
把以上表达式带入我们原始方程,可达到如下表达式:
化简方程 (10)可得如下表达式:
(11)
将(8)和(9)代入(11)可得如下方程式:
其中表达式方程为:
(13)
参数g是重力加速度将公式(2)和(3)代入(13)可得如下方程式:
接下来需要解答函数及其复共轭函数。其中方程可用如下方程式表示:
将(8)和(9)代入(15)可得方程式:
其中参数和是由高斯随机数发生器产生的独立绘制,均值为0,均方差为1。函数是Phillips spectrum,其方程表达式如下:
其中是波移动的方向,是海水升起的最大可能的波长度,V是持续的风的速度。K为波的数量,是归一化的风向,消除了海浪在运动方向上和风向垂直部分的能量,从而保证海浪运动方向大致与风向一致。由此得到方程:
将(18)代入(16)可得到方程,由于和是复共轭函数,也可得到,再向上逆推可解得波高度函数方程,从而获得海洋波高度场,接下来我们需要评估一个位移矢量来生成波涛汹涌的海浪和在每个顶点照明计算法向量。位移矢量方程如下所示:
化简(19)可得方程式:
解得法线向量的公式如下:
(21)
在解方程的过程中,本文假定M=N(N是2的n次方)和,运用欧拉方程对于任意的实数x满足下面的方程:
(22)
以上建模算法利用快速傅里叶变换完成了对海浪几何建模以及海面光照法线矢量的计算。
3 生成海水网格
为了完成对实时性要求比较高的大面积海域在移动平台的模拟,鉴于目前移动平台的处理能力,采用的是将海面定义成6*6个海洋网格块,每块网格的三角形数量是32*32,每块网格的大小是128*128。建立网格无缝拼接,为了消除不同细节层次网格边缘的裂缝,采用的是细节层次LOD(Level Of Details)[8],最大分层为4,保证它们之间LOD级别相差1之内即可。然后利用快速傅里叶变换(FFT)海水仿真算法生成动态的海水高度场,并将高度场存入到定点纹理中,在顶点着色器中通过取顶点纹理的值对网格进行扰动,形成动态的海水效果。海面网格如图1-1,算法流程图如图1-2。
从程序执行的流程图中可以看出,首先需要定义要生成的网格数量,生成对应的网格块并对网格数据进行初始化,利用快速傅里叶变换进行2次傅里叶变换生成海浪高度场,采用LOD处理块与块之间出现裂缝,最后通过GPU编程对海面进行实时渲染。如图1-3和1-4海浪在风力作用下的效果图
4 GPU渲染
为了提高在移动端的运行效率利用GPU对浮点纹理进行双线滤波和法线计算,然后再用这张经过滤波处理和法线预计算的浮点纹理作为顶点着色器的高度场和法线纹理进行高度扰动,形成海浪效果。同时对海面光照,反射以及折射也通过GPU处理,从而减轻了移动端CPU处理数据的压力,优化了效率。GPU部分核心代码,顶点结构体定义和法线,光照实现方法如下:
struct v2f
{
float4 pos : SV_POSITION; //位置
float4 projTexCoord : TEXCOORD0; //映射纹理
float2 bumpTexCoord : TEXCOORD1; //bump纹理
float3 viewDir : TEXCOORD2; //视角方向
float3 objSpaceNormal : TEXCOORD3; //法线
float3 lightDir : TEXCOORD4; //光线方向
float2 foamStrengthAndDistance : TEXCOORD5; //风力强度和距离
};
v2f vert (appdata_tan v)
{
v2f o;
o.bumpTexCoord.xy = v.vertex.xz/float2(_Size.x, _Size.z)*5; //纹理坐标
o.pos = mul (UNITY_MATRIX_MVP, v.vertex); //矩阵换算
o.foamStrengthAndDistance.x = v.tangent.w; //噪音产生方向
o.foamStrengthAndDistance.y = clamp(o.pos.z, 0, 1.0); //数据采样
float4 projSource = float4(v.vertex.x, 0.0, v.vertex.z, 1.0); //纹理映射
float4 tmpProj = mul( UNITY_MATRIX_MVP, projSource);
o.projTexCoord = tmpProj;
float3 objSpaceViewDir = ObjSpaceViewDir(v.vertex); //对象空间视角方向
float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );//法线
float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal ); //旋转
o.objSpaceNormal = v.normal;
o.viewDir = mul(rotation, objSpaceViewDir); //视角方向
o.lightDir = mul(rotation, float3(_SunDir.xyz)); //光照方向
return o;
}
实现了反射,折射效果如图1-5和1-6所示;
5 实验数据
测试使用了市场比较流行的两个厂家手机:一是韩国产的三星GT-N7100手机,其硬件配置是CPU四核1.6GHz、GPU 为Mali 400MP、内存RAMGB、ROM16GB;操作系统Anroid4.3;二是国内小米2手机硬件配置是CPU四核1.5GHz、GPU Adreno 320、内存RAM2GB 、ROM16GB、操作系统 MIUI android4.1。
使用的是6*6块海洋网格,每块网格大小是128*128,每块网格是由32*32三角形组成,在移动平台测试了各项实验数据。
为了在移动端真实模拟海洋效果,我们需要开启反射以及折射,上述测试数据满足了在移动端使用海水的渲染,保证了程序运行的的流程性,目前该技术正运用于3D海战手游开发。
6 结束语
本文通过快速傅里叶变换FFT算法和基于GPU编程实现了海水在移动端的运行,实现了海水随着风力的变化而变化,在移动端实现了海浪的反射以及折射,光照效果。进一步的工作,我们将模拟浪花效果的实现,以及将海洋网格块的生成以及LOD移植到GPU编程处理,使其性能继续提高。
最后关于移动端海水实现代码和原理可以参考我在CSDN的讲课视频《移动端海水技术实现》。
参考文献
[1]FOUMIER A. ,REEVES W T. A simple model of ocean waves [J]. Computer Graphics and ACMProceedings of SIGGRAPTH,, l986, 20(4):75-84.
[2]JensenL.Deep-WaterAnimationandRendering.http://www.gamaasutra.com/gdce/2001/Jensen/Jensen_01.htm,2001
[3] TessendorfJ.Simulatiing Ocean Water.GIGGRAPTH 2001 Course notes.
http://home1.gte.net/tssndrf/index.html,2001
[4]徐迎庆,苏成,李华等。基于物理模型的流水及波浪模拟.计算机学报,1996,19(增刊):153-160.
[5] G A Mastin,P AWatterberg,J F Mareda.Fourier synthesis of ocean scenes[J]. IEEE ComputerGraphics and Application, 1987,7(3):16-23.
[6]Chen J X,Lobo NV. Toward INteractive-rate Simulation of Fluids with Moving Obstacles UsingNavier-Stokes Equations.Graphical Model and Image Processing, 1995,57(2):107-116.
[7]杨怀平,孙家广.基于海浪谱的波浪模拟.系统仿真学报,2002,14(9):1175-1178.
[8]ThatcharUlrich. Chunked LOD:Rendering Massive Terrains using Chunked Level of DetailControl.In:Course at ACM SIGGRAPH’02,2002