Search Unity

Animated PNG sequence - Sprite vs. UI Image

Discussion in 'UGUI & TextMesh Pro' started by Simon_says, Feb 17, 2016.

  1. Simon_says

    Simon_says

    Joined:
    Oct 19, 2013
    Posts:
    141
    I have a rendered png sequence of a gif/video animation, and I'm animating it using the animation system to create a gif effect. Is it better to use a SpriteRenderer or a UI Image for this?

    In Unity while profiling I've found that changing Image every frame cost much more than changing the Sprite of the SpriteRenderer, but now I see that UI Image makes 2 Tris and 4 Verts, and same Sprite makes 120 Tris and 124 Verts but the Sprite option gives more fps.

    What are the performance differences between these? What are the cases when it's best to use any of them(like having usual background rendered, or even a whole game UI based/Sprite based)? What need to pay attention about optimizations(vertices etc)?

    What my animator does is basically changing the sprite each few frames, there's no movement or physics or anything else.
     
  2. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    I'd go for sprite if it needs to move relative to camera; for UI if it's in screen coordinates. Just because this seems logical. I doubt performance difference is that big.
    Amount of tris and verts below 1000 per object almost never impacts performance directly. It's draw calls (batches and setpasses) that matter, also exact algorithm they use to play animation (hidden as it's Unity internals).
    This amount of tris and verts possibly mean that animation in sprite is actually 'unpacked' into a lot of vertexes and triangles so when you're playing animation all it does is change what vertex are rendered (only indice array as opposed to whole vertex data) which might cause a bit less CPU/GPU overhead when playing animation, but a bit higher memory usage. I'm not sure about it though. If that's the case, then Sprites are better for animations, but be wary of them moving with each Camera movement: recalculating Transforms might eat all performance gains if they're in screen space. This is subject to profiling.

    I suspect Sprite is better for world-space objects while Image is better for screen-space objects. Possibly also Sprite is better for animated obejcts while both are same for non-animated. I don't know by how much exactly those "better" are.

    Also never trust FPS, it likes to jump a lot - only trust profiler's millisecond cost. For precise profiling, try to avoid profiling inside editor and try to profile on release build.

    Also relevant: http://forum.unity3d.com/threads/performance-ui-image-versus-sprite.315177/
     
  3. Simon_says

    Simon_says

    Joined:
    Oct 19, 2013
    Posts:
    141
    My animated sprites are child objects of the Main Camera, so whenever the camera moves, sprites hold the same position. About verts I just gave an example for 1 sprite, in reality I use more than one sprite(just checked scene, ~2.3k tris, ~2.5k verts and 24 draw calls). Changing rendered vertex in Sprite instead of changing full texture in Image makes sense about performance, but how my animation works is that it changes the texture in both cases, as it's png sequence(1 texture for each frame).

    Is there a better (performance) approach to animating gif/video rather than png sequence?
     
  4. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    Each change of parent Transform also changes child transforms. You can ask profiler that.
    I said "per object" and "directly". Indirectly it increases amount of batches - that decreases performance a bit. Cost of 1 additional batch is a lot of times higher than cost of rendering additional 10000 triangles because you need to switch context using CPU instructions while rendering triangles is purely GPU work. Per object means my statement applies to any amount of objects if each one has that amount of vertices/triangles. Even if you use 1000000 objects. In that case you will run into slowdowns because there's too many batches and dynamic batching happening, not because there's too many triangles/vertices.
    Not full texture, but only vertex position+UVs(5 or more floats if there are normals and such per vertice) instead of only indices(1 int per vertice). If you're changing texture itself, that's additional SetPass call.
    That's inefficient way. Use sprite packer to create sprite atlas - it should start batching your animated sprites thus reducing amount of batches and/or SetPass calls if you have several Sprites (All performance cares on single object are preemptive optimization so I assume you have a lot of them).