張文娟,吳 瓊,曹欣然
(西安石油大學(xué) 計算機(jī)學(xué)院,陜西 西安 710000)
粒子系統(tǒng)是迄今為止模擬不規(guī)則物體最成功的算法之一,目前國內(nèi)外已有許多成功使用粒子系統(tǒng)與其他技術(shù)相結(jié)合的案例,以模擬現(xiàn)實(shí)生活中雨雪、火焰、爆炸、噴泉等場景。與之相結(jié)合的技術(shù)主要有OpenGL、WebGL,使用的編程語言也多為C++或者C#。Latta等采用GPU進(jìn)行粒子系統(tǒng)的模擬,能實(shí)時處理超過100萬個粒子,使得大規(guī)模粒子模擬成為可能,也使越來越多的人開始關(guān)注并研究基于GPU的粒子系統(tǒng)動畫模擬。李曉萍對基于GPU的粒子系統(tǒng)進(jìn)行了深入研究,利用基于GPU的粒子系統(tǒng)模擬了噴泉,并在CPU中處理了噴泉粒子的產(chǎn)生和消亡,在GPU中更新粒子的屬性,顯示粒子[1]。袁霞等對粒子系統(tǒng)的方法及應(yīng)用做了較為系統(tǒng)詳盡的研究,并利用3D MAX模擬了水泡上升的自然現(xiàn)象[2]。羅維佳等使用C++語言,將雨粒子產(chǎn)生區(qū)域定義為一個視圖體頂部的外接長方體,用像素點(diǎn)和直線作為對雨粒子的形狀、降落過程的重力作用的模擬,完成了對降雨過程的仿真[3]。徐利明等使用將粒子系統(tǒng)與OpenGL相結(jié)合的方式,把模擬雨、雪的粒子在一個新的視口中視線有效區(qū)域內(nèi)進(jìn)行繪制,然后與原視口中的場景一起顯示于窗口中,實(shí)現(xiàn)了對雨雪效果的模擬[4]。
隨著互聯(lián)網(wǎng)技術(shù)的不斷發(fā)展,網(wǎng)頁制作技術(shù)起到了越來越重要的作用,在網(wǎng)頁制作的過程中,3D技術(shù)具有十分明顯的優(yōu)勢,它可以使用戶對所需瀏覽的內(nèi)容的感知更加真實(shí)。目前實(shí)現(xiàn)3D網(wǎng)頁的主要技術(shù)有Flash3D、java3D、Unity3D等等[5]。但這些技術(shù)在網(wǎng)頁上的實(shí)現(xiàn)均需要安裝特定的插件,而插件的安裝則會對網(wǎng)頁的穩(wěn)定性和跨平臺性有所影響。其次,很多技術(shù)只針對特定的行業(yè),不具備較強(qiáng)的通用性,例如Unity3D只適合游戲開發(fā)。而WebGL的產(chǎn)生則解決了這些問題[6]。
WebGL是一項(xiàng)可以在瀏覽器中繪制、顯示三維計算圖形并與之交互的技術(shù)。曾經(jīng)只有高端的計算機(jī)或?qū)iT的游戲終端才能渲染三維圖形,因?yàn)檫@需要大量復(fù)雜的編程才能實(shí)現(xiàn)[7]。然而隨著個人計算機(jī)以及瀏覽器性能的提高,使用網(wǎng)頁技術(shù)渲染三維圖形也成為可能。和OpenGL和Direct3D不同,WebGL程序可存在于網(wǎng)頁中并在瀏覽器中執(zhí)行,而不必安裝任何其他的插件和庫[8]。然而,直接使用WebGL編程是十分復(fù)雜的,需要了解WebGL的內(nèi)部細(xì)節(jié),學(xué)習(xí)復(fù)雜的著色器語法[8],因此文中使用一個基于WebGL的開源框架Three.js。
Three.js基于WebGL,封裝了底層的圖形接口,使得使用者不需要掌握冗雜的圖形學(xué)知識,就能用簡單的代碼完成三維場景的渲染。理論上,更高的封裝程度往往意味著靈活性的犧牲,但Three.js在這方面做得很好,幾乎不存在WebGL支持而Three.js不能實(shí)現(xiàn)的情況。目前,國內(nèi)主要將這一技術(shù)應(yīng)用于物體的真實(shí)化展示。如高辰飛將其應(yīng)用于海洋樣品的三維可視化研究,實(shí)現(xiàn)了對海洋樣品的虛擬可視化[9]。
綜上,在研究粒子系統(tǒng)的基礎(chǔ)上,利用WebStorm開發(fā)工具在Windows平臺下進(jìn)行降雨場景的模擬,建立粒子系統(tǒng)和雨滴系統(tǒng)模型。
粒子系統(tǒng)由Reeves W T于1983年提出,并成功模擬了灰塵、噴泉等效果。其基本思想是利用形狀簡單的微小粒子作為元粒子來描述不規(guī)則的模糊物體。粒子系統(tǒng)并不是一個簡單的靜態(tài)系統(tǒng),而是動態(tài)變化的。每個元粒子具有大小、形狀、位置、顏色、速度以及生命周期等屬性[10-11]。與其他描述不規(guī)則物體的方法相比,粒子系統(tǒng)具有三個主要特點(diǎn):
(1)對物體的描述是通過一組定義在空間的原始粒子,而不是利用原始的具有邊界的面元[12]。
(2)粒子系統(tǒng)不是一個靜態(tài)系統(tǒng),每個粒子的屬性均隨時間的變化而變化。
(3)粒子系統(tǒng)所描述的物體不是預(yù)先定義好的,其相關(guān)屬性均可使用隨機(jī)過程來描述[12]。
從應(yīng)用的角度可將粒子系統(tǒng)分為三類,分別是隨機(jī)粒子系統(tǒng)、結(jié)構(gòu)化粒子系統(tǒng)、方向粒子系統(tǒng)。隨機(jī)粒子系統(tǒng)通過可控制的隨機(jī)過程控制粒子屬性的變化,用來生成灰塵、煙、爆炸等場景圖像[13]。結(jié)構(gòu)化粒子系統(tǒng)可以用來模擬具有一定結(jié)構(gòu)的現(xiàn)象或物體,如樹、草等。方向粒子系統(tǒng)則考慮了粒子間的相互影響,粒子除具有位置和速度等動態(tài)屬性之外,還應(yīng)該具有方向?qū)傩?,用來模擬可變物體。由于落葉場景沒有固定的結(jié)構(gòu),在模擬時亦不需要考慮葉粒子之間的相互作用,因此適合采用隨機(jī)粒子系統(tǒng)進(jìn)行模擬。
在隨機(jī)粒子系統(tǒng)中,隨著時間的變化,粒子的運(yùn)動狀態(tài)及形式不斷發(fā)生變化,元粒子狀態(tài)的改變引起粒子群整體的變化。在這一過程中,舊粒子不斷死亡,新粒子不斷產(chǎn)生,粒子生命周期及其變化都可以使用隨機(jī)過程進(jìn)行模擬[3]。通常,粒子系統(tǒng)實(shí)現(xiàn)的主要步驟如下:
(1)分析粒子的靜態(tài)特性,定義新粒子。
(2)引入隨機(jī)函數(shù),建立粒子屬性動態(tài)變化特征。
(3)根據(jù)粒子動態(tài)特性更新粒子屬性[14]。
(4)刪除生命周期結(jié)束的粒子。
(5)渲染產(chǎn)生新粒子。
隨著HTML5標(biāo)準(zhǔn)的頒布以及主流瀏覽器功能的日益強(qiáng)大,直接在瀏覽器中展示三維圖形和動畫已經(jīng)變得越來越容易,也越來越受關(guān)注。但是,三維圖形和動畫本身就比較復(fù)雜,不僅需要具備豐富的數(shù)學(xué)、圖形學(xué)等方面的基礎(chǔ)知識,還需要了解材質(zhì)、貼圖等各種創(chuàng)建三維場景所必須的要素。除此之外,直接使用WebGL在瀏覽器中創(chuàng)建動畫也十分煩瑣[15]。
Three.js的出現(xiàn)解決了這個矛盾,它將WebGL的強(qiáng)大功能融匯在其中,同時語法簡單、易于使用,即使使用者對WebGL的底層細(xì)節(jié)并不清楚,也能借助Three.js創(chuàng)建出絢麗多姿的三維場景和動畫。Three.js支持多種渲染器進(jìn)行場景渲染并提供了點(diǎn)、線、面、向量、矩陣等創(chuàng)建三維物體所必須的要素,同時可以使用十分簡單的語法將照相機(jī)(鏡頭)、光線、物體等對象添加到場景當(dāng)中。
用Three.js創(chuàng)建三維物體并在網(wǎng)頁上顯示的主要步驟如下:
(1)場景設(shè)置:場景實(shí)質(zhì)上就是一個三維空間,后續(xù)創(chuàng)建的物體均需要添加到場景中。在Three.js中,創(chuàng)建三維場景的代碼為:var scene=new THREE.Scence()。場景可以理解成一個巨大的容器,在程序最開始執(zhí)行的時候完成場景的實(shí)例化,然后通過add()方法向場景中添加對象。
(2)相機(jī)設(shè)置:Three.js中有兩種不同的相機(jī),分別是正投影相機(jī)和透視相機(jī)。透視相機(jī)可以模擬出最自然的視圖,在同一場景中如果選用透視相機(jī),則距離相機(jī)越遠(yuǎn)的物體會被渲染的越小,而如果采用正投影相機(jī),則同一場景中物體距離相機(jī)的遠(yuǎn)近不會影響該物體的大小[13]。在進(jìn)行自然現(xiàn)象的模擬中通常使用透視投影,因?yàn)檫@更接近人眼的觀察效果,圖1分別表示同一場景在兩種相機(jī)下的顯示情形。
圖1 透視相機(jī)(左)與正投影相機(jī)(右)
可以看到,透視相機(jī)照射出的物體明顯具有近大遠(yuǎn)小的效果。而在傳統(tǒng)的模擬中,需要對Z軸進(jìn)行一系列控制,才能渲染出近大遠(yuǎn)小的效果。如周強(qiáng)等的基于粒子系統(tǒng)的三維降雪場景仿真中,在Z軸上需要對雪花進(jìn)行深淺的分類才能模擬出此效果[13]。而使用Three.js只需選擇合適的相機(jī)并對所渲染物體的參數(shù)設(shè)置合理,就可以很容易地模擬出這種效果,而不需要添加函數(shù)控制或者引入其他粒子。
(3)光源設(shè)置:Three.js中提供了多種光源,每種光源都有特定的用途,一個場景中可以設(shè)置多個光源,基本上都是將環(huán)境光源和其他光源組合起來,根據(jù)三維場景中顯示物體的不同,可以選擇不同的光源組合。
(4)物體模型的設(shè)置:Three.js本身提供了大量的幾何體,例如球、長方體等。也可選擇合適的庫來加載其他格式的三維模型,如obj、json等格式的模型,通過導(dǎo)入外部三維模型,可以達(dá)到更加真實(shí)的仿真效果。
(5)渲染器設(shè)置:渲染器的工作是將三維場景中的物體映射到二維平面上[16],即映射到電腦的顯示器上。在場景中添加了物體、設(shè)置好相機(jī)之后,就可以調(diào)用渲染器的渲染函數(shù)來渲染整個場景。
通過以上五個步驟,就可以搭建一個簡單的三維場景。圖2為Web上顯示三維場景的基本結(jié)構(gòu)模塊。
圖2 三維場景的構(gòu)成
Three.js中使用ParticleBasicMaterial(基礎(chǔ)粒子材質(zhì))創(chuàng)建和設(shè)計粒子,使用ParticleSystem(粒子系統(tǒng))創(chuàng)建一個粒子集合。通常,使用Three.js創(chuàng)建粒子系統(tǒng)的步驟如下:
(1)搭建三維場景;
(2)定義一個三維幾何體;
(3)對所需創(chuàng)建的粒子系統(tǒng)中的粒子定義材質(zhì);
(4)利用雙層循環(huán)為每個粒子創(chuàng)建一個定點(diǎn),并利用push方法將其添加到幾何體中;
(5)創(chuàng)建ParticleSystem對象,將三維幾何體和材質(zhì)進(jìn)行融合;
(6)利用scene.add()方法將ParticleSystem添加到場景中。
圖3是一個簡單的粒子系統(tǒng)。在該例中,首先創(chuàng)建了一個THREE.Geometry對象,之后利用循環(huán)語句在隨機(jī)的位置上創(chuàng)建粒子,并將其添加到幾何體中,最后再使用ParticleSystem類來顯示粒子。ParticleSystem類的構(gòu)造函數(shù)接收兩個參數(shù),一個是幾何體、一個是材質(zhì)。材質(zhì)用來給粒子上色和添加紋理,而幾何體用來指定將粒子放在哪里,每個頂點(diǎn),即定義幾何體的各個點(diǎn),將會以粒子的形態(tài)展示出來。
圖3 簡單粒子系統(tǒng)
對葉粒子降落的運(yùn)動過程進(jìn)行分析,確定葉粒子的屬性。葉子在下降過程中,會受到風(fēng)力、重力等因素的影響,在視覺上并不是沿直線降落,同時,加速度和速度也在不斷變化。在X軸上,落葉受風(fēng)力影響位置左右飄動,在Y軸上落葉滴受空氣浮力以及重力的作用做下降運(yùn)動且各時刻速度均不相同。利用WebGL的第三方庫Three.js模擬落葉效果與傳統(tǒng)模擬方法的主要區(qū)別在于不需要對Z軸進(jìn)行額外的控制。在傳統(tǒng)方法中,要模擬出遠(yuǎn)處的物體看上去比近處的物體小一些的效果,需要對Z軸上粒子的深淺程度進(jìn)行控制。而利用Three.js除了可以使用透視相機(jī)來達(dá)到這一目的外,還可以在創(chuàng)建粒子時對sizeAnnutation屬性進(jìn)行設(shè)置,將該屬性設(shè)置為false時,系統(tǒng)中的粒子無論距相機(jī)多遠(yuǎn),都將具有相同的尺寸,而如果設(shè)置為true,則粒子的大小取決于其距離相機(jī)的遠(yuǎn)近。通過相機(jī)與sizeAnnutation屬性的配合使用,就能很好地模擬出遠(yuǎn)處的物體看上去比近處小的效果,而不需要引入額外的控制,這就簡化了實(shí)現(xiàn)步驟,并不影響模擬效果的真實(shí)性。當(dāng)雨粒子下降到地面時,重新對其設(shè)置位置屬性,如此循環(huán)模擬降雨場景。
由于在實(shí)驗(yàn)中,對相機(jī)所能渲染的范圍設(shè)置為1 000,即屏幕上的物體均可被渲染出來。因此,在葉子飄落的過程中,可以將顯示器頂部作為粒子的初始位置。
在此次實(shí)驗(yàn)中,采用加載外部圖片的方法來格式化粒子系統(tǒng)中的粒子。Three.js中可以使用THREE.ImageUtils.loadTexture()方法加載外部圖片,使用外部圖片來格式化粒子的優(yōu)點(diǎn)是使得所模擬物體更加形象逼真。文中采用128*128的png圖片來格式化落葉粒子系統(tǒng),如圖4所示。
圖4 落葉粒子紋理
加載完外部圖形之后,需要將圖片應(yīng)用于粒子的材質(zhì)中,Three.js中實(shí)現(xiàn)這一效果的主要代碼如下:
var material=new THREE.ParticleBasicMaterial({
size:10,
transparent:true,
opacity:0.3,
map:texture,
blending:THREE.AdditiveBlending,
sizeAttenuation:true,
color:0xffffff
});
其中,map屬性就指向加載的外部圖片。
在完成粒子的格式化之后,需要對粒子運(yùn)動時的速度進(jìn)行控制。為了簡化落葉粒子運(yùn)動過程,提高系統(tǒng)的實(shí)時性,對每個落葉粒子的速度都使用隨機(jī)控制函數(shù),使得每個粒子的速度狀態(tài)都不一致,通過大量速度狀態(tài)不一致的落葉葉粒子,營造出落葉的效果。第i個粒子的速度描述公式如下:
particle.velocityX=(Math.random()-0.5)/800
particle.velocityY=0.1 + Math.random()/1 000;
velocityX用來定義粒子以多快的速度橫向運(yùn)動,velocityY定義粒子以多快的速度下降。至此,粒子的初始屬性設(shè)置完畢。通過for循環(huán)中參數(shù)的設(shè)置,可以產(chǎn)生多個雨粒子,通過改變這個參數(shù),可以實(shí)現(xiàn)模擬下雨量。
傳統(tǒng)的模擬方法中,需要對超出生命周期的粒子進(jìn)行刪除,增加了復(fù)雜度。在此次實(shí)驗(yàn)中,通過對粒子位置的控制以避免粒子的刪除,其主要實(shí)現(xiàn)代碼如下:
If(v.y<=0) v.y=80;
If(v.x <=-50||v.x>=50) v.veloxityX=v.velocityX* -1;
這兩行代碼保證了粒子處在被定義的范圍之內(nèi),如果y方向的位置低于零,就將落葉粒子放回頂部,如果x方向的位置超出邊界,將橫向運(yùn)動速度去反,讓落葉粒子反彈。這樣,系統(tǒng)中粒子的數(shù)目其實(shí)是固定的,只是通過對系統(tǒng)內(nèi)粒子位置的調(diào)整來模擬出不斷有新的粒子產(chǎn)生和舊粒子消亡的過程。這樣不僅簡化了實(shí)現(xiàn)方法,也節(jié)約了渲染時間。
實(shí)驗(yàn)的硬件環(huán)境為主頻2.5 GHz的i5CPU,顯卡為NVIDIA GeForce GT 740M,運(yùn)行內(nèi)存為4G的PC機(jī),選用WebStorm 11.0.1開發(fā)工具在Windows平臺下,利用WebGL的第三方庫Three.js進(jìn)行模擬。實(shí)驗(yàn)結(jié)果如圖5和圖6所示。
圖5 系統(tǒng)內(nèi)粒子數(shù)量為1 000時落葉的模擬
圖6 系統(tǒng)內(nèi)粒子數(shù)量為2 000時落葉的模擬
在傳統(tǒng)的粒子系統(tǒng)算法的基礎(chǔ)上,通過對粒子系統(tǒng)內(nèi)每個粒子的位置狀態(tài)的控制,簡化了粒子消亡過程的控制。結(jié)合WebGL的第三方開源庫Three.js,避免了為實(shí)現(xiàn)粒子近大遠(yuǎn)小的視覺效果而需要對Z軸上添加控制因子。結(jié)合這兩種優(yōu)勢,大大簡化了實(shí)現(xiàn)方法。同時,通過對粒子系統(tǒng)內(nèi)粒子數(shù)量的控制,可以根據(jù)需要模擬出落葉多少的效果,在簡化實(shí)現(xiàn)方法的同時也具有逼真的三維仿真效果。
文中代碼具有良好的擴(kuò)展性,在此基礎(chǔ)上,可以加載其他外部圖片作為粒子紋理,模擬不同的自然現(xiàn)象,例如降雨、煙花等。也可以對粒子運(yùn)動速度進(jìn)行控制,模擬不同天氣情況下的降雨效果。
參考文獻(xiàn):
[1] 李曉萍.基于GPU的粒子系統(tǒng)的研究與應(yīng)用[D].長春:吉林大學(xué),2009.
[2] 袁 霞,張玉啄.粒子系統(tǒng)方法及其應(yīng)用[J].云南師范大學(xué)學(xué)報:自然科學(xué)版,2003,23(3):14-16.
[3] 羅維佳,都金康,謝順平.基于粒子系統(tǒng)的三維場地降雨實(shí)時模擬[J].中國圖象圖形學(xué)報,2004,9(4):495-500.
[4] 徐利明,姜昱明.基于粒子系統(tǒng)與OpenGL的實(shí)時雨雪模擬[J].計算機(jī)仿真,2005,22(7):242-245.
[5] 榮艷冬.基于WebGL的3D技術(shù)在網(wǎng)頁中的運(yùn)用[J].信息安全與技術(shù),2015(8):90-92.
[6] XU Zhao,ZHANG Yang,XU Xiayan.3D visualization for building information models based upon IFC and WebGL integration[J].Multimedia Tools & Applications,2016,75(24):17421-17441.
[7] 魏云申.基于WebGL的全景3D漫游系統(tǒng)的設(shè)計與實(shí)現(xiàn)[D].南京:南京大學(xué),2016.
[8] 頓儒源.基于WebGL的織物三維展示系統(tǒng)[D].杭州:浙江大學(xué),2016.
[9] 高辰飛.基于WebGL的海洋樣品三維可視化的研究[D].青島:中國海洋大學(xué),2014.
[10] REEVES W T.Particle systems-a technique for modeling a class of fuzzy objects[C]//Seminal graphics.[s.l.]:ACM,1998:203-220.
[11] REEVES W T,BLAU R.Approximate and probabilistic algorithms for shading and rendering structured particle systems[C]//Proceedings of the 12th annual conference on computer graphics and interactive techniques.[s.l.]:ACM,1985:313-322.
[12] 王潤杰,田景全,倪政國.基于粒子系統(tǒng)的實(shí)時雨雪模擬[J].系統(tǒng)仿真學(xué)報,2003,15(4):495-496.
[13] 周 強(qiáng),汪繼文.基于粒子系統(tǒng)的三維降雪場景仿真[J].計算機(jī)技術(shù)與發(fā)展,2017,27(1):130-133.
[14] DANCHILLA B. Three.js framework[M]//Beginning WebGL for HTML5.[s.l.]:[s.n.],2012:173-203.
[15] 朱麗萍,李洪奇,杜萌萌,等.基于WebGL的三維WebGIS場景實(shí)現(xiàn)[J].計算機(jī)工程與設(shè)計,2014,35(10):3645-3650.
[16] HUANG Youliang,ZHOU Mingquan.Design and development of the virtual acupuncture training using WebGL[J].Advanced Materials Research,2013,756-759:2076-2080.