前面一篇說了pvs資料的預處理,當時是用純cpu來計算patch之間的可見性。後來聽說有個idirect3dquery9介面可以判mesh的可見性,就試了一下,果然比用純粹cpu計算快了很多。計算同樣的512地圖的pvs資料,原來的演算法需要4.7小時,利用gpu之後縮短到了不到800秒,快了大約20倍。更重要的是從不同尺寸地圖的pvs預處理得到的大致演算法複雜度估計從原來的 n ^ log_2( 48 ),降低到 n ^ log_2( 16 )。另外,新的演算法在誤差上比原來要少很多,只發現幾處距離較遠的patch有幾個象素的跳變,可能是因為預處理用的表面較小(640x480)並且視角較大(pi / 3,實際遊戲使用 pi / 4)
具體演算法:
對於每個pvs單元,就是單個patch的一層,我們稱為乙個unit。每個unit分別朝若干個(我取8個)方向渲染(因為無法一次在螢幕上渲染所有的patch),每個方向:
在unit上平面去若干個攝像機位置取樣點,這裡仍然取4個角及中心一共5個
使用中心攝像機位對所有patch進行視錐剪裁,只留下視錐內的patch,注意這裡要考慮多個攝像機位的情況,所以邊界需要留得大一些。另外對於完全落在視錐內,也就是包圍球整體落在視錐內的patch打上標記,同樣指的是對於多個攝像機位都能完全在視錐內,所以這個邊界需要比單個攝像機更嚴格一些。
全部渲染剪裁後留下的所有patch,得到乙個最終的z-buffer
對所有完全落在視錐內的patch挨個單獨渲染,查詢它的可見性。對於idirect3dquery9介面的使用網上很容易查到,就不贅述了。
如果乙個目標patch對於乙個unit內的所有的攝像機取樣點來說都不可見,那麼就認為它對於該unit是不可見的。注意渲染單個patch時,如果該patch之前已經判為可見就不用再渲染了。
這個演算法有個小缺陷,就是對於乙個unit的某個方向上的渲染,只有那些能完全落入視錐的patch才有機會被判為不可見的(因為如果patch有一部分在螢幕外,你無法判定它是否被遮擋),所以不同的方向之間必須有部分重疊,比如我取每個方向 pi / 3 的fov,一圈共取樣8個方向。但即便如此,仍然會有一些距離攝像機比較近的patch會沒有機會進行可見性判定,也就是說它們是永遠可見的。我粗略統計這個數字大約是30~50個patch,考慮到它們離攝像機很近,本來可見的機率就比較大,所以我認為可以接受。如果要減小這個數字,可以採用更大的fov角或更多的取樣渲染角度。
武俠世界,基於Ogre的地形分析
早期的天龍八部跟武俠世界基本相似。scene 場景的一些基本資訊,包括light,skydome,環境光,霧以及場景中靜態模型staticentity等。摘錄部分檔案如下 terrain 地形的分塊方式,乙個tile由n個grid組成,tile為ogre的mesh,grid不可再分。scale為gr...
實時繪製基於LOD的地形相關技術
lod levels of etails細節層次 是解決大規模地形實時渲染的一項關鍵技術。在地形中實現lod技術後大大加速了地形的渲染。其基本思想是 對地形生成具有不同層次 不同解析度 的多個版本,在繪製地形時依據視點來選擇合適的層次細節進行繪製。本文用基於四叉樹構建的地形來實現相關lod演算法,有...
基於linux的patch生成及使用方法
old.txt為原檔案,new.txt 為已修改後的檔案,現在要做的是 製作patch,更新old.txt檔案 wln localhost 02 cat old.txt 123456 qwert dasfg fdsaf wln localhost 02 cat new.txt 1123456 qqw...