【厚積薄發】Unity Batches與glDrawElements的關係

2021-02-20 侑虎科技

這是第222篇UWA技術知識分享的推送。今天我們繼續為大家精選了若干和開發、優化相關的問題,建議閱讀時間10分鐘,認真讀完必有收穫。

UWA 問答社區:answer.uwa4d.com

UWA QQ群2:793972859(原群已滿員)

本期目錄:

Q:Unity裡用FrameDebug顯示DrawCall是422個,Batches是435個,在SnapDragonProfiler裡抓取出來glDrawElements數目是1449個,怎麼理解這種差異?


A1:可參考以下幾點:

1. 題主的數據有一點問題,DrawCall數目應該大於等於Batches。根據特定的規則,多個DC可以視為一個Batch,一個Batch中包含多個DrawCall,節省了一部分CPU提交數據的操作。

2. 調用glDrawElements函數進行繪製就是DrawCall的一種形式。

感謝Vest@UWA問答社區提供了回答

A2:這部分可以參考UWA DAY 2020裡張強老師的分享《Unity移動遊戲項目優化案例分析(上)》(https://edu.uwa4d.com/course-intro/1/197)中的第二小節。


感謝範君UWA問答社區提供了回答,迎大家轉至社區交流:

https://answer.uwa4d.com/question/5f33b10e9424416784ef1bdd

Q1:渲染大面積草地時,如何降低消耗?


A1:有以下幾點:

1. 使用DrawMeshInstance。

2. 上面這個API是不會進行視距剔除,視錐體剔除和遮擋剔除的。

下面有兩種方案:

a. 將草地按區域分組,用每組的中心點計算視距,依據距離切換網格LOD或剔除。

還能用向量點乘簡單剔除在相機後方的草地。(注意臨界問題)

b. 藉助CullingGroup。

CullingGroup.onStateChanged事件綁定,通過事件觸發調整傳入DrawMeshInstanced的Matrix順序和渲染數量。(比較難的是,DrawMeshInstanced只能指定渲染前幾個Matrix)

通過cullingGroup.SetBoundingSpheres實現視錐體剔除和遮擋剔除;

通過cullingGroup.SetBoundingDistances實現視距剔除和LOD;

這個方案也最好進行區域分組,不然CullingGroup的事件監聽佔用會比較高。中端機上4000個監聽會佔約2ms。

以後如果有對比兩種方案的性能,我再進行補充。

附:

《CullingGroup API的使用說明》

https://blog.csdn.net/foxyfred/article/details/74357093

《Unity 3D研究院之Lightmap支持GPU Instancing》

https://www.xuanyusong.com/archives/4640

《如何高效使用GPU Instancing技術來進行草叢渲染》

https://edu.uwa4d.com/course-intro/0/78

《Unity2018升級DrawMeshInstanced不生效》

感謝題主李先生@UWA問答社區提供了回答

A2:可以使用Indirect模式的Instancing,配合ComputerShader實現視錐剔除和遮擋剔除。

感謝鄒春毅@UWA問答社區提供了回答

A3:推薦一個使用URP製作的草海效果,親測可在Mobile端使用。

Unity URP Mobile Draw Mesh Instanced Indirect Example:

https://lab.uwa4d.com/lab/5f1f503e0f247485d93d9016

性能測試:

can handle 10 million instances on Samsung Galaxy A70 (GPU = adreno612, not a strong GPU), 50~60fps, performance mainly affected by visible grass count on screen(draw distance = 125)

can handle 10 million instances on Lenovo S5 (GPU = adreno506, a weak GPU), 30fps, performance mainly affected by visible grass count on screen(draw distance = 75)

感謝Vest@UWA問答社區提供了回答,迎大家轉至社區交流:

https://answer.uwa4d.com/question/5e919a528cabe84a011afcde

Q:HUD為什麼會隨著攝像機偏移?

代碼如下:

    Vector3 midVe1   = obj.transform.position;
    Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1 + new Vector3(0, 2, 0));
    viewPose.x *= Screen.width;
    viewPose.y *= Screen.height;
    hud.anchoredPosition = viewPose;

