Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Another Post about Draw Calls

Discussion in 'UGUI & TextMesh Pro' started by Drowning-Monkeys, Nov 7, 2014.

  1. Drowning-Monkeys

    Drowning-Monkeys

    Joined:
    Mar 6, 2013
    Posts:
    328
    Hi Guys,

    So, my current UI is using somewhere between 90-280 draw calls. This is for a couple of reasons, many of which leave me dumbfounded, and previous posts have not really answered my questions:

    1. Objects that are off screen (or outside the drawing canvas) still generate draw calls. Is this expected behavior?
    2. Sprites that are part of the same atlas still generate many draw calls. For example, I have a list of 41 portraits, that are masked out by an image. This list generates as much as 9 draw calls.
    3. Each piece of text is a draw call. Are there any plans to do something like what TextMesh Pro does? Or should I just switch to that? Also, that seems very difficult, given that TextMeshPro does not draw to a canvas, so I wouldn't be able to just attach text mesh pro objects to ui elements
    4. Invisible objects are a draw call. This is true wether I alpha out the Image component or the Canvas Group component. And actually to be honest, this is inconsistent. I've seen it where a canvas group alpha set to 0 will remove the draw call, but most of the time it won't. And most of the time setting the image alpha to 0 has no effect as well.

    I am also not having a problem I read about where having UI elements on top of each other is what is creating additional draw calls. I have the same draw calls if i move the elements that are layered on top of each out and separate them as i do when they are on top of each other.

    The only thing that absolutely affects DC's (as is expected) is disabling the game object. But handling a million disabled GO's would be too difficult to tackle.

    Looking forward to some thoughts on the subject.

    The bug report is #646032
     
    Last edited: Nov 7, 2014
  2. Drowning-Monkeys

    Drowning-Monkeys

    Joined:
    Mar 6, 2013
    Posts:
    328
    bump. Is anyone else experiencing these issues?
     
  3. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Only if a vertex belonging to that mesh is within any camera view frustum, depending on visible layers.

    They'll only batch if the *materials* use the same settings. Sometimes, depth will cause them not to batch as efficiently (for example a sprite on a different atlas is in between). Sprites of different scales might not batch either - but you'll have to test. Unity5 afaik is ok with different scales.

    Additionally, referencing a material in code will cause it to instantiate (create a unique material and a unique draw call). Use .sharedMesh if you want to avoid this. Check during playmode if you have any (instanced) materials.

    Sounds very wrong really. Are you sure that you have dynamic batching ticked on in player settings at all? TextMeshPro rocks regardless and is simply the best text solution.

    Alpha = 0 is never invisible. It just means it's still drawn with alpha = 0. To remove it from rendering, disable .renderer or SetActive(false).
     
    Stephan-B likes this.
  4. Drowning-Monkeys

    Drowning-Monkeys

    Joined:
    Mar 6, 2013
    Posts:
    328
    Thanks for your response.

    Ok - that definitely is, and is not, what is happening here. For example, I have a camera that is only set up for showing inventory. To test what you are saying, I set it lightyears (10,000 distance) away from all the other game objects and canvases, etc. This camera is in charge of viewing 1 thing, the inventory canvas. There was a masked out part of the inventory, tipping into the camera. When I moved the inventory further away from the camera, the draw calls went away. But I've seen it where this is also not the case, for example, testing the example scenes in the unity 4.6 RC1 project, this did not work.

    However, the main UI is a Screen Space Overlay. So the elements that are outside the overlay are not visible to any camera, the main cameras in the game cull out ui elements, and yet i am still being penalized for UI elements outside the canvas' overlay space.

    What if the UI's images have no material attached to them? Would that break batching? should i place materials on all the images i use in the UI? The default for any button or image is to have no material. I also do not touch these materials in any way.


    Yup, I have unity pro, and all batching is clicked. To use TextMeshPro, I'm guessing i'd need to move everything out of being in screen space overlay, and use a camera, right? because screen space overlay does not display objects like TextMeshPro, or sprites, etc.
     
    Last edited: Nov 10, 2014
  5. Drowning-Monkeys

    Drowning-Monkeys

    Joined:
    Mar 6, 2013
    Posts:
    328
    Well, I've done some digging and some experiments, I've carefully reconstructed my entire GUI piece by piece and watched what happened to the Draw Call Count as I did it. I thought I'd post my findings here for anyone who is interested:

    1. I had read that overlapping can cause increased draw calls. What I didn't realize was how finicky the issue of an overlap can be. Some images in my GUI have an invisible buffer, if text is beneath that sliver, even though it's invisible, I saw as many as 5 increased DC's. Also, speaking of text, try to keep it on top of everything. Hiding it behind elements makes it go bonkers for some reason.

    2. For whatever reason, moving GUI elements out of the screen overlay space or overlay camera space, does not reduce draw calls. My experiments were not 100% conclusive. Sometimes i saw a decrease, but 95% of the time i did not. So if you have anything sitting on off screen that you like to bring in in an animated fashion, disable/enable it while it's offscreen. Do a quick test, disable it while it's off screen to see if it's saving you anything.

    3. If you built your GUI before RC1, consider rebuilding it

    4. Try to stay away from masked lists. I have to say the whole issue of alpha'd out images still causing draw calls is a big problem. This is not the case in EZ GUI or nGUI. So my image that holds the portrait of the hero? I use a script with an array holding all the portraits. My shop with a list of weapons to buy? That one is still a list. Thankfully performance is not a problem when that is active, because you aren't playing the game.

    5. Neither Alpha = 0 or Canvas Group Alpha = 0 reduces draw calls. If you want to save a DC, you'll have to disable the GameObject.

    After all this work, I was able to reduce my GUI from 90 Draw Calls to 11 while the main HUD is active.
     
    kayy and Yukichu like this.
  6. mrs_gold

    mrs_gold

    Joined:
    Oct 25, 2014
    Posts:
    3
    Hi Drowning Monkeys,

    what I've just noticed is if you have UI elements grouped within a canvas it increases DCs. Best options would be use only one main canvas, or use empty game objects to group elements. I've got all UI assets in one atlas, and I've got only one DC for whole UI + one DC for text.

    Hope it'll help!
     
    Last edited: Feb 11, 2015
    Drowning-Monkeys likes this.
  7. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Well, this information in the tutorial project would be nice, or FAQ, or something. Thank you for researching this, and many thanks for posting it. Makes sense now that I read it, but it definitely didn't seem intuitive (to me.)
     
    JamesArndt likes this.
  8. denis_va

    denis_va

    Joined:
    Apr 21, 2015
    Posts:
    9
    Setting Canvas Group Alpha to 0 does save draw calls, if you also attach a Canvas to the same GameObject.
     
  9. funshark

    funshark

    Joined:
    Mar 24, 2009
    Posts:
    225
    Could you post a screen or something of your hierarchy?
     
  10. mrs_gold

    mrs_gold

    Joined:
    Oct 25, 2014
    Posts:
    3
    It's something like this:
    Code (csharp):
    1. + UICanvas
    2.   > Group_1 (empty game object)
    3.     * Group_1_1 (empty game object)
    4.       - Image
    5.       - Image
    6.     * Group_1_2 (empty game object)
    7.       - Image
    8.       - Image
    9.     * Group_1_3 (empty game object)
    10.       - Image
    11.       - Image
    12.   > Group_2 (empty game object)
    13.     * Group_2_1 (empty game object)
    14.       - Image
    15.       - Button (with image)
    16.     * Group_2_2 (empty game object)
    17.       - Image
    18.       - Button (with image)
    19.     * Group_2_3 (empty game object)
    20.       - Image
    21.       - Button (with image)
    22.   > Group_3 (empty game object) [this is where game credits are]
    23.     * Image
    24.     * Image
    25.     * Background
    26.     * Mask
    27.       - Whole text group (Empty game object)
    28.         | Text_1
    29.         | Text_2
    30.         | Text_3
    31.         | Text_4
    32.     * Close button (with image)
    I might own you a bit of explanation why I have so many groups. In my game (there are some gifs and pngs on my twitter if you want to take a look) UI is composed of signs on sticks and lines, so I'm using a lot of sliced images, which compose bigger picture. At the same time all of them are being animated (because why not?), and it seemed easier to me to group them and animate them at once.
     
    Last edited: Aug 27, 2015
  11. zxgats1986

    zxgats1986

    Joined:
    May 23, 2017
    Posts:
    2
    Add a componet Rectmask2d on screen space overlay canvas could resolve the first question.