劉雪梅 馬瑞志
摘 要:針對(duì)傳統(tǒng)隨機(jī)中點(diǎn)位移法在地形仿真中存在的繪制過(guò)程復(fù)雜、細(xì)節(jié)表現(xiàn)不足、山頂處易出現(xiàn)失真的問(wèn)題,提出一種在Unity3D下利用Perlin噪聲構(gòu)造分形,并對(duì)網(wǎng)格頂點(diǎn)進(jìn)行位移映射進(jìn)而生成地形的方法。根據(jù)設(shè)定好的分辨率構(gòu)造網(wǎng)格,計(jì)算并疊加各頂點(diǎn)不同頻率的噪聲值構(gòu)造分形,最后對(duì)網(wǎng)格頂點(diǎn)進(jìn)行位移映射,生成滿(mǎn)足要求的地形。在噪聲計(jì)算過(guò)程中修改了隨機(jī)梯度選取方法,可使梯度選取更具有隨機(jī)性,且計(jì)算出的噪聲值分布更加均勻,避免了在山頂處出現(xiàn)失真的現(xiàn)象。實(shí)驗(yàn)結(jié)果表明,該方法可以很方便地實(shí)現(xiàn)三維地形仿真,并能很好地表現(xiàn)地形細(xì)節(jié)特征,解決了因山頂過(guò)于尖凸出現(xiàn)的失真問(wèn)題。
關(guān)鍵詞:隨機(jī)中點(diǎn)位移法;地形仿真;Unity3D;Perlin噪聲;分形;位移映射
DOI:10. 11907/rjdk. 191054
中圖分類(lèi)號(hào):TP317.4文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1672-7800(2019)004-0174-05
0 引言
三維地形仿真是構(gòu)建虛擬自然場(chǎng)景的重要組成部分。隨著計(jì)算機(jī)技術(shù)的發(fā)展,特別是計(jì)算機(jī)仿真技術(shù)的日趨成熟,動(dòng)態(tài)地形仿真被廣泛應(yīng)用于軍事仿真、游戲、動(dòng)畫(huà)及電影制作等領(lǐng)域[1-2]。針對(duì)三維地形繪制,國(guó)內(nèi)外學(xué)者已進(jìn)行了大量研究。如Clark[3]首先提出一種判定可見(jiàn)面的層次細(xì)節(jié)模型,利用物體和視點(diǎn)之間的距離,加載不同分辨率的物體模型,解決了計(jì)算機(jī)運(yùn)算負(fù)荷過(guò)大的問(wèn)題,奠定了層次細(xì)節(jié)技術(shù)(Level of Detail,LOD)的研究基礎(chǔ);Hoppe[4-5]提出一種大規(guī)模場(chǎng)景地形網(wǎng)格預(yù)處理技術(shù),以及高效實(shí)現(xiàn)漸進(jìn)網(wǎng)格數(shù)據(jù)結(jié)構(gòu)的方法,可以表現(xiàn)復(fù)雜地貌,但缺點(diǎn)是數(shù)據(jù)結(jié)構(gòu)復(fù)雜、占用內(nèi)存較大,且效率不高;Boer[6]在文獻(xiàn)[4]的基礎(chǔ)上,將多辨率(GeoMipMapping)算法與GPU并行處理相結(jié)合,提高了仿真系統(tǒng)的實(shí)時(shí)性。
在國(guó)內(nèi),張潤(rùn)花等[7]利用隨機(jī)中點(diǎn)位移法繪制地形,但由于網(wǎng)格細(xì)分的隨機(jī)范圍難以抉擇,導(dǎo)致生成的地形可能出現(xiàn)失真現(xiàn)象;李玉娟等[8]利用基于數(shù)字高程模型(Digital Elevation Model,DEM)的方法,實(shí)現(xiàn)了大規(guī)模地形渲染和漫游,但是該方法需要處理海量地形數(shù)據(jù),繪制效率較低,實(shí)時(shí)性較差;馬海鳳[9]對(duì)GeoMipMapping算法進(jìn)行改進(jìn),利用基于GPU的四叉樹(shù)瓦片LOD繪制算法繪制地形,提高了繪制速度,且效果較好,但未考慮動(dòng)態(tài)地形的情況;劉瑤等[10]利用Perlin噪聲構(gòu)造分形進(jìn)而生成地形的方法,在GPU上進(jìn)行噪聲計(jì)算與疊加過(guò)程,提高了地形繪制效率,但是隨著數(shù)據(jù)量增加,GPU和CPU之間的數(shù)據(jù)傳遞會(huì)占用大量時(shí)間,影響繪制效率;鄭顧平等[11]采用WebGL標(biāo)準(zhǔn)進(jìn)行動(dòng)態(tài)地形繪制,但實(shí)際上只是實(shí)現(xiàn)了幾何剪切圖算法。
綜合分析上述算法后,針對(duì)文獻(xiàn)[6]使用隨機(jī)中點(diǎn)位移法生成地形存在的細(xì)節(jié)表現(xiàn)不足、山頂尖凸失真問(wèn)題,本文在Unity3D平臺(tái)下,通過(guò)對(duì)傳統(tǒng)Perlin噪聲計(jì)算過(guò)程中的隨機(jī)梯度選取方法進(jìn)行改進(jìn),使噪聲分布更加均勻,從而使得繪制出的地形細(xì)節(jié)更為豐富。
1 Perlin噪聲
在計(jì)算機(jī)圖形學(xué)中,噪聲是指通過(guò)引入一些隨機(jī)變量以表現(xiàn)自然景物中的隨機(jī)效果,如云[12]、波浪[13]、水面[14]、湍流[15]、雪花[16]、場(chǎng)景渲染[17-18]等。最常見(jiàn)的噪聲即類(lèi)似舊式電視機(jī)無(wú)信號(hào)時(shí)出現(xiàn)的隨機(jī)雪花像素點(diǎn),如圖1所示。然而,完全隨機(jī)變化的數(shù)據(jù)是無(wú)用的,在計(jì)算機(jī)圖形學(xué)中需要一種可重復(fù)的隨機(jī)數(shù)函數(shù),也稱(chēng)為偽隨機(jī)函數(shù),即對(duì)于同一輸入,得到的結(jié)果是相同的。Perlin[19]在1985年的SIGGRAPH大會(huì)上首次提出該函數(shù),并給出了具體算法描述,稱(chēng)為經(jīng)典Perlin噪聲。為了簡(jiǎn)化計(jì)算,并方便利用硬件進(jìn)行實(shí)現(xiàn),Ken Perlin[20]于2001年改進(jìn)了該算法,也即后來(lái)的SimpleX噪聲。目前,Perlin噪聲已被廣泛應(yīng)用于三維游戲、計(jì)算機(jī)仿真等領(lǐng)域。
Perlin噪聲的本質(zhì)是根據(jù)輸入?yún)?shù)(可以是N維向量)生成一個(gè)位于(-1,1)之間的隨機(jī)數(shù)。根據(jù)輸入?yún)?shù)的維度,有一維、二維和三維等不同維度的噪聲。Perlin噪聲是基于晶格(一維下是線段,二維下是方格,三維下是立方格)的噪聲,其生成過(guò)程可分為確認(rèn)晶格、選取隨機(jī)梯度向量、計(jì)算點(diǎn)積、計(jì)算插值因子并進(jìn)行插值4個(gè)階段。Perlin最初使用如式(1)所示的三次多項(xiàng)式進(jìn)行插值因子計(jì)算。
但是式(1)的二階導(dǎo)函數(shù)不連續(xù),2002年P(guān)erlin[21]將光滑函數(shù)修改為一個(gè)五次多項(xiàng)式。
式(1)與式(2)雖然相似,但是式(2)具有連續(xù)的二階導(dǎo)數(shù),能更好地適用于計(jì)算機(jī)圖形學(xué)中諸如凹凸貼圖、位移映射等場(chǎng)景的渲染。單一的Perlin噪聲看上去很單調(diào),一般都是通過(guò)疊加不同倍頻、頻率和振幅的噪聲構(gòu)造分形生成各種有趣的效果。
2 基于三維Perlin分形噪聲生成地形的方法
由于本文主要利用三維Perlin噪聲構(gòu)造分形,下面將分別從三維Perlin噪聲生成、分形構(gòu)造與地形生成三方面進(jìn)行詳細(xì)介紹。
2.1 三維Perlin噪聲生成
在三維空間上,噪聲函數(shù)用Noise(p)表示,p是一個(gè)三維向量,表示輸入點(diǎn)位置。計(jì)算給定點(diǎn)p處的噪聲需要經(jīng)過(guò)以下過(guò)程:
(1)確定晶格。三維情況下的晶格是單位立方體,如圖2所示,中間點(diǎn)p是給定點(diǎn)。要確定其所在晶格,只需確定晶格左下角及背面右上角的坐標(biāo)即可,也即確定圖中p0(x0,y0,z0)和p1(x1,y1,z1)的坐標(biāo)。其中p0是離p最近的整數(shù)點(diǎn),可求得p0的坐標(biāo)如下(floor表示對(duì)參數(shù)向下取整):
(2)選取隨機(jī)梯度向量。晶格確定之后,接下來(lái)為晶格每個(gè)頂點(diǎn)挑選一個(gè)偽隨機(jī)梯度向量。挑選基本思路如下:首先,生成一個(gè)隨機(jī)排列表P[N1],這里采用Perlin的方法,將0~255的數(shù)字隨機(jī)打亂放入表P中。為避免重復(fù),將打亂后的數(shù)字再?gòu)?fù)制一遍,也放入表P中;然后設(shè)置一個(gè)位掩碼hashMask用于隨機(jī)選擇,令hashMask=255;接著,生成一個(gè)隨機(jī)梯度表G[N2],Perlin建議選取單位球內(nèi)不同方向的12個(gè)向量。由于12不是2的整數(shù)次冪,所以為了方便隨后進(jìn)行的位運(yùn)算,將其拓展到16個(gè)。最終得到的隨機(jī)梯度表G[N2]如下:
經(jīng)過(guò)以上兩個(gè)步驟,得到P[N1]和G[N2]。在Perlin給出的算法中,采用式(9)進(jìn)行晶格頂點(diǎn)處梯度的選擇。
其中i、j、k分別取0或1,如G000代表晶格點(diǎn)(X0,Y0,Z0)處的梯度,n取255即hashMask的值。在實(shí)際應(yīng)用中,為了簡(jiǎn)便可以不必進(jìn)行求模運(yùn)算,采取位運(yùn)算留下低8位的值即可,如式(10)所示。
為了使梯度選取更具有隨機(jī)性,并使最終生成的噪聲分布更均勻,本文在生成隨機(jī)梯度表時(shí),設(shè)置一個(gè)梯度位掩碼gradientMask,取值為15。將式(10)修改為:
2.2 構(gòu)建分形
構(gòu)建分形的過(guò)程其實(shí)是疊加不同頻率、振幅的噪聲值,如式(31)-(33)所示。
式(31)中,fractal是最后的分形噪聲,octaves表示需要疊加的噪聲個(gè)數(shù),frequency是計(jì)算噪聲時(shí)的采樣頻率,amplitude表示振幅。在每一次迭代中,式(32)、(33)用來(lái)控制頻率與振幅變化,其中l(wèi)acunarity是決定頻率變化的因子,一般是大于等于1的浮點(diǎn)數(shù);persistence是決定振幅變化的因子,一般取不大于1的浮點(diǎn)數(shù)。
由于振幅變化可能會(huì)引起最終噪聲值超出(-1,1)區(qū)間,所以在程序中設(shè)置了一個(gè)變量range記錄振幅變化。在每次振幅發(fā)生變化時(shí),用式(34)記錄當(dāng)前振幅的值,在噪聲計(jì)算完成后,再利用式(35)將fractal的值規(guī)范到(-1,1)區(qū)間內(nèi)。
圖3、圖4分別展示了octaves為2、frequency為8,以及l(fā)acunarity為2、3、4與persistence為0.5、0.75、1時(shí)的三維Perlin分形噪聲。
2.3 地形生成
三維Perlin分形噪聲生成地形的基本思想是:利用噪聲函數(shù)生成高度場(chǎng),對(duì)原平面網(wǎng)格頂點(diǎn)進(jìn)行位移映射,構(gòu)建地形。整個(gè)過(guò)程可分為網(wǎng)格構(gòu)建、高度場(chǎng)生成與映射位移3部分。
2.3.1 網(wǎng)格構(gòu)建
(1)在Unity中新建一個(gè)空對(duì)象,并為其添加Mesh組件。
(2)指定要生成地形的分辨率,分辨率用resolution表示。分辨率越大,最后生成的地形細(xì)節(jié)表現(xiàn)得越充分。
(3)計(jì)算網(wǎng)格頂點(diǎn)和頂點(diǎn)法線。假設(shè)要構(gòu)建一個(gè)分辨率為resolution * resolution的地形,則總頂點(diǎn)數(shù)目為(resolution+1)2,將頂點(diǎn)坐標(biāo)保存在數(shù)組vertices中,數(shù)組vertices的成員用三維向量表示。用數(shù)組normals保存頂點(diǎn)法線,頂點(diǎn)坐標(biāo)計(jì)算如下:
Unity的坐標(biāo)系統(tǒng)是左手坐標(biāo)系,Y軸代表垂直方向,X軸代表水平方向,Z軸代表深度。由于要構(gòu)建的是水平平面地形,這里只計(jì)算了頂點(diǎn)的X和Z坐標(biāo),并按照先X方向、后Z方向的順序進(jìn)行計(jì)算。X和Z坐標(biāo)減0.5的作用是為了使最終生成平面網(wǎng)格的中心仍位于原點(diǎn)處。因?yàn)闃?gòu)建的平面是基于X-Z的,每個(gè)頂點(diǎn)的法線都是沿Y軸朝上,所以法線可以用Unity中的內(nèi)置變量Vector3.up表示。最后將計(jì)算出的頂點(diǎn)和法線分別賦給Mesh組件的vertices屬性和normals屬性。
(4)網(wǎng)格生成。Unity中的網(wǎng)格都是以三角形為基礎(chǔ)的,用Mesh組件的triangles屬性保存所需的三角形。
定義一個(gè)triangles數(shù)組,triangles數(shù)組主要保存構(gòu)建三角形時(shí)所用到的頂點(diǎn)索引。由于一個(gè)四邊形由2個(gè)三角形構(gòu)成,因此對(duì)于分辨率為resolution*resolution的網(wǎng)格,數(shù)組大小為resolution2*6。利用之前計(jì)算出的頂點(diǎn)可以構(gòu)造出需要的網(wǎng)格,需要注意的是,Unity中三角形的前向面頂點(diǎn)是依順時(shí)針排列的。以圖5所示4*1的分辨率為例,構(gòu)建第一個(gè)四邊形所用到的頂點(diǎn)索引為0,1,5,6,則對(duì)應(yīng)的兩個(gè)三角形分別為0,5,1和1,5,6。對(duì)于分辨率為resolution*resolution的網(wǎng)格,triangles數(shù)組生成過(guò)程如圖6所示。
圖6中用t表示構(gòu)成四邊形的頂點(diǎn)索引,按照先X方向、后Z方向的順序,每個(gè)四邊形構(gòu)建完畢之后,t值增加6。
2.3.2 高度場(chǎng)生成與位移映射
網(wǎng)格構(gòu)建完成后,利用之前構(gòu)造的分形噪聲fractal生成高度場(chǎng)。按照先X方向、后Z方向的順序,分別求出每個(gè)頂點(diǎn)處的fractal值。為了能夠動(dòng)態(tài)調(diào)整最終生成地形的起伏程度,設(shè)置一個(gè)strength變量調(diào)整fractal的值,如式(39)所示,strength范圍為(0,1]。
然后將其賦值給頂點(diǎn)的Y坐標(biāo),完成位移映射,如式(40)所示。
對(duì)頂點(diǎn)作位移映射之后,可以利用Mesh組件自帶的RecalculateNormals()函數(shù)重新計(jì)算頂點(diǎn)法線。
3 實(shí)驗(yàn)結(jié)果與分析
根據(jù)本文方法,在Unity3D 2017.3.1f平臺(tái)下,利用C#語(yǔ)言在VisualStdio2017下編寫(xiě)腳本,最終生成的地形效果如圖7所示。圖7(a)為分辨率100*100的地形,圖7(b)為分辨率200*200的地形。從圖中可以看出,在200*200分辨率下,如地表褶皺等地形細(xì)節(jié)特征表現(xiàn)得更加充分。采用一個(gè)漸變的顏色帶對(duì)最終地形進(jìn)行著色,藍(lán)色越深表示海拔越低,黃色表示高海拔地帶。
Unity3D可以自動(dòng)處理光照和陰影,當(dāng)向場(chǎng)景中添加光照,生成的地形效果如圖8所示,其中圖8(a)為關(guān)閉Unity陰影效果,圖8(b)為開(kāi)啟陰影效果。
圖9展示了通過(guò)改變strength的值調(diào)整地形起伏狀態(tài)。
最后,與隨機(jī)中點(diǎn)位移法生成的地形相比,如圖10所示,可以看到隨機(jī)中點(diǎn)位移法生成的山頂過(guò)于尖凸,而且如山體表面褶皺等地形細(xì)節(jié)表現(xiàn)不夠充分。利用本文算法生成的地形山頂表現(xiàn)自然,沒(méi)有過(guò)于尖凸的現(xiàn)象出現(xiàn),而且山體表面褶皺也表現(xiàn)較好,整體而言本文算法效果更佳。
4 結(jié)語(yǔ)
本文提出一種在Unity3D平臺(tái)下,利用三維Perlin噪聲構(gòu)造分形進(jìn)而生成地形的方法。對(duì)經(jīng)典Perlin噪聲中晶格頂點(diǎn)處隨機(jī)梯度的選取方法進(jìn)行改進(jìn),從而使最終生成的噪聲更具有隨機(jī)性。利用Unity3D中Mesh組件的自動(dòng)計(jì)算法線功能,簡(jiǎn)化了頂點(diǎn)在位移映射之后計(jì)算法線的過(guò)程。但是本文方法還存在一些不足,如當(dāng)分辨率過(guò)大時(shí),需要計(jì)算的頂點(diǎn)數(shù)目也相應(yīng)增多,耗費(fèi)時(shí)間較長(zhǎng),幀數(shù)也會(huì)急劇下降,而且地形起伏不能通過(guò)局部進(jìn)行調(diào)整,這是下一步需要改進(jìn)的地方。本文方法在生成地形方面效果較好,能夠充分表現(xiàn)出地形細(xì)節(jié)特征,且過(guò)程簡(jiǎn)單,能夠滿(mǎn)足地形仿真需求。
參考文獻(xiàn):
[1] 吳欣. 大場(chǎng)景可變地形特效技術(shù)研究[D]. 北京:北方工業(yè)大學(xué),2016.
[2] 邢玥. 基于GPU的動(dòng)態(tài)地形實(shí)時(shí)繪制[D]. 北京:華北電力大學(xué),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] 張潤(rùn)花,劉樹(shù)群,趙付青. 地形生成的細(xì)分隨機(jī)移位方法[J]. 華中師范大學(xué)學(xué)報(bào):自科版, 2012, 46(5):533-536.
[8] 李玉娟,譚同德. 三維場(chǎng)景中大規(guī)模地形地貌的生成[J]. 計(jì)算機(jī)應(yīng)用與軟件,2013,30(11):131-135.
[9] 馬海鳳. 大規(guī)模地形可視化技術(shù)研究[D]. 西安:西安電子科技大學(xué),2015.
[10] 劉瑤,庹先國(guó),李懷良,等. Perlin噪聲生成地形的一種高效率并行方法[J]. 科技通報(bào),2016,32(3):200-204.
[11] 鄭顧平,白若林. 基于WebGL的動(dòng)態(tài)地形實(shí)時(shí)繪制[J]. 軟件導(dǎo)刊,2017,16(12):202-205.
[12] 王帥. 基于Simplex噪聲繪制云的方法[J]. 遼寧石油化工大學(xué)學(xué)報(bào),2009,29(3):58-61.
[13] 石秋華. 利用Perlin噪聲生成水波面的動(dòng)態(tài)模擬研究[J]. 軟件導(dǎo)刊,2012,11(2):140-142.
[14] 項(xiàng)予,許森. 基于Perlin噪聲的動(dòng)態(tài)水面實(shí)時(shí)渲染[J].? 計(jì)算機(jī)工程與設(shè)計(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] 徐建華,顧浩,康鳳舉,等. 真實(shí)感降雪場(chǎng)景可視化[J]. 系統(tǒng)仿真學(xué)報(bào),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.
(責(zé)任編輯:黃 健)