遊戲渲染效能最佳化,渲染效能最佳化
忘記了以前是不是寫過類似的文章了,不管了,結合近幾年經驗總結一下。
先從最核心的部分開始。如果熟悉圖形API的朋友都應該可以理解,要想渲染一個模型,我們至少需要做兩個操作,設定各種狀態,調用繪圖函數。這兩個操作都會引起效能損失。我們分頭來說
先說設定各種狀態。都什麼狀態呢,比如使用什麼紋理,是用什麼著色器,是否開啟Alpha測試,是否雙面顯示,是否使用混合以及怎麼混合,等等。我們可以管這些狀態統稱為材質。這些資訊通過調用圖形API,再通過驅動進而設定給顯卡。這需要時間,而且有些狀態改變很耗時。
那麼如何最佳化呢,問題出在哪就在那裡解決,簡單來說就是儘可能減少狀態的改變!
對遊戲而言引起狀態改變比較多的首先是紋理的不同,這也是為什麼要講求紋理打包。舉個例子,有三個模型,分別對應三張貼圖,那麼渲染這三個模型時勢必會分別為他們設定三次紋理,這就造成了紋理狀態的改變。如果把這三個模型的紋理放到一張紋理上之後,只需要設定一次紋理,然後分別渲染他們即可,這樣就省掉了兩次切換紋理。同樣的道理也適用於Shader。
如果是自研引擎的話,可做的事情可以更多
1.抽象出一層圖形API層,在其中做好狀態緩衝,當同樣API被調用多次且內容一致時,只有第一次會真正去調用圖形API.
2.做好材質排序,並給予材質進行渲染。簡單來說情境裡面有很多模型,他們有相當一部分材質相同,那麼把使用相同材質的模型收集起來,設定一次材質,然後逐個進行渲染。
3.要搞清楚不是所有狀態改變代價都相同,而且完全相同的材質也會比較有限,所謂材質排序只是排序那些切換代價比較大的狀態即可,比如紋理,比如Shader等。
接下來再說調用繪圖函數本身,一次調用就是一次DrawCall.
這個函數不用多說,它內部進行各種設定後就開始渲染了。要想最佳化他就需要搞清楚現代GPU的一些特性。
現代GPU一般都可以一次渲染大量多邊形,但是對drawcall數量較為敏感。PC上3000個以上就會顯著影響效能了,手機上不要超過200個為好。與此同時雖說一次可以渲染大量多邊形,但其也是有限度的,不是越大越好。如何平和drawcall數量以及單次渲染多邊形的數量成為了關鍵。基本的方法就是根據具體情境情況,適當合并模型。
如果是自研引擎的話,可以做的事情可以更多
1.更有效情境管理以及篩選方法,使送入渲染引擎的多邊形數量最少
2.使用執行個體(移動平台上只有GLES3以上才支援)
總結以上兩點就是,儘可能少的狀態改變,儘可能少的DrawCall!
其他
目前手機上送入圖形API進行渲染的多邊形儘可能控制在10w三角面以下,如果考慮適配幾年前的機型,那麼這個數量還要再低!
能用LightMap表現的就不要用即時光,而且目前也很難大面積高效能的使用!
Shader要儘可能演算法簡單,能在VS階段算的就不要放在FS上算。也不要是用什麼pow這樣的函數。
終極最佳化
有時候技術人員想破腦袋也搞不定的最佳化,也許美術人員三兩下就在max裡面搞定了。
有時候技術人員和美術人員想破腦袋也搞不定的最佳化,也許在策劃那邊稍微改變一下要求就搞定了。
說到底是還是遊戲開發各個環節上的人員要多溝通!