Q1:移動遊戲場景中,相同的怪物,Draw Call會動态合并嗎?如下設定可行嗎?
預設情況下,帶蒙皮的Mesh是不支援動态合批的。如果場景中相同材質的蒙皮網格數量很多,可以考慮通過插件MeshBaker來進行合并,具體方法大家可以參考好插件讓你事半功倍!
Q2:Draw Call和Setpass Call,這兩個名額主要是看哪一個?關于這點衆說紛纭,很多地方都是說看SetPass Call,但是在UWA的性能測試中,還是把Draw Call當成唯一名額。
在 Unity 5.x 中,SetPass Call與 Draw Call相比,SetPass Call的名額與性能相關性更大(比如Static Batching的開啟不影響Draw Call數,而SetPass Call通常會明顯下降)。但 SetPass Call在某些情況下也同樣存在問題,比如往一個場景中添加任意個相鄰且材質相同的大網格物體(使Dynamic Batching失效)時,SetPass Call并不會變化。是以在UWA中,我們所使用的是類似Profiler 中 Total Batches 這一項名額,通常該數值與 Frame Debugger 中的數值基本一緻,是以可以通過該工具來檢視每個Batch的内容,進而更有針對性地進行優化。
Q3:我UWA報告中“渲染子產品”界面中看到大部分場景中的三角面片數是正常的,但在某一幀時DrawCall、Traingle、蒙皮網格數驟然提升,請問這可能是什麼原因導緻的?這三個參數的變化曲線是否有規律?為什麼我在切換場景的時候也會有400多的DrawCall呢?
從圖中看,這種情況發生在場景切換處。這種情況的發生原因很可能為一次性動态加載大量GameObejct,然後再手動Deactive目前并不需要使用的GameObject。研發團隊可以檢視該峰值處的場景名稱和相關截圖,進而來進一步定位發生該問題的根本原因。
Q4:關于Static Batching, 場景中物件組合成大的Mesh,那麼判斷子Mesh要合入大的Mesh中的依據是什麼?材質?勾選Static?
我有一個模型A并勾選Static,使用材質A,怎麼看到也和其他材質的Mesh合并到一塊去了(Combined Mesh)?
勾選Static的GameObject下的Mesh都會被合入CombineMesh(無論什麼材質),且每個Mesh都作為SubMesh存在。在Unity 5.3之前,對于渲染順序相鄰且材質相同的SubMesh則會動态将其索引數組拼合,進而合成一個Draw Call。而Unity 5.3之後則不再拼合索引數組,因為在不切換材質時産生多個Draw Call的開銷并不大,而這多個Draw Call會被統計為一個Batch。
Q5:Unity對Dynamic Batching的數量是否有限制?或者說對Saved by Batch的數量是否有限制?
Unity對于任何Mesh的面片都有65536的個數限制,拼合後的面片數也是如此。
Q6:請教,角色分部件換裝可行嗎?比如衣服褲子分開,都是用Skinned Mesh Render,有沒有辦法合并降低Draw Call?
可以通過合并網格的方式來達到降低Draw Call的效果,具體可檢視Asset Store中的換裝例子:Character Customization。但是,在角色換裝時需要注意以下幾點: (1)裝備與角色必須是共用一套骨骼的; (2)各裝備之間所用的材質必須相同。 開發者需要注意,隻有同時滿足以上兩個條件時,才能達到隻使用少量Draw Call來進行動态換裝的效果。
Q7:請問,Canvas裡的東西移出了螢幕後,DrawCall沒降低,那麼它還會每幀去繪制嗎?
DrawCall沒降低,說明CPU依然将這部分的網格送出到了GPU。是以雖然UI元素已經不可見,但其CPU開銷(包括切換渲染狀态,送出VBO等)依然是在的,隻是對GPU不會造成明顯影響,因為最終并沒有進行像素的渲染。
Q8:能否對提升NGUI的渲染效率提供一些思路?
開發團隊可以從以下幾點入手: 通常一個Panel會産生1個或多個Draw Call,以一個Panel為機關,Draw Call 的數量通常由目前 Panel 中使用的Atlas、Font的數量所決定。 要降低UI渲染時的 Draw Call數量則需要對 Atlas 的制作進行合理的規劃,即在保證使用較少的 Atlas 的同時,還需要保證 Atlas之間不會存在交叉遮擋。 要注意UI Texture的使用,每個UITexture自身會占用一個Draw Call,同時如果其Depth值穿插在了其他來自相同Atlas的UISprite中,還會導緻Draw Call的打斷,造成不必要的額外Draw Call。 另外還可以借助Panel Tool和Draw Call Tool來對UI部分的Draw Call進行分析,前者可以顯示每個UIPanel包含了多少個Draw Call,而後者可以顯示每個Draw Call由哪些UIWidget組成。"
Q9:關于場景中玩家和NPC名字的DrawCall的問題。我們項目中是使用TextMesh挂到場景機關上,但是這樣每個名字就占了一個DrawCall,請問有沒有好的辦法優化呢?
遊戲中的HUD的做法一般有兩種,一種是如上的做法,另一種則是通過NGUI/UGUI來制作HUD。第二種的實作方法大緻如下: 計算螢幕中角色在螢幕中的位置; 根據螢幕中的位置來計算各自HUD的位置,并根據HUD的數量分别放置在一個或幾個Panel/Canvas下。 第二種方法的優勢是盡可能用少的Draw Call數來渲染角色的HUD。開發團隊可以就該方法來進行嘗試。
Q1:這個批渲染是什麼?好像開銷很高 。
從圖中看出,這是場景中不透明物體的渲染開銷。建議研發團隊對當時場景中的不透明物體(地形、建築等)進行進一步檢測,主要檢視其三角面片數是否過高、Shader是否過于複雜等。
Q1:我們遊戲用的是T4M,4層Tilling貼圖+1層融合貼圖,發現手機發熱現象嚴重,影響性能的表現,請問有什麼标準或者參考資料嗎?
對于中低端機器來說,我們建議地形紋理所刷的層數要盡可能小于3層。在中低端裝置中,紋理采樣次數越多,則GPU的壓力越大,發熱效果也就越明顯。 在UWA性能測評報告中,我們加入了針對Graphics.PresentAndSync的統計,進而讓大家來看到項目運作過程中,GPU的壓力情況。同時,在裝置的溫度顯示中,建議大家關注溫度的走勢圖,看看是否存在大幅向下回落的情況,如果存在,則很可能是裝置因為過熱而主動降頻。 Graphics.PresentAndSync耗時統計 裝置溫度走勢
Q1:我們在編譯安卓版本時,在某些裝置上(Sony L36h,小米4)調試時,發現有一個時間消耗項叫Graphics.PresentAndSync,該函數對性能的消耗會特别誇張(渲染20毫秒,這個能達到50毫秒)。查了相關文檔,發現該函數好像和安卓裝置的垂直同步有關,但是大部分安卓裝置的垂直同步是不可以關閉的。請問有什麼好的辦法解決嗎?
概括來說,該值很高表示 GPU 負擔很重,可以從降面,或者簡化shader入手。 Graphics.PresentAndSync 是指主線程進行Present時的等待時間和等待垂直同步的時間。該參數在Profiler中CPU占用通常較高,且僅在釋出版本中可以看到。究其原因,其實是CPU和GPU之間的垂直同步(VSync)導緻的,主要是與項目是否開啟多線程渲染有關。當項目開啟多線程渲染時,你看到的則是Gfx.WaitForPresent;當項目未開啟多線程渲染時,看到的則是Graphics.PresentAndSync。 其中的原理,可以參照我們之前對其函數的詳細解釋:扒一扒Profiler中這幾個“占坑鬼”。
Q1:我們現在有一個場景,Draw Call和面數都在正常範圍内,Camera的距離也和其他場景一樣,但是VBO卻非常高。下圖是該場景的資料情況,該場景下有很多複用的模型,如果不勾選Static那VBO會下降,但是Draw Call會上升。那我能否通過合并模型的方式把VBO降下來呢?
當你勾選Static時,Unity 會将其進行 Static Batching,進而将生成一個較大的VBO來進行渲染,同時降低Draw Call。而如果不勾選時,則引擎無法對其進行Batch,是以VBO會降低,而Draw Call升高。 對此,我們的建議如下: 1、一般來講,降低Draw Call的意義大于降低VBO; 2、在Draw Call較低的情況下,比如目前的50+,可以考慮适當增加一些Draw Call來降低VBO的占用,一方面可以降低帶寬的壓力,另一方面也可以适當降低一些記憶體。
Q1:關于抗鋸齒和BLOOM,有什麼好的優化方案或者優秀插件推薦?
通常在中低端的裝置上,抗鋸齒并沒有比較高效的方案;而對于中高端的裝置,可嘗試直接使用 Unity 内置的 MSAA 功能,但也隻推薦使用 2x。 關于Bloom效果,以下是适用于移動端,且評價較好的一款插件:BloomPro
Q2:如何在移動裝置上,對Bloom和全屏抗鋸齒進行優化?Unity标準資源裡面自帶的效率比較低(已經嘗試過Bloom(Optimized))。
建議使用Asset Store上适合移動端的Bloom Shader插件,比如FxPro: Bloom&DOF和BloomPro等。 對于AA,目前在移動裝置上并沒有特别優化的方法,僅能建議在低端裝置上關閉AA功能,而在高端裝置上可嘗試開啟較低倍數(2x)的MSAA。
Q1:圖中的Material.SetPassFast占用很高,這是我在第一次執行個體化一個特效,但是第二次執行個體化就不會出現高值了,請問能怎麼優化嗎?
該過程是在處理Shader,Unity 5.3以後在第一次顯示時才會将Shader進行Warmup,是以就會造成一次峰值卡頓。研發團隊可以參考我們之前的分享:Unity加載子產品深度解析之Shader篇以加深了解。
Q2:Shader.Parse 和 Shader.CreateGpuProgram 到底是做什麼的?它們什麼時候執行?
Shader.Parse展現的是Shader的加載和解析, Shader.CreateGpuProgram 是将Shader傳入GPU的一次送出,GPU驅動會對其進行編譯,以适應于特定的裝置或平台。在Unity 5.x版本中,Shader.Parse在Shader資源加載時進行執行,而 Shader.CreateGpuProgram在所在GameObject第一渲染時進行執行。
Q1:如下圖,我們發現WaitingForJob這個函數消耗過高導緻了卡頓,請問該卡頓是否由于渲染壓力過大導緻?
從圖中看,該線程最後是在等待 Canvas.sortjob,而這是 UI 排序造成的開銷(自Unity5.2版本開始,UGUI的部分計算已經移出了主線程)。 詳情參考:http://blogs.unity3d.com/2015/09/07/making-the-ui-backend-faster/ 是以理論上,這是 UI 的 canvas.sortjob 在指定的時間上沒有完成,進而使得渲染線程等待,且最終導緻主線程進行等待而造成的開銷。
原文出處:侑虎科技
本文作者:admin
轉載請與作者聯系,同時請務必标明文章原始出處和原文連結及本聲明。