Unity - 使用2D Sprite時改變SortingLayer或SortingOrder造成Draw Call大量增加的問題

  為了稍微增進一點效能,節省Draw Call的情況下,使用Unity內建的Sprite Packer,這可以把設定相同Tag的圖片合成一張Atlas,這是個很方便的功能,也就可以省去使用外部軟體自己合成一張Atlas的步驟。

關於Sprite Packer的相關使用說明就請自行參考官網說明文件
http://docs.unity3d.com/Manual/SpritePacker.html


  不過有時候在使用這個功能卻發現DrawCall並沒有預期中的減少,反而是增加許多的情況,一開始其實覺得有些莫名其妙,稍微研究一下後才發現事有蹊俏。


  先說結論,當sprite都在同個tag底下,不管是改變SortingLayer或是SortingOrder都不會對DrawCall有影響;但是當有的sprite是在別的tag底下,依據Render的順序,當遇到下一個物件是不同tag的時候,就會呼叫draw一次。


設定條件:
Layers:
0:Default
1:Background
2:Middle
3:Foreground

Objects:
A1 - Sprite Tag : GroupA
A2 - Sprite Tag : GroupA
A3 - Sprite Tag : GroupA
B1 - Sprite Tag : GroupB




情況一:
A1 - Background - Order:1
A2 - Background - Order:10
A3 - Background - Order:20
Result:Draw Call 1

情況二:
A1 - Background - Order:1
A2 - Background - Order:10
A3 - Foreground - Order:1
Result:Draw Call 1

情況三:
A1 - Background - Order:1
A2 - Foreground - Order:10
A3 - Background - Order:20
Result:Draw Call 1


  由此可以知道都是相同Tag,也就是相同Atlas物件的情況下,不論改變Layer或Order都沒有影響,這也是符合預期的情況。




情況四:
A1 - Background - Order:1
A2 - Background - Order:10
B1 - Background - Order:20
Result:Draw Call 2



情況五:
A1 - Background - Order:1
B1 - Background - Order:5
A2 - Background - Order:10
Result:Draw Call 3



情況六:
A1 - Background - Order:1
A2 - Middle- Order:1
B1 - Foreground - Order:1
Result:Draw Call 2



情況七:
A1 - Background - Order:1
A2 - Foreground- Order:11
B1 - Middle - Order:1
Result:Draw Call3




  這邊就可以看出結果了,DrawCall會受到Render 2D sprite物件順序的影響,也就是說,當不同Tag的物件,彼此Order不同,互相交互穿插越多就會造成Draw call越多(也就是開頭圖片的結果,照理DrawCall應該只有2)。

  如果都是Default並且Order=0的情況下,那就要看物件建立的順序來決定先後,也是會造成相同的情況。如果不使用SortingLayer或SortingOrder,而是使用Z軸來調整物件前後的話也是要注意同樣的問題。

  解決辦法:盡可能讓相同sprite tag的物件,設定它們的sorting order都在相近的區間之內,中間盡量不要穿插太多不同sprite tag的物件。

No comments:

Post a Comment