- Home /
Asynchronously loading large images from url
Is it just not possible to download a large 2048x2048 image into a texture in Unity3D without stutter?
I'm using a coroutine and the WWW class to do the download, however the WWW.GetTexture function shows up on the profiler taking 235ms on a PC.
It gets even worse if I want to create a texture with mipmaps as just constructing the Texture2D takes 450ms before using LoadImageIntoTexture or texture.SetPixels etc...
Surely there has to be a way to create textures (that are not being rendered yet) and upload to GPU asynchronously.
Anyone got any ideas? I'm assuming that I can't create a thread as Unity's API is not thread safe.
Answer by zharramadar · Apr 22, 2014 at 01:15 PM
The problem is, Unity will always load the entire image in memory when you create a Texture2D, no matter the method used. This takes time, and there's no way to avoid it. It won't parse the file and get bits of the image data, or load slowly per frame. This happens with any instantiation of anything in Unity, be it images, terrain, objects created by Instantiate(), etc.
If you require only the image data for some processing, I would suggest using a library like libjpeg or libpng (in a C# rendition of it) to get the data in another thread (you can use another thread as long as you don't invoke Unity methods), but if you have to display it, I don't see a way you're going to stop the lag.
Two things you could try, and I'm not sure it would render any results, is to create an array of Color32 containing the image data by using an external lib as I said before, and try to create a texture to it, see if it is faster than Texture2D creation via WWW, or you could try to setup a scene with your loading script, and call Application.LoadLevelAdditiveAsync() to load your scene, and see if it executes your script and create your Texture2D async or not (not sure a script will run before or after the scene is loaded async).
I do unfortunately need a renderable texture, what's frustrating is that the operation I wish to do should not take anywhere near the time it is doing. I've successfully loaded asynchronously large textures like these into the GPU without stutters when coding natively. There are quite a few similar questions to this on the net.
Has anyone out there managed to setup large up to 2048x2048 NPOT textures without Unity stuttering?
I've added some yields between the operations (texture construction, set pixels etc) and that actually makes things worse with the PC waiting for over 1027ms in Gfx.WaitForPresent.
It's totally crazy as we know the hardware is capable of loading and displaying large jpgs (so decompressing over a couple of frames and uploading to gpu and displaying within one) with no stutter as there are plenty photo viewer apps that do just that across the platforms (iOS, PC etc).
Really the www class should be coping with this as any solution creating C# arrays of Color32s is bound to be jumping through lots of unecessary hoops and the class is supposed to be the way to asynchronously load such assets.
If I find a solution I'll post here, until then I pray that someone else does, there must be plenty of people who want to keep a fluid frame rate while loading external textures. For now I'll restructure the app to cope with a pause. I love Unity but this is a real restriction.
Your answer
Follow this Question
Related Questions
Texture3D stays black no matter what? 1 Answer
Textures are Missing 1 Answer
Hexagonal Grids 2 Answers
What is the best way to create a simple colored plane object in NGUI? 1 Answer
How to create Sprite from loaded texture 0 Answers