摘 要:介紹了一種利用可編程圖形硬件來實現水面實時渲染的方法。該渲染過程分為兩個階段,即水面建模和光照實現。通過當前圖形硬件新提供的頂點紋理技術來對水面進行建模,并結合環境紋理映射技術和二維紋理映射技術實現了水面上的反射與折射等光照現象。實驗證明,該方法大大提高了渲染速度,增強了水面渲染的交互性和實時性。
關鍵詞:水面渲染; 頂點紋理; 環境紋理映射; 二維紋理映射; 交互性; 實時性
中圖分類號:TP391.9 文獻標志碼:A 文章編號:1001-3695(2008)08-2387-03
Interactive real-time water rendering
WU Lei, CHEN Lei-ting, HE Ming-yun
(School of Computer Science Engineering, University of Electronic Science Technology of China, Chengdu 610054, China)
Abstract:This paper presented a way supported by programmable graphics hardware to render water in real-time. The rende-ring process included two stages: water surface modeling and illumination simulation. It took advantage of the vertex texture to model the water surface and simulated the reflection, refraction with environment texture mapping and texture mapping. The experiment proves that it can improve the efficiency of rendering.
Key words:water rendering; vertex texture; environment texture mapping; texture mapping; interactive capability; real-time capability
水面在計算機模擬中相當的普遍,尤其是在游戲當中,它們是能夠顯著提高場景真實度級別的重要元素。但是能真實地描述它們卻是一個很困難的問題,原因在于光線與水面的交互作用,會帶來很高的視覺復雜度。在非實時渲染中,由于沒有時間和效率上的考慮,人們能夠顧及到各種因素對水面的影響,提出了許多水面渲染模型并成功地將它們投入到了商業應用中。Jerry Tessendorf[1]就成功地利用了FFT技術結合海洋學的統計數據,采用Pierson-Moscowitz譜模型實現了對大場景水面的模擬,并將其運用到了《泰坦尼克》《水世界》等好萊塢電影的特效制作中,取得了巨大的成功。但是,由計算機圖形硬件的限制,對于實時渲染水面一直不夠理想。尤其在游戲當中通常都是采用多重紋理來作一種近似地模擬,雖然交互性能得到很好的滿足,但是渲染的真實感較差,遠不能滿足人們對真實感的需要。本文采用的方法是利用頂點紋理對以前的水面渲染技術進行有效簡化,使其在渲染效率和質量上達到一個良好的平衡,并將其運用到實時模擬當中。
1 相關研究的分析
實時水面的渲染一直都是眾多學者研究的領域,并相繼提出了一些水面渲染的模型。Nick Foster[2]采用了Navier-Stokes方程對三維水面進行渲染。Kei Nakano[3]成功地采用粒子系統對小范圍的水面進行渲染。Jerry Tessendorf[1]通過快速傅里葉變換(FFT)和Pierson-Moscowitz譜模型產生高度場,并利用該高度場對水面進行模擬。這種方法具有很強的靈活性,并且由于它的數據基礎來自于海洋統計學模型,因此渲染出來的水面真實感較強。但是,該方法的缺點在于很難將其應用到幀頻率要求較高的實時水面渲染中。原因在于,在每一幀中計算高度場耗時巨大,并且隨著水面高度的變化,還應根據高度場重新計算水面每個頂點的法向量的改變以求達到較為真實的水面光照效果。 Vladimir Belyaev[4]對Jerry Tessendorf[1]中的方法進行優化,在水面網格中引入了層次細節(levels of detail),這大大降低了遠處場景的相關計算,但是在實時渲染中仍然不能具有良好的交互性。本文對文獻[1,4]中所提出的方法進行了進一步的優化,并不實時計算水面高度場,而是采用多張事先手工繪制的高度圖,通過與時間相關聯的融合系數對這些高度圖進行疊加。這充分利用了圖形顯卡的特性,大大地提高了渲染效率。另外,將水面上和水面下的景物分別繪制成紋理,并結合環境紋理映射技術和二維紋理映射技術從而實現水面上光線反射、折射和菲涅爾等光照效果,大大增強了水面渲染的真實感。
2 水面模型分析
對于水的模擬來說,最具有真實感是那些基于流體動力學和快速傅里葉變換(FFT)發展而來的模型。這些模型提供了非常真實的渲染結果,但不幸的是它們需要相當大的數學計算,使它們不適用于交互式的應用程序。當前大部分游戲均采用非常簡單的水面模型,其中的大部分都是用法向映射(normal maps)來產生視覺細節。但是,這個方法不能提供足夠的真實感,也不能真實地表現水面上產生的波浪。本文所采用的技術結合了上面兩種方法的優點,使其既具有法向映射的速度又具有FFT方法的視覺真實感。
2.1 高度場的產生
本文中所采用的高度場是通過一些重疊的高度圖來產生的。這些高度圖是事先通過手工制作并保存下來。其中,每一張高度圖在時間和空間上是彼此分離的。將這些高度圖紋理疊加在一起就形成了水面的高度場。其中,每一個紋元就代表了對應點的高度值。
在疊加這些高度圖時使用不同的縮放系數。同時,將時間作為一個自變量引入進來,這樣就可以獲得復雜的水面波動效果。表達式為
H(x,y,t)=∑Ni=0b(Axix+BxiAyix+Byi,Atit+Btt)
其中:x和y是水平面的空間坐標;t表示時間;N是高度圖的數量。對于參數Ai和Bi通過實驗仔細選擇以避免水面波動明顯的周期性。
2.2 采樣高度場
要想渲染出不斷波動的水面,除了具有表示高度場的紋理外,還需要對此紋理進行采樣,以確定水面各頂點的高度值。本文借鑒了LOD的思想并對其進行了精心的簡化,大大減少了對計算量的要求。筆者采用的是放射狀的柵格(圖1),它的中心位于相機所在的位置。
這樣的柵格可以在靠近觀察點處采樣頻率更高,能提供較高的細節,而遠處采樣頻率較低節省了計算的開銷。下面的方程式展現了如何計算放射狀柵格的頂點位置。
r=a0+a1i4;xi,j=r cos(2πj/M);yi,j=r sin(2πj/M)
其中:i代表同心圓的編號,它的取值為0~N-1;j代表在一個圓上的采樣點編號,它的取值0~M-1;N和M都是選定的常數。最小圓的半徑r0=a0,而最大圓的半徑rN-1=a0+a1(N-1)4。其中,a0和a1也是選定的常數。
3 水面光照分析
水面環境主要是由水面、大氣、光照和水面下的水體這四個部分組成。其中,水面上的光照是影響水面特征最為重要的因素。通常,水面上的任何一點的光照強度由三部分構成:太陽光、環境光和來自于水面下的透射光。筆者認為在水面上主要發生的光照現象是光線的折射和反射,當然,水體自身也存在對光線散射和吸收的作用。正是由于光線在水面上會發生反射和折射,水面才會出現水面以上景物倒影和水面以下物體影像相互重合的現象。在這里,出于對問題簡化的考慮,筆者只考慮光線折射和反射對水面的影響,而水體的自身作用暫時不進行計算。因此,水面的顏色可用下面的表達式進行描述。
Cwater=FCreflect+(1-F)Crefract
其中:F是菲涅爾系數。菲涅爾系數采用統計學的觀點描述了光子從一種傳播介質到達另一種傳播介質的表面上時,發生反射和折射的概率。菲涅爾系數可采用下式進行計算:
F=(g-k)2/2(g+k)2(1+(k(g+k)-1)2/(k(g-k)+1)2)
k=cos α;g=na/nb+k2-1
其中:na和nb分別是空氣和水的折射率,可以將其值近似地取為1.333;α是入射光線和表面法向量之間的夾角。由此可見,菲涅爾系數的變化完全取決于k的變化,當表面法向量不斷變化時(水面不斷波動時),菲涅爾系數就頻繁變化,從而導致水面顏色的變化。
3.1 光的反射
當前的圖形加速硬件都支持立方體紋理映射,可以使用六張紋理構成一個環境紋理盒來模擬水面所在空間四周的環境(圖2)。如果視線方向為E,水面的法向量是N,則反射光線為R=E-2(E×N)N(圖3),它與環境紋理的交點顏色,就是沿E方向所看到的水面環境反射顏色(Cenv)。除了考慮環境反射顏色之外,筆者通常還要考慮太陽光在水面上所形成的波光粼粼的效果(Cspecular)。因此,將上面兩種因素結合在一起就可以得到下面的表達式:Creflect=Cenv+Cspecular。
3.2 光的折射
光線在水面發生反射的同時也發生了折射。對于特定的視向量E,折射光線的方向可以通過Snell定律來進行計算,公式如下:ηi sin(θi)=ηt sin(θt)。其中:ηi和ηt分別是空氣與水面的光線折射率;而θi和θt是光線的入射角和光線的折射角。
折射光線的顏色同樣是由兩部分構成,即水面下物體的顏色(CunderWater)和水體本身的顏色(CwaterVal)。因此,折射光線的顏色為Crefract=CwaterVol+CunderWater。水面下物體的顏色采用下面的公式計算而得CunderWater=Cobjecte-ks。其中:Cobject是水面下物體本身的顏色;k是水對光線的散射系數;Sc是水面下物體到相機的距離。同時,水體(CwaterVol)的顏色由多種因素決定。為了簡化問題,將水體的顏色作為一種常數來進行處理。因此,將水面考慮成為平面事先計算水面下物體顏色和水體顏色的組合將其保存在一張紋理圖。
3.3 菲涅爾系數
為了提高渲染效率減少計算量,筆者事先計算菲涅爾系數,并將它保存在一張2D紋理中。假設水面當前頂點的法向量與Z軸平行,2D紋理中保存了針對視向量所有可能入射角的菲涅爾系數值。紋元(s,t)對應單位視向量:V=(s-0.5,t-0.5,1-(s-0.5)2+(t-0.5)2)的菲涅爾系數,如圖4 所示。而圖5是最終的保存菲涅爾系數的2D紋理圖。
對于水面上的特定點N=(xn,yn,zn),可以計算此點的單位視向量V=(xV,yV,zV)。但是,此向量是在世界坐標系下計算的,因此(xV,zV)不能直接作為紋理坐標來進行紋理映射。必須將單位視向量V變換到N點的局部坐標下(N點的法向量與Z軸平行),再進行紋理映射。
3.4 泡沫
當風浪足夠強時,可以通過產生泡沫來提高真實感。筆者所采用的方法是對于高度超過H0的頂點使用一張預處理過的泡沫紋理進行混合。根據以下公式來計算泡沫的透明度:Foam.a=saturate((H-H0)/(Hmax-H0))。其中:Hmax表示可能出現泡沫的最高位置;H0為基準高度;H表示當前高度。為了簡化問題,本文所使用的泡沫紋理是手動創建的。
4 優化與實現
實時水面渲染最大的問題就是如何減少渲染過程中所需要的大量計算。在設計實現的過程中,要充分考慮如何簡化一些對視覺效果影響不大的計算。筆者主要針對紋理采樣和頂點裁剪進行優化,以達到提高渲染效率的目的。
4.1 紋理采樣
本文采用的是頂點紋理技術。在渲染過程中需要從保存水面柵格各頂點高度的紋理中采樣與之對應頂點的高度值。由于當前的圖形硬件不支持直接對頂點紋理過濾。因此,必須在頂點片斷程序中手動編寫紋理過濾代碼。常見的紋理過濾技術是雙線性過濾和三線性過濾,但是這兩種技術都存在為獲取一個像素信息須多次采樣的缺點。以雙線性紋理過濾為例,要采樣給定點的紋理值,就必須對該點周圍的四個紋元進行采樣,并通過相應的權值將這四點的值求平均,從而得到給定點的紋理值。如果所要渲染的水面區域較大,頂點數較多,則效率不高,不能獲得理想的效果。假設采用的是三線性過濾,所需的紋理拾取數還會翻倍,因為這需要在鄰近的mip層中進行雙線性過濾并對結果進行均值計算。
為了解決這一問題,本文將前期制作的水面高度場紋理進行預處理。把每一張單通道的高度圖融合到一張四通道的紋理當中,充分利用R、G、B、A,這樣采樣四通道紋理一次就能同時獲得目標圖元四周的像素信息。這樣就大大降低了紋理采樣的總次數(采樣次數是沒有優化情況下總次數的四分之一)。具體的處理方法如下:
a)將一幅高度場的單通道灰度圖讀入到顯存中;
b)逐像素地查找每一圖元上下左右四個圖元數據,并進行保存(如果是邊界圖元,就將該圖元數據保存四份作簡化處理);
c)對所得到數據進行像素數據包裝,返回到b)繼續執行;
d)渲染到紋理并保存為tga文件;
e)按上述方法依次處理所有四張單通道高度圖。
4.2 頂點裁剪
即使優化了紋理采樣,渲染過程中紋理的采樣次數還是相對較高。本文采用的是大量三角面片來渲染水面,這樣一些三角形就會完全處于視域體以外。對于這些三角形,頂點程序同樣將會執行,這浪費了寶貴的計算資源。因此,在頂點片斷程序中應該先裁剪掉位于視域體外的頂點。
頂點程序一次計算只能處理一個頂點,所以不能記錄頂點間的拓撲信息。因此,只能在頂點層次作出優化。如圖6所示。
在視景體投影區外側,適當添加一個安全區域。對于超出視景體,但又位于此安全區域內的頂點并不將其裁剪掉。(如三角形1正下方兩個頂點)這樣可以有效地避免裁剪掉一個三角形位于視景體外側的一部分頂點而帶來的邊界失真。下面是實現頂點裁剪的偽代碼。
//將輸入頂點INP坐標轉換到視點坐標中
//ModeViewProj當前系統的空間變換矩陣
Float4 ClipPos=mul(ModeViewProj, INP);
Float3 check;
//判斷頂點是不是在安全區域的外側
check=abs(ClipPos.xyz)<(ClipPos.www*C0+C1);
If(all(check))
{
//頂點處于視域體內要進行處理
}
這里C0和C1是特殊的裁剪常量,控制了三角形的頂點延伸出攝像機視景體多少距離將會觸發裁剪,即控制圖中安全區域的大小。由于系統渲染的三角面片較小,因此安全區域只需比相機視景體投影區稍寬一點就可以大大降低對跨越視景體投影區域的三角面片頂點(如三角形2)進行裁剪的概率,有效地避免了邊界失真。
4.3 實驗結果
本文的實現平臺是普通PC機(CPU: P4 2.8 GHz,內存:1 GB,顯卡:NV Quadro FX 3400/4400),并利用標準OpenGL圖形庫和CG著色器,在VC++.NET 2003集成開發環境下實現。首先,加載需要的各種紋理,再在頂點片斷程序中對高度場紋理采樣,并根據所得的高度數據進行頂點坐標變化。同時,計算出泡沫紋理的透明度、菲涅爾紋理坐標、折射紋理坐標和反射紋理坐標。最后,在像素片斷程序中根據前面所計算的紋理坐標進行混合。放射狀柵格的采樣數是影響實時渲染效率的主要因素,如果柵格分辨率較高,渲染逼真度較好,分辨率較低則會導致逼真度較差。通過多次實驗,筆者采用放射狀柵格的分辨率為512×348時畫面效果較好,圖7~9是實驗過程中的三個屏幕截圖。同時通過實驗數據的對比,可以證明對紋理采樣的優化和頂點裁剪可以顯著地提高渲染效率,實驗數據對比如表1所示。由表1可知,在沒有采用任何優化技術的情況下,平均幀頻率在21.1 fps左右,渲染速率不是太理想,僅采用頂點裁剪技術將平均渲染速率提高到30 fps,而僅采用紋理采樣優化可將渲染速率提高到38.5 fps,同時應用兩種優化技術平均渲染速率穩定在45 fps左右。這樣的幀頻率能夠保證良好的實時交互性。
表1 實驗數據對比表柵格分辨率頂點裁剪紋理采樣優化幀頻率/fps512×348否否21.1512×348是否30512×348否是38.5512×348是是455 結束語
實時水面渲染是當前比較受關注的一個研究領域。本文的水面渲染是從平衡實時性和逼真性的角度出發,充分利用當前圖形加速卡的一些新特性來實現。其算法思想簡單,實驗效果較為逼真,同時也達到了實時性的要求。
但仍然還存在一些需要在以后工作中不斷完善的地方。例如增加局部光照效果來模擬水面物體所形成的倒影以及影像之間的相互作用,以及考慮水面上漂浮的物體所形成的波紋和漣漪等來實現更加真實的模擬。
參考文獻:
[1]邱捷, 陳雷霆. 基于物理模型的實時海面模擬[J]. 計算機與數學工程, 2006, 34(1): 4-7.
[2]FERNANDO R, KILGARD M.CG教程—可編程實時圖形權威指南[M].洪偉,劉亞妮,李騎,等譯.北京:人民郵電出版社,2004.
[3]吳恩華. 圖形處理器用于通用計算的技術、現狀以其挑戰[J].軟件學報,2004,15(10):1493-1504.
[4]fOSTER N,METAXAS D.Realistic animation of liquids[J]. Gra-phical Models and Image Processing (S1077-3169), 1996, 58(5):471-483.
[5]NAKANO K.Water surface using particle system[EB/OL].[2002].http://graphics.sfc.keio.ac.jp/papers/2002a/nakano2002.pdf.
[6]Tessendorf.Simulating ocean water [EB/OL].[2001].http://homel.gte.net/tssndr/index.html.
[7]BELYAEV V.Real-time simulation of water surface[EB/OL].[2003].http://www.graphicon.ru/2003/Proceedings/Technical/paper316.pdf.
[8]JENSEN.Deep-water animation and rendering[EB/OL].[2001]. http://www.gamasutra.com/gdce/Jensen/Jensen_01.htm.
[9]MASTIN G A, WATTERGER P A, MAREDA J F. Fourier synthesis of ocean scenes[J]. IEEE CGA,March, 2001:16-23.
[10]PERMOZE S, ASHIKHMIN M. Rendering natural waves[J]. Computer Graphics Forum, 2001, 20(4):189-200.
[11]CABRAL B, OLANO M, NEMEC P. Reflection space and image-based rendering[C]//Proc of SIGGRAPH.1999:165-170.
[12]FOURNIER A, REEVES W T. A simple model of ocean waves[J]. Computer Graphics, 1986,20(4):75-84
注:本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文