How to reduce memory usage of dynamically loaded Textures in Unity? - unity3d

Overview:
Currently working on a project in Unity for iOS and Android, where at runtime we download and store images in PNG format for later use. When we need to we load these textures as well as some from a web server using Unity's WebRequestTexture and both file:// and https:// schemes respectively.
Problem:
The problem we are facing is that when we use the WebRequestTexture method the memory usage of the textures increases significantly.
Question:
Is there a way to potentially pre-compress the locally downloaded images into device compatible compressed formats, and then load them directly to the GPU without it increasing the memory size required?
If this is possible would using Texture2D.CreateExternalTexture allow us to then use these textures without further increasing the memory usage?

Related

Does Unity3D supports different pixel densities like native android?

Native android supports different pixel densities like ldpi, mdpi, hdpi, xhdpi, xxhdpi and so on. This feature balances app quality and app size.
Currently I'm facing this issue in Unity mobile games (iOS & android) when I use,
high quality graphics it increases crashes and lagging in low-end devices.
low quality graphics it looks blurry and pixelated in high-end devices like iPad Pro etc.
I can use 2 different quality images but again it increases app size as the low-end devices end up downloading the HD images too.
How to solve this issue?
I suggest looking at the Unity Addressables system available in Unity 2020 LTS and beyond. This is a whole new tool that you'll have to investigate so I cannot provide a quick class or line of code to solve your problem. However, the Unity Addressables system is available in the Package Manager with docs available here.
Using this system will likely make it easier to run hi-res assets on lower-end devices. Since assets are streamed in when needed your texture memory is going to be significantly reduced as textures are unloaded as soon as you're done with them.
Addressables can also be used to load in assets remotely which would reduce your total file size. However, depending on how far you are in development this could be a big change.
You may also want to look at splitting the application binary if changing over to Addressables is too much work. If you split the binary, you can reduce the initial download of the application and have users opt-in to hi-res textures. There are a variety of other solutions provided by the Unity docs on Android builds here.
Good luck on getting your game to a shipped state!

Unity - native texture formats explained

I have read the following here:
When you use a Texture compression format that is not supported on the
target platform, the Textures are decompressed to RGBA 32 and stored
in memory alongside the compressed Textures. When this happens, time
is lost decompressing Textures, and memory is lost because you are
storing them twice. In addition, all platforms have different
hardware, and are optimised to work most efficiently with specific
compression formats; choosing non-compatible formats can impact your
game’s performance. The table below shows supported platforms for each
compression format.
Let's discuss a specific case. Say I stored a .png file on a disc and packaged my game from Android. Now I play that game on an Android device whose GPU requires ETC2 as native texture format. Am I correct that when I enter the game the following should happen:
Read PNG file from disk to RAM (RAM is used for storing PNG file data)
Decompress PNG to RGBA32 (RAM is used for both PNG and for decompressed data)
Compress RGBA32 to ETC2 and upload to GPU (on RAM if I have a texture cash, then I might deallocate memory for PNG file data but I need to store RGBA32 for future reuse or at least I need to store ETC2)
This means I am doing lots of conversions between PNG->RBGA32->ETC2 and during that conversions I not only use CPU resource but also significantly utilize RAM. My question - did I correctly understood what happens when one does not package with native texture formats for targeted platform?
Yes, you kind of correctly understood what's going on here. However you misunderstood something: The way PNG relates to all of this. The compression methods implemented by GPUs to be applied on textures are very different to the filter+deflate method of PNG, so with every kind of GPU you have this kind of behavior.
What the Unity devs are trying to tell you is, that textures can be stored in the very format the GPU works with, and that for optimal performance you should identify which compression formats are supported on your target platform and bundle your asset file for that.
So for a game for platform X identify the compression formats supported by X GPUs, then pack your assets with that and ship the X version with that. Rinse and repeat for other platforms.

Is there a difference between uploading from file vs an in memory UIImage?

I'm trying to upload a file from UIImagePickerController. Is it better to upload an image from memory or save it to disk then upload to S3
Which takes less resources? Currently weaker devices like an iPhone 5 struggles to upload the file.
Your problem is that older devices have lower cellular speeds. There should not be any significant difference in WiFi speeds between iPhone 5 and newer models.
Since it is the uplink speed that is the problem, it makes no difference whether you are sourcing your image from memory or disk. Moving an image from memory to disk and then back to memory before uploading has no advantages except for the fact that only parts of the image maybe kept in memory waiting for upload.

GPU usage of webp on iphone, compared to png

I am currently working on an iOS game and the image resources seem to be a little too much. I heard of webP and wanted to know more about it.
I did some researches on webP and know that this new format requires much less space than PNG and its encoding/decoding speed is fast. But I found no article discussing the GPU burden when using WebP pictures, compared to PNG ones.
Is there any article out there on this topic?
Or can I do the experiment myself? I am coding in VS using cocos2d-x. I don't know what to do if I want to simulate an iOS GPU and monitor its memory usage.
Many thanks!
You can assume that the textures generated remain the same, ie render at the same speed, using the same amount of memory.
If you want faster loading and rendering and less memory usage, use the .pvr.ccz format.

Having to store too many image files

So I have a huge app. It is full of features, most of which require a couple images, and all of which have to be saved as part of the binary file. I worked really hard before the release to get under the 20MB threshold, to make the app more accessible to users. My release binaryt was 18.1MB.
So now, with the new iPad and its retina display, what should I do about updating all of my images for this new display. If I did include an updated copy, I would be way over the 20MB limit. Currently, I store some image files on my sever, and download/cache them as the user needs them, but im hesitant to do this with major features because I'm concerned some users may not always have internet access. And without some of those images, the app is useless.
Is there any way I can have an iPhone only install the iPhone graphics, and visa versa?
Apple has since raised the limit for all devices to 50 MB due to the release of the new iPad. This should hopefully allow you to fit all of the pictures in your app bundle.
One approach to minimize the size of your files is by compressing your PNG files. This will only minimize the size, and the images will continue to work correctly.
The links provided below will help you find a crusher you desire.
PNG Crush
PNG Compressor
ImageOptim