譚德林, 譚 良,2
(1.四川師范大學(xué)計(jì)算機(jī)科學(xué)學(xué)院四川省可視化計(jì)算和虛擬現(xiàn)實(shí)重點(diǎn)實(shí)驗(yàn)室,四川成都610101;2.中國科學(xué)院計(jì)算技術(shù)研究所,北京100080)
地形繪制在游戲虛擬場景、地理信息系統(tǒng)、飛行仿真系統(tǒng)、城市規(guī)劃、駕駛模擬以及虛擬戰(zhàn)場等虛擬環(huán)境中應(yīng)用廣泛。因此目前國內(nèi)外關(guān)于地形繪制算法的研究相當(dāng)廣泛。基于LOD的思想,Duchaineau于1996年提出了ROAM地形繪制算法;Lindstrom于1997年提出了動(dòng)態(tài)LOD地形繪制算法;De-Boer于2000年提出了GeoMipMapping地形繪制算法。以上3種算法是地形繪制算法的基礎(chǔ)算法,以后的很多地形繪制算法都是由以上幾種算法發(fā)展而來的。如北京大學(xué)的王宏武于2000年提出的基于四叉樹的多分辨率地形繪制算法;Levenberg于2002年提出的CABBT算法;浙江大學(xué)的陸燕青于2003年提出的基于層次二叉樹的多分辨率頂點(diǎn)繪制算法;J.Bittner于2004年提出的GPU遮擋剔除算法等等。對(duì)地形繪制算法的研究,可以人為的把其分為兩個(gè)階段,即以CPU為核心的地形繪制算法和以GPU為核心的地形繪制算法。在早期,由于受限于以CPU為核心的圖形處理流水線,該時(shí)期的地形繪制算法都是依賴于CPU的地形繪制算法,如ROAM算法、動(dòng)態(tài) LOD算法和以它們?yōu)榛A(chǔ)而改進(jìn)的地形繪制算法等都屬于以CPU為核心的地形繪制算法;隨著計(jì)算機(jī)圖形適配器的發(fā)展,GPU運(yùn)算能力被提出并得到廣泛應(yīng)用,以CPU為核心的地形繪制算法已經(jīng)不符合當(dāng)代圖形適配器的圖形處理框架,因此基于GPU的地形繪制算法也相應(yīng)的被提出,如GeoMipMapping算法或者以GeoMipMapping算法為基礎(chǔ)進(jìn)行改進(jìn)后所得到的地形繪制算法。國內(nèi)對(duì)基于GPU的地形繪制算法研究較多,如基于索引模板的Patch-LOD地形繪制算法[1]、基于受限法向錐的誤差計(jì)算方法[2]、基于GPU加速的分形地形生成算法[3]、基于地平線遮擋裁剪的層次化可見性計(jì)算方法[4]、基于現(xiàn)代GPU的大地形可視化算法[5]、基于頂點(diǎn)紋理的LOD地形渲染算法[6]等。隨著以GPU為核心的地形繪制算法的出現(xiàn),使地形的繪制不再完全依賴于CPU?;贕PU為核心的地形繪制算法是把地形繪制過程中的地形繪制這部分工作交由GPU來完成。這使得以GPU為核心的地形繪制算法不但能充分的利用當(dāng)代圖形適配器的圖形處理功能,同時(shí)也把CPU從繁瑣的地形繪制算法中解放出來,讓其不用過多的參與地形的繪制。通過進(jìn)一步解放CPU,使得CPU可以直接去參與系統(tǒng)中其它工作的處理。以 GPU為核心的地形繪制算法是當(dāng)前圖形適配器下地形繪制算法的主流。
通過對(duì)以上各種地形繪制算法的分析可以發(fā)現(xiàn),目前的以GPU為核心的地形繪制算法大多都是以Geomipmapping算法為基礎(chǔ),或者對(duì)其進(jìn)行改進(jìn)而得到的。而根據(jù)Geomipmapping算法的原理可知,在地形繪制的過程中,需要有紋理加載的過程。通過分析可得,傳統(tǒng)的以GPU為核心的地形繪制算法的紋理加載方法的工作流程[7]如圖1所示。
圖1 傳統(tǒng)的紋理加載原理
由圖1可以看出,傳統(tǒng)的紋理加載方法的基本原理為:首先將紋理源的紋理數(shù)據(jù)加載到系統(tǒng)內(nèi)存中,然后再將數(shù)據(jù)從系統(tǒng)內(nèi)存拷貝到紋理對(duì)象,其整個(gè)過程都需要由CPU來對(duì)其進(jìn)行控制。由此可見,傳統(tǒng)的地形繪制算法中的紋理加載方法顯然不符合當(dāng)前以GPU為核心的地形繪制算法的“進(jìn)一步把CPU中地形繪制的過程中解放出來以使其能更多的參與到其它工作的處理中去”的思想。因此傳統(tǒng)的紋理加載方法成為了當(dāng)前圖形適配器下各種以GPU為核心的地形繪制算法的瑕疵。為了解決這個(gè)問題,在地形繪制算法中引入了PBO[8]。PBO(pixel buffer object)即像素緩存對(duì)象,該對(duì)象屬于GPU的緩存的一部分。因?yàn)镻BO采用了DMA技術(shù),它在紋理數(shù)據(jù)從PBO復(fù)制到紋理對(duì)象的過程中無需CPU而是由GPU來控制。因此在紋理加載時(shí)應(yīng)用 PBO,可以進(jìn)一步的解放CPU;同時(shí)由于PBO的DMA技術(shù)采用異步方式,因此可以通過使用雙PBO機(jī)制來加載紋理。雙PBO的引入,使得紋理數(shù)據(jù)的加載可以用異步并行的方式完成,這進(jìn)一步加快了紋理數(shù)據(jù)的加載速度。
由圖1可知,傳統(tǒng)的紋理加載方法需要CPU來全程控制,這顯然與當(dāng)前以GPU為核心的地形繪制算法的解放CPU的思想不相符。因此,這里在紋理加載的過程中引入了PBO?;赑BO的紋理加載方法的工作原理流程圖如圖2所示。
從圖2可以看出,引入PBO后,紋理源的像素?cái)?shù)據(jù)直接被傳到PBO中,這個(gè)過程仍需由CPU來進(jìn)行控制;而當(dāng)紋理數(shù)據(jù)從PBO復(fù)制到紋理對(duì)象的過程中,則是采用PBO的DMA技術(shù)來完成的,這個(gè)過程則由GPU來對(duì)其進(jìn)行控制。由于在這個(gè)過程中不需要CPU對(duì)其進(jìn)行控制,因此這時(shí)CPU就可以直接去完成其它的任務(wù)而不需要等待像素?cái)?shù)據(jù)傳遞的結(jié)束。
圖2 基于PBO的紋理加載原理
由于DMA技術(shù)是采用異步方式來完成的,也就是說,在完成紋理源到PBO的數(shù)據(jù)傳輸后,可以不需要立刻把PBO中的數(shù)據(jù)復(fù)制到紋理對(duì)象?;谶@個(gè)原理采用了雙PBO機(jī)制,其工作原理為當(dāng)某一個(gè)PBO正在和紋理對(duì)象進(jìn)行關(guān)聯(lián)操作時(shí),另外一個(gè)PBO則和像素源進(jìn)行新的數(shù)據(jù)傳輸。通過采用雙PBO機(jī)制,使得像素?cái)?shù)據(jù)傳輸?shù)絇BO的操作和從PBO中復(fù)制數(shù)據(jù)到紋理對(duì)象并行工作,雙PBO機(jī)制的工作原理如圖3所示。
圖3 雙PBO工作原理
由圖3可知,當(dāng)?shù)匦卫L制到第n幀時(shí),紋理源在CPU的控制下把像素?cái)?shù)據(jù)寫入PBO1的同時(shí),PBO2將其中的像素?cái)?shù)據(jù)復(fù)制到紋理對(duì)象。在 n+1幀時(shí)則 PBO1和 PBO2的工作過程剛好相反。通過使用雙PBO,可以使紋理數(shù)據(jù)的加載并行處理,這進(jìn)一步提高了紋理加載的速度。
基于PBO的地形繪制算法是在Geomipmapping地形繪制算法的基礎(chǔ)上引入PBO而得到的。Geomipmapping地形繪制算法也叫幾何誤差算法,它是最早的以GPU為核心的地形繪制算法。以后的很多 GPU友好的地形繪制算法都是在它的基礎(chǔ)上,并對(duì)其進(jìn)行改善優(yōu)化后形成的。Geomipmapping地形繪制算法的基本思想是對(duì)整個(gè)地形進(jìn)行分塊,每一個(gè)塊的大小為2n+1。根據(jù)每塊離視點(diǎn)的距離,可以把它標(biāo)識(shí)為可見和不可見。如該地形分塊不可見,則直接被裁剪體裁剪掉;如地形塊可見,則根據(jù)其離視點(diǎn)的距離,又可分為很多細(xì)節(jié)層次等級(jí),每個(gè)細(xì)節(jié)層次等級(jí)對(duì)應(yīng)不同的紋理圖像。等級(jí)越低,離視點(diǎn)越近,其紋理圖像的分辨率也越高;反之等級(jí)越高,離視點(diǎn)越遠(yuǎn),其紋理圖像的分辨率也越低。在分塊的層次等級(jí)中,0級(jí)為分塊的層次等級(jí)中最低的,其分辨率卻是最大的,隨著等級(jí)的增大,分別率則變小。
基于PBO的地形繪制算法也就是在加載紋理數(shù)據(jù)時(shí),借助PBO,讓紋理源數(shù)據(jù)直接進(jìn)入PBO,然后再通過PBO把紋理數(shù)據(jù)復(fù)制到紋理對(duì)象。為此,需要先生成PBO對(duì)象,接著把PBO和紋理對(duì)象進(jìn)行綁定。這樣就可以讓紋理源數(shù)據(jù)直接傳遞到PBO中,然后再將PBO中的數(shù)據(jù)復(fù)制到紋理對(duì)象。為了完成以上功能,需要借助opengl擴(kuò)展庫中的擴(kuò)展函數(shù)來完成。根據(jù)不同的參數(shù),可以對(duì)PBO進(jìn)行讀和寫。如當(dāng)參數(shù)為GL_STREAM_DRAW_ARB時(shí),表示將像素從紋理源加載到PBO中,而參數(shù)為GL_STREAM_READ_ARB時(shí),表明從PBO中把像素?cái)?shù)據(jù)進(jìn)行異步讀出。
同時(shí)為了使雙PBO能協(xié)調(diào)工作,需要對(duì)這兩個(gè)PBO進(jìn)行有效控制,這里將通過使用兩個(gè)變量來分別標(biāo)識(shí)這兩個(gè)PBO。在某一幀時(shí),第一個(gè)PBO接受像素?cái)?shù)據(jù)的讀入,另一個(gè)PBO則把其中的像素?cái)?shù)據(jù)拷貝到紋理對(duì)象;而在下一幀,這兩個(gè)PBO的功能則剛好進(jìn)行交換。
圖4為基于PBO的地形繪制算法的體系結(jié)構(gòu)?;赑BO的地形繪制算法的體系結(jié)構(gòu)中,存在著兩條流水線,分別為集合流水線和像素流水線,這兩條流水線將于光柵化器處匯合在一起。在該體系結(jié)構(gòu)中,高程圖生成器用來產(chǎn)生虛擬環(huán)境中地形的高度圖,通過高度圖,就可以唯一確定世界坐標(biāo)系中某一點(diǎn)的高度;幾何處理器是用來對(duì)頂點(diǎn)進(jìn)行幾何變換如平移、旋轉(zhuǎn)、縮放等;像素流水線則對(duì)像素進(jìn)行相應(yīng)的操作;顯示列表[9]是用來把圖元信息或者其它的信息作為對(duì)象保存到服務(wù)器中,這就避免了代價(jià)較高的傳輸和重新生成的問題;光柵化器用來負(fù)責(zé)生成片段或者說那些可能位于幾何對(duì)象中的像素;幀緩存[10]位于OpenGL流水線上最后顯示階段像素所在處,幀緩存可以視為二維數(shù)組,或opengl使用的存儲(chǔ)區(qū)域,它包括了顏色緩存、深度緩存、模板緩存和累積緩存。如圖所示,通過PBO映射,還可以將opengl控制的緩存對(duì)象與客戶端地址空間進(jìn)行內(nèi)存映射。這樣客戶端可通過函數(shù)glMapBufferARB()和glUnmapbufferARB()來修改緩存對(duì)象的數(shù)據(jù)。
在實(shí)現(xiàn)基于PBO的地形繪制算法的過程中,可以分為指定PBO擴(kuò)展的函數(shù)指針、創(chuàng)建PBO對(duì)象、傳輸像素?cái)?shù)據(jù)等步驟,如下為其部分代碼實(shí)現(xiàn):
(1)生成雙PBO:
圖4 基于PBO的地形繪制體系結(jié)構(gòu)
(2)把數(shù)據(jù)從PBO復(fù)制到紋理對(duì)象:
(3)紋理映射:
(4)解除綁定:
如上代碼的主要實(shí)現(xiàn)了生成兩個(gè)PBO,把PBO綁定到紋理對(duì)象以及讓客戶端地址空間的內(nèi)存與PBO進(jìn)行映射已經(jīng)傳輸完數(shù)據(jù)后把PBO和紋理對(duì)象解除綁定。
基于PBO的地形繪制算法實(shí)現(xiàn)的硬件環(huán)境為:CPU Pentium?Dual-core CPU,內(nèi)存為 2GB,顯卡為 nvidia geforce g210M。軟件環(huán)境為:Windows7Proffessional32位操作系統(tǒng)下,使用VC++6.0和OpenGL 2.0完成的。在如上開發(fā)環(huán)境下,渲染了一個(gè)高度圖大小1025*1025,窗口大小為1024*768的地形。如圖5所示為渲染結(jié)果圖。
圖5 基于PBO的地形
表1所示為渲染不同大小的地形、是否使用PBO以及不同頂點(diǎn)數(shù)目時(shí)的CPU利用率。
由表1可以看出,使用PBO時(shí)CPU利用率比不使用PBO時(shí)的CPU利用率要低很多。通過使用PBO,使得在紋理載入時(shí),由PBO復(fù)制紋理數(shù)據(jù)到紋理對(duì)象的過程中不需要CPU的控制,以便進(jìn)一步解放出CPU,使其可以直接去進(jìn)行其它的工作。
表1 CPU使用率比較
針對(duì)當(dāng)前以 GPU為核心的地形繪制算法以及當(dāng)前解放CPU和充分的利用GPU的思想,這里以Geomipmapping算法的基礎(chǔ)引入了PBO,提出了基于PBO的地形繪制算法。通過使用PBO,減少了CPU對(duì)地形繪制的控制,進(jìn)一步解放了CPU和使用GPU。同時(shí),由于PBO的DMA技術(shù)采用異步方式,所以可以通過雙PBO對(duì)象來使得從紋理源傳遞像素到PBO和從PBO復(fù)制紋理數(shù)據(jù)到紋理對(duì)象并行進(jìn)行,這也進(jìn)一步提高了像素傳遞的速度。由實(shí)驗(yàn)結(jié)果可知,基于PBO的地形繪制算法完全符合當(dāng)前解放CPU并充分利用GPU的地形繪制算法的思想。
[1]皮學(xué)賢,楊旭東,李思昆,等.基于索引模板的Patch-LOD地形繪制算法[J].計(jì)算機(jī)研究與發(fā)展,2005,4(增刊):183-187.
[2]李勝.超大規(guī)模地形場景的高性能漫游[J].軟件學(xué)報(bào),2006,17(3):535-545.
[3]馬淑芳.基于GPU加速的分形地形生成方法[D].大連:大連理工大學(xué),2008.
[4]何旭鋒.大規(guī)模復(fù)雜場景的加速繪制方法研究與實(shí)現(xiàn)[D].成都:電子科技大學(xué),2009.
[5]潘宏偉,李輝,廖昌閣,等.一種基于現(xiàn)代GPU的大地形可視化算法[J].系統(tǒng)仿真學(xué)報(bào),2007,19(7):3241-3244.
[6]張桀寧,李帥.一種基于頂點(diǎn)紋理的LOD地形渲染算法[J].系統(tǒng)仿真學(xué)報(bào),2008,20(4):1758-1764.
[7]紋理加載方法[EB/OL].http://blog.sina.com.cn/s/blog_4062094 e0100alvt.html,2008.
[8]PBO介紹[EB/OL].http://www.songho.ca/opengl/gl_pbo.html,2007.
[9]段菲.openGL編程基礎(chǔ)[M].3版.北京:清華大學(xué)出版社,2008:66-69.
[10]幀緩存[EB/OL].http://blog.sina.com.cn/s/blog_4062094e0100 alvv.html,2008.