宋云鵬, 劉 芳, 劉 娜, 康一梅
(1.北京航空航天大學(xué)軟件學(xué)院,北京100191;2.中國科學(xué)院軟件研究所計算機(jī)科學(xué)國家重點(diǎn)實(shí)驗(yàn)室,北京100190;3.中國科學(xué)院研究生院北京100049)
屏幕空間環(huán)境光遮擋技術(shù)是在傳統(tǒng)的環(huán)境光遮擋技術(shù)基礎(chǔ)上發(fā)展起來的一種近似的全局光照計算方法。它利用屏幕空間中的深度信息,重建場景中每個點(diǎn)及其周圍幾何體的空間相對位置關(guān)系,以此計算當(dāng)前點(diǎn)被周圍幾何體遮擋的情況,即當(dāng)前點(diǎn)的環(huán)境光遮擋值。相對于傳統(tǒng)環(huán)境光遮擋方法使用光線跟蹤的計算方法,這種方法更加高效。隨著可編程圖形處理器的發(fā)展,出現(xiàn)了一些使用GPU加速的屏幕空間環(huán)境光遮擋計算方法,Bavoil等[2]提出了一種完全在GPU上計算的基于水平線的屏幕空間環(huán)境光遮擋算法,該方法利用水平角逼近的方式估計周圍幾何體的形狀,并由此計算環(huán)境光遮擋值,對以往的方法做了很大的改進(jìn)。
本文首先介紹了環(huán)境光遮擋算法以及深度剝離技術(shù)的發(fā)展情況,其中詳細(xì)介紹了使用GPU加速的屏幕空間環(huán)境光遮擋算法以及桶型深度剝離算法。然后本文在BAVOIL等[2]的算法基礎(chǔ)上提出了一種使用多層深度采樣的屏幕空間環(huán)境光遮擋算法,對傳統(tǒng)的屏幕空間環(huán)境光遮擋算法進(jìn)行了一定的改進(jìn)。之后,本文對實(shí)驗(yàn)結(jié)果進(jìn)行了分析與總結(jié)。
本文中解決的問題是Bavoil等[2]算法中由于深度信息不足造成的不可見點(diǎn)的遮擋貢獻(xiàn)丟失的問題。下面介紹一些與本文工作相關(guān)的環(huán)境光遮擋算法。
Pharr等[7]最先利用GPU加速計算環(huán)境遮擋的算法,其基本原理是采用陰影圖來確定從當(dāng)前繪制點(diǎn)某個方向上發(fā)出的光線是否被場景中的其它物體遮擋。該算法需要繪制場景多遍,但仍比基于光線跟蹤的環(huán)境遮擋算法有了較大的加速。Kontkanen等[8]提出環(huán)境遮擋域算法,通過對場景中的物體建立包圍盒來加速光線與場景的求交過程。Bunnell等[9]使用圓盤來表示場景中的物體,通過計算圓盤間的相互遮擋值來近似場景中物體的遮擋情況。這類算法由于需要對場景預(yù)計算,所以難以高效地繪制動態(tài)變形的場景。REN等[10]采用球形遮擋物體和球面調(diào)和函數(shù)來計算近似環(huán)境遮擋值。由于其預(yù)計算量較小,可以較好地支持可變形物體,但是對于包含較多數(shù)量物體的場景,其性能下降。
Shanmugam等[1]采用GPU計算環(huán)境遮擋值,其核心思想是采用當(dāng)前繪制點(diǎn)在屏幕空間上的投影像素點(diǎn)的鄰域信息來計算該點(diǎn)的遮擋值。其優(yōu)點(diǎn)是計算過程與場景的幾何復(fù)雜度無關(guān)且無需預(yù)計算,但其不足之處在于在采樣過程中將物體表面采樣區(qū)域近似為球體,導(dǎo)致對遮擋面積的過度估計,使得繪制結(jié)果通常比真實(shí)結(jié)果更暗。
Bavoil等[2]提出了一種新的基于水平線的屏幕空間環(huán)境遮擋計算方法。該方法解決了Shanmugam等[1]方法中的遮擋估計不足的問題,且不需要任何與場景相關(guān)的預(yù)計算,因而可以實(shí)時的模擬場景的中的間接光照。但是與Shanmugam等[1]的方法類似,該方法的采樣過程全部在可見點(diǎn)上進(jìn)行,對于處于復(fù)雜幾何體遮擋下的不可見點(diǎn)的遮擋值沒有進(jìn)行計算,因此會造成遮擋不足的問題。對于深度復(fù)雜度較高的場景,產(chǎn)生的繪制錯誤尤為明顯。進(jìn)而導(dǎo)致最終渲染生成的圖像真實(shí)感不足。
傳統(tǒng)的深度剝離算法一次繪制只能收集一個層次的深度信息,盡管這種方法可以獲得精確的層次深度信息,但是當(dāng)需要多層深度信息時,就需要進(jìn)行多次的繪制,效率十分低下。Bavoil提出的K-Buffer[6]算法使用GPU上提供的多重渲染目標(biāo)緩存(MRT)保存多個片元的信息,對每一個片源根據(jù)深度進(jìn)行插入排序,可以在一個場景繪制過程中為每個像素至多收集K個片元。但由于在GPU上無法保證正確的讀寫順序,當(dāng)多個片元對應(yīng)同一個存儲位置時就會出現(xiàn)錯誤。之后Bavoil[11]利用NVIDIAGeforce8開始支持的輸出紋理的最大、最小混合方式,實(shí)現(xiàn)了一個最大(最小)深度緩存,可以在一遍場景繪制過程中同時輸出最近和最遠(yuǎn)的深度信息。
LIU[3]提出了一種在一遍繪制過程中收集多層深度信息的算法。首先使用Bavoil[11]的方法輸出當(dāng)前場景中每個像素的最近和最遠(yuǎn)深度,然后根據(jù)當(dāng)前像素的深度范圍劃分為若干個深度段,每個段中的深度信息由不同的輸出紋理來保存。通過將場景繪制一遍,在片元著色器中將位于不同深度段的片元深度信息保存在不同的紋理中,從而達(dá)到了在一遍繪制中收集多層深度信息的目的。盡管該方法不能獲得每一層的精確深度,但是卻可以為一些效果計算提供足夠的深度信息。
本文假設(shè)場景中的物體之間沒有相交的情況,并約定法向量朝向視點(diǎn)方向?yàn)橄蚯胺较?,反之則是向后方向。片元的深度則是指在視點(diǎn)坐標(biāo)系中片元到視平面的距離。
本文算法的流程是:第一遍從視點(diǎn)繪制場景,將每個像素上的最大深度和最小深度保存下來,這樣就得到了每個像素上的深度變化范圍。第二遍仍然從視點(diǎn)繪制場景,利用在第一遍繪制的場景深度圖,根據(jù)每個像素的深度變化范圍,使用桶型深度剝離算法將每個像素的多個深度輸出到多個 MRT中。第三遍根據(jù)前兩遍獲得的深度信息,計算整個場景的環(huán)境光遮擋。
LIU[3]的方法首先需要將場景中每一個像素的最大與最小深度保存到一張紋理中。這樣就可以獲得場景中每個像素對應(yīng)的深度范圍。然后再從視點(diǎn)方向繪制場景,在繪制的過程中,根據(jù)每個像素的深度范圍,將深度等分為n(n=1,2,3…)個深度段,并用不同的輸出紋理保存不同深度段中的值。在繪制片元的過程中,根據(jù)每個片元的深度,計算該片元對應(yīng)的深度段,將片元的深度保存在對應(yīng)的紋理中。在保存的過程中,可以根據(jù)不同的需要設(shè)置輸出紋理的混合方式,如最大值混合或者最小值混合,相應(yīng)地可以得到每個深度段中的最大或者最小深度值。
在本文的第一遍繪制過程中,首先關(guān)閉場景的深度檢測,開啟最大紋理混合,在片元程序中將當(dāng)前片元的深度取負(fù)存儲在輸出紋理的第一個通道,將原深度值存儲在第二個通道。這樣,在繪制結(jié)束后就可以得到一張存儲了當(dāng)前場景每一個像素的最小和最大深度值的紋理。
第二遍仍然從視點(diǎn)繪制場景,關(guān)閉深度檢測,開啟最小紋理混合。在片元處理程序中,根據(jù)第一遍繪制紋理對應(yīng)像素上的深度范圍和使用的輸出紋理數(shù)量,將深度分割為N段(N為使用MRT數(shù)目的兩倍)。這里需要注意,為了減少場景繪制次數(shù),將每個多重渲染目標(biāo)(MRT)的4個顏色通道分配給兩個“桶”,即每個桶占用兩個顏色通道。其中一個通道存儲法向量方向向前的片元的深度,另一個通道則用于存儲法向量向后的片元深度。這樣每個桶就同時存儲了這一深度段內(nèi)的法向量向前的片元深度,以及法向量向后的片元深度。之后,需要計算當(dāng)前片元法向量與視點(diǎn)向量的點(diǎn)積,如果為正則該片元方向向前,存儲于桶的第一個通道中,反之則存儲于對應(yīng)桶的第二個通道中。
當(dāng)兩次場景繪制完成后,就可以得到一組存儲有該場景不同深度段深度信息的紋理,這些紋理的每個通道中都存儲著一個紋理值。這些紋理值根據(jù)它們存儲的通道位置的不同(r通道存正向片元深度,g通道存儲反向片元深度,b通道存儲正向片元深度,a通道存儲反向片元深度)存儲不同朝向的片元深度。
首先回顧Bavoil等[2]提出的基于水平線的環(huán)境光遮擋算法,該算法的核心是通過在屏幕空間內(nèi)進(jìn)行采樣,確定當(dāng)前被遮擋片元周圍最大的遮擋體的體積,從而計算當(dāng)前片元被周圍幾何物體遮擋的程度。
對于場景中的每個片元P,其環(huán)境光遮擋值可以采用以下公式近似計算
式(1)中所有采樣點(diǎn)的坐標(biāo)采用球面坐標(biāo)系。如圖1所示,其中 (∈[0,2])為采樣點(diǎn)方位角,h()為沿該方向與P點(diǎn)構(gòu)成的最大水平仰角,t()為水平線與法向平面的夾角。W()函數(shù)為用戶定義的線性衰減函數(shù)。在具體的公式中,定義W()=max(0,1-r()/R),其中r()為P點(diǎn)與 方向上最大水平仰角對應(yīng)點(diǎn)的距離,R是對P點(diǎn)有遮擋影響的最大半徑,該函數(shù)用于消除處于最大半徑R之外的點(diǎn)對P的影響。
圖1 BAVOIL [2]算法原理
當(dāng)P點(diǎn)周圍存在多個層次的幾何物體時,由于算法只關(guān)心P點(diǎn)周圍最大的水平仰h()max,就會造成P點(diǎn)遮擋值計算錯誤,如圖2所示。因此就需要使用桶型深度剝離的方法提取足夠的深度信息,以消除由于深度信息不足造成的遮擋錯誤。
圖2 在出現(xiàn)多層物體時遮擋錯誤
使用桶型深度剝離算法調(diào)整后的算法原理如圖3所示。在每個片元方向向前的深度層次上尋找該層次內(nèi)的最大水平仰角,反之則尋找最小的水平仰角。最后將各個層次的環(huán)境光遮擋值按照片元的朝向進(jìn)行求和操作。在具體的實(shí)現(xiàn)過程中需要從之前完成的深度紋理中讀取深度信息,由于硬件速度的限制,因此不能夠無限制的讀取紋理數(shù)據(jù),只能采用有限采樣的方法。在片元處理程序中,當(dāng)前片元P的環(huán)境光遮擋計算公式如下所示
式中:h()=max(t(),h()[i],…)(i=0,2,4…),即 h()——在第 i層深度沿 方向的最大水平仰角。反之,當(dāng)i為奇數(shù)時,h()=min(t(),h()[i],…)(i=1,3,5…),即 h()為在第 i層深度沿 方向的最小水平仰角。這樣就可以有效的消除多層幾何體重疊造成的反方向片元的遮擋影響。
圖3 使用多層深度信息修正后的算法
下面介紹本文算法在最后一遍繪制中的環(huán)境光遮擋計算過程:首先在當(dāng)前繪制片元周圍的一定范圍內(nèi)進(jìn)行采樣點(diǎn)采樣,沿采樣方向 進(jìn)行采樣。根據(jù)采樣點(diǎn)屏幕空間坐標(biāo)(u,v)讀取在第二遍輸出紋理中保存在該像素點(diǎn)上的n個深度段中的深度值,并將其存入一個float型的數(shù)組Depth[n]中,并且將第一個桶的第一通道數(shù)據(jù)存儲在下標(biāo)為0的元素中,第一個桶的第二個元素存儲在下標(biāo)為1的元素中,以此類推。然后按照下標(biāo)遞增的順序遍歷這個數(shù)組,在遍歷數(shù)組的過程中尋找各個層次的最大水平仰角h()并計算各層深度對P點(diǎn)的環(huán)境光遮擋值。
具體計算過程如下:每次在進(jìn)行深度遍歷和計算h()時,需要根據(jù)片元的朝向?qū)ふ以搶由疃鹊淖畲骽()或最小h()。因此,設(shè)置一個float類型的數(shù)組h[n],用于保存在 方向上各深度層對應(yīng)的h()。在遍歷的過程中,假設(shè)當(dāng)前標(biāo)號為i的深度值為Depth[i],向量n和P為當(dāng)前片元的法向量和屏幕空間坐標(biāo),向量v為當(dāng)前片元到視點(diǎn)的向量。根據(jù)深度編號i以及深度值的不同,分為以下幾種情況:
(1)對下標(biāo)為i(i=0,2,4,6……),即i為偶數(shù)的數(shù)組元素,根據(jù)前文提到的深度裝填方法,這些元素存儲的深度值都是正向片元的深度值。在這種情況下,計算當(dāng)前片元P與采樣點(diǎn)S之間的水平仰角h(),即
比較這個h()與h[i]元素中存儲的值的大小,取兩者間較大的賦值給h[i]。
(2)對下標(biāo)為i(i=1,3,5…),即i為奇數(shù)的h[n]數(shù)組元素,這些元素存儲的深度值為反向片元的深度值。在這種情況下,同樣參照式(4)計算當(dāng)前片元與采樣點(diǎn)S間的水平仰角h(),比較h()與h[i]元素中存儲的值的大小,取兩者間較小的賦值給h[i]。
(3)當(dāng)深度值Depth[i]為0或者1時,證明該元素沒有存儲任何有效的深度值,不做任何進(jìn)一步計算。
當(dāng)遍歷深度元素結(jié)束后,h[n]數(shù)組中就存儲了沿 方向的所有深度層次中的最大水平仰角h()max,這時開始計算這一方向上的混合屏幕空間環(huán)境光遮擋值。使用式(3)計算每一個h[n]數(shù)組元素的環(huán)境光遮擋值HAO(,i)(i=0,1,2…)。片元著色程序繼續(xù)對下一個采樣方向進(jìn)行采樣,完成所有方向的遮擋值計算,使用式(2)計算對P點(diǎn)的最終環(huán)境光遮擋值。
我們使用Ogre1.7.1(object-oriented graphics rendering engine)渲染引擎以及C for Graphics(Cg)著色語言實(shí)現(xiàn)了本文的主要算法。文中使用的深度范圍保存部分使用了(rendertotexture,RTT),桶型深度剝離算法通過(multirendertargets,MRT)完成。實(shí)驗(yàn)所用系統(tǒng)平臺為UbuntuLinux9.10,3DAPI為OpenGL 3.2,硬件平臺為IntelCore22.8GHzCPU,GPU采用NVIDIAGe-Force GTX260+896MB顯存。
在獲取每個像素點(diǎn)的最大以及最小深度的時,啟用最大混合方式,禁用背面裁剪和深度測試,輸出紋理格式使用Ogre渲染引擎提供的PF_FLOAT32_RGBA格式。在片元著色程序中輸出如下值:float4(-Z,Z,0.0f,0.0f),其中Z是當(dāng)前片元在視點(diǎn)坐標(biāo)系中的深度值。在最后輸出紋理中每個紋素的R分量保存了該像素上的最小深度,G分量保存了該像素的最大深度。
在第二遍繪制場景進(jìn)行桶型深度剝離的過程中,啟用最小混合方式,禁用背向面裁剪和深度測試,這樣可以保證距離視點(diǎn)最近處的深度可以被正確的剝離出來。在輸出時使用了4張紋理作為MRT來保存深度段中的值。由于所用MRT的格式為PF_FLOAT32_RGBA,所以MRT的每個顏色分量都可以保存一個32位的深度值,這樣一張MRT的每個紋素可以保4個深度值。但是由于我們使用每兩個分量保存一個深度段內(nèi)的前向片元深度以及后向片元深度值,因此4張MRT紋理可以保存8個深度段的16個深度值。在最后一遍進(jìn)行環(huán)境光遮擋計算的過程中,恢復(fù)背向面裁剪和深度測試,并且關(guān)閉所有顏色混合方式。按照本文的算法將最終結(jié)果繪制出來。
本文中的實(shí)驗(yàn)結(jié)果輸出分辨率均為800x600。采樣方向?yàn)?個,每個采樣方向上15個采樣點(diǎn),采樣半徑45像素。一些實(shí)驗(yàn)結(jié)果如圖4所示,繪制幀率如表1所示。
本文的算法與Bavoil[2]的方法相比,計算了在復(fù)雜幾何場景下的多層深度的片元的遮擋貢獻(xiàn),使得最終的結(jié)果更加真實(shí)。
圖4 Buddha Dragon Bunny模型的繪制效果
表1 本文方法的繪制幀率
對比bavoil[2]算法與本文方法對相同的Dragon模型的渲染結(jié)果。如圖5所示,可以明顯看出,在使用桶型深度剝離算法獲取更多層的深度信息后,更多的物體陰影細(xì)節(jié)被更加準(zhǔn)確的計算出來,相對于僅考慮單一深度的原算法,具有更加準(zhǔn)確的渲染質(zhì)量和真實(shí)感。
圖5 本文方法與Bavoil等 [2 ]方法的渲染結(jié)果對比
由于本文的方法只能保存有限層數(shù)的深度信息,所以在計算的過程中不可避免的出現(xiàn)一些誤差。對一般的場景來說,本文算法中使用的16層深度信息基本上可以用來產(chǎn)生理想的結(jié)果。通過實(shí)驗(yàn)表明,當(dāng)使用的深度超過4層以后,對渲染質(zhì)量的影響很小,但是卻會極大的降低性能。
本文通過使用桶型深度剝離算法對BAVOIL[2]的算法進(jìn)行擴(kuò)展,提出一種使用多層深度采樣的屏幕空間環(huán)境光遮擋算法。這是一種多遍繪制的方法,在充分考慮場景深度層次信息基礎(chǔ)上計算環(huán)境遮擋,對部分遮擋不足的區(qū)域進(jìn)行加權(quán)遮擋補(bǔ)償,使得計算的結(jié)果更加符合真實(shí)的場景情況。
但是該算法仍然是一種基于圖形后處理階段的環(huán)境光遮擋計算方法,即渲染出的環(huán)境光遮擋紋理實(shí)際上保存的是一種環(huán)境光的權(quán)值,需要和原場景進(jìn)行乘積混合,進(jìn)而生成最終的計算結(jié)果。在這種算法中,即便獲取了足夠的深度信息,仍然不能夠有效的計算間接光反射造成的陰影減弱的問題。未來將在場景的光照計算階段將間接光反射的因素考慮進(jìn)來,對本文的方法進(jìn)行改進(jìn)。
[1]Shanmugam P,Arikan O.Hardware accelerated ambient occlusion techniques on GPUs[C].Gooch B,Sloan P-P J.Proceedings of ACM Symposium in Interactive 3D Graphics and Games.ACM,2007:73-80.
[2]Bavoil L,Sainz M,Dimitrov R.Image-space horizon-based ambient occlusion[C].ACM SIGGRAPH Sketches,2008.
[3]Liu F,Huang MC,Liu X-H,et al.Efficient depth peeling via bucket sort[C].Proceedings of the 1st High Performance Graphics Conference,2009:51-57.
[4]Liu X-H,Hao X-G,Huang M-C,et al.Fast soft shadow by depth peeling[C].ACM SIGGRAPH Posters,2010.
[5]Ristchel T,Grosch T,Seidel H.Approximating dynamic global illumination in image space[C].Interactive 3D Graphics and Games.Boston,Massachusetts:ACM,2009.
[6]Bavoil L,Callaham S,Comba J,et al.Multi-fragment effects on the GPU using the k-buffer[C].Interactive 3D Graphics and Games.Seattle,Washington:ACM,2007.
[7]Pharr M,Green S.GPU Gems:programming techniques,tips,and tricks for real-time graphics[M].Dynamic Ambient Occlusion and Indirect Lighting,Boston:Addison-Wesley,2004:279-292.
[8]Kontkanen J,Laine S.Ambient occlusion fields[C].Proceedings of the Symposium on Interactive 3D Graphics and Games.Washington DC:ACM,2005:41-48.
[9]Bunnell M.Dynamic ambient occlusion and indirect lighting[C].GPU Gems,Pharr M.Addison Wesley,2005:223-233.
[10]RenZ,Wang R,Snyder J,et al.Real-timesoft shadows in dynamic scenes using spherical harmonic exponentiation[C].ACM SIGGRAPH Papers.New York,USA:ACM,2006:977-986.
[11]Bavoil L,Myers K.Order independent transparency with dual depth peeling[R].Santa Clara:NVIDIA Cooperation,2008.
[12]劉芳,黃夢成,劉學(xué)慧,等.基于桶內(nèi)動態(tài)融合的透明現(xiàn)象的高效繪制[J].計算機(jī)輔助設(shè)計與圖形學(xué)學(xué)報,2010,22(3):382-387.