Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Efficient way to render many images at once in a Unity scene to make a kind of photo browser?

Discussion in 'Editor & General Support' started by AzzyDude24601, Feb 3, 2021.

  1. AzzyDude24601

    AzzyDude24601

    Joined:
    Sep 28, 2016
    Posts:
    51
    I am developing a type of multimedia analytics tool using Unity and the primary data we are targeting is a dataset of around 200,000+ images. All of the actual analysis takes place on a server but I need an efficient way to handle and render all the image results in Unity once I receive the file names from the server.

    Right now I am hosting the 200k images locally on my PC running Unity and when I need to render a set of results in the scene (anywhere from 10-20 to sometimes 500+ images) I just convert the JPGs to bytes using File.ReadAllBytes() and then use Texture.LoadImage() to read the bytes as a Texture2D's. Then I just apply those textures to some game objects in the scene.

    This works, but it is obviously not very efficient. Furthermore, once you get over a certain number of images, it really starts to lag, and the loading time can get ridiculous. There definitely must be a way around this because we have implemented a similar browsing system in Chrome, rendering the same images, and there was no lag at all, so I am sure it is possible with Unity.

    Does anyone any recommendations?
     
  2. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    What part does lag? Loading them or all the time once its loaded?
    What size are the images and do you load the full resolution of all images of your set?
    It may be possible to have thumbnais loaded and only load / unload images that you are actively looking at / need the full resolution.
    I have used the UnityWebRequest
    class before for loading image files from disk and that worked fine as long as you not load to many per frame.
     
  3. AzzyDude24601

    AzzyDude24601

    Joined:
    Sep 28, 2016
    Posts:
    51
    Well the two major bottlenecks are when the game objects are being generated and I am converting the JPG's to bytes and then to Texture2D's and then applying them. This is all happening at runtime after the user submits a query and it can take quite some time to load if there are a lot of results. The second bottleneck is when the objects with their textures are actually loaded and when you're dealing with over 500 images the frame rate starts to lag.

    Right now the original image resolutions are kinda big (like 3-4MB in size) so I have downscaled them (to around 200KB-400KB). I guess I could make them even lower res when the user is far away from a game object and load higher res when they get closer...? Is there a way to do this without having to duplicate all my data at different resolutions?

    And I didn't know you could use UnityWebRequest for local files - is that more efficient than what I am doing with File.ReadAllBytes() and then use Texture.LoadImage() ??
     
    Last edited: Feb 3, 2021
  4. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
  5. AzzyDude24601

    AzzyDude24601

    Joined:
    Sep 28, 2016
    Posts:
    51
    In my actual code I am reading the files in a separate thread and it does work well, but it doesn't change the fact nothing happens for a long period while the images are being read. Like, the game doesn't freeze but when you need to load several hundred images, the loading time can be over 10 seconds so I was just wondering is there a better way to do this so it doesn't take so long to load? Is Texture2D.LoadRawTextureData() better to use in this instance instead of Texture.LoadImage()?

    And what exactly would you like me to confirm with Profiler?
     
  6. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    Profiler, just to see whats happening in mainthread, if there lots of garbage collection generated, which methods are slowest, how much memory used, framerate etc.
     
  7. AzzyDude24601

    AzzyDude24601

    Joined:
    Sep 28, 2016
    Posts:
    51
    Very little garbage collection occurring and the methods are pretty fast until you get a result with a lot of images in it. It is next to impossible to load any reasonable number of high res images. I have had to use the low res ones exclusively at the moment to produce anything feasible. I wonder is it possible to downsample the image programmatically when the bytes are being read by Unity...

    I also read Unity doesn't do garbage collections on Texture2D's you make at runtime, so you need to make sure to Destroy() them yourself?