圖片如下:

A:題主說的這現象是合理的。

Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1);
Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1 + new Vector3(0, 2, 0));

這兩個算出來的viewPos.x是不一樣的。所以可以改成先算x,再偏移y。大概是這樣:

Vector3 midVe1 = obj.transform.position;
Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1);        
viewPose.x *= Screen.width;
viewPose.y *= Screen.height;
viewPose.y += 130;
hud.anchoredPosition = viewPose;

這裡面y方向上的偏移值(130)就要自己調整了。

感謝Xuan@UWA問答社區提供了回答,迎大家轉至社區交流:

https://answer.uwa4d.com/question/5f804eff9424416784ef2587

Q1:針對Unity中如何在豎屏模式的UI之上顯示強制橫屏的UI,我們現在有兩種思路:

1. 改Screen.orientation之後再顯示。

2. 將新UI旋轉依z軸轉-90度顯示。

請問,兩者哪種更好呢?

A1:一個簡單的方式:

Canvas的RenderMode改成World Space,管它攝像機怎麼裁剪,UI畫布也不會發生變化。

如果自適應不了,在Canvas上根據你自己的需求做好自適應就好。

感謝鄭驍@UWA問答社區提供了回答

A2:我們之前項目裡剛好有個類似的需求,在橫屏遊戲中,個別玩法切換到豎屏。

當時採用的解決方案是修改Screen.orientation,同時修改UI全局根節點上的CanvasScaler的referenceResolution(豎屏時設置為1080,1920,橫屏設置為1920,1080),matchWidthOrHeight(和項目的適配策略相關,豎屏時設置為0,橫屏時為1),切換時會有一個全屏遮罩的fade效果,來避免切換時顯示錯誤。

感謝範君@UWA問答社區提供了回答


Q2:請問為什麼不考慮轉90度的做法?


A:我們當時沒有測過旋轉的方案。現在大概想想有兩個問題:

1. 單純旋轉角度應該只能在橫屏的中間部分顯示一個豎屏界面吧?感覺還需要其他處理。

2. 對工作流是否有影響,如果要一個豎屏界面是否是要在製作時先做成一個橫屏界面?內部控制項是否要處理?例如最終呈現出豎屏效果的劇情文字從左到右出現,旋轉之前應該是橫屏的從下到上出現,同時每個單一文字也是旋轉的。

感謝範君@UWA問答社區提供了回答

Q3:RectTransform的尺寸會被延遲修改這件事, 沒有造成什麼問題嗎?


A:印象中沒有遇到什麼大問題。不過我們當時這類需求切換時都是全屏UI,加了遮罩Fade後沒有什麼明顯的穿幫。


感謝範君@UWA問答社區提供了回答,迎大家轉至社區交流:

https://answer.uwa4d.com/question/5f8166d99424416784ef25b0

Q:我在Xcode真機調試中發現能耗始終處於Very High,而我項目的基本情況是(每幀GPU渲染3.5ms,每秒60幀,渲染解析度為750*1624,設備iPhone XS,場景中只有UGUI沒有其它3D或2D物體),麻煩大家幫忙看看這個電量消耗屬於正常嗎?還有沒有優化的空間(幀數和解析度估計是沒有辦法下降了,會影響項目效果),謝謝。

A1:測試過空場景Average Energy Impact也會顯示Very Hight(如下圖),題主的GPU能耗佔比較大說明CPU相對而言還是壓力比較小的:

