We recently created an asset that displays data in a table layout in the 'new' (> 4.6) Unity UI. Some of our users are asking about draw call performance and we are wondering what (if any) options we have to improve draw calls in the UI.
So the above table sticks pretty consistently at 19 draw calls...
It runs fine on anything ipad2-level and above, but Unity dev's (understandably) hate draw calls so we want to minimize that number as much as possible.
You can see the hierarchy we are creating for our table in the above screenshot. We are using masks for the Header/Footer/Body and the ColumnOverlay. Per Unity, it appears that each Mask takes a minimum of 2 draws:
http://forum.unity3d.com/threads/unity-4-6-ui-mask-component-takes-2-draw-calls.279840/
Also, we are obviously using a bunch of the Unity UI Text and Sprite elements to draw everything. The basic nature of a table layout pretty much means that there are multiple layers of Sprite and Text objects on top of each other (cell data on top of cell background, etc). Unity dev's seem to say that there's simply no way to NOT have multiple draw calls when this happens as the engine requires a draw per "layer"... period.
http://forum.unity3d.com/threads/solved-new-ugui-and-too-many-draw-calls.266631/
So... it seems that as soon as you have a non-trivial UI layout in the Unity UI you are pretty much guaranteed to have a non-trivial (10-20) amount of draw calls. Is that true? If it isn't, does anyone have any ideas on anything we could do to minimize draws in our table?
I was able to reduce my draw-calls by one by inactivating a custom 'measure' element I have on each data row. It's basically a hacked "Text" object but I'm just using it to measure cells for grid sizing and it was taking an extra draw call. The measure features actually work fine with the GameObject deactivated.
Found a big improvement. I mentioned above that my Header/Footer/Body and ColumnOverlay all use masks elements. Turns out, I was able to restructure my system to include a single Mask on a new root-level element and remove the Masks on the Header, Footer, and ColumnOverlay. Now I just have a Mask on that root element and the Body.
So each row contains that bottom border line image to offset it from it's siblings. I thought maybe it's printing 'on top' of the Text elements and forcing an extra draw. Turns out no... it's not.
Also... all my background Image elements have no sprite property defined. They are just using "null" with a color applied. I thought maybe if I created a single generic 'white' sprite and applied it to all my null Image objects it might improve batching and reduce my draw calls. Turns out no... it doesn't.
As I understand your problem is UI batching.
Now I will try to explaine how it works.
When you create an empty scene in Unity you have only one draw call due your camera and your canvas. Lets look to the pic below:
So when you add new Image
object to the scene you obtain a new one.
It is happened because you add a new material to the scene. If you add some more objects with the same materials, they will be batched to the one draw call and not produce new one.
If you add to the scene an object with a new one material it produced an additional draw call.
It looks like ok. But if the object with new material located between batched objects in hierarcy and intersect with any of it you will have a problem. You batchig will be separated to the two part and will produce two drow calls.
So I thik your problem is here. You need to look to you hierarchy closely, and remember, that Image
and Text
objects has defferent materials. So each Text
located between two Image
objects in heierarcy prodeced additional draw call when text's shape intersect with image's shape.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With