Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Most optimal way of rendering many, many sprites?

Discussion in 'Scripting' started by Thomas-Mountainborn, Sep 28, 2015.

  1. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    489
    Hey there,

    I created a Matrix-like code rain effect for a project (entirely Matrix unrelated and with a different set of symbols and colours, the client just likes the effect), and while I get a smooth 60 FPS with 2 layers of the effect running on my dev PC (with about 12.5 k symbols each each), it runs ever so slightly laggy on the target hardware, a recent laptop. I was wondering if anyone had any advice to share on how to optimize the effect.

    I started out using a Canvas and Images, because that seemed like the obvious choice at first. However, the effect was very, very slow, even in Unity 5.2 which was supposed to have optimized the UI for many elements. The profiler showed there was a lot of overhead created by the Canvas elements.

    I'm now using a grid of Sprites, and all code symbols share the same sprite sheet. Deactivating the renderers of sprites that are not currently displaying anything is also a big performance boost, obviously. I'm also caching WaitForSeconds in the coroutines of all participants to avoid garbage piling up and requiring collection. Is there anything else I can do with this set up to improve its performance? Nothing really jumps out in the profiler anymore, it's mostly just that there's a whole lot of sprites that need dealing with by the camera.

    I thought about having a shader fill a texture with the symbols and having the CPU only decide what elements should be active with which symbol and color by encoding that data in a texture and sending it to the GPU (one pixel per symbol), but that would require a lot of work that might not be necessary.
     
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Tried a particle system? Particle systems are designed for showing high numbers of similar images with decent performance.
     
    Not_Sure likes this.
  3. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    I would try to reduce the amount of sprites. 12.5k sounds as you do create sprites to completely fill a 111x111 matrix. But the rain effect hardly ever covers all 12.5k fields at any given time. It probably uses 50% (or less if you limit the effect) of the matrix field.
    So I would build a sprite object pool having the maximum amount of sprites my taget device an handle. The I would take sprites from the pool if I need to show a char and move the sprite to the matrix field. Then I would release the sprite if the field gets empty/black again. I guess you could easily cut the amount of sprits bis 50% and double your performance doing this.

    [e] sorry for all the typos. this is a mobile device ;)
     
    Last edited: Sep 29, 2015
  4. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    489
    I took a fresh look at the profiler this morning, and noticed that were was still one thing remaining after all - the Update loop of the script on the individual sprites. There was nothing in that Update yet - I was planning on adding some additional colour changing behaviour in there later. But obviously, even empty Updates need calling, and it adds up when there's a lot of them. Taking that out improved the FPS a boatload.

    Duugu, that's indeed a good observation - I'm already disabling the sprite renderers of non-active symbols though, and now that there's no Update anymore at all in the elements, there would be no benefit to shuffling the game objects around in a pool, as far as I'm aware. It would reduce the instantiation time though, but that's not an issue here.

    BoredMormon, using a particle system in this way is definitely something I'll try next time I need to create an effect with similar requirements.
     
  5. MikaelT

    MikaelT

    Joined:
    Mar 23, 2013
    Posts:
    15
  6. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,541
    Are you caching their transform?