這個帖子(https://gamedev.stackexchange.com/questions/177867/high-energy-consumption-in-empty-scene-unity-ios)也是類似的問題,看上去是因為Unity引擎本身相對於普通APP體量較大,所以能耗表現較高,降低目標幀率會有所改善。

Energy Impact表徵的是全局(非單個APP)的能耗,而且測試的時候USB連接充電是如何在統計中避免的不太清楚機制,建議使用Xcode Instruments工具的Energy Log模版測一下單個APP的能耗情況。

Energy Log文檔:

https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/MonitorEnergyWithInstruments.html

關於能耗的優化先關注整體的是GPU還是CPU(或其他方面),GPU的用FrameCapture定位一些比較高耗時的Shader進行優化,CPU結合Time Profiler模版定位一些高能耗的CPU Bound。

感謝羽飛@UWA問答社區提供了回答


A2:GPU的用FrameCapture定位一些比較高耗時的Shader進行優化。關鍵是Capture哪一幀,這個會很盲目。

感謝山中千年@UWA問答社區提供了回答,歡迎大家轉至社區交流:

https://answer.uwa4d.com/question/5f81af2d9424416784ef2642

封面圖來源於網絡

今天的分享就到這裡。當然,生有涯而知無涯。在漫漫的開發周期中,您看到的這些問題也許都只是冰山一角,我們早已在UWA問答網站上準備了更多的技術話題等你一起來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之「石」,也能攻你之「玉」。

官網:www.uwa4d.com

官方技術博客:blog.uwa4d.com

官方問答社區:answer.uwa4d.com

UWA學堂:edu.uwa4d.com

官方技術QQ群:793972859(原群已滿員)

(長按識別二維碼進入UWA問答)

UWA發布 | Unity手遊性能藍皮書

近期精彩回顧

【學堂上新】移動遊戲開發核心技術講解

【萬象更新】3分鐘就能掌握的視頻/音頻優化技巧

【學堂上新】Linux三劍客與Airtest的應用

【學堂上新】Console級寫實畫面遊戲的技術探索之路

相關焦點

  • Students Start Return to School in Phases & Batches This Month
    The provincial novel coronavirus pneumonia prevention command headquarters has decided that students of all levels of schools in the province will return to school in phases and batches starting from April
  • 【厚積薄發】Airtest工具在使用時的卡頓問題
    [RPC] private object IsModuleVisible(List<object> param)然後air代碼裡添加:from poco.utils.simplerpc.utils import sync_wrapperfrom poco.drivers.unity3d
  • 【厚積薄發】CommandBuffer的GPU開銷
    測試工程(CBTest.unitypackage)已經上傳至UWA問答社區。感謝張言豐@UWA問答社區提供了回答,歡迎大家轉至社區交流:https://answer.uwa4d.com/question/5c90b148276f530b35fdd6deQ:Unity官方教程(https://docs.unity3d.com
  • 【厚積薄發】LWRP+UGUI使用方式
    參考了以下文檔:https://docs.unity3d.com/Manual/SL-PlatformDifferences.htmlhttps://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html
  • 【厚積薄發】如何通過Timeline的形式實現技能編輯器
    該問答由UWA提供A2:可參考官方的Timeline擴展,2017年Unite也有個相關的主題:https://assetstore.unity.com你可以參考幾個Unity 的插件:https://assetstore.unity.com/packages/tools/animation/cinematic-sequencer-slate-56558 推薦SLATE,擴展起來比較方便:https://assetstore.unity.com/packages/tools/animation
  • 【厚積薄發】如何在Editor中監聽Prefab修改後Auto Save的事件
    推薦看這篇文章,對於Unity動畫文件裡的曲線保存方式和相關選項做了細緻的描述:http://nfrechette.github.io/2017/01/30/anim_compression_unity5/總體來說,Optimal就是讓Unity自動選擇最優的曲線表達方式,從而佔用最小的存儲空間。
  • 【厚積薄發】使用GPU Instancing屏幕花屏問題
    而且在魅族5上面運行測試場景的時候,通過Logcat可以看到會有報錯的Log:GLSL: unexpected struct parameter 'unity_Builtins2Array[1].unity_SHCArray』GLSL:unexpected struct parameter 'unity_Builtins0Array[1].hlslcc_mtx4x4unity_WorldToObjectArray
  • 【厚積薄發】Unity中紋理格式探究
    A:升級到2018.3https://issuetracker.unity3d.com/issues/renderpipelinemanager-dot-cleanuprenderpipeline-increasing-alocated-memory-every
  • 【厚積薄發】Android 10系統下的PSS數值統計不準
    我們發現Unity新推出的Scriptable Build Pipeline(https://docs.unity3d.com/Packages/com.unity.scriptablebuildpipeline@1.10/manual/index.html)有更快的打包速度(1個小時降為15分鐘),但是作為兼容之前AssetbundleManifest
  • 新手如何從零開始學習unity
    自從 unity5發布免費過後,有很多獨立遊戲開發者轉向unity遊戲開發,unity的優勢就是多終端跨平臺打包,入門也快,很多人感覺自己的英文不好,就覺得學不會,其實這是一個誤區,unity的界面雖然是英文的,但是它的窗口就只有那麼幾個,用的次數多了,也就自然的熟練了,那麼新手該如何從零開始學習unity呢?
  • 【厚積薄發】如何更深入地掌握研發項目的物理性能?
    另外,也可以試試這兩個函數EditorApplication.LockReloadAssemblies/ UnlockReloadAssemblies,參考文檔:https://docs.unity3d.com/ScriptReference/EditorApplication.LockReloadAssemblies.html該問題由UWA
  • Unity編碼篇 Rigidbody類
    (FixedUpdate 函數是固定頻率調用的 , 與你的硬體配置沒有關係 , 忘記的小夥伴請參考之前的九大生命周期)下面介紹一下常用的方法 :AddForce 方法 : 給物體加一個瞬時的力 , 物體受這個力運動 (扔手雷的時候就是用這個方法) ;
  • 說「大器晚成」與「厚積薄發」
    由此看來,在句法構造上,4個小句中,只有位居第二的「大器晚成」具有順承關係,不能加上「反而」;前頭和後頭的3個小句卻都具有逆接關係,它們都可以加上「反而」。這不能不引發一個問題:「大器晚成」的本義,有沒有別的解釋?
  • Unity腳本生命周期
    作為一個unity從業人員,相信許多人有時候都會記不住unity的生命周期,記不住沒關係,有了這張圖,一切都是浮雲。
  • unity什麼意思
    unity什麼意思unity,聯合、統一、團結、和睦。學單詞,只記住意思可不行,會用才行,小夥伴們可以在評論區造句,我們一起學習哦!我先來:造句:Unity is strength.
  • 使用Unity ECS開發《我的世界》
    直播課程:Facial AR Remote面部捕捉解決方案課程(第一期)直播地址:https://connect.unity.com/events/unitychina-facialarUnity官方教師培訓報名火熱進行中Unity將在10月22-26日,舉辦為期5天的專業的Unity官方教師培訓課程,誠邀廣大教師與Unity一同學習分享最新技術
  • 【厚積薄發】粒子特效美術標準
    感謝deviljz@UWA問答社區提供了回答A2:影響粒子系統性能的很大部分可能就是DrawCall,如果處理的好,400個也無可厚非,但是粒子系統Update的開銷和粒子數量的大小也還是有一定關係的。
  • 【厚積薄發】Instruments如何看Mono內存分配
    一般來說,Unity Editor會按照腳本的依賴關係編譯代碼,其主要分為以下四個步驟:編譯Standard Assets、Pro Standard Assets和Plugins文件夾中的Runtime Script;編譯以上三個文件夾中Editor文件夾下的Script;編譯項目中所有剩餘的Runtime Script(Editor文件夾以外Script)
  • unity的自學之旅
    對比之後選擇了unity。主要用c#語言來寫腳本。創建物體,燈光,粒子等等。unity書籍慢慢的可以跟著做遊戲了。做了以前的坦克大戰,憤怒的小鳥等等。夢想能做出有趣的遊戲。
  • Unity 重Built-in到URP函數對應整理
    本文提供重 Built-in 到 URP 的示例總結,希望可以幫助到大家1.開始之前這裡有一些連結可以幫助你深入了解URPUnity URP 官方文檔 https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal%408.1/manual/index.html