Search Unity

[SOLVED] new uGUI and Too Many Draw Calls

Discussion in 'UGUI & TextMesh Pro' started by FuguFirecracker, Sep 4, 2014.

  1. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    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...
     
    Last edited: Sep 5, 2014
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    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.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    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+)
     
  4. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    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. :|
     
  5. ortin

    ortin

    Joined:
    Jan 13, 2013
    Posts:
    221
    Yeah, seems default images are not atlased for some reason. May be to force users not to use them and make own UI "skin"? :)
     
  6. Giometric

    Giometric

    Joined:
    Dec 20, 2011
    Posts:
    170
    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.
     
    Tim-C and ortin like this.
  7. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    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.
     
    twobob likes this.
  8. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    As in: "Sprite Packer Mode: Always Enabled" ?

    First thing I checked. Makes no difference.
     
  9. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    So what does your scene look like?
     
  10. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    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.
     
  11. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    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)
     
  12. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    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
     
  13. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    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.
     
  14. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    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... :(

    Compare this (default sprite):
    badbatch.PNG

    Tag'd sprites Goodbatch.PNG

    I'll fix up the packing tags :)
     
    John3D, twobob, lukos and 2 others like this.
  15. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    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.
     
  16. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Nice work Tim C! Thanks for looking into it.
     
  17. davechang_

    davechang_

    Joined:
    Oct 10, 2014
    Posts:
    1
    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.
     
  18. Giometric

    Giometric

    Joined:
    Dec 20, 2011
    Posts:
    170
    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.
     
  19. Rom-

    Rom-

    Joined:
    Nov 26, 2008
    Posts:
    90
    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
     
  20. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    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?
     
  21. Streamfall

    Streamfall

    Joined:
    Aug 8, 2011
    Posts:
    43
    Before I forget, here is a method that I've found works well (but is still imperfect).

    My scene is organized so that GameObjects' components add functionality to them. I decided on that pattern long ago, and it worked when I was working with NGUI. This worked great because I never had an issue with draw calls.
    The new UI system definitely still has issues with draw calls, especially with complex UI designed by a third party, I can't control what it looks like. The end result has been hundreds of draw calls.

    So here's what I figured out. A two canvas parent system works pretty well, switching individual transforms over to those canvases. Each of these Canvas objects are set to Screen Space - Camera. That canvas, when set to that mode, shows a 'Sorting Layer', which I've created another layer for. The Camera I am using renders two such layers. Camera A is one the layer which is not being culled. When I don't need a set of UI, I'm just moving it over to the second Canvas parent, whose Canvas is set to the second (Culled) layer. I also have CanvasGroups on every set of UI I want to move around.

    Right now I'm having trouble in which items that I am generating from data on the web is appearing quite far off on Z, thus they are not rendered. Fixed this by making the camera's clipping planes cover more area.
     
    Last edited: Oct 18, 2015
  22. standardcombo

    standardcombo

    Joined:
    Jun 28, 2012
    Posts:
    19
    What could make this behave differently per platform? I have a simple scene with 3 images in a canvas. They batch if my platform is set to iOS but do no batch when set to PC, Mac & Linux Standalone. I checked the Packing Tag and there doesn't seem to be a way to set those on a per-platform basis.

    (version 5.2.2f1)

    Ideas?