Stats渲染資料統計視窗

请明月發表於2024-10-18

Statistics視窗,全稱叫做 Rendering Statistics Window,即渲染統計視窗(或渲染資料統計視窗),視窗中羅列出關於渲染、聲音、網路狀況等多種統計資訊 ,下面詳細的解釋一下這些項的意義。

FPS(Time per frame andFPS)
frames per seconds 表示引擎處理和渲染一個遊戲幀所花費的時間,該數字主要受到場景中渲染物體數量和 GPU 效能的影響,FPS 數值越高,遊戲場景的動畫顯示會更加平滑和流暢。一般來說,超過 30FPS 的畫面人眼不會感覺到卡,有視覺殘留的特性,光在視網膜上停止用後人眼還會保持 1/24 秒左右的時間,因此遊戲畫面每秒幀數至少要保證在 30 以上。

另外,Unity 中的 FPS 數值僅包括此遊戲 Scene 裡更新和渲染的幀,編輯器中編輯的 Scene 和其它監視視窗的程序不包括在內。

CPU
獲取到當前佔用 CPU 進行計算的時間絕對值,或時間點,如果 Unity 主程序處於結束通話或休眠狀態時,CPU time將會保持不變。

Render thread
GPU 渲染程序處理影像所花費的時間,具體數值由 GPU 效能來決定。

Batches
Batches 即 Batched Draw Calls, 是 Unity 內建的 Draw Call Batching 技術。
首先解釋下什麼叫做“Draw call”,CPU每次通知GPU發出一個glDrawElements(OpenGl中的圖元渲染函式)或者 DrawIndexedPrimitive(DirectX中的頂點繪製方法)的過程稱為一次Draw call,一般來說,引擎每對一個物體進行一次 DrawCall,就會產生一個 Batch,這個 Batch 裡包含著該物體所有的網格和頂點資料,當渲染另一個相同的物體時,引擎會直接呼叫 Batch 裡的資訊,將相關頂點資料直接送到 GPU, 從而讓渲染過程更加高效,即 Batching技術是將所有材質相近的物體進行合併渲染。

對於含有多個不同 Shader 和 Material 的物體,渲染的過程比較耗時,因為會產生多個 Batches。每次對物體的材質或者貼圖進行修改,都會影響 Batches 裡資料集的構成。因此,如果場景中有大量材質不同的物體,會很明顯的影響到 GPU 的渲染效率。有關 Batches 最佳化相關的方案:

雖然 Unity 引擎自帶 Draw Call Batching 技術,我們也可以透過手動的方式合併材質接近的物體;
儘量不要修改 Batches 裡物體的 Scale, 因為這樣會生成新的 Batch。
為了提升 GPU 的渲染 效率,應當儘可能的在一個物體上使用較少的材質,減少 Batches 過多的開銷。
對於場景中不會運動的物體,考慮設定 Static 屬性,Static 宣告的物體會自動進行內部批處理最佳化。
SetPass calls
在 Unity4.x 和 3.x 原來的 Stats 皮膚的第一項是“Draw calls”,然而到了 Unity5.X版本, Stats 上沒有了“Draw calls”,卻多出來一項“SetPass calls”。

比如說場景中有 100 個 gameObject,它們擁有完全一樣的 Material,那麼這 100 個物體很可能會被 Unity 裡的 Batching 機制結合成一個 Batch。所以用 “Batchs”來描述 Unity 的渲染效能是不太合適,它只能反映出場景中需要批處理物體的數量。

那麼可否用 “Draw calls”來描述呢?答案同樣是不適合。每一個“Draw calls”是CPU傳送個 GPU 的一個渲染請求,請求中包括渲染物件所有的頂點引數、三角面、索引值、圖元個數等,這個請求並不會佔用過多的小號,真正消耗渲染資源的是在 GPU得到請求指令後,把指令傳送給對應物體的 Shader, 讓Shader 讀取指令並通知相應的渲染通道(Pass)進行渲染操作。

假設場景中有 1 個 gameObject ,希望能顯示很酷炫的效果,它的 Material 上帶有許多特定的 Shader。為了實現相應的效果,Shader 裡或許會包含很多的 Pass,每當GPU 即將去執行一個 Pass 之前,就會產生一個 “SetPass call”,因此在描述渲染效能開銷上,“SetPass calls”更加有說服力。

Batches and DrawCall
這個是繪製影像的重要指標,可以作為衡量場景繪製效率的首要參考。

一個 Draw Call, 等與呼叫一次 DrawlndexedPrimitive(DX) or glDrawElements(OGL),等於一個 Batch。

NVIDIA 在 GDC 上曾提出 25k batch/sec 的渲染量會使 1GHz 的 CPU 達到 100% 的使用率,因此使用公式:25Kn(GHZ)Percentage/Framerate=Batch/Frame

可以推算出某些 CPU 可以抗多少 Batch。例如紅米手機 CPU 為 1.5Hz, 假設分出 20% 資源供渲染,希望遊戲跑到 30 幀 。那麼能抗多少 DrawCall ? 25k * 1.5 * 0.2 / 30 = 250。 因此從這方面也能看出,如果 CPU 不能分出更多的資源供渲染計算,能抗的 D人awCall 就會變少。

