APP下载

Unity3D下一种基于Perlin噪声的地形仿真方法

2019-06-09刘雪梅马瑞志

软件导刊 2019年4期
关键词:晶格分形顶点

刘雪梅 马瑞志

摘 要:针对传统随机中点位移法在地形仿真中存在的绘制过程复杂、细节表现不足、山顶处易出现失真的问题,提出一种在Unity3D下利用Perlin噪声构造分形,并对网格顶点进行位移映射进而生成地形的方法。根据设定好的分辨率构造网格,计算并叠加各顶点不同频率的噪声值构造分形,最后對网格顶点进行位移映射,生成满足要求的地形。在噪声计算过程中修改了随机梯度选取方法,可使梯度选取更具有随机性,且计算出的噪声值分布更加均匀,避免了在山顶处出现失真的现象。实验结果表明,该方法可以很方便地实现三维地形仿真,并能很好地表现地形细节特征,解决了因山顶过于尖凸出现的失真问题。

关键词:随机中点位移法;地形仿真;Unity3D;Perlin噪声;分形;位移映射

DOI:10. 11907/rjdk. 191054

中图分类号:TP317.4文献标识码:A文章编号:1672-7800(2019)004-0174-05

0 引言

三维地形仿真是构建虚拟自然场景的重要组成部分。随着计算机技术的发展,特别是计算机仿真技术的日趋成熟,动态地形仿真被广泛应用于军事仿真、游戏、动画及电影制作等领域[1-2]。针对三维地形绘制,国内外学者已进行了大量研究。如Clark[3]首先提出一种判定可见面的层次细节模型,利用物体和视点之间的距离,加载不同分辨率的物体模型,解决了计算机运算负荷过大的问题,奠定了层次细节技术(Level of Detail,LOD)的研究基础;Hoppe[4-5]提出一种大规模场景地形网格预处理技术,以及高效实现渐进网格数据结构的方法,可以表现复杂地貌,但缺点是数据结构复杂、占用内存较大,且效率不高;Boer[6]在文献[4]的基础上,将多辨率(GeoMipMapping)算法与GPU并行处理相结合,提高了仿真系统的实时性。

在国内,张润花等[7]利用随机中点位移法绘制地形,但由于网格细分的随机范围难以抉择,导致生成的地形可能出现失真现象;李玉娟等[8]利用基于数字高程模型(Digital Elevation Model,DEM)的方法,实现了大规模地形渲染和漫游,但是该方法需要处理海量地形数据,绘制效率较低,实时性较差;马海凤[9]对GeoMipMapping算法进行改进,利用基于GPU的四叉树瓦片LOD绘制算法绘制地形,提高了绘制速度,且效果较好,但未考虑动态地形的情况;刘瑶等[10]利用Perlin噪声构造分形进而生成地形的方法,在GPU上进行噪声计算与叠加过程,提高了地形绘制效率,但是随着数据量增加,GPU和CPU之间的数据传递会占用大量时间,影响绘制效率;郑顾平等[11]采用WebGL标准进行动态地形绘制,但实际上只是实现了几何剪切图算法。

综合分析上述算法后,针对文献[6]使用随机中点位移法生成地形存在的细节表现不足、山顶尖凸失真问题,本文在Unity3D平台下,通过对传统Perlin噪声计算过程中的随机梯度选取方法进行改进,使噪声分布更加均匀,从而使得绘制出的地形细节更为丰富。

1 Perlin噪声

在计算机图形学中,噪声是指通过引入一些随机变量以表现自然景物中的随机效果,如云[12]、波浪[13]、水面[14]、湍流[15]、雪花[16]、场景渲染[17-18]等。最常见的噪声即类似旧式电视机无信号时出现的随机雪花像素点,如图1所示。然而,完全随机变化的数据是无用的,在计算机图形学中需要一种可重复的随机数函数,也称为伪随机函数,即对于同一输入,得到的结果是相同的。Perlin[19]在1985年的SIGGRAPH大会上首次提出该函数,并给出了具体算法描述,称为经典Perlin噪声。为了简化计算,并方便利用硬件进行实现,Ken Perlin[20]于2001年改进了该算法,也即后来的SimpleX噪声。目前,Perlin噪声已被广泛应用于三维游戏、计算机仿真等领域。

