1)使用GPU Instancing屏幕花屏問題
2)如何優化AssetBundle大小
3)如何使用GPU Skinning提高性能
4)iOS上Shader裏tex2D採樣偏移的問題
5)如何管理銷燬拍攝的內置深度圖html
Q:機器:魅族MX5
Unity版本:2019.1.5f1
渲染設置:OpenGL ES3,Dynamic Batching,GPU Instancingwindows
問題表現:場景有時候會忽然花屏隨機閃爍, 經過排除法發現是在渲染其中一個樹的時候致使的(樹的材質勾選了GPU Instancing,只要不渲染這個樹就不閃爍)。 數組
嘗試改變渲染設置:僅關閉動態批處理或者GPU Instancing就都不花屏了, 二者同時存在就會花屏。多線程
不知道這是Unity的Bug仍是魅族機器有問題。編輯器
A:根據題主提供的信息,咱們作了如下嘗試。
測試機:魅族5; 對比測試機:小米6
測試場景:客戶提供測試現象:
魅族5開啓了Dynamic和Instancing,會花屏,UBO數組長度爲2,有Log報錯。函數小米6和OPPO K1均不花屏,UBO數組長度均爲128,無Log報錯。工具
魅族5在RenderDoc的數據:
當開啓GPU Instancing的時候,在Vertex Shader裏面會有2個UBO(Uniform Buffer Object)。性能
它們的內容分別以下:
測試
第一個記錄的是SH函數的係數,第二個是每一個Instance的變換矩陣。優化
在魅族5上面數組長度爲2,能夠理解爲魅族5不支持Instance。而在小米6和OPPO K1,是支持128個Instance的,以下圖所示:
說明它們是支持Instancing的。
在移動平臺上,一個Buffer的大小上限是16KB,一個Instance須要記錄ObjectToWorld和WorldToObject的矩陣,總共是16x4x2=128 Byte,因此總的Instance上限數量是16x1024 Byte/128 Byte = 128。
從RenderDoc上的信息裏面能夠看到確實是長度爲128的數組,而在魅族5上面只有2。
並且在魅族5上面運行測試場景的時候,經過Logcat能夠看到會有報錯的Log:
GLSL: unexpected struct parameter 'unity_Builtins2Array1.unity_SHCArray’
GLSL:unexpected struct parameter 'unity_Builtins0Array1.hlslcc_mtx4x4unity_WorldToObjectArray[這兩個正是Instancing須要的UBO裏面的數據。
還有一點須要說明的是,在測試場景中,使用的是239個三角形的那個Mesh,在魅族5上面一樣會花屏。不論有沒有開啓Dynamic Batching,都會有上面的報錯,因此本質上是魅族5不支持Instancing致使的。
建立了一個場景,場景中有3棵相同的樹,並且開始了Instancing,能夠看到OpenGL使用的接口是glDrawElements。在小米6上調用的接口是glDrawElementsInstannced,以下圖:
沒有對模擬器進行測試,理論上是同樣的狀況。
該回答由UWA提供
Q:咱們AssetBundle超過3.8G了,也作了分類,可是資源太多致使總大小超過3.8G,不少玩家安裝不上。有沒有相關解決思路?
A1:隨着硬件的發展,玩家對畫質要求的提升,基本上包體愈來愈大是必然的,關鍵仍是看大的是否合理,基本上能夠順着幾個點去檢查下。(1)首先使用UWA的資源檢測工具看下是否AssetBundle內重複資源過多,若是有,能夠根據檢測結果調整,並按期提交UWA測試。
(2)配合一些資源分析的工具在編輯器內人工的工程內部資源大體過一遍,看看是否有冗餘的資源。這點仍是很常見的,隨着遊戲開發版本不斷迭代,常常會出現以前作的一些東西被推翻了或者大改了(策劃或美術須要),這時候就會產生一些資源可能沒有被用到可是仍然留在工程中,若是打包時沒有相應地去掉,就會有無用的資源進版。
(3)檢查資源導入是否合理。好比:貼圖是否使用了正確的壓縮格式,動畫文件是否進行了合理的壓縮,打圖集是否合理,圖集裏是否有大量的浪費等等。
(4)若是通過檢查仍然沒有什麼進展,那隻能說大家的項目真的須要這麼大的資源包,爲了讓用戶能有較好的遊戲體驗,能夠根據偉昊說的,規劃一部分資源在啓動後下載。這塊能夠結合產品須要,作成啓動後一次性下載完或者根據遊戲進程一部分一部分下載。
感謝範君@UWA問答社區提供了回答A2:說一個資源重複可能有些人沒注意到的點,就是同一份資源常常被更名放到不一樣的地方被不一樣的資源引用,通過實際檢測,這個重複量大過了個人預測,你們能夠自測一下本身的項目。
感謝noah@UWA問答社區提供了回答
Q:咱們的遊戲參考了UWA Blog上的那篇《GPU Skinning加速骨骼動畫》,發現真機環境幀數提高不是很明顯,連上Profiler發現開啓/關閉GPU Skinning總批次竟然沒啥變化,SetPass Calls卻是變化明顯,在編輯器切到Android平臺我測試過總批次會提高100+,有點奇怪爲何到了Android真機裏沒什麼變化?
PS:原來角色動畫Animator + SkinMeshRenderer,使用GPU Skinning後換成了MeshRenderer同時把Animator勾去掉的。
A:可汗文章中單純的GPU Skinning並非去下降渲染Draw Call的,只有結合GPU Instancing纔會下降Draw Call。GPU Skinning最主要下降的是Animators.Update和MeshSkinning.Update的耗時,若是在使用後,你發現這兩個值沒有變化或者優化不大,那麼十有八九是用法不對。下圖是咱們在UWA DAY 2019《如何根據UWA制定技術選型》時作的具體的性能測試,裏面講解了多種不一樣方法所能達到的收益和限制,題主有興趣能夠詳細查看。
同時,咱們將以前作過的一些定量測試放在這裏,但願你們對於GPU Skinning帶來的性能改變有更爲定量的理解。
經過GPU Skinning方式
該方法是徹底摒棄Unity引擎的MeshSkinning和Animator模塊,自行對蒙皮網格進行採樣,將骨骼結點的矩陣信息以紋理的方式進行儲存,而後在GPU中完成頂點計算並直接進行渲染。優勢在於極大地下降SkinnedMesh.Update和Animator.Update的CPU佔用。將骨骼結點信息經過紋理來進行儲存,於是數據量較之方案兒會大爲下降。
開源庫下載連接:
https://lab.uwa4d.com/lab/5bc6f85504617c5805d4eb0a測試場景:
建立相同案例,場景模型數量分別爲50和200,各自測試1000幀,播放Walk動畫。結果:
該方案測試效率以下圖所示,除Camera.Render外,MeshSkinning.Update和Animator.Update已經消失,但增長了GPUSkinning.Start和GPUSkinning.Update函數。經過分析可知,在紅米Note2設備上,開啓多線程渲染功能,測試幀數總計1000幀,50個模型的CPU平均耗時0.6ms;200個模型的CPU平均耗時1.6ms。
圖1:使用GPU Skinning方案後,紅米Note2上的Top10 CPU佔用狀況使用GPU Skinning方案後,紅米Note2上的Camera.Render耗時狀況。
圖2:50個模型
圖3:200個模型使用GPU Skinning方案後,紅米Note2上的50個模型時的Camera.Render耗時狀況。
圖4同時,GPU Skinning.Start和GPU Skinning.Update耗時在遊戲運行過程當中很小,如圖5所示。
圖5:GPU Skinning.Start和GPU Skinning.Update耗時在遊戲運行過程當中的CPU耗時總結:
(1)該方案能夠大幅下降Animators.Update和MeshSkinning.Update的CPU耗時,同時內存佔用較小小。以r_gunman模型爲例,其全部動畫文件時長8秒,若是採樣率爲30fps時,經過紋理來進行記錄,只須要128x128的紋理便可獲得更爲精細的動畫數據;
(2)該方案對於GPU的壓力更大,須要研發團隊對GPU方面的壓力進行進一步權衡。
該回答由UWA提供
Q:我是用世界座標去採樣一張Filter Mode爲Point的紋理,PC和Android真機上採樣是正確的,Mac和iPhone7/7Plus上採樣結果產生了偏移。
PC上的截圖(分別爲輸出UV和輸出採樣結果):
Mac上的截圖:
注意看網格線的對比,Mac上的採樣圖出現了偏移,但UV是正確的(爲了方便觀察,UV進行了縮放,採樣是用未縮放的UV)。
有人碰到過相似的問題嗎?怎麼處理的?
A1:問題根源並無找到,目前採用了一個取巧的方案繞過該問題。本來需求就是用世界座標採樣一張Filter Mode 爲Point 的紋理,所以直接在Shader中棋盤化採樣點,僞代碼:
float2 uv = floor(worldPos.xz / rectSize) / texSize.xy + 1.0 / (3.0 * texSize.xy);
(rectSize 爲棋盤格子的大小;texSize 爲採樣圖的大小)最後加的那個值(1.0 / (3.0 * texSize.xy))是測試發現若是沒有該值,PC採樣結果和Mac下會有誤差,所以加上了三分之一個單位的偏移。
感謝珂@UWA問答社區提供了回答A2:應該和這個問題相似吧,不過half pixel offset好像是bilinear filter纔會有的,point可能也有不一樣平臺採樣結果不同的問題。
https://docs.microsoft.com/zh-cn/windows/win32/direct3d9/nearest-point-sampling
能夠看看上面兩個連接有沒有幫助。
感謝noah@UWA問答社區提供了回答
Q:在同一個場景我前後使用不一樣的攝像機不一樣的角度拍攝深度,那麼應該獲得多張不一樣的深度圖,我想了解Unity對這多張深度圖是怎麼管理的?好比:我只保留其中一張,其它的深度圖都不須要了,我該怎麼處理?
A:Unity默認渲染管線是多相機共享RenderTexture的方式,即多個相機逐一使用公共的CameraDepthRenderTexture繪製,每一個相機繪製完是否Clear,取決於你下一個相機的ClearMode。至於RenderTexture的內存分配和管理,與你全部的相機是否開啓繪製深度有關,所有關掉繪製深度底層會釋放掉RenderTexture。若是要保留一張給下一幀使用,那麼建議拷貝出來,這樣不會影響下一幀其它相機使用。
感謝Wangtao@UWA問答社區提供了回答
今天的分享就到這裏。固然,生有涯而知無涯。在漫漫的開發週期中,您看到的這些問題也許都只是冰山一角,咱們早已在UWA問答網站上準備了更多的技術話題等你一塊兒來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之「石」,也能攻你之「玉」。
官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com
官方問答社區:answer.uwa4d.com
UWA學堂:edu.uwa4d.com 官方技術QQ羣:793972859(原羣已滿員)