Unity優化之減少Drawcall

2021-07-15 21:47:47 字數 2455 閱讀 1583

簡單來說,drawcall就是螢幕渲染一次所需要的開銷,為了較少消耗,提高效能,一般有以下幾種方法。

一: 批處理

1.動態批處理

如果動態物體共用著相同的材質,那麼unity會自動對這些物體進行批處理。動態批處理操作是自動完成的,並不需要你進行額外的操作,你可以在buildsetting中設定他。

動態批處理是消耗2倍的記憶體來提公升顯示的速度,也就是空間換時間,如果記憶體消耗過大,需要考慮時間和空間的平衡。

如果發現動態批處理後dc並沒有減少,你可以檢查以下方面:

<1>批處理動態物體需要在每個頂點上進行一定的開銷,所以動態批處理僅支援小於900頂點的網格物體。

<2>如果你的著色器使用頂點位置,法線和uv值三種屬性,那麼你只能批處理300頂點以下的物體;如果你的著色器需要使用頂點位置,法線,uv0,uv1和切向量,那你只能批處理180頂點以下的物體。請注意:屬性數量的限制可能會在將來進行改變。

<3>不要使用縮放尺度(scale)。分別擁有縮放尺度(1,1,1)和(2,2,2)的兩個物體將不會進行批處理。

<4>統一縮放尺度的物體不會與非統一縮放尺度的物體進行批處理。使用縮放尺度(1,1,1)和 (1,2,1)的兩個物體將不會進行批處理,但是使用縮放尺度(1,2,1)和(1,3,1)的兩個物體將可以進行批處理。

<5>使用不同材質的例項化物體(instance)將會導致批處理失敗。

<6>擁有lightmap的物體含有額外(隱藏)的材質屬性,比如:lightmap的偏移和縮放係數等。所以,擁有lightmap的物體將不會進行批處理(除非他們指向lightmap的同一部分)。

<7>多通道的shader會妨礙批處理操作。比如,幾乎unity中所有的著色器在前向渲染中都支援多個光源,並為它們有效地開闢多個通道。

2.靜態批處理

只要物體不移動,並且擁有相同的材質,那麼就可以進行靜態批處理。因此,靜態批處理比動態批處理更加有效,你應該盡量低使用它,因為它需要更少的cpu開銷。

為了更好地使用靜態批處理,你需要明確指出哪些物體是靜止的,並且在遊戲中永遠不會移動、旋轉和縮放。想完成這一步,你只需要在檢測器(inspector)中將static核取方塊打勾即可,如下圖所示:

使用靜態批處理操作需要2倍的記憶體開銷來儲存合併後的幾何資料。

二:渲染順序

u3d的渲染是有順序的,u3d的渲染順序是由我們控制的,控制好u3d的渲染順序,你才能控制好drawcall

乙個drawcall,表示u3d使用這個材質/紋理,來進行一次渲染,那麼這次渲染假設有3個物件,那麼當3個物件都使用這乙個材質/紋理的 時候,就會產生一次drawcall,可以理解為一次將紋理輸送到螢幕上的過程,(實際上引擎大多會使用如雙緩衝,快取這類的手段來優化這個過程,但在這 裡我們只需要這樣子認識就可以了),假設3個物件使用不同的材質/紋理,那麼無疑會產生3個drawcall

接下來我們的3個物件使用2個材質,a和b使用材質1,c使用材質2,這時候來看,應該是有2個drawcall,或者3個drawcall。 應該是2個drawcall啊,為什麼會有3個drawcall???而且是有時候2個,有時候3個。我們按照上面的drawcall分析流程來分析一 下:

1.渲染a,使用材質1 

2.渲染b,使用材質1 

3.渲染c,使用材質2

在這種情況下是2個drawcall,在下面這種情況下,則是3個drawcall

1.渲染a,使用材質1 

2.渲染c,使用材質2 

3.渲染b,使用材質1

因為我們沒有控制好渲染順序(或者說沒有去特意控制),所以導致了額外的drawcall,因為a和b不是一次性渲染完的,而是被c打斷了,所以導致材質1被分為兩次渲染

那麼是什麼在控制這個渲染順序呢?首先在多個相機的情況下,u3d會根據相機的深度順序進行渲染,在每個相機中,它會根據你距離相機的距離,由遠到近進行渲染,在ui相機中,還會根據你ui物件的深度進行渲染

那麼我們要做的就是,對要渲染的物件進行一次規劃,正確地排列好它們,規則是,按照z軸或者深度,對空間進行劃分,然後確定好每個物件的z軸和深度,讓使用同乙個材質的東西,盡量保持在這個空間內,不要讓其他材質的物件進入這個空間,否則就會打斷這個空間的渲染順序

在這個基礎上,更細的規則有:

場景中的東西,我們使用z軸來進行空間的劃分,例如背景層,特效層1,人物層,特效層2 

ngui中的東西,我們統一使用depth來進行空間的劃分 

人物模型,當人物模型只是用乙個材質,drawcall只有1,但是用了2個以上的材質,drawcall就會暴增(或許對材質的renderqueue 進行規劃也可以使drawcall只有2個,但這個要拆分好才行),3d人物處於複雜3d場景中的時候,我們的空間規則難免被破壞,這只能在設計的時候盡 量去避免這種情況了 

使用了多個材質的特效,在動畫的過程中,往往會引起drawcall的波動,在視覺效果可以接受的範圍內,可以將特效也進行空間劃分,假設這個特效是2d顯示,那麼可以使用z軸來劃分空間

什麼是DrawCall?如何減少DrawCall

cpu呼叫影象程式設計介面。在shader渲染流水線的應用階段,當cpu準備好場景資料,設定好渲染狀態,就會呼叫drawcall命令,開啟乙個渲染過程 cpu每次呼叫drawcall,都需要向gpu傳送許多資料 狀態,在傳送前cpu需要從硬碟讀取到視訊記憶體的資料 設定的渲染狀態以及呼叫drawca...

什麼事DrawCall?怎麼減少DrawCall?

什麼是drawcall?drawcall是對底層圖形繪製介面的呼叫命令gpu進行渲染,gpu和cpu並行工作,他們之間通過命令緩衝區連線,cpu像gpu傳送渲染命令,gpu接受並執行相對應的渲染命令。怎麼減少drawcall?提交很多小的drawcall會造成cpu的效能瓶頸,cpu的時間都浪費了在...

unity 優化之六

優化方式 使用九宮,對稱貼圖 提高貼圖復用率 shader 利用shader合併貼圖通道,實現灰度圖等。alpha通道存alphatest和高光,貼圖乙個通道存陰影乙個通道存ao等,alpha通道存在貼圖的其他通道便於壓縮等等。這點在做軒轅傳奇的時候大幅使用。壓縮動畫減少關鍵幀 前面有介紹 及時解除...