Perlin噪声的本质是根据输入参数(可以是N维向量)生成一个位于(-1,1)之间的随机数。根据输入参数的维度,有一维、二维和三维等不同维度的噪声。Perlin噪声是基于晶格(一维下是线段,二维下是方格,三维下是立方格)的噪声,其生成过程可分为确认晶格、选取随机梯度向量、计算点积、计算插值因子并进行插值4个阶段。Perlin最初使用如式(1)所示的三次多项式进行插值因子计算。

但是式(1)的二阶导函数不连续,2002年Perlin[21]将光滑函数修改为一个五次多项式。

式(1)与式(2)虽然相似,但是式(2)具有连续的二阶导数,能更好地适用于计算机图形学中诸如凹凸贴图、位移映射等场景的渲染。单一的Perlin噪声看上去很单调,一般都是通过叠加不同倍频、频率和振幅的噪声构造分形生成各种有趣的效果。

2 基于三维Perlin分形噪声生成地形的方法

由于本文主要利用三维Perlin噪声构造分形,下面将分别从三维Perlin噪声生成、分形构造与地形生成三方面进行详细介绍。

2.1 三维Perlin噪声生成

在三维空间上,噪声函数用Noise(p)表示,p是一个三维向量,表示输入点位置。计算给定点p处的噪声需要经过以下过程:

(1)确定晶格。三维情况下的晶格是单位立方体,如图2所示,中间点p是给定点。要确定其所在晶格,只需确定晶格左下角及背面右上角的坐标即可,也即确定图中p0(x0,y0,z0)和p1(x1,y1,z1)的坐标。其中p0是离p最近的整数点,可求得p0的坐标如下(floor表示对参数向下取整):

(2)选取随机梯度向量。晶格确定之后,接下来为晶格每个顶点挑选一个伪随机梯度向量。挑选基本思路如下:首先,生成一个随机排列表P[N1],这里采用Perlin的方法,将0~255的数字随机打乱放入表P中。为避免重复,将打乱后的数字再复制一遍,也放入表P中;然后设置一个位掩码hashMask用于随机选择,令hashMask=255;接着,生成一个随机梯度表G[N2],Perlin建议选取单位球内不同方向的12个向量。由于12不是2的整数次幂,所以为了方便随后进行的位运算,将其拓展到16个。最终得到的随机梯度表G[N2]如下:

经过以上两个步骤,得到P[N1]和G[N2]。在Perlin给出的算法中,采用式(9)进行晶格顶点处梯度的选择。

其中i、j、k分别取0或1,如G000代表晶格点(X0,Y0,Z0)处的梯度,n取255即hashMask的值。在实际应用中,为了简便可以不必进行求模运算,采取位运算留下低8位的值即可,如式(10)所示。

为了使梯度选取更具有随机性,并使最终生成的噪声分布更均匀,本文在生成随机梯度表时,设置一个梯度位掩码gradientMask,取值为15。将式(10)修改为:

2.2 构建分形

构建分形的过程其实是叠加不同频率、振幅的噪声值,如式(31)-(33)所示。

式(31)中,fractal是最后的分形噪声,octaves表示需要叠加的噪声个数,frequency是计算噪声时的采样频率,amplitude表示振幅。在每一次迭代中,式(32)、(33)用来控制频率与振幅变化,其中lacunarity是决定频率变化的因子,一般是大于等于1的浮点数;persistence是决定振幅变化的因子,一般取不大于1的浮点数。

由于振幅变化可能会引起最终噪声值超出(-1,1)区间,所以在程序中设置了一个变量range记录振幅变化。在每次振幅发生变化时,用式(34)记录当前振幅的值,在噪声计算完成后,再利用式(35)将fractal的值规范到(-1,1)区间内。

图3、图4分别展示了octaves为2、frequency为8,以及lacunarity为2、3、4与persistence为0.5、0.75、1时的三维Perlin分形噪声。

2.3 地形生成

