天天看點

Unity優化之減少Drawcall

簡單來說,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複選框打勾即可,如下圖所示:

Unity優化之減少Drawcall

使用靜态批處理操作需要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軸來劃分空間

原文連結:https://blog.csdn.net/u011926026/article/details/52073811