在基於高度圖的遊戲大世界中該怎麼做動態物體的遮擋剔除比較好呢?

前不久請教了不少知乎大牛,做了小場景下的軟光柵遮擋剔除,用了軟光柵+多線程,另外配合了一些自己hack的離線遮擋體提取演算法,效果還不錯,現在我這裡有個大世界的地圖(1000x1000),比較平坦,地形是離線製作的mesh但是我其實可以去提取高度圖,發現在大世界下,如果想遮擋較遠的動態物體,比如人物,軟光柵器就得去渲染範圍相當大的一片地形,性能消耗就是多線程也顯得有點吃力了,畢竟是在手機上,我以前看過有些體素大世界遊戲比如mincraft使用連通性做遮擋剔除,因此對於高度圖地形,我想也許可以更簡單,用這種做法:在提取的高度圖上,從當前相機位置向距離較遠的一個人物發射一條射線,就是做raymarching,如果在高度圖上這條射線被高度所阻擋,那麼就判斷不可見,原理上感覺完全可行,就是想以前比較經典的的引擎比如CE,UE,Gamebryo是否這麼做過呢?其實還是怕自己發明的東西弄出來一大堆坑。。


謝邀。

CE的室外這塊兒當時研究重點不在這塊兒,UE是並沒有針對這個地方的特殊處理的。但都有可以簡化的方案,比如針對大山這類的場合,使用幾個片或替代的低Poly模型來做Occluder(或者題主所說的Logic Trace亦可,但一般不會直接Trace地表,畢竟Trace地形開銷比Trace單個片和Low Poly Convex還是要大多了)。

首先個人認為,剔除類問題有一個前提:

根本的目的是利用快速手段儘可能快排除掉那些不可見物體。

快和排除不解釋,但不可見物體這裡需要強調一點:本身就能看見的物體,就算想辦法優化剔除也沒有意義,必須通過其他遊戲設計手段來優化。

所以這個問題根本上取決於項目的特點,項目本身遊戲系統的設計上是否就已經考慮到了遮擋需求,或者換句話說,如何利用遊戲系統的核心設計目標來同時為遮擋剔除留下足夠的騰挪空間,是最根本的優化。等到需要用到種種優化手段的時候往往已經」背後就是紅場「了,千萬莫把自己逼到這個程度。

那針對題主問題,個人考慮先主要從下面幾個地方開始分析:

1、地貌特點:

就是看遮擋體的密度,單純從地形系統本體考慮,主要遮擋體很簡單,就是山和坑。如果納入Foliage,可能再考慮一些大樹。地形本身山體密度高地貌,比如千針石林、逆風小徑,這種的遮擋體密度顯而易見的就會很高,場景剔除性好。而山體密度低的地貌,比如貧瘠之地、西部荒野,場景剔除性顯而易見就會很低。一般來說以外場景為主的大地圖遊戲,地形一般來說很少會是到處坑坑窪窪,逆風小徑這樣的地形比重也會相對較低,因為外場景大世界從選擇這個表達方式的目的上就更多是為寬闊的視野準備的,強調視野通透性,舒緩節奏。而視野受限區域,節奏壓迫,作為輔助。

所以場景設計之初就應該考慮到這個問題,在平坦的地區採取一些手段,比如主動降低布怪密度,比如經常採用的NPC距離遠就是看不到,或者」不見兔子不撒鷹「,直到主角到來,才突然從天上傘降敵軍、地下跳出敵軍等等。反之,在地形剔除性較好的山地和谷地、則可以布置高密度的怪物,布置玩家的爭奪區域。同時考慮利用任務路線或者其他什麼的方式,將玩家分散開。

而地形這個級別的優化,我所知道的經典的做法是採取在山地區域手插或自動生成虛片或替代遮擋體的方式,生成近似遮擋體,而這些近似遮擋體面數低、數量少,可能視野里一整個山脈,綿延數里,全部Level0下來數百萬面,但近似模型應該也就數百面綽綽有餘。地形起伏畢竟多是連續雜訊,分布不會抖得那麼狠。這個方法對內存的耗費也不是太大。

2、被遮擋體分布