在 Stats 皮膚中看到的 Batches 是渲染的總 Batch 這個值等於同於 DrawCall。 但 Unity 中可以獲取到末批次處理之前的 DrawCall。 因此需要注意不要混淆感念。

Saved By Batching :
這個值是由於 Batch 減少的 DrawCall, 可以間接的看到場景最佳化的效果。這個值有兩部分組成: Static Batching 和 Dynamic Batching。

這個由 Unity 內建自動合併雖然優點多多,但也不是沒有缺陷。靜態合併會引發記憶體和儲存的額外開銷,動態合併會增加 CPU 的負擔。 這部分內容參考 Unity 官方文件。

總體上講所以希望批次渲染的元素要有相同的材質。通常兩個材質如果只有貼圖不同,可以將貼圖合併到一張大圖中,這就是所謂的和圖。另外在使用 ShadowCaster 時,只要材質相同,即使貼圖不同也可以合併渲染。

Dynamic Batches
動態合併在滿足以下條件時時自動完成:

模型總頂點數小於 900。
?不包含映象 transform 改變。 不改變 Scale。
如果使用動態 lightmap 需要指定正確。
不使用多 Pass 的 Shader。
由於需要在合併時透過 CPU 計算轉為世界座標,這項技術只在 CPU 消耗比 DrawCall 消耗“便宜”時才值得。這個衡量標準會根據平臺產生差異,例如蘋果平臺上 DrawCAll的消耗便宜,就不應該使用這項技術。這個功能可以在 Editor–> Project Setting –>Player 中進行設定開啟與關閉。

Static Batches
場景中不能移動的物件可以使用靜態合併,它不受頂點數的限制,可以大幅較少 DrawCall。 但為了將元素合併到一個大模型中,這項技術需要額外的記憶體。主要的記憶體消耗在於共享多邊形會在記憶體中重複建立。因此有時候需要犧牲渲染效率來避免靜態合併,來保證記憶體夠小。例如在茂密的樹林中使用這項技術會導致大量的記憶體消耗。

關於 Tris 和 Verts
Verts攝像機視野(field of view)內渲染的頂點數。

Tris攝像機視野(field of view)內渲染的三角面總數量。

1、 Camera 的渲染效能受到 Draw calls 的影響。之前說過,對一個物體進行渲染,會生成相應的 Draw call,處理一個 Draw Call 的時間是由它上邊的 Tris 和 Verts 數目決定。儘可能得合併物體,會很大程度的提高效能。舉個很簡單例子,比如場景一種有 1000 個不同的物體,每個物體都有 10 個 Tris; 場景二中有 10 個不同的物體,每個物體有 1000 個 Tris 。 在渲染處理中,場景一中會產生 1000 個 Draw Calls,它的渲染時間明顯比場景二慢。

2、Unity stats 檢視中的 Tris 和 Verts 並不僅僅是視錐中的梯形內的 Tris 和 Verts,而是 Camera 中 field of view 所有取值下的 tris 和 verts,換句話說,哪怕你在當前 game 檢視中看不到這個 cube, 如果當你把 field of view 調大到179 過程中都看不到這個 cube,stats 皮膚才不會統計, GPU 才不會渲染,否則都會渲染,而且 unity 不會把模型拆分,這個模型哪怕只有 1 個頂點需要渲染, Unity 也會把整個模型都渲染出來。(參考自Mess的《Unity Camera元件部分引數詳解》)

3、新建一個空的場景,裡面沒有新增任何物體,為什麼 status 皮膚上顯示有 1.7k Tris 以及 5.0k Verts 。這是因為空的場景自帶預設的天空盒、Windows—>Lighting開啟 Ligh下的 Scene 皮膚,把 Skybox 裡的材質設為空。刪掉它,就會發現 Tris 和 Verts 都會變為0了。

Screen
獲取當前 Game 螢幕的解析度大小,後面的 值 表示總的記憶體使用。

Shadow casters
表示場景中有多少個 可以投射陰影的物體,一般這些物體都作為場景中的光源。

Animations
正在播放動畫的數量。

指令碼獲取值
在編輯模式下這些資料是可以透過指令碼獲取到的,不過打出包來不太成,程式碼如下:

GUILayout.TextField("Total DrawCall: " + UnityStats.drawCalls);
        GUILayout.TextField("Batch: " + UnityStats.batches);
        GUILayout.TextField("Static Batch DC: " + UnityStats.staticBatchedDrawCalls);
        GUILayout.TextField("Static Batch: " + UnityStats.staticBatches);
        GUILayout.TextField("DynamicBatch DC: " + UnityStats.dynamicBatchedDrawCalls);
        GUILayout.TextField("DynamicBatch: " + UnityStats.dynamicBatches);
        GUILayout.TextField("Tri: " + UnityStats.triangles);
        GUILayout.TextField("Ver: " + UnityStats.vertices);

相關文章