[SOLVED] new uGUI and Too Many Draw Calls

Update: The conclusion is that the default UI sprites shipped with Unity didn’t use packing tags. Use your own sprites and draw call is not an issue. Now you don’t have to read this thread.

Trying out the 4.6 beta 18. The new UI system looks really neat… let’s see

I start with an empty scene. Just the main camera. 1 Draw call.
Create> UI > Panel. We go to 2 draw calls. Expected as much.
Create > UI > Button. 4 Draw calls. What?
Create > UI > Slider. Now we’re at 6 Draw calls!
Create > UI > Scrollbar. 8 draw calls! What’s going on here?
Hmm… Let’s add another Scroll bar… 2 MORE DRAW CALLS!!! Now we’re at 10!!!
Do I dare add a toggle? Yup… 12
`Nother toggle? 14.

Uh…
A button, a slider and 2 scrollbars and I’m at 10 draw calls?

What’s with all the draw calls? Why isn’t this batching? Why isn’t this all on the one atlas?
What am I missing?

Any insight into the excessive draw call situation would be appreciated.

Thanks!

Tried searching for this before posting… I’m surprised no one had made mention of this before… Or I just can’t find any prior discussion as search feature for these forums is quite lackluster…

4 Likes

I’d have to see your project to be sure, but I’m betting your images don’t have a packing tag set (also, I think the Sprite Packer is a Pro-only feature?). Without that, they will exist as separate images, and will have separate draw calls.

If you don’t have Pro, then they won’t automatically pack. I believe you can still have them in one atlas by importing the images as an atlas yourself, using the ‘Multiple Sprites’ slicing options.

And, it’s definitely the search being failtastic, I have seen at least one “why so many draw calls?” post every day on this forum. (Usually it’s like, “There are 3 draw calls instead of 1 like in NGUI”, not 14+)

These are not my images. These are the default UI elements Unity places in the scene…

I place 1 slider in the scene and the draw calls jump to 3.

So I import a bunch of sprites, set the packing tag for each, make sure sprite packing mode is “always enabled” in the Editor settings, and I go about changing the default slider images to use my sprites…

Draw calls go up to 4. :expressionless:

Yeah, seems default images are not atlased for some reason. May be to force users not to use them and make own UI “skin”? :slight_smile:

Yeah, the built-in UI graphics don’t seem to be set up for batching/packing. Maybe when a build is created they get batched, but in the editor they don’t. However, if you draw the same texture one right after the other, those do get batched together. For instance, in this setup, try moving one of the Scrollbars so that it’s placed right after the Panel. Since the background of the scrollbar and the panel both use the same sprite, at least one draw call will be dropped. (you may have to click in the game window to see the draw call count change)

As StarManta and ortin mention, if you use your own set of images they will get batched better (though the batching doesn’t happen until you start Play Mode). Note that text will still cause extra draw calls since Unity fonts use their own atlas image. When using my own images with all the same Packing Tag, this same setup goes from 13 draw calls to 4 with the various labels turned on, and 1 without.

Something pretty neat I noticed while testing all this, is that Unity seems to do some smart re-ordering of the image drawing in order to reduce draw calls, as long as the image and text objects are not overlapping each other. The setup in your original post drops down to 5 draw calls if I make sure none of the elements (except the Panel which is covering the whole screen) are overlapping at all.

2 Likes

In the Editor Settings you can change when sprite packing is used. By default it is just when you build a player. You can change the setting to make it batch in editor mode also.

1 Like

As in: “Sprite Packer Mode: Always Enabled” ?

First thing I checked. Makes no difference.

So what does your scene look like?

There is nothing in it except for the new UI elements as supplied by Unity.

Can you try this experiment?

Open a new new scene with nothing but the main camera. Turn on ‘stats’ in the Game tab and add UI elements from the Create menu… Watch the draw calls increase with every UI element.

Just did this, and I cannot replicate your results. The draw calls appear to be entirely based on how many UI elements are overlapping each other, but if they’re placed side by side, I can add scrollbars all day and stay at 3 draw calls. (panel, scrollbar, scrollbar thumb)

Add one of each element. Button, Scrollbars, Toggle, etc …How many draw calls do you have now?

And yeah… if they overlap the draw calls increase even more so

With one of everything (except Image/RawImage), it seems to top out at 6 draw calls. Multiples of everything do not have any further effect.

Taking a look now, I think we might not be making a sprite sheet from the built in graphics… let me check…

Looks like we didn’t set a packing tag on the default sprites… :frowning:

Compare this (default sprite):
1762687--111650--badbatch.PNG

Tag’d sprites 1762687--111651--Goodbatch.PNG

I’ll fix up the packing tags :slight_smile:

5 Likes

Yeah… I’m topped out at 8. I think my earlier experimentations hitting 14 draw calls was due to the UI elements overlapping.

STILL! That’s 7 too many draw calls. I hope they sort this out for release.

Nice work Tim C! Thanks for looking into it.

Hey, has anyone found a solution to the problem of extra draw calls resulting from placing sprites/UI elements on top of one another?

As long as our sprites aren’t touching, the sprite packer seems to reduce draw calls appropriately.

Unfortunately, all of this is lost as soon as our sprites start overlapping, which is quite a common occurrence.

I don’t think that’s a bug; if you use the same sprite more than once and they’re not overlapping, Unity can change the order in which it draws them so they’re one after another (even if they normally wouldn’t be because of being in different places in the hierarchy, etc). Then it can draw them both at once, in one draw call. This can be done even if the sprites don’t have a packing tag.

I think the reason Unity can do this only when they’re not overlapping is because, if the two sprites are not overlapping, then the order in which they’re drawn (relative to each other, at least) doesn’t matter at all. When two sprites are overlapping, you have to draw them in the correct back-to-front order, or they don’t look right.

The criteria for when it’s possible to re-order the sprites like this is probably a little more complicated than just “sprite a is not overlapping sprite b”, since there might be situations where there’s a third sprite between them and and then you have to preserve the correct draw order, etc. But, I think that’s the basic idea.

All that said, if your sprites are all custom ones, make sure they have a packing tag set, and that it’s the same one for all your sprites. If you’re using nothing else except sprites you’ve made this way, they should get batched together regardless of overlap. If you have text in the mix, things will be different since text doesn’t get batched with sprites.

What are the packing tags for the built-in UI sprite assets? Also, can we get to the assets themselves to make our own versions from the file Resources/unity_builtin_extra?

Thanks

I don’t believe you can pack with the built-in assets (though it seems that they are packed with each other) - this is one of those situations where you’re encouraged to create your own assets to differentiate your game, I suspect.

Being able to obtain the source images for the default assets is not a bad idea, though. Perhaps they could be posted alongside the Unity download, much like the default shaders are?