Unity Batches與glDrawElements的關係

1)Unity Batches與glDrawElements的關係
​2)渲染大面積草地時,如何下降消耗
3)HUD隨着攝像機偏移
4)Unity中如何在豎屏模式的UI之上顯示強制橫屏的UI
5)iOS能耗問題
html


UWA 問答社區:answer.uwa4d.com
UWA QQ羣2:793972859(原羣已滿員)
ios

Rendering

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

A1:可參考如下幾點:app

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

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

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

A2:這部分能夠參考UWA Day 2020裏張強老師的分享《Unity移動遊戲項目優化案例分析(上)》中的第二小節。性能

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


Rendering

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的使用說明

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

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

升級Unity 2018過程當中,遇到的DrawMeshInstanced不生效的問題

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

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

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

Q2:手機上能用嗎?

A:推薦一個使用URP製做的草海效果,親測可在Mobile端使用。
Unity URP Mobile Draw Mesh Instanced Indirect Example

性能測試:

  • 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問答社區提供了回答


Rendering

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問答社區提供了回答


UGUI

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

1. 改Screen.orientation以後再顯示。
- 須要考慮外層RectTransform是否已經「完成」了轉屏致使的變化,而後才能去適配內層。還沒有找到可靠的事件。
- 須要處理背景,半透明背景可能透出後面的UI排版混亂。

2. 將新UI旋轉依z軸轉-90度顯示。
- 對劉海屏的適配須要作相應的修改。
- 沒法轉屏(由於仍是豎屏,且不支持Upside Down)。可是這個應該能夠克服。

請問,二者哪一種更好呢?

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問答社區提供了回答


iOS

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

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

這個帖子也是相似的問題,看上去是由於Unity引擎自己相對於普通APP體量較大,因此能耗表現較高,下降目標幀率會有所改善。

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

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

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

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

感謝山中千年@UWA問答社區提供了回答

封面圖來源於網絡


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

官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com
官方問答社區:answer.uwa4d.com
UWA學堂:edu.uwa4d.com 官方技術QQ羣:793972859(原羣已滿員)

相關文章
相關標籤/搜索