基于Vega的閃電渲染方法
時(shí)間:2009-06-13 17:33:00
來源:UltraLAB圖形工作站方案網(wǎng)站
人氣:9002
作者:admin
1 概述
閃電模擬一直是視景仿真[1]中一個(gè)的重點(diǎn)。目前關(guān)于閃電模擬的方法基本都是采用粒子系統(tǒng)[2]。使用粒子系統(tǒng)模擬閃電,就是實(shí)時(shí)控制每一個(gè)粒子運(yùn)動(dòng)和變化,這樣粒子運(yùn)動(dòng)的軌跡就構(gòu)成了閃電[3~4]。
視景仿真主要基于Vega進(jìn)行開發(fā)。Vega是美國Multi Gen-Paradigm公司用于虛擬現(xiàn)實(shí)、實(shí)時(shí)視景仿真、聲音仿真以及其他可視化領(lǐng)域的世界領(lǐng)先級視景開發(fā)軟件。Vega有自己的粒子系統(tǒng),但是它沒有辦法進(jìn)行閃電模擬。Vega的粒子系統(tǒng)是封裝好的,用戶只要設(shè)定好粒子的數(shù)量、產(chǎn)生方式、各種速度(風(fēng)速、矢量速度和隨機(jī)速度等)、顏色和重力加速度,就可以使所有的粒子按照要求開始運(yùn)動(dòng)和變化。由于這樣的封裝,Vega的粒子系統(tǒng)使用起來非常方便,尤其是實(shí)現(xiàn)雨和雪模擬的時(shí)候,然而也是由于這樣的封裝,用戶只能知道整體粒子系統(tǒng)是按照什么方式工作的,根本不能得到單獨(dú)一個(gè)粒子的實(shí)時(shí)狀態(tài)和位置,因此使用Vega的粒子系統(tǒng)難以控制粒子模擬閃電。
現(xiàn)在,基于Vega的閃電模擬目前主要采用的是播放紋理技術(shù),所謂播放紋理就是事先把閃電現(xiàn)象做成一系列的連續(xù)圖片,當(dāng)要產(chǎn)生閃電的時(shí)候,系統(tǒng)就高速播放這些連續(xù)的圖片,就像播放閃電動(dòng)畫一樣。然而這個(gè)技術(shù)存在很大的缺點(diǎn):(1)因?yàn)槊看尾シ诺亩际峭瑯拥募y理圖片,所以閃電樣子單一;(2)當(dāng)閃電位置和大小變化的時(shí)候,都要對紋理圖片進(jìn)行縮放、變形,因此存在一定的失真;(3)由于閃電是紋理實(shí)現(xiàn)的,因此它無法實(shí)現(xiàn)因?yàn)殚W電顯現(xiàn)而產(chǎn)生的特效[5~6],比如閃電與地面物體的碰撞、閃電的光照現(xiàn)象、閃電云彩效果等。
圖1 使用播放紋理技術(shù)產(chǎn)生的閃電現(xiàn)象
1994年,T.Reed[3]比較系統(tǒng)地提出了用粒子系統(tǒng)實(shí)現(xiàn)CG閃電模擬。具體方法:在云中放一個(gè)粒子,然后這個(gè)粒子隨機(jī)產(chǎn)生幾個(gè)子粒子,子粒子隨機(jī)地產(chǎn)生向下的角度,向下運(yùn)動(dòng),子粒子又隨機(jī)地產(chǎn)生新粒子……,這樣就產(chǎn)生了整個(gè)閃電整體。在渲染方面,他采用光線跟蹤技術(shù),不過僅僅只渲染了閃電主枝。由于當(dāng)時(shí)技術(shù)的限制,他的閃電模擬做得比較粗糙,只追求模擬閃電的樣子。1999年,楊子華[4]進(jìn)一步總結(jié)闡述了T. Reed的閃電模擬方法。同年,P.Kruszewski[7]在隨機(jī)二叉樹的理論基礎(chǔ)上,提出了一個(gè)可以改變參數(shù)的閃電模型。只要設(shè)定好模型的多個(gè)參數(shù),就可以產(chǎn)生出令人滿意的閃電樣子。由于在渲染上,他還是采用T. Reed模型中的方法,因此他也只考慮閃電主枝的渲染,閃電分支以及周圍物體的渲染沒有考慮進(jìn)去。
2001年,B.Sosorbaram等[6]提出自己的閃電模擬方法,在他之前的閃電模型、閃電形態(tài)的參數(shù)都是從圖片或者錄像中估計(jì)出來的,而B.Sosorbaram強(qiáng)調(diào)使用物理的參數(shù),這樣產(chǎn)生的閃電才更加真實(shí)。而且在他文章中也實(shí)現(xiàn)了閃電對周圍云彩的光照效果。
閃電模擬中,閃電分支越多,渲染就越復(fù)雜,占用的時(shí)間就越多,而降低閃電分支的復(fù)雜度,整個(gè)閃電模擬就會失真,因此,閃電模擬還沒有廣泛應(yīng)用到大型的虛擬現(xiàn)實(shí)仿真系統(tǒng)中。基于此,本文提出一種閃電渲染算法,可以通過簡單的閃電形狀,模擬出效果真實(shí)的閃電。
2 Vega中閃電渲染的新方法
2.1 可行性
圖2是開發(fā)Vega應(yīng)用的層次關(guān)系[8],從底層實(shí)現(xiàn)來看,Vega實(shí)際上是基于場景圖(scene graph)之上的,而場景圖管理系統(tǒng)本身又建立在OpenGL這樣的標(biāo)準(zhǔn)圖形庫之上。在SGI平臺上,Vega所依附的場景圖管理系統(tǒng)就是Performer,而在Windows平臺上,Vega所依附的是一套被稱為“Jolt”的場景圖管理系統(tǒng)(Jolt實(shí)際上就是PC上的Performer實(shí)現(xiàn))。另外,Vega不但提供大量的API函數(shù),還提供回調(diào)函數(shù)(CALLBACK)[8],因此,可以在回調(diào)函數(shù)中實(shí)現(xiàn)OpenGL命令和Vega API函數(shù)的結(jié)合。
圖2 開發(fā)Vega應(yīng)用的層次關(guān)系
Vega應(yīng)用有3個(gè)必需步驟[8]:初始化系統(tǒng)(vgInitSys()),定義系統(tǒng)(vgDefineSys()),配置系統(tǒng)(vgConfigSys()),之后就可以進(jìn)入Vega應(yīng)用的主循環(huán)來渲染幀和幀同步(vgSync Frame()和vgFrame())。本文在配置系統(tǒng)之后使用vgAddFunc (vgGetChan(0), VGCHAN_POSTDRAW, Lightning, NULL ),定義一個(gè)名為Lightning的VGCHAN_PREDRAW回調(diào)函數(shù),它的參數(shù)為空。VGCHAN_PREDRAW回調(diào)函數(shù)是在創(chuàng)建通道之后、開始畫圖之前調(diào)用。 #p#page_title#e#
2.2 閃電結(jié)構(gòu)生成
為了提高模擬的真實(shí)度,采用以下方法進(jìn)行優(yōu)化:(1)采用優(yōu)化過的隨機(jī)函數(shù)來控制閃電段的角度和長度。(2)對所有閃電段都增加了參數(shù)來表示它的能量,同一層次的分支中,能量隨著閃電段延續(xù)而減小,不同級別的分支,其初始能量也是不一樣的,這樣最終閃電效果不像傳統(tǒng)方法中閃電粗細(xì)始終不變。(3)整個(gè)閃電段都共面,這個(gè)面是一個(gè)垂直地面的Billboard,其法向量平行于視線。
2.2.1 數(shù)據(jù)結(jié)構(gòu)
struct segment //閃電段的結(jié)構(gòu)
{
Vector3 start; //段的上節(jié)點(diǎn)坐標(biāo)
float power_start; //上節(jié)點(diǎn)處能量
Vector3 end; //段的上節(jié)點(diǎn)坐標(biāo)
float power_end; //下節(jié)點(diǎn)處能量
}; //閃電分支結(jié)構(gòu)
{
Vector3 start; //分支最頂節(jié)點(diǎn)坐標(biāo)
float power; //分支初始能量
float angle; //分支的初始角度
};
2.2.2 算法描述
Step1 取云間一點(diǎn)作為整個(gè)閃電的起始點(diǎn),生成branch對象,隨機(jī)生成它的power和angle,并將這個(gè)branch壓入分支棧。
Step2 判斷分支棧是否為空,如果為空,表示整個(gè)閃電結(jié)構(gòu)已經(jīng)生成,則轉(zhuǎn)Step7;否則,從分支棧中彈出一個(gè)分支,以它的坐標(biāo)和能量作為新生成segment對象上節(jié)點(diǎn)的坐標(biāo)和能量。
Step3 隨機(jī)決定是否在segment對象上節(jié)點(diǎn)處是否產(chǎn)生新的閃電分支,如果產(chǎn)生,則上節(jié)點(diǎn)的坐標(biāo)作為新branch對象的start,而power和angle都采用優(yōu)化隨機(jī)函數(shù)產(chǎn)生(注:power小于上節(jié)點(diǎn)能量),并將此新的branch對象壓入分支棧。
Step4 根據(jù)segment對象的上節(jié)點(diǎn)和能量以及整個(gè)分支的angle,采用隨機(jī)函數(shù)生成其下節(jié)點(diǎn)的坐標(biāo)和能量。因?yàn)樵谕环种е心芰窟f減,所以要控制隨機(jī)函數(shù),使得下節(jié)點(diǎn)的能量小于上節(jié)點(diǎn)能量而且還不能引起能量巨變。
Step5 保存上面生成segment對象,并將其下節(jié)點(diǎn)坐標(biāo)和能量作為新的segment對象的上節(jié)點(diǎn)坐標(biāo)和能量。
Step6 對新segment對象上節(jié)點(diǎn)的坐標(biāo)和能量進(jìn)行判斷,如果它已經(jīng)到達(dá)地面或者它的能量已經(jīng)太小(可忽略),則轉(zhuǎn)Setp2;否則Step3。
Step7 生成過程結(jié)束。
生成的segment對象集合就構(gòu)成了整個(gè)閃電結(jié)構(gòu)。
2.3 紋理生成
2.3.1 紋理結(jié)構(gòu)生成
采用2.2.2節(jié)的生成算法在紋理圖片上生成一個(gè)小型的閃電,這個(gè)閃電結(jié)構(gòu)簡單,分支少。然后根據(jù)分支的層次,以每個(gè)segment的上、下節(jié)點(diǎn)連線為中心向兩邊擴(kuò)展,生成segment面。閃電主枝為最高層,因此它的面最寬,從上層分支上生成的分支為下一層,寬度比上一層遞減,如圖3。
圖3 閃電紋理的結(jié)構(gòu)層次
2.3.2 紋理著色
通常閃電段周圍會有一些別的顏色,顏色是閃電與空氣中化學(xué)物質(zhì)發(fā)生作用以及物理作用產(chǎn)生的,稱為閃電的燃燒顏色,一般其為粉紅色或者淡藍(lán)色。首先將2.2.1節(jié)生成的segment面著色為白色用來表示閃電本身的顏色;然后每個(gè)閃電段的燃燒顏色由式(1)計(jì)算: 2exp(())iiidGgWλλ=− (1)
其中,iGλ為段i在光線λ下的燃燒顏色;gλ為光線λ的最大值;為段i周圍燃燒區(qū)域?qū)挾鹊囊话耄阉O(shè)置為段i的長度;為距離段i的距離。由于當(dāng)>2.2倍的時(shí),ididiW2exp(())iidW−的值已經(jīng)小于1%,因此在計(jì)算的時(shí)候只需要計(jì)算閃電段兩側(cè)2.2倍距離以內(nèi)的點(diǎn),這樣就大大減小計(jì)算的復(fù)雜度。
圖4是采用光線λ為淡藍(lán)色時(shí)候渲染出來的紋理圖片,其中,黑色部位為透明。
圖4 渲染紋理
2.4 實(shí)現(xiàn)
在2.2.2節(jié)算法生成的閃電結(jié)構(gòu)中,閃電被分解成閃電段,根據(jù)segment結(jié)構(gòu),以上、下節(jié)點(diǎn)連線為中心向兩邊擴(kuò)展形成segment面,擴(kuò)張寬度大小由上、下節(jié)點(diǎn)的能量power控制,這樣就體現(xiàn)了分支層次結(jié)構(gòu)以及閃電能量的遞減。在每個(gè)擴(kuò)展的segment面上都映射[9]2.3節(jié)生成的紋理,這樣就完成了閃電本身的渲染。
對閃電周圍環(huán)境的渲染,包括閃電對場景和云層的照亮效果,通過Dobashi[5]提出的在主要的閃電分支上增加數(shù)個(gè)點(diǎn)光源實(shí)現(xiàn)。
2.5 實(shí)驗(yàn)結(jié)果 #p#page_title#e#
與Vega中的播放紋理技術(shù)相比,本文提出的方法靈活,閃電的形狀變化豐富,而且實(shí)現(xiàn)閃電本身渲染、閃電對周圍環(huán)境的光照特效。
與其他的閃電渲染算法相比,此方法最大的特點(diǎn)就是簡單,如果傳統(tǒng)方法產(chǎn)生的閃電有10 000個(gè)閃電段,那么就必須計(jì)算10 000個(gè)閃電段,渲染10 000個(gè)閃電段,而如果采用此方法,制作的閃電紋理里面包含20個(gè)閃電段,整體閃電的閃電分支就只需要500個(gè),那么程序就只需要計(jì)算520個(gè)閃電段,渲染20個(gè)閃電段就可以達(dá)到同樣逼真的效果。
圖5是近距離的效果,閃電主枝上的小分支非常多,采用紋理映射技術(shù),只需要不到8個(gè)閃電就實(shí)現(xiàn)了。圖6是遠(yuǎn)距離的效果,閃電形狀更加真實(shí),而且閃電對周圍環(huán)境的光照特效也非常明顯。
圖5 近距離效果
圖6 遠(yuǎn)距離效果
2.6 使用新方法需要注意的問題
Vega并不是所有的回調(diào)函數(shù)都可以使用OpenGL指令繪圖,準(zhǔn)確地說只有在屬于Draw繪制進(jìn)程[8]的回調(diào)函數(shù)中才可以調(diào)用OpenGL指令繪圖。
由于在繪圖通道中狀態(tài)改變耗費(fèi)嚴(yán)重,為了高性能運(yùn)行,Vega和OpenGL都采用惰性狀態(tài)評價(jià)。因此,在程序中使用OpenGL命令改變狀態(tài)之前,一定要保存以前的狀態(tài),命令運(yùn)行結(jié)束之后,也要及時(shí)恢復(fù)這些狀態(tài)。
3 結(jié)束語
本文提出了一種新的閃電渲染方法,該方法與傳統(tǒng)方法相比,實(shí)現(xiàn)簡單,模擬效果真實(shí),運(yùn)算量小,尤其是在閃電本身渲染方面,適合實(shí)時(shí)性要求高的仿真系統(tǒng);同時(shí),結(jié)合Vega的特點(diǎn),成功地將此方法應(yīng)用到Vega環(huán)境中,解決了基于Vega的視景仿真中無法實(shí)現(xiàn)隨機(jī)閃電渲染的難題,該方法產(chǎn)生的閃電模擬應(yīng)用到民用飛機(jī)模擬器視景仿真中,取得了良好的仿真演示效果,此外其對于Vega中復(fù)雜模型的建立也有重要意義。
閃電模擬一直是視景仿真[1]中一個(gè)的重點(diǎn)。目前關(guān)于閃電模擬的方法基本都是采用粒子系統(tǒng)[2]。使用粒子系統(tǒng)模擬閃電,就是實(shí)時(shí)控制每一個(gè)粒子運(yùn)動(dòng)和變化,這樣粒子運(yùn)動(dòng)的軌跡就構(gòu)成了閃電[3~4]。
視景仿真主要基于Vega進(jìn)行開發(fā)。Vega是美國Multi Gen-Paradigm公司用于虛擬現(xiàn)實(shí)、實(shí)時(shí)視景仿真、聲音仿真以及其他可視化領(lǐng)域的世界領(lǐng)先級視景開發(fā)軟件。Vega有自己的粒子系統(tǒng),但是它沒有辦法進(jìn)行閃電模擬。Vega的粒子系統(tǒng)是封裝好的,用戶只要設(shè)定好粒子的數(shù)量、產(chǎn)生方式、各種速度(風(fēng)速、矢量速度和隨機(jī)速度等)、顏色和重力加速度,就可以使所有的粒子按照要求開始運(yùn)動(dòng)和變化。由于這樣的封裝,Vega的粒子系統(tǒng)使用起來非常方便,尤其是實(shí)現(xiàn)雨和雪模擬的時(shí)候,然而也是由于這樣的封裝,用戶只能知道整體粒子系統(tǒng)是按照什么方式工作的,根本不能得到單獨(dú)一個(gè)粒子的實(shí)時(shí)狀態(tài)和位置,因此使用Vega的粒子系統(tǒng)難以控制粒子模擬閃電。
現(xiàn)在,基于Vega的閃電模擬目前主要采用的是播放紋理技術(shù),所謂播放紋理就是事先把閃電現(xiàn)象做成一系列的連續(xù)圖片,當(dāng)要產(chǎn)生閃電的時(shí)候,系統(tǒng)就高速播放這些連續(xù)的圖片,就像播放閃電動(dòng)畫一樣。然而這個(gè)技術(shù)存在很大的缺點(diǎn):(1)因?yàn)槊看尾シ诺亩际峭瑯拥募y理圖片,所以閃電樣子單一;(2)當(dāng)閃電位置和大小變化的時(shí)候,都要對紋理圖片進(jìn)行縮放、變形,因此存在一定的失真;(3)由于閃電是紋理實(shí)現(xiàn)的,因此它無法實(shí)現(xiàn)因?yàn)殚W電顯現(xiàn)而產(chǎn)生的特效[5~6],比如閃電與地面物體的碰撞、閃電的光照現(xiàn)象、閃電云彩效果等。
圖1 使用播放紋理技術(shù)產(chǎn)生的閃電現(xiàn)象
1994年,T.Reed[3]比較系統(tǒng)地提出了用粒子系統(tǒng)實(shí)現(xiàn)CG閃電模擬。具體方法:在云中放一個(gè)粒子,然后這個(gè)粒子隨機(jī)產(chǎn)生幾個(gè)子粒子,子粒子隨機(jī)地產(chǎn)生向下的角度,向下運(yùn)動(dòng),子粒子又隨機(jī)地產(chǎn)生新粒子……,這樣就產(chǎn)生了整個(gè)閃電整體。在渲染方面,他采用光線跟蹤技術(shù),不過僅僅只渲染了閃電主枝。由于當(dāng)時(shí)技術(shù)的限制,他的閃電模擬做得比較粗糙,只追求模擬閃電的樣子。1999年,楊子華[4]進(jìn)一步總結(jié)闡述了T. Reed的閃電模擬方法。同年,P.Kruszewski[7]在隨機(jī)二叉樹的理論基礎(chǔ)上,提出了一個(gè)可以改變參數(shù)的閃電模型。只要設(shè)定好模型的多個(gè)參數(shù),就可以產(chǎn)生出令人滿意的閃電樣子。由于在渲染上,他還是采用T. Reed模型中的方法,因此他也只考慮閃電主枝的渲染,閃電分支以及周圍物體的渲染沒有考慮進(jìn)去。
2001年,B.Sosorbaram等[6]提出自己的閃電模擬方法,在他之前的閃電模型、閃電形態(tài)的參數(shù)都是從圖片或者錄像中估計(jì)出來的,而B.Sosorbaram強(qiáng)調(diào)使用物理的參數(shù),這樣產(chǎn)生的閃電才更加真實(shí)。而且在他文章中也實(shí)現(xiàn)了閃電對周圍云彩的光照效果。
閃電模擬中,閃電分支越多,渲染就越復(fù)雜,占用的時(shí)間就越多,而降低閃電分支的復(fù)雜度,整個(gè)閃電模擬就會失真,因此,閃電模擬還沒有廣泛應(yīng)用到大型的虛擬現(xiàn)實(shí)仿真系統(tǒng)中。基于此,本文提出一種閃電渲染算法,可以通過簡單的閃電形狀,模擬出效果真實(shí)的閃電。
2 Vega中閃電渲染的新方法
2.1 可行性
圖2是開發(fā)Vega應(yīng)用的層次關(guān)系[8],從底層實(shí)現(xiàn)來看,Vega實(shí)際上是基于場景圖(scene graph)之上的,而場景圖管理系統(tǒng)本身又建立在OpenGL這樣的標(biāo)準(zhǔn)圖形庫之上。在SGI平臺上,Vega所依附的場景圖管理系統(tǒng)就是Performer,而在Windows平臺上,Vega所依附的是一套被稱為“Jolt”的場景圖管理系統(tǒng)(Jolt實(shí)際上就是PC上的Performer實(shí)現(xiàn))。另外,Vega不但提供大量的API函數(shù),還提供回調(diào)函數(shù)(CALLBACK)[8],因此,可以在回調(diào)函數(shù)中實(shí)現(xiàn)OpenGL命令和Vega API函數(shù)的結(jié)合。
圖2 開發(fā)Vega應(yīng)用的層次關(guān)系
Vega應(yīng)用有3個(gè)必需步驟[8]:初始化系統(tǒng)(vgInitSys()),定義系統(tǒng)(vgDefineSys()),配置系統(tǒng)(vgConfigSys()),之后就可以進(jìn)入Vega應(yīng)用的主循環(huán)來渲染幀和幀同步(vgSync Frame()和vgFrame())。本文在配置系統(tǒng)之后使用vgAddFunc (vgGetChan(0), VGCHAN_POSTDRAW, Lightning, NULL ),定義一個(gè)名為Lightning的VGCHAN_PREDRAW回調(diào)函數(shù),它的參數(shù)為空。VGCHAN_PREDRAW回調(diào)函數(shù)是在創(chuàng)建通道之后、開始畫圖之前調(diào)用。 #p#page_title#e#
2.2 閃電結(jié)構(gòu)生成
為了提高模擬的真實(shí)度,采用以下方法進(jìn)行優(yōu)化:(1)采用優(yōu)化過的隨機(jī)函數(shù)來控制閃電段的角度和長度。(2)對所有閃電段都增加了參數(shù)來表示它的能量,同一層次的分支中,能量隨著閃電段延續(xù)而減小,不同級別的分支,其初始能量也是不一樣的,這樣最終閃電效果不像傳統(tǒng)方法中閃電粗細(xì)始終不變。(3)整個(gè)閃電段都共面,這個(gè)面是一個(gè)垂直地面的Billboard,其法向量平行于視線。
2.2.1 數(shù)據(jù)結(jié)構(gòu)
struct segment //閃電段的結(jié)構(gòu)
{
Vector3 start; //段的上節(jié)點(diǎn)坐標(biāo)
float power_start; //上節(jié)點(diǎn)處能量
Vector3 end; //段的上節(jié)點(diǎn)坐標(biāo)
float power_end; //下節(jié)點(diǎn)處能量
}; //閃電分支結(jié)構(gòu)
{
Vector3 start; //分支最頂節(jié)點(diǎn)坐標(biāo)
float power; //分支初始能量
float angle; //分支的初始角度
};
2.2.2 算法描述
Step1 取云間一點(diǎn)作為整個(gè)閃電的起始點(diǎn),生成branch對象,隨機(jī)生成它的power和angle,并將這個(gè)branch壓入分支棧。
Step2 判斷分支棧是否為空,如果為空,表示整個(gè)閃電結(jié)構(gòu)已經(jīng)生成,則轉(zhuǎn)Step7;否則,從分支棧中彈出一個(gè)分支,以它的坐標(biāo)和能量作為新生成segment對象上節(jié)點(diǎn)的坐標(biāo)和能量。
Step3 隨機(jī)決定是否在segment對象上節(jié)點(diǎn)處是否產(chǎn)生新的閃電分支,如果產(chǎn)生,則上節(jié)點(diǎn)的坐標(biāo)作為新branch對象的start,而power和angle都采用優(yōu)化隨機(jī)函數(shù)產(chǎn)生(注:power小于上節(jié)點(diǎn)能量),并將此新的branch對象壓入分支棧。
Step4 根據(jù)segment對象的上節(jié)點(diǎn)和能量以及整個(gè)分支的angle,采用隨機(jī)函數(shù)生成其下節(jié)點(diǎn)的坐標(biāo)和能量。因?yàn)樵谕环种е心芰窟f減,所以要控制隨機(jī)函數(shù),使得下節(jié)點(diǎn)的能量小于上節(jié)點(diǎn)能量而且還不能引起能量巨變。
Step5 保存上面生成segment對象,并將其下節(jié)點(diǎn)坐標(biāo)和能量作為新的segment對象的上節(jié)點(diǎn)坐標(biāo)和能量。
Step6 對新segment對象上節(jié)點(diǎn)的坐標(biāo)和能量進(jìn)行判斷,如果它已經(jīng)到達(dá)地面或者它的能量已經(jīng)太小(可忽略),則轉(zhuǎn)Setp2;否則Step3。
Step7 生成過程結(jié)束。
生成的segment對象集合就構(gòu)成了整個(gè)閃電結(jié)構(gòu)。
2.3 紋理生成
2.3.1 紋理結(jié)構(gòu)生成
采用2.2.2節(jié)的生成算法在紋理圖片上生成一個(gè)小型的閃電,這個(gè)閃電結(jié)構(gòu)簡單,分支少。然后根據(jù)分支的層次,以每個(gè)segment的上、下節(jié)點(diǎn)連線為中心向兩邊擴(kuò)展,生成segment面。閃電主枝為最高層,因此它的面最寬,從上層分支上生成的分支為下一層,寬度比上一層遞減,如圖3。
圖3 閃電紋理的結(jié)構(gòu)層次
2.3.2 紋理著色
通常閃電段周圍會有一些別的顏色,顏色是閃電與空氣中化學(xué)物質(zhì)發(fā)生作用以及物理作用產(chǎn)生的,稱為閃電的燃燒顏色,一般其為粉紅色或者淡藍(lán)色。首先將2.2.1節(jié)生成的segment面著色為白色用來表示閃電本身的顏色;然后每個(gè)閃電段的燃燒顏色由式(1)計(jì)算: 2exp(())iiidGgWλλ=− (1)
其中,iGλ為段i在光線λ下的燃燒顏色;gλ為光線λ的最大值;為段i周圍燃燒區(qū)域?qū)挾鹊囊话耄阉O(shè)置為段i的長度;為距離段i的距離。由于當(dāng)>2.2倍的時(shí),ididiW2exp(())iidW−的值已經(jīng)小于1%,因此在計(jì)算的時(shí)候只需要計(jì)算閃電段兩側(cè)2.2倍距離以內(nèi)的點(diǎn),這樣就大大減小計(jì)算的復(fù)雜度。
圖4是采用光線λ為淡藍(lán)色時(shí)候渲染出來的紋理圖片,其中,黑色部位為透明。
圖4 渲染紋理
2.4 實(shí)現(xiàn)
在2.2.2節(jié)算法生成的閃電結(jié)構(gòu)中,閃電被分解成閃電段,根據(jù)segment結(jié)構(gòu),以上、下節(jié)點(diǎn)連線為中心向兩邊擴(kuò)展形成segment面,擴(kuò)張寬度大小由上、下節(jié)點(diǎn)的能量power控制,這樣就體現(xiàn)了分支層次結(jié)構(gòu)以及閃電能量的遞減。在每個(gè)擴(kuò)展的segment面上都映射[9]2.3節(jié)生成的紋理,這樣就完成了閃電本身的渲染。
對閃電周圍環(huán)境的渲染,包括閃電對場景和云層的照亮效果,通過Dobashi[5]提出的在主要的閃電分支上增加數(shù)個(gè)點(diǎn)光源實(shí)現(xiàn)。
2.5 實(shí)驗(yàn)結(jié)果 #p#page_title#e#
與Vega中的播放紋理技術(shù)相比,本文提出的方法靈活,閃電的形狀變化豐富,而且實(shí)現(xiàn)閃電本身渲染、閃電對周圍環(huán)境的光照特效。
與其他的閃電渲染算法相比,此方法最大的特點(diǎn)就是簡單,如果傳統(tǒng)方法產(chǎn)生的閃電有10 000個(gè)閃電段,那么就必須計(jì)算10 000個(gè)閃電段,渲染10 000個(gè)閃電段,而如果采用此方法,制作的閃電紋理里面包含20個(gè)閃電段,整體閃電的閃電分支就只需要500個(gè),那么程序就只需要計(jì)算520個(gè)閃電段,渲染20個(gè)閃電段就可以達(dá)到同樣逼真的效果。
圖5是近距離的效果,閃電主枝上的小分支非常多,采用紋理映射技術(shù),只需要不到8個(gè)閃電就實(shí)現(xiàn)了。圖6是遠(yuǎn)距離的效果,閃電形狀更加真實(shí),而且閃電對周圍環(huán)境的光照特效也非常明顯。
圖5 近距離效果
圖6 遠(yuǎn)距離效果
2.6 使用新方法需要注意的問題
Vega并不是所有的回調(diào)函數(shù)都可以使用OpenGL指令繪圖,準(zhǔn)確地說只有在屬于Draw繪制進(jìn)程[8]的回調(diào)函數(shù)中才可以調(diào)用OpenGL指令繪圖。
由于在繪圖通道中狀態(tài)改變耗費(fèi)嚴(yán)重,為了高性能運(yùn)行,Vega和OpenGL都采用惰性狀態(tài)評價(jià)。因此,在程序中使用OpenGL命令改變狀態(tài)之前,一定要保存以前的狀態(tài),命令運(yùn)行結(jié)束之后,也要及時(shí)恢復(fù)這些狀態(tài)。
3 結(jié)束語
本文提出了一種新的閃電渲染方法,該方法與傳統(tǒng)方法相比,實(shí)現(xiàn)簡單,模擬效果真實(shí),運(yùn)算量小,尤其是在閃電本身渲染方面,適合實(shí)時(shí)性要求高的仿真系統(tǒng);同時(shí),結(jié)合Vega的特點(diǎn),成功地將此方法應(yīng)用到Vega環(huán)境中,解決了基于Vega的視景仿真中無法實(shí)現(xiàn)隨機(jī)閃電渲染的難題,該方法產(chǎn)生的閃電模擬應(yīng)用到民用飛機(jī)模擬器視景仿真中,取得了良好的仿真演示效果,此外其對于Vega中復(fù)雜模型的建立也有重要意義。