王全占,吳 博
(西南交通大學 電氣工程學院,成都 610031)
大規模場景模型動輒數GB、甚至數十GB的超大數據量與計算機內存以及計算性能嚴重不匹配,引起了國內外虛擬現實、視景仿真領域的極大重視。文獻[1]對大規模場景的實時繪制技術進行了綜述,但未就單一技術進行深入探討。文獻[2]對單一巨大模型的核外簡化及實時繪制技術進行了詳細的闡述,但是很遺憾該文獻中的方式更適用于單個的巨大物體,而對于如數字地球、虛擬現實等領域的眾多小模型組合而來的大規模復雜場景模型顯得不太合適,并且不太適用于多紋理模型的繪制。文獻[3][4]等則是從核外計算的角度對數據的I/O優化策略進行了對比研究,并未就場景繪制這一方面進行研究。本文對文獻中的核外資源處理的思想進行繼承,并提出了基于OGRE圖形引擎的、更適用于大規模多紋理場景模型的實時繪制的新思路。該方法首先將仿真業界的事實標準Open Flight格式的三維場景模型按照區域劃分,分割成若干適合圖形工作站內存大小、能夠達到數據預取要求的小模型,然后利用模型轉換工具將該小模型從Open Flight格式轉化為OGRE引擎支持的MESH模型,最后利用數據預取技術以及多線程編程技術完成大規模場景數據的實時讀取、實時渲染。
OGRE(object-oriented graphic render engine,面向對象的圖形渲染引擎)是用C++開發的面向對象且使用靈活的3D引擎。其目的是讓開發者能更方便和直接地開發基于3D硬件設備的應用程序或游戲。引擎中的類庫對更底層的系統庫(如:Direct3D和OpenGL)的全部使用細節進行了抽象,并提供了基于現實世界對象的接口。引擎中資源加載與渲染是分離的兩部分,因此能夠支持后臺加載。
OGRE能直接利用的模型文件為:.mesh文件,與之對應有一個.materail文件,以及若干紋理圖片(png,jpg,tga等)。其中.materail文件中存儲了若干個材質,每個材質包含有折射率、反射率、紋理圖片名稱等信息。.mesh文件中包含有若干submesh(子網格),每個子網格與一個材質名相對應,每個子網格里有應用該材質的頂點的坐標、法向量、紋理貼圖uv值等信息。
當代的GPU更適合于渲染少數的大批次的幾何體,而不是許多小的批次。這里的批次是指GPU渲染狀態的改變,包括折射、反射、紋理等。也正是如此,單純的三角形數目已經不是GPU關注的熱點,渲染一個單一批次的100萬個三角形的場景,可能到300幀/s以上,然而渲染1 000個批次,每個批次中有1 000個三角形的場景卻可能只有30幀/s。
為了防止材質的頻繁切換,OGRE的.mesh文件以材質為單位進行組織,極大限度的減少材質的切換。
核外算法的I/O策略包括數據篩選、數據預取、數據重用等方式。數據篩選主要指為了降低外存訪問次數、提高內外存交換的有效數據量而采取的一系列措施。數據預取技術的主要思想是利用數據處理的時間,并行地預取下一時間段需要處理的數據。這就要求I/O操作的數據與CPU/GPU處理的數據不重疊,并且需要保證數據預取的時間要小于數據處理的時間。數據重用主要是指為實現內存中數據的重復利用率而采取的一系列措施。
基于以上討論,OGRE支持.mesh格式的網格模型的渲染,并且在渲染期間會按照不同的材質重新排列,按照批次進行渲染,以實現更適合當代GPU渲染的渲染隊列。而核外渲染的I/O優化策略包括數據篩選、數據預取、數據重用3種方式。大規模的場景數據都是存在外存(硬盤等)中的,讀取到內存中的數據必須包括當前幀所需要的模型數據以及預取的在一個時間段內需要的模型數據冗余。
首先需要將大的場景模型按照三維空間分塊成小的模型,用以動態加載/卸載,這里有2個問題,一是小模型如何存儲,二是切分的小模型的大小如何確定。由于OGRE是以資源組的形式進行資源管理,因此只需將切分好的模型數據,包括三角形數據、材質文件、紋理文件均放到同一文件夾下,然后聲明該文件夾為一個資源組,這樣就可以實現該模型的所有數據同時加載/卸載。

圖1 模型的大小
至于如何確定小模型的大小,由于需要將同一三維空間內的模型數據單獨放到一個文件夾內,這就無形中增加了不少冗余數據,比如同一張紋理在區域A中要用到,同時也在區域B中也要用到。因此切分的小模型必須在保證渲染的實時性的前提下,越少越好。因此將模型劃分為34個小模型,模型大小以及所含紋理數量如圖1、圖2所示。

圖2 模型的紋理數量
相對應的出現卡幀現象的區域塊如表1所示:

