Unity引擎後處理效能優化方案解析

2021-08-28 01:09:41 字數 3341 閱讀 2341

作者主頁:

作者也是u sparkle活動參與者,uwa歡迎更多開發朋友加入u sparkle開發者計畫,這個舞台有你更精彩!

目前我們專案使用的後處理外掛程式是unity-technologies/postprocessing。選用前,我們對比過眾多後處理外掛程式,最後根據效果和使用方便程度,結合策劃的需求,選用了unity-technologies/postprocessing(我用的v1,大家可以嘗試v2版本)。這裡我們不討論後處理的效果,或者哪個外掛程式的好壞。本文將介紹乙個能通用的後處理效能優化方案。

在我們看到的後處理教程或者後處理外掛程式中,通常的處理方式是在onrenderimage方法中處理後處理。

在我剛開始整合後處理的過程中發現,即使不做任何後處理,僅僅一句graphics.blit(source, destination),也會導致嚴重的掉幀,這看起來是不符合邏輯的。在google後,找到問題的說明post process mobile performance : alternatives to graphics.blit , onrenderimage,原因如下:

答主給的解決方案如下:

也就是在onprerender中,將rendertexture賦值給camera,在onpostrender中處理後處理渲染。

通過這種方案能大幅度減少掉幀。我們測試過用同樣的後處理(例如bloom)在使用onrenderimage的時候,從60fps掉到40fps左右。改用prepost方法後,從60fps掉到55fps左右,改善明顯(用中低端手機測試效果明顯些,我們是用的360手機。不同手機改善的程度略有差異,但是還是能看到至少幾幀的提公升)。相信這個優化方案,有不少同學之前已經看到過並已經在使用。

這個方案略有麻煩的一點是,當我們的camera開啟msaa或者hdr的時候,會導致後處理不起效果。我猜測應該是msaa和hdr會啟用unity引擎內部的渲染流程必須走onrenderimage。

這裡要特別注意的一點是,我們用的是gamma color space,如果我們要hdr的效果,最好不要用prepost這個優化方式,因為經測試會導致負優化,幀數反而下降。目前我還沒找到好的辦法,這裡我們按照不需要hdr效果來說。

我們還是可以支援msaa,解決方案是,根據qualitysettings.antialiasing和我們的方式來建立temp的rendertexture。同時,我們需要關閉攝像機的msaa和hdr選項。

這裡要注意處理的邏輯是:當我們在遊戲設定介面開關後處理的時候,要配對地處理camera的msaa選項和rendertexture的建立引數,以免出現後處理不起作用,或者關閉後處理後,抗鋸齒沒有正確開啟的問題。

這應該是乙個能立竿見影的優化,相對需要注意處理好一些細節和各種設定切換的處理,做好測試。

當我們使用unity引擎早期的image effect,或者一些單個效果後處理外掛程式的時候,他們通常沒有考慮整合的效率問題。以onrenderimage的做法舉例:通常是每個效果是乙個指令碼,它有自己的onrenderimage,如果我們有4個效果,那就是4個單獨的onrenderimage,這在**層面的簡潔性和易擴充套件性上,當然是有優勢的。但是這樣做效能是有問題的,我們需要盡量將各種後處理效果,整合到同乙個onrenderimage(或prepost方法)中,這樣能帶來一些效能提公升,雖然不如上面的prepost效果明顯,但是優化是一點點積累的,也是值得做。

具體方法,unity-technologies/postprocessing這個就比較有代表性,它將所有的效果整合到同乙個onrenderimage和同乙個shader中處理,只是通過材質的enablekeyword來開關對應的功能。詳細請看鏈結裡的**。

這裡提一句,如果用prepost方式優化,將不能和onrenderimage方式在同乙個camera下混用,這裡整合的時候,要根據專案的需求處理好。我們現在是用unity的 post processing方案,改為prepost的方式。

同時,大家使用各種後處理外掛程式、效果,要注意根據需求做一些裁剪,某些不需要的效果盡量注釋或刪除,讓整合的**更加清晰可讀,也減少一些額外的效能消耗(shaderlab記憶體等)。

通常的例子**中,會使用string作為key的方式來修改mat的屬性,很多shader的外掛程式內也是這麼用的。

string的方式

這裡,我們通過反編譯可以看到,string的方式實際上會呼叫shader.propertytoid,所以,我們應該將整個id cache下來,通過id的方式來呼叫。

這也是乙個很小的點,但是如果是後處理這種,可能每幀都會呼叫的地方,所帶來的優化效果還是很有意義的。

還有一些優化,比如減少rendertexture的尺寸等,在網上很多關於優化的文章中都有提到,就不具體說了。

總結一下,主要的優化就是onrenderimage轉換為prepost的方式,能大大地改善後處理的渲染效率(opengles2和opengles3都測試過)。我們使用的unity版本是5.6.4,其它版本未測試,如果用其它版本,大家需要自己先測試一下。

無論優化多好,後處理始終對效能影響很大,特別是手機電量不足或者發熱導致手機降頻的時候,後處理將會導致掉幀加重。如果必須要使用後處理(策劃,美術要求),那麼做好效能開關、優化好後處理的效能是必須要做的。

最後說明一點:prepost的優化方案只有在不需要hdr效果下才有優化效果(基於我的測試),如果需要hdr效果,還是用onrenderimage來做吧。這塊優化需要多多測試,不注意就容易出問題哦。

參考文章:

1.post process mobile performance : alternatives to graphics.blit , onrenderimage ?

2.onrenderimage() is slow when msaa is on

近期重磅 | 他們說「這個工具省下的時間可不是一點點」

Unity 後處理效果的優化嘗試

主要是在最近工作中的一些心得體會。後處理效果的效能問題主要在 1.螢幕每個畫素都要進行計算。2.可能會建立多張rendertexture的空間占用。3.多次blit操作,比如高斯模糊多次迭代。4.偶爾還需要新建攝像機渲染到rendertexture。優化提公升效能的思路也比較簡單,不過要結合具體後處...

Unity3D物理效能優化

unity3d物理效能優化 unity所用的nvidia physx物理引擎目前可用於ios系統上,但是在移動平台比台式電腦上更容易達到硬體的效能極限。優化物理使其在ios上得到更好的效能 首先,可以調整的固定的時間步長設定 在時間管理器內 來減少物理更新上花費的時間。增加時間步長將減少花費在物理準...

c 程式大資料量處理效能優化

1.現在處理的程式為每秒鐘處理20w條資料,甚至更多,加快處理速度,總結了一些經驗,記錄下來 程式的資料結構裡面盡量避免string,map這樣的資料結構,因為string雖然不用自己管理指標,但是在構造和析構的時候很費資源,還有在執行c str 的時候要new出一塊記憶體來,這樣的頻繁執行的程式塊...