三维Perlin分形噪声生成地形的基本思想是:利用噪声函数生成高度场,对原平面网格顶点进行位移映射,构建地形。整个过程可分为网格构建、高度场生成与映射位移3部分。

2.3.1 网格构建

(1)在Unity中新建一个空对象,并为其添加Mesh组件。

(2)指定要生成地形的分辨率,分辨率用resolution表示。分辨率越大,最后生成的地形细节表现得越充分。

(3)计算网格顶点和顶点法线。假设要构建一个分辨率为resolution * resolution的地形,则总顶点数目为(resolution+1)2,将顶点坐标保存在数组vertices中,数组vertices的成员用三维向量表示。用数组normals保存顶点法线,顶点坐标计算如下:

Unity的坐标系统是左手坐标系,Y轴代表垂直方向,X轴代表水平方向,Z轴代表深度。由于要构建的是水平平面地形,这里只计算了顶点的X和Z坐标,并按照先X方向、后Z方向的顺序进行计算。X和Z坐标减0.5的作用是为了使最终生成平面网格的中心仍位于原点处。因为构建的平面是基于X-Z的,每个顶点的法线都是沿Y轴朝上,所以法线可以用Unity中的内置变量Vector3.up表示。最后将计算出的顶点和法线分别赋给Mesh组件的vertices属性和normals属性。

(4)网格生成。Unity中的网格都是以三角形为基础的,用Mesh组件的triangles属性保存所需的三角形。

定义一个triangles数组,triangles数组主要保存构建三角形时所用到的顶点索引。由于一个四边形由2个三角形构成,因此对于分辨率为resolution*resolution的网格,数组大小为resolution2*6。利用之前计算出的顶点可以构造出需要的网格,需要注意的是,Unity中三角形的前向面顶点是依顺时针排列的。以图5所示4*1的分辨率为例,构建第一个四边形所用到的顶点索引为0,1,5,6,则对应的两个三角形分别为0,5,1和1,5,6。对于分辨率为resolution*resolution的网格,triangles数组生成过程如图6所示。

图6中用t表示构成四边形的顶点索引,按照先X方向、后Z方向的順序,每个四边形构建完毕之后,t值增加6。

2.3.2 高度场生成与位移映射

网格构建完成后,利用之前构造的分形噪声fractal生成高度场。按照先X方向、后Z方向的顺序,分别求出每个顶点处的fractal值。为了能够动态调整最终生成地形的起伏程度,设置一个strength变量调整fractal的值,如式(39)所示,strength范围为(0,1]。

然后将其赋值给顶点的Y坐标,完成位移映射,如式(40)所示。

对顶点作位移映射之后,可以利用Mesh组件自带的RecalculateNormals()函数重新计算顶点法线。

3 实验结果与分析

根据本文方法,在Unity3D 2017.3.1f平台下,利用C#语言在VisualStdio2017下编写脚本,最终生成的地形效果如图7所示。图7(a)为分辨率100*100的地形,图7(b)为分辨率200*200的地形。从图中可以看出,在200*200分辨率下,如地表褶皱等地形细节特征表现得更加充分。采用一个渐变的颜色带对最终地形进行着色,蓝色越深表示海拔越低,黄色表示高海拔地带。

Unity3D可以自动处理光照和阴影,当向场景中添加光照,生成的地形效果如图8所示,其中图8(a)为关闭Unity阴影效果,图8(b)为开启阴影效果。

图9展示了通过改变strength的值调整地形起伏状态。

最后,与随机中点位移法生成的地形相比,如图10所示,可以看到随机中点位移法生成的山顶过于尖凸,而且如山体表面褶皱等地形细节表现不够充分。利用本文算法生成的地形山顶表现自然,没有过于尖凸的现象出现,而且山体表面褶皱也表现较好,整体而言本文算法效果更佳。

4 结语