表1 出現卡幀現象的區域塊
由表1可見,發生卡幀現象的區域編號全是與較大模型塊相對應的。由于動態優化是有代價的,尤其是尋求全局最優解,更由于不同紋理、不同組織結構的模型等使得尋求全局最優基本不可能。因此根據反復測試,歸納出適用于當前使用機器的模型大小為:單個模型大小不超過3 MB,紋理數量不超過200張。該結構可作為以后在該計算機上實時大模型時的經驗數據。
實時渲染的同時,啟動一個資源管理線程,完成資源的后臺調度功能。處理流程如圖3所示。
渲染線程根據當前漫游方向以及速度來計算當前視點參數,并進行相應渲染操作,同時將當前速度、方向、視點位置等數據寫入公共數據區。資源管理線程負責判斷當前視點下,是否需要進行I/O操作并及時更新場景圖。
具體的資源管理策略,選用了OGRE的后臺加載隊列進行后臺加載。這個類提供了一個簡單的接口,可自動創建一個后臺線程去加載/卸載資源,并在處理完畢后返回到主線程一個ID編號。由于返回的信息太少,因此在OGRE主線程中創建了一個專門用于調度的資源管理線程,該線程負責加載/卸載資源組,并建立資源組編號與后臺處理隊列ID的映射關系。

圖3 處理流程圖
這樣,首先對分割好的小模型建立相應的資源組編號,以及對應的三維空間包圍盒數據,然后資源管理線程通過讀取公共緩沖區的當前視點及其運動參數,進行下一幀的視點預測,然后根據當前幀以及下一幀的視點位置所在的區域塊,以及視域的設置來確定下一時刻需要在內存中的資源組編號,并根據當前區域的屬性來決定是否進行資源加載/卸載操作。區域塊的數據結構設計如下:

然后通知OGRE的后臺加載策略進行加載/卸載操作,OGRE會另外開辟一個線程去加載/卸載資源組,在這個資源組中,包含模型的mesh網格模型、材質文件以及相應的紋理,OGRE會在后臺完成網格數據的加載/卸載,并解析材質文件找到需要處理的紋理文件,將紋理進行加載/卸載操作。資源處理完成將返回給資源管理線程資源處理完畢的標志,以便資源管理線程及時更新場景圖。
在資源管理線程進行資源處理的同時,渲染線程會按批次渲染當前場景圖中的三維場景。當前存在于內存中的數據只是略大于視域范圍的較小區域的場景,因此場景視域剔除的效率會很高。影響GPU渲染效率的主要因素就是渲染狀態的頻繁改變,即渲染批次的數量很大地影響了圖形渲染的效率。OGRE本身是面向GPU加速的圖形引擎,它會在力所能及的范圍內盡量把相同渲染狀態的物體一起渲染,進而減少渲染狀態改變。OGRE也尊重用戶設置的Renderable整體(也就是說Renderable是處理批次的最小原子結構),并不進行拆分。比如,有若干個使用相同材質的片段組成的模型,就可以把它們合并成一個Renderable對象,這樣就可以省略掉系統檢查這些片斷是否是一個相同的渲染狀態的步驟,從而可以一次處理完畢。基于上述討論,渲染線程會在響應突發事件(運行故障等)、及視點計算的基礎上根據當前場景圖,將同一個材質的片段的模型重組到一個Renderable,最后OGRE按材質的優先級、按批次地完成當前場景的渲染,實現GPU加速。
根據以上模型分塊以及核外渲染方法,筆者在西南交通大學智能控制與仿真工程研究中心的高性能圖形工作站上實現了所設計的系統。完成了3 000 km×2 km范圍內的大規模場景模型的實時繪制,模型總量為4 GB,超過了試驗機系統內存。圖4為完成后的效果圖,圖5為幀速率曲線。

圖4 大規模場景模型繪制的效果圖

圖5 幀速率曲線
大規模場景模型的實時渲染,在列車仿真器視景系統等計算機圖形系統中占有非常重要的地位。實時渲染超過內存大小的超大模型,更是近年來的研究熱點。本文基于OGRE開源圖形引擎,構建了一個簡單、高效的大場景核外渲染方法。經過實驗證明,該方法能夠實現數GB乃至數十GB模型的實時渲染,并且幀率穩定,能夠適應高速鐵路列車仿真器超長線路場景實時渲染的要求。
[1]崔雪峰,王林旭,王玨.大規模復雜場景的交互繪制技術[C]//劉曉平,蔣建國,李琳,等.全國第19屆計算機技術與應用(CACIS)學術會議論文集(上冊).合肥:中國科學技術大學出版社,2008:129-134.
[2]王威,胡銘曾.核外計算中I/O優化策略的研究[J].哈爾濱商業大學學報.2005,21(5):600-603.
[3]王海洋,蔡康穎,王文成,等.外存模型簡化中數據讀取及內存分配的優化[J].計算機輔助設計與圖形學學報.2005,17(8):1736-1743.
[4]段化鵬,楊衛平,孫農亮,等.基于OGRE和ODE的碰撞檢測在巷道漫游系統中的研究[J].電腦知識與技術,2009,5(19):5219-5221.
[5]李云飛,程甜甜,何偉.一種湖面波浪模擬的方法[J].系統仿真學報,2009,21(23):7507-7510.
[6]蘇虎,金煒東.列車駕駛仿真器及其關鍵技術[J].科技導報,2007,25(12):12-17.
[7]劉波.大規模城市場景的高效建模及其實時繪制研究[D].浙江大學,2008.