分布密度如果是在三十米範圍內就已經成百上千的物體出去了,這個一般是沒法用傳統遮擋剔除方式來處理的。這個範圍內遮擋體得是個什麼樣的情況才能把被遮擋體給有效剔除掉啊?搞不好一頓剔除下來,發現成百上千個就砍掉了幾十個。真是這種地方的話,最優先的我感覺還是場景設計上趕緊的把這個區域給打隔斷是最合理的做法,比如通過門廊、斷壁殘垣、遺迹,將目標互相隔離開。否則就得考慮用一些比如局部Instancing、動畫Instancing的手段,直接放棄在遮擋剔除上糾結,因為事情已經起變化,主要矛盾已經不在剔除上了。

但如果分布主要集中在遠景,那可以動腦筋的地方就比較多了。結合前面考慮地形本身的地貌特點,轉圜的餘地會比較大。實在不行就在某一級LOD下開啟Instancing機制或者Sprite機制、並砍掉無效材質比如高光、Metallic、AO等分支,不做遮擋,這倆可以把渲染壓力降一些,很可能反而比大規模剔除本身的開銷要小。反正真遠到一定程度,本身顯示上還剩下幾個像素都不一定,而且可能連續幾個幀的移動變化搞不好也就是幾個像素,Instancing和Sprite帶來的硬過渡問題一般來說不會影響體驗,畢竟也沒多少玩家會放著占屏幕有效像素一半的大屁股和當面敵人不管不顧,偏要去挑邊角遠景上那幾個像素的Error嘛。

然後遠景剔除還有個優化方案,遠景物體運動變化相對較慢,同樣一米每秒的速度,一米距離一幀就能明顯感知到,但是100米外一幀就不是那麼明顯了,所以遠景部分物體的剔除,可以分幀執行,而不用像近景這樣必需壓在一幀內來做,這也是一個可以潛在優化的點。

物體密度如果太高,但是分布很有規律,比如有群聚性,那麼還有一種在特定情況下比較有效的手段,就是利用球樹或者特定四叉樹,將一批群聚性物件構築外包圍盒、作為一個Occludee先進行剔除預判,過了剔除預判後再做群內單一物體的剔除,或者乾脆不做剔除開始硬渲。

粗略想到這些,不知道是不是答非所問了。說到這個地步也就多說兩句題外話吧:

個人的感覺:一般來說我們現在做優化,第一個不會首先去看優化技術本身,所有優化技術都是一種等價交換、甚至賠本交換,很少有賺。如果優化技術Match了當前遊戲的核心設計目標,那麼就達到了目的,如果沒有,那就得不償失了,所有優化技術,無一例外,全部」帶傷「,這個地方省掉的,另一個地方一定損失了。

即便優化方案本身不帶任何損失,但它對程序結構、工作流往往也會提出特定的要求!程序本身維護性降低還是其次,更可怕的是因此影響了設計時的方案選擇,使得本來可以通過上層設計解決的問題卻被功能層次的要求給壓倒,整個項目喪失活動空間。這也是為啥人們一直都說」過早的優化就是地獄「的意思。

個人對於自己現在的優化原則,掛在嘴邊的話就是:「不做專門的優化,是最好的優化」,解釋一下:

上策是考慮在系統設計角度就解決問題,這個時候轉圜餘地最大,也是最有效的時候,不治已病而治未病,整個系統設計本身達成一種功能性、穩定性和藝術性的調和,這是最完美的,一開始就不把自己逼到最後要去採取局部優化的路上去。這並不是說不需要用到優化技術,而是在明確遊戲核心設計目標之後,針對性在某些系統上根據核心目標一開始就確定好與核心目標相稱的美術目標和美術技術方案

做這些技術方案的時候也許也會有一些優化技術。比如千人戰,那肯定一開始就要用到Animated Skeletal Instancing技術,但這個首先不是為了做千人戰而去做千人戰,而是遊戲系統整個從劇情、到機制、到表現力,全部把千人戰做成系統核心設計要點時才會去做(一個遊戲不會有太多要點的,會互相衝突、主題也會不突出)。然後也不是一開始就做,一開始先把千人戰的核心數學模型抽取出來,做紙面原型和白模原型,確認千人戰這個確實好玩,適合做成一個產品,然後再去做這個驗證,同時紙面原型和白模原型也可以把周圍除了核心系統資源外還需要什麼給你說清楚:場景規模到底應該是巷戰這種小道還是大平原?場景有木有天氣效果或者其它什麼效果?幾種最極端情況是什麼?這樣一開始依據這些設定的美術標準,80%的問題都解決掉了,根本不會留到最後,最後那點就相對好辦了。除非項目中間發生重大轉折(當然只要不走原型開發,重大轉折那就是常態,前面說的所有這些都完全沒意義,只能跟著感覺走)