本文提出一种在Unity3D平臺下,利用三维Perlin噪声构造分形进而生成地形的方法。对经典Perlin噪声中晶格顶点处随机梯度的选取方法进行改进,从而使最终生成的噪声更具有随机性。利用Unity3D中Mesh组件的自动计算法线功能,简化了顶点在位移映射之后计算法线的过程。但是本文方法还存在一些不足,如当分辨率过大时,需要计算的顶点数目也相应增多,耗费时间较长,帧数也会急剧下降,而且地形起伏不能通过局部进行调整,这是下一步需要改进的地方。本文方法在生成地形方面效果较好,能够充分表现出地形细节特征,且过程简单,能够满足地形仿真需求。

参考文献:

[1] 吴欣. 大场景可变地形特效技术研究[D]. 北京:北方工业大学,2016.

[2] 邢玥. 基于GPU的动态地形实时绘制[D]. 北京:华北电力大学,2016.

[3] CLARK J H. Hierarchical geometric models for visible-surface algorithms[J]. ACM SIGGRAPH Computer Graphics,1976,10(2):267-267.

[4] HUAGUES H. Progressive meshes[C]. Proceedings of the 23rd Annual Conference on Computer Graphics and Interactive Techniques. ACM Press,1996: 99-108.

[5] HUAGUES H. View-depedent refinement of progressive meshes[C]. Proceedings of the 24th Annual Conference on Computer Graphics and Interactive Techniques. ACM Press,1997:189-198.

[6] BOER W H D. Fast terrain rendering using geometrical mipmapping[C]. World Wide Web Conference Series,2000.

[7] 张润花,刘树群,赵付青. 地形生成的细分随机移位方法[J]. 华中师范大学学报:自科版, 2012, 46(5):533-536.

[8] 李玉娟,谭同德. 三维场景中大规模地形地貌的生成[J]. 计算机应用与软件,2013,30(11):131-135.

[9] 马海凤. 大规模地形可视化技术研究[D]. 西安:西安电子科技大学,2015.

[10] 刘瑶,庹先国,李怀良,等. Perlin噪声生成地形的一种高效率并行方法[J]. 科技通报,2016,32(3):200-204.

[11] 郑顾平,白若林. 基于WebGL的动态地形实时绘制[J]. 软件导刊,2017,16(12):202-205.

[12] 王帅. 基于Simplex噪声绘制云的方法[J]. 辽宁石油化工大学学报,2009,29(3):58-61.

[13] 石秋华. 利用Perlin噪声生成水波面的动态模拟研究[J]. 软件导刊,2012,11(2):140-142.

[14] 项予,许森. 基于Perlin噪声的动态水面实时渲染[J].  计算机工程与设计,2013, 34(11): 3966-3970.

[15] ROBERT B,JIM H,MARCUS N. Curl-noise for procedural fluid flow[J]. ACM Transactions on Graphics (TOG),2007,26(3):46-48.

[16] 徐建华,顾浩,康凤举,等. 真实感降雪场景可视化[J]. 系统仿真学报,2014,26(10):2391-2394,2399.

[17] BARNARD R, URAL S.Rendering translucency with Perlin noise[C]. International Conference on Computer Graphics and Interactive Techniques in Australasia and South East Asia. ACM,2005:131-134.

[18] CONINX A,BONNEAU G P,DROULEZ J, et al. Visualization of uncertain scalar data fields using color scales and perceptually adapted noise[C]. ACM SIGGRAPH Symposium on Applied Perception in Graphics and Visualization, ACM, 2011:59-66.

[19] PERLIN K. An image synthesizer[C]. ACM Siggraph Computer Graphics, 1985, 19(3):287-296.

[20] PERLIN K. Noise hardware[C]. Real-Time Shading SIGGRAPH Course Notes, 2001.

[21] PERLIN K. Improving noise[J]. ACM Transactions on Graphics, 2002, 21(3):681-682.

(责任编辑:黄 健)

猜你喜欢

晶格分形顶点
过非等腰锐角三角形顶点和垂心的圆的性质及应用(下)
感受分形
非线性光学晶格中的梯度流方法
分形之美
关于顶点染色的一个猜想
分形——2018芳草地艺术节
分形空间上广义凸函数的新Simpson型不等式及应用
一个新非线性可积晶格族和它们的可积辛映射
一族拉克斯可积晶格方程
三维复式晶格的热容研究