劉遙等



摘 要: 在此利用HTML5中的異步加載技術進行地形高程數據的加載和調度,用WebGL技術中的Three.js引擎進行地形繪制,在瀏覽器上實現了基于離散型LOD的3D大地形實時繪制,將異步加載和實時繪制動態交替進行。實驗表明,該方法消除了因數據加載而產生的“卡頓”現象,給用戶更流暢的Web3D體驗。
關鍵詞: 異步加載; WebGL; 大地形; 離散型LOD
中圖分類號: TN911?34 文獻標識碼: A 文章編號: 1004?373X(2015)08?0080?04
Research on real?time rendering technology of 3D large terrain based on Web service
LIU Yao, HUA Wen?yuan , WANG Yu?mei
(Department of Command and Control System, North China Institute of Computer Technology, Beijing 100086, China)
Abstract: In this paper, the asynchronous loading technology in HTML5 is used for loading and scheduling the terrain elevation data, and the three.js engine in WebGL is adopted for terrain drawing. The real?time 3D large terrain rendering based on discrete LOD was achieved in the browser. Asynchronous loading is alternated with real?time rendering in the entire process. The experiment result shows that this method can eliminate the "pause" phenomenon generated by loading data. It offers for a smoother Web3D experiencefor.
Keywords: asynchronous loading; WebGL; large terrain; discrete LOD
近年來,3D技術和Web技術的發展十分迅速,如何在瀏覽器上實現大規模的、可實時繪制的3D場景成為研究的熱點話題。傳統的Web3D主要有Java Applet、Adobe公司的Flash Player瀏覽器插件和微軟Silverlight技術。但是,Java Applet不僅需要下載一個巨大的支持環境,而且畫面非常粗糙,主要原因是其在圖形渲染時,并沒有直接利用圖形硬件本身的加速功能,因此,顯卡性能的提升對其三維渲染不起任何作用。Flash Player瀏覽器插件和微軟Silverlight技術解決了這一問題,利用圖形硬件的加速功能,實現了高性能的圖形渲染,但這兩種方案也存在一些問題,比如它們是通過瀏覽器插件形式實現的,這就對不同的操作系統和瀏覽器版本的插件有不同的要求。
WebGL的出現完美的解決了上述兩個問題:首先,它通過JavaScript腳本本身實現Web交互式三維圖形程序的制作,而無需任何瀏覽器插件支持;其次,它利用底層的圖形硬件加速功能進行的圖形渲染,是通過統一的、標準的、跨平臺的OpenGL ES2.0接口實現的[1]。但是,WebGL技術只解決了對地形的快速渲染,不能動態地對大規模數據進行加載。在傳統的繪制中,一般是將外部數據通過JSON或者文本形式同步地一次性傳到CPU,將所有數據加載完成后再將頂點、紋理等數據傳到GPU進行繪制,當數據量過大時,在繪制之前會有很長時間的數據加載時間,在場景中會出現較長時間的“卡頓”現象。為解決傳統方法繪制前下載數據時間過長,并實現一種一邊加載數據一邊繪制場景的效果,本文采用規則網格進行地形數據的存儲,運用HTML5的異步加載技術對數據進行動態的加載和調度,用WebGL的Three.js引擎繪制,實現了大規模地形數據的動態加載和離散型LOD場景的實時繪制。
1 相關技術
1.1 WebGL
WebGL是一組用于在Web頁面繪制3D圖形的繪圖標準接口,繼承自OpenGL ES2.0規范,因而具有強大的圖形功能。WebGL技術標準可以為HTML5 Canvas提供硬件3D加速渲染,用于創建復雜3D結構的網站頁面,這免去了安裝網頁專用渲染插件的麻煩,因而具有良好的跨平臺移植能力。WebGL已得到了Google Chrome,Safari,Firefox,Opera等瀏覽器的支持[2]。
1.2 Three.js庫
Three.js是由Ricardo開發,它面向對象,以簡單、直觀的方式封裝了3D圖形編程中常用的對象,在開發中使用了很多圖形引擎的高級技巧,極大地提高了性能。它將WebGL原生API細節抽象化,將3D場景拆解為網格、材質和光源等。開發者可以使用上層的JavaScript對象和調用JavaScript函數,并可以使用流行的3D建模軟件導出文本格式的文件,然后使用Three.js加載;也可以使用Three.js自己的JSON格式或者二進制格式。
要想使用Three.js把圖形渲染到頁面中,一個應用至少需要執行如下步驟:
(1) 創建一個畫布元素;
(2) 獲取畫布的上下文;
(3) 創建Three.js場景類;
(4) 創建相機、光照等;
(5) 創建自定義物體,并添加到場景;
(6) 運行渲染循環[3]。
1.3 HTML5異步加載技術
異步加載技術是相對于同步加載技術而言的。同步模式,又稱阻塞模式,在數據完成加載之前會阻止瀏覽器的后續處理和解析。
異步加載又叫非阻塞加載,瀏覽器在加載js的同時,還會進行后續頁面的處理[4]。本文中,使用異步加載技術進行高程數據的加載和解析,同時使用解析完成的高程數據動態的構建場景樹,這樣,可以在加載多張高度圖的同時非阻塞地將已加載完成并解析好的高程數據動態地構建場景樹,以減少因大量數據加載而產生的場景“卡頓”現象。
2 實驗步驟
2.1 Web服務器端的數據組織
2.1.1 高程數據存儲格式
在GIS中,DEM一般有3種類型的格網數據:規則格網RSG和不規則格網TIN以及兩者的混合結構。其中,規則網格數據結構由于其頂點呈規則分布,只需要記錄數據的基本信息和每個網格的高程值,結構簡單、操作方便、便于簡化,非常適合于大規模地形數據的組織和管理。
本文處理的原始地形數據以均勻采樣的地形網格數據形式存儲,制作一個JPG格式的高度圖。高度圖是存儲地形高度信息的二維貼圖,它們通常是8位的灰度圖,圖像上的每個點存儲地形對應位置的高度。它的高度值變化范圍是在0~255之間,其中0(黑色)表示最低高度而255表示最大高度。在實際中,可以乘以一個縮放值乘以默認高度值,增加其范圍,但會使兩個高度之間的誤差增大,也可以使用多個字節來表示一個高度。
JPG格式高度圖的每一個像素都由R,G,B值和透明度α值4個值組成,像素的順序從左到右,從上到下,按行存儲。本文實驗中的高度圖用兩個字節表示一個高程值,每個高程值的范圍為0~65 535,則一個像素可以表示兩個高程值,易知:
[H1=256×R+GH2=256×B+α]
2.1.2 地形數據的四叉樹表示
建立三維地形網格模型過程中,四叉樹結構是一種常用的數據結構,由一個根節點、若干個樹枝節點及葉節點組成,且每個節點上最多只有4棵子樹。四叉樹中的根節點,包含對應地形區域的4個頂點的坐標和4個指向其孩子節點的指針;樹枝節點不僅包含以上信息。還包含一個指向其雙親節點的指針;若這個節點是葉子節點,包含4個頂點的坐標和一個指向其雙親節點的指針。
采用四叉結構建立地形多分辨率模型的基本過程為將原始地形看作一個正方形區域,對應四叉樹結構的根節點,未經過任何細分,其細節精度為0,用level = 0表示,如圖1所示;對節點進行迭代細分,當節點滿足某個條件時,將此節點劃分成4個相等的正方形,即4個節點;然后對4個子節點繼續判斷,如果滿足上述節點,則繼續細分,如果不滿足上述條件,則停止細分,如此迭代,知道最后的節點數等于全部DEM數據點個數或所有節點已不滿足上述條件。
2.2 LOD地形數據的異步加載和動態調度
由以上內容可知,在四叉樹的數據結構下,假設level = 0時的網格有128×128個頂點,即需要128×128的高度圖來存儲頂點高度,那么level = 1時就需要4張128×128的高度圖來存儲高度數據,level= 2時需要16張,以此類推。當精度層級增長時,需要加載的高度圖數據呈指數倍增長。如果等待所有層級的高度數據完全加載完畢之后再繪制,會使用戶等待時間過長,當數據量過大時,還可能使瀏覽器崩潰。
當分析這一問題時發現,在瀏覽器中要構建大數據量的場景,就要動態調度高程數據以逐步構建場景樹。最佳流程應該是在下載完成一張高度圖并讀取這張高度圖之后就立刻將這張高度圖所對應的網格繪制完畢并加載到場景中,然后等待,直到下一精度層級的高度圖加載并繪制完成。這種在加載數據的同時依然可以進行場景繪制的方式就是異步加載。
在HTML5中提供了異步加載文件的函數onload(),異步加載一張高度圖數據至少需要執行以下步驟:
(1) 創建一個canvas畫布對象;
(2) 獲取canvas對象及其上下文;
(3) 創建一個Image對象;
(4) 指定需要加載Image對象的位置;
(5) 執行Image對象的onload(),異步加載高度圖;
(6) 加載完畢后,從canvas上下文中讀取數據。
通過異步加載實現動態構建場景樹的程序流程圖如圖2所示。
由圖2可知,在場景初始化階段,只需要將根節點高度圖異步加載到內存中,讀取高度數據后,創建根節點,并將根節點加入場景,然后開始動態地構建場景樹。
構建場景樹時要首先判斷4個子節點是否已經加載,判斷的必要性在于考慮到在未來的程序開發中有可能遇到以下情況:當地形數據加載過多,而某些地形在距離當前視點過遠或者用戶已經長時間沒有訪問該地形時,這些數據的存在會給瀏覽器帶來過大的負擔,需要對這些數據進行剔除,所以有可能會出現某些子節點曾經加載過而現階段已經被剔除掉的情況。
當判斷完成,找到應該加載的節點后,異步加載所需加載節點的高度圖,在這里就體現了異步加載的必要性。假如沒有異步加載機制,就必須等待到當前正在加載的高度圖加載完畢之后才能繪制,這樣,由于同步加載的阻塞機制,會出現一直在執行加載程序而繪制程序一直被阻塞的情況,無法完成加載完成一張高度圖就繪制一個LOD節點,并且很可能在數據量過大時瀏覽器在繪制第一幀之前瀏覽器就已經因不堪重負而崩潰,從而無法在瀏覽器上看到任何場景。異步加載的作用就在于:首先,GPU繪制當前幀的場景時,CPU可以同時加載場景暫時還不需要但之后可能需要的高度圖數據;其次,在每一幀中,可以無阻塞地根據高度圖的加載進度選擇應該構建的場景節點;另外,在每一幀中,并不是所有數據都要繪制,在繪制循環中可以方便地根據視點的位置等信息進行數據的動態剔除,以減少瀏覽器的壓力。
2.3 場景繪制循環
由圖2可知,在每一幀中,都要執行一個加載函數和一個繪制函數,這樣做的目的是實現CPU和GPU的協同工作以達到較好的用戶體驗效果。加載函數的作用是異步的加載高度圖和紋理圖,并在每一對高度圖和紋理圖加載完成之后分別用一個標志數以記錄當前的加載進度。
在繪制函數中,通過一個數組來記錄當前已經加載進場景的物體類,一個標志數來記錄已加載入場景中的物體個數。每一幀的繪制過程為:
(1) 判斷當前視點位置;
(2) 遍歷記錄當前已經加載進場景的物體類數組,根據當前視點位置,判斷應該顯示的物體編號,并將應該顯示的物體的顯示標志設為true,不應該顯示的物體顯示標志設置為false;
(3) 調用繪制網格的命令,繪制當前應該顯示在場景中的物體類;
(4) 更新記錄數組和場景數據。
3 實驗及結果分析
實驗所用的每一張高度圖都是32×64的JPG格式的服務器端文件,可表示64×64個高程值。
本文實驗程序是在Google Chrome 33.0.1750.154版本的瀏覽器上開發完成,硬件條件 Intel(R) Core(TM)2 Quad CPU,3 GB內存,顯卡NVIDIA Quadro NVS 290。
試驗程序分別做了一個3層LOD模型,總共需要下載1+4+16=21張高度圖,一個2層LOD模型,需要加載1+4=5張高度圖,將本文所述的異步加載方法和將傳統的同步加載方法進行對比,通過單步跟蹤,得到數據如表1所示。
表1 實測對比數據
對實測數據及場景變化的描述如下:
(1) 傳統方法在初始化階段有明顯的“卡頓”現象,且沒有場景節點被繪制出來。
(2) 傳統方法加載完成之后只需要約1~2 f即可全部繪制完成,這一階段的繪制幀率為58~60 f/s。
(3) 異步加載方法在初始化階段只需加載一張圖,約1.5 f,在第2 f末已繪制完成第一層LOD模型,幾乎沒有“卡頓”現象。
(4) 異步方法3層模型從初始化完成到整個場景繪制完成的過程中需要29 f,幀率有一定的起伏,但總體呈現逐漸加快的趨勢,明顯的可以看到場景中逐步顯現出LOD各個子節點。
(5) 異步方法2層LOD模型從初始化完成到場景繪制完成需要7 f,幀率為平穩的46 f/s。
(6) 場景繪制完成后,對場景中的物體進行拖拽、旋轉操作時,兩層LOD幀率幾乎不變,而3層LOD則由于三角形數目的增多因此在重繪時幀率會有明顯下降。
由以上數據可以看出,異步加載方法雖然不能減少從加載到繪制的總時間,但是可以明顯地減少“卡頓”時間,并且可以實現一邊加載高度圖一邊將加載好的數據實時的繪制出來,給用戶比較流暢自然的Web3D體驗。
4 結 語
本文使用Three.js框架,通過HTML5的異步加載技術動態地構建WebGL大地形場景樹,目標在于實現CPU加載和GPU繪制的相互協作,給Web用戶更好的3D體驗。本文的實驗程序所構建出的場景距離比較完美還有以下不足:首先,對場景中長期沒有用到的節點還沒有做到動態剔除,因此,還沒有實現對最大數據量的平衡控制;其次,在LOD場景控制時沒有消除因LOD層級過渡而產生的裂縫,以后,程序可以從這兩方面加以改進。
參考文獻
[1] 方強.基于WebGL的3D圖形引擎研究與實現[D].合肥:安徽大學,2013.
[2] CANTOR D, JONES B.WebGL編程指南[M].李強,譯.北京:清華大學出版社,2013.
[3] PARISI T. WebGL up and running [M]. Sebastopol: OReally. 2012: 2?16.
[4] 張亞飛.HTML5和RIA網站設計[M].北京:清華大學出版社,2013.
[5] CHANG K.地理信息系統導論[M].5版.陳建飛,張筱林,譯.北京:科學出版社,2010.
[6] ROGERS D F.計算機圖形學算法基礎[M].北京:機械工業出版社,2002.
[7] 佚名.three.js教程[EB/OL]. [2010?01?06].http://github.com/tparisi/WebGLBook.