中策是利用系統設計,利用規則限制作出美術標準限制。與前者的區別是不去影響設計,而是被動跟著設計走,用玩法規則限制來限制美術標準。這種情況下和諧是沒戲了,統一還是可以的,而且仍然有輾轉騰挪的空間。麻煩的是國內這種不做原型開發的環境下,設計往往幾個月就變,美術標準也被迫會需要經常與時俱進。但無論如何,到這個層次都還有一定的餘裕。

下策則是設計導致的性能衝突點未被預判,在鋪量階段爆發問題後被動應對。這個情況下,由於整個戰役已經全面鋪開,所有部隊和資源都已經投入,搞不好預備隊都上了,這個情況下的優化,往往是毫無空間,只能硬肛正面,最後的結果一定是舍A求B,做各種帶傷優化。比如縮貼圖、砍面數、削動畫、砍視野……所謂什麼藝術性和實用性的統一,在這種情況下根本就不現實!不傷及藝術表現力的核心,就已經可以燒高香了!就不要說受折磨的感覺,被這種優化拖死掉的項目都有不少,到這一步基本是聽天由命了……

所以我個人還是建議樓主先從遊戲系統的設計角度考慮問題。比如怪物密度、物件組織結構、數量和差異性的平衡這些問題。特別是先把實際遊戲原型跑起來,大概知道物件密度和地形大體的地貌起伏,然後再考慮根據這些特點來評估設計和具體的表達方案。很有可能的情況是,等這些東西鋪進去的時候,您會發現瓶頸完全沒有在剔除這一點。

說實話,我個人的經驗,過去做過的所有大場景項目,地形本身的剔除一直都不是最大的丟分點遊戲系統設計合理的情況下,開啟關閉地形剔除帶來的優勢多數情況下並不大。前面也說了,外世界大場景從這個表達方式上就先天需要開闊作為主體驗,場景開闊了,能看見的就是能看見,剔除做得再高效,也不可能把本來就能看見的東西給剃掉,更何況剔除本身還要吃掉性能。

最近幾年很少關注大場景優化技術方面的信息了,可能已經落後很多,以上僅代表一家之言,若有顧慮不周,萬望多多包涵。

順祝好運!


謝邀,先簡單回答一下。

看過cry engine的實現,關於地形的剔除,其實就是你說的這種高度圖"Ray marching",將bbox投影的四個點,於視點做四條射線,分成不等可配置的步長,與高度圖比較高度來"求交"

當然這是初篩,篩剩下的還是會有軟光柵化等高級剔除。

粗答一發,先明確題主想法的正確性,有時間可以詳細寫寫!


  1. 地形的software rasterize不是直接光柵化地形 而是用raymarching的方式 ,計算出每個像素的地形的深度值,這樣計算複雜度是相對固定的,不會因為需要光柵化的三角形過多而增加跟多開銷
  2. 手機上software rasterize比pc要慢很多 因為cpu差,雖然有neon可以加速,但比pc上的SSE慢不少,之前試過移動voxel類型的遊戲做depth 的 software rasterize,也用raymarching的方式, 雖然某些情況下能把draw call降到很低,但做software rasterize的開銷差不多和降draw call的開銷持平


推薦閱讀:

OpenGL適合用來加速圖像處理嗎?
請問光柵化與渲染這兩個術語的區別和聯繫是什麼?
如何評價蘋果在 WWDC 2017 更新的圖形 API Metal 2?
影視渲染和遊戲渲染的區別?
斐波那契數列 費馬螺旋 如何在AI畫出向日葵生長規律圖形?

TAG:遊戲開發 | 渲染 | 計算機圖形學 | 虛幻引擎 | 計算幾何 |