Search Unity

Android: Poor Performance w/ Large Images

Discussion in 'UGUI & TextMesh Pro' started by gskinner, Jan 8, 2016.

  1. gskinner

    gskinner

    Joined:
    Aug 28, 2014
    Posts:
    43
    I'm working on a App (not a game!) built with Unity, and it consists of a number of full screen panels.

    Testing with a 2013 Android Nexus 7, I've noticed that performance drops extremely quickly as I stack full screen images. I think this is somewhat related to a poor fill rate on the Nexus 7, but uGUI shows much worse performance than Sprite Renderers.

    I made a test scene, where I stack a bunch of fullscreen images on top of eachother, and compare the performance of ugui's Image vs SpriteRenderer.

    Here you can see my setup scene:


    Results from testing:
    SpriteRenderer x 5 = 60fps
    SpriteRenderer x 10 = 49fps

    uGui Image x 5 = 30fps
    uGui Image x 10 = 17fps

    I have submitted a bug report here: https://fogbugz.unity3d.com/default.asp?760192_9lv0ioh3cn80fkl2

    Attached is a demo project.
     

    Attached Files:

    Last edited: Jan 8, 2016
    MrEsquire likes this.
  2. gskinner

    gskinner

    Joined:
    Aug 28, 2014
    Posts:
    43
    Bump. Any idea why images rendered in uGui are drastically slower than Sprites?
     
  3. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    324
    Any reponse guys? There's a great test case here, and some pretty shocking performance differences, would be nice to know if this is acknowledged and being worked on.
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Turn on wireframe. I believe the sprite renderer creates a tighter mesh so the fill rate is lower.

    They are also very different systems so its not unusual. The UI shader does more work as well from what i can recall. I'm not near the code at the moment.

    Try assigning the sprite shader to a material and assign to the UI images, see if it makes a difference. Also see what the profiler is showing.
     
    Last edited: Jan 20, 2016
  5. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Its also the batching process and how it treats larger images. Sprites just get rendered where uGUI images get processed. The bug has not even made it to me yet as it needs to get through QA first.
     
    karl_jones likes this.
  6. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    324
    Thanks guys, I tried some of your suggestions, but none seemed to work.

    Also, I tested this on my Asus Zenfone 2, which has a PowerVR G6430 gpu and an Intel Atom Z3580, so it's certainly not limited to the Nexus 7.

    Testing different materials:
    4 Images = 51fps
    4 Images w/ Sprites-Default = 52fps
    10 Images = 26fps
    10 Images w/ Sprites-Default = 26fps
    15 SpriteRenderers = 58 fps

    It shouldn't be a batching issue as the uGui canvas is using just 2 draw calls according to the stats window.

    Meshes don't look like they're the problem:


    I know this is maybe looks like a contrived use-case, but I'm trying to build a hi performance, low battery drain app, and my app views will contain ScrollRect's, Image Manipulation and various other intensive features. So I really need the basic Gui to be as performant as possible, leaving as much resources available for my views as possible.

    Currently 4 uGui Images is all I need to get force the device below 60fps, while the SpriteRenderers can handle about 15. Fwiw, the results are the same when the images are transparent (Alpha = 0) or fully opaque, doesn't seem to affect things at all.
     
    Last edited: Jan 20, 2016
  7. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    The reason uGui canvas is using 2 draw calls is because it has been batched, so batching is still possibly the issue. Have you tried looking at the profiler?
     
  8. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    324
    I tried disabling static and dynamic batching for Android, seems to have no effect.

    The profiler is not too helpful. 32ms spent in Graphics.PresentAndSync > Device.Present, but the trail goes cold from there.

     
    Ianaa likes this.
  9. rutz

    rutz

    Joined:
    Aug 21, 2013
    Posts:
    51
    Any update here? I also have the same problem on Android.
     
  10. FastPaolo71

    FastPaolo71

    Joined:
    May 5, 2015
    Posts:
    2
    Hi,
    I'm not a serious programmer, so ... sorry for any funny word I can use.

    Btw, my experience is: I'm doing a small Words game (like Ruzzle). Same issue. I use basically ONLY GUI items (image, text, sprites) and the game goes to 30fps.

    Then I tried to deactivate the biggest images (background and a huge panel I had under the letter buttons) and the frame rate jumped to almost 60.

    Then, I've read on forum about the fact the Unity doesn't like that images (only UI images??!!) have an empty field in the "Material" field, so I applied the default SPRITE material to ALL my images in the game.
    Result: now the game plays at 60fps.

    hope it helps.

    Bye
    P
     
  11. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    The reason you got better performance here is that an empty material slot will mean that the default UI material and shader are used. In this case you switched them to use the default sprite material which uses the sprite shader which is a much lighter shader to use, it however does not support all the UI features such as masks.
     
    IzzySoft likes this.
  12. voporak5

    voporak5

    Joined:
    Jul 1, 2013
    Posts:
    31
    I'm seeing the same thing. I'm working in 2D.

    I have several backgrounds enabled and I'm transitioning between them in by simultaneously fading in my intended background while fading out the previous background. First I was getting 20 fps drop, 60 down to 40 when I had them all active at the same time but now I switched it so that it's only possible to fade 1 in and 1 out at any given time which brought me back up to 50.

    First I tried this by having my backgrounds as 2D sprites and after reading FastPaolo's results I tried throwing them onto my UI canvas and assigning the default sprite material, but I'm still getting the 10 fps drop.

    My transition calls are very inexpensive on hardware, it's this Image/SpriteRenderer problem where if the image is super big then there's the FPS drop and I know this for a fact because if I'm just sitting there doing nothing with all 3 backgrounds active then I get the FPS drop AND the files for the backgrounds aren't very large either.

    How should I set up the Image/SpriteRenderer components so I don't get this FPS drop?
     
  13. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Can you share some screenshots so I can understand better? When you say the issue happens when the sprites are really big my first thought is maybe it is an overdraw/fillrate problem. Have you tried running the profiler?
     
  14. ortin

    ortin

    Joined:
    Jan 13, 2013
    Posts:
    221
    Any idea why UI doesn't use conditional compilation default shader to enable masking code only when it's needed (i.e. object inside mask)? AFAIK you can easily enable masking keyword only when it's needed as you already update stencils and 2D Rect for UI objects which get into a mask.

    Yes, it would add a few drawcalls due to having two default material instances, but the difference of using a cheap UI material on everything outside masks is HUGE on middle-low end devices and even on high end it would contribute to the battery saving.
     
    Paul-Chen and Claytonious like this.
  15. Paul-Chen

    Paul-Chen

    Joined:
    Feb 25, 2016
    Posts:
    6
    Any updates? I also have this problem. I have to scale down the screen resolution. My game was a simple 2d game with uGui.
     
  16. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    The original issue that this thread refers to was not reproducible for our UI team and so they could not fix it.
    If you are able to provide a simple project that has the issues and submit it as a bug then we would be happy to investigate. Post the number if you do please.
     
  17. LeifStro

    LeifStro

    Joined:
    Mar 23, 2015
    Posts:
    29
    @karl_jones Did this ever get resolved? I noticed that on my android device the frames drop when I zoom the screen in such that a couple large images take up most of the screen (see image 1 -> image2, the FPS counter is bottom left corner of screen). However, if I move the screen to the left so that the large image is slightly off scree (or simply zoom out), then the FPS goes back up. Batching, vertex count, profiler etc don't give any indication as to why the FPS drop occurs.
    I am using URP, Unity 2020.3.15f2. The mobile device is a Samsung Galaxy 8.
    Please see attached images.

    Im guessing that the issue is overdraw. As the clouds each use the Shadow + Outline UI scripts.
     

    Attached Files:

    Last edited: Apr 6, 2022
  18. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    I don't know, it was 6 years ago and if you are having the same problem then I would say it did not get resolved. We still need a bug report with a project that has the issue so we can reproduce and investigate.
     
  19. LeifStro

    LeifStro

    Joined:
    Mar 23, 2015
    Posts:
    29
    @karl_jones Hey Karl, I think the issue is overdraw. The problem is that my project's URP version does not come with the Render Debugging window so I can't debug that aspect properly. But when I removed the outline and shadow modifiers the framerate went back up to 60fps (so overdraw was the likely cause).
     
    karl_jones likes this.
  20. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    That sounds plausible.