Search Unity

Unity iOS Image Sizes

Discussion in 'Editor & General Support' started by MattRix, Dec 18, 2012.

  1. MattRix

    MattRix

    Joined:
    Aug 23, 2011
    Posts:
    121
    So I'm making a 2D game for iOS and I have one texture atlas for the Retina iPad that's 4096x4096. My source png file is 1mb.

    In Unity, I have it set to an "advanced" texture so I can disable mip-maps, and the only viable export format option if I want it to look decent is RGBA 32-bit. At this export setting, the image size balloons up to 64mb (4096x4096*4), which when combined with my other huge images, makes my app a ridiculous 122mb (but only 14mb when zipped!).

    Am I missing something? Is there some export setting that will export a lossless yet compressed image (ex. png)? When I build for the WebPlayer, the app size gets compressed down to only a few MB (I guess due to the LZMA compression), I don't really see why Unity wouldn't do something similar with an app's resources.assets package on iOS, a platform where file size is even more crucial.
     
    Last edited: Dec 18, 2012
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, although you can save them as PNG files and use System.IO or the WWW class to load them at runtime, though obviously you lose some workflow efficiency when doing that.

    As you mentioned, you zip the app and send it to Apple, so it shouldn't be an issue, at least as far as downloads go. While the executable itself doesn't compress well after being subjected to the DRM, the rest of the assets do. The web player build is smaller because it's not including the engine, only the assets. The Unity web player plugin is what actually contains the engine.

    --Eric
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    If you use ARGB32 then your image has a size of width * height * 4 bytes.
    Anything thats meant to be smaller (after load it will always have this size in memory - loading from external in any form will cost you 2-3 times that memory at least - and memory might be a thing you need to worry more than filesize in the end) needs to use PowerVR hardware compression as only these images can be smaller.

    But the real problem here is that you look at the raw image size in the editor. Its not the size of the image afterwards or its resource actually.
    To get that, do a build to iOS and look into the editor log to see how big it is then. This size will be further reduced later on through the compression of the IPA for the sending but it gives you a good idea. It will definitely not be remotely close to 64mb anymore normally :)
     
  4. Glockenbeat

    Glockenbeat

    Joined:
    Apr 24, 2012
    Posts:
    669
    Just to emphasize this a bit more: Although current devices have much more memory than older ones like the 3GS you can run into some heavy trouble with such huge textures, meaning run out of memory which will crash the app. On the 3GS for example you'll certainly get not more than around 100 MB (which is already a quite high estimation!) to use for your app, and usually textures (including lightmaps) take the majority of that.

    So you'll possibly need to reduce the atlas size depending on the target devices.
     
  5. MattRix

    MattRix

    Joined:
    Aug 23, 2011
    Posts:
    121
    That's a huge pain for something that could easy be built in to the Unity workflow though, no? iOS handles PNGs fantastically, I don't know why they wouldn't at least be used on that platform.


    If I understand correctly, even though the build I send Apple may be compressed, the final size on the app store is uncompressed (note that I'm not really sure about this). I want to make sure my app size is as small as possible, it's very important to be below the 50mb limit. And even if the actual app download is compressed, I don't want the app taking up hundreds of mb on the user's device, because it'll be way more likely to be deleted.

    I'm not worried about memory usage at all. My game has only a few atlases, and there are different ones for different devices, so I won't ever be loading more than I need. PVRTC texture compression is fine for a 3D game, but is awful for a 2D game. File size is incredibly important on iOS, being under the 50mb limit can make-or-break your app, especially if it's a free app.


    I'm pretty sure that's incorrect. When you see the image in the Unity editor library, it is overlayed with the resolution and size of the image *for your specific platform and output settings*, so when it says 64mb, it shows up in the IPA as 64mb. I've looked at the actually .app file and it is well over 100mb, which is ridiculously huge for what it is.

    I'm using different atlases for different devices based on their screen sizes, so on a 3GS the atlas will only be 1024x1024.



    I've gotta be honest, I'm amazed that people seem so unconcerned about this issue... it seems like a huge deal to me. How is it acceptable to have each texture stored uncompressed in the file system, especially on iOS, which can handle PNG files really well? File size is still a big deal on iOS.... not to mention the fact that if an app is huge, a user will be more likely to be delete it from their device now that iOS makes it easy to check which apps take up the most space.
     
    Last edited: Dec 18, 2012
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, as I said, only the executable isn't compressed. The rest is.

    Because it's mostly compressed on the store.

    --Eric
     
  7. MattRix

    MattRix

    Joined:
    Aug 23, 2011
    Posts:
    121
    Sorry I just edited the post to add that I'm also concerned about the app being huge on the user's device... I don't want it to be some gigantic 200mb app, because then it'll be much more likely to be deleted. Worth mentioning that a large app size takes way longer to transfer to the device when testing... and also, isn't the png compression still much better for the image files than the ordinary zip compression?
     
    Last edited: Dec 18, 2012
  8. MattRix

    MattRix

    Joined:
    Aug 23, 2011
    Posts:
    121
    As an update, I've switched to importing png files manually. This has given me much smaller app file sizes, and the loading performance seems to be basically the same (at least for my purposes). It also has the added benefit of making iOS builds and deploys much faster, because now the app is 1/10th of the size that it used to be :) . but anyway, here's the code I'm using (note that I had to rename my image extensions to .bytes instead of .png):

    Code (csharp):
    1. string filePath = "path/path/myImageName"; 
    2. TextAsset text = Resources.Load (filePath, typeof(TextAsset)) as TextAsset;
    3. Texture2D texture = new Texture2D(0,0,TextureFormat.ARGB32,false);
    4. texture.LoadImage(text.bytes);
    5. //do stuff with the texture
    That's it! Pretty simple. Why this isn't already built into Unity is crazy to me.. :)
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Assuming you are talking about 24-bit PNGs, not that much better, since they are both lossless compressed. The only way that PNG can be compressed significantly better than zip is if you're using 8-bit PNGs.

    --Eric
     
  10. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    What others have said. Right now the built-in textures in Unity all use GPU-ready image formats: uncompressed or DXT/PVRTC/... compressed. So for example, a 1024x1024, uncompressed (4 bit/pixel) image without mipmaps is exactly 4MB. Both in the game data file and in memory.

    Now, many platforms will compress game data files by themselves. E.g. on iOS, the AppStore does compress the data (using pretty much "zip"). In web player, Unity itself will compress the data (using LZMA). And so on.

    So in the "app store", the game will be smaller since it will be compressed somewhat. When it is downloaded and unpacked into the device, it will expand and will take up more space.

    And yes, you could use PNGs yourself if you want somewhat better compression (*) and smaller game size, when installed unpacked on the device. Loading speed might be somewhat slower due to PNG decompression.

    (*) in theory both "regular app store compression" (ZIP) and PNG use exactly the same ("deflate") lossless compression algorithm. However, PNGs also have lossless "pixel predictors" to aid compression, and in the case of textures with very smooth gradients or large portions of same-color areas, PNG will compress better than just zipping the pixel data.

    Currently we don't have immediate plans to add "native" texture JPG/PNG format support in game builds. The thought has been on the minds of some developers, but no one really started working on it yet.
     
    BruceBai likes this.
  11. MattRix

    MattRix

    Joined:
    Aug 23, 2011
    Posts:
    121
    Thanks for the info Aras. It's good to know that it has at least been considered. We've found that at the very least, using pngs has decreased our *deploy* times on iOS *dramatically*, so consider this a vote for it to be added in the future! :)
     
  12. davekalina

    davekalina

    Joined:
    Apr 2, 2013
    Posts:
    39
    Please consider this a strong vote for the implementation of "native" texture PNG format support.

    Much like Matt, I'm fairly surprised to find that this functionality doesn't already exist, given its importance to 2D mobile game development.

    Why I think Unity should add this functionality natively:

    - Installed package size matters. Yes, the pre-distribution compression of an iOS .ipa will bring the package size down a bit -- and then it explodes to uncompressed size once on the user's device. Mobile devices do not have 'unlimited' storage capacity as they effectively do on PC, and users often make purchase decisions (and 'should I keep this installed?' decisions) based on the size of the application.

    - Deployment time matters. In my pre-Unity life as an iOS developer, I tested on device far more frequently. Deploying from Unity onto an iOS device is now an extremely slow process, and a big part of that is the fact that these perfectly lossless compressed PNGs are, unfortunately, decompressed before the lengthy processes of building an xcode project and then copying the package to the device over a USB connection.

    - Give us the capacity to choose the set of trade-offs appropriate for our own projects -- am I ok with a larger package size so that I may have faster loading times? Or perhaps I would rather reduce package size and take the hit when the software decompresses a PNG into texture memory at runtime? The developer is basically always the one in the best position to make this decision for their project.

    - Asking us to work around the issue with code like the sample Matt posted creates workflow difficulties and poses problems for working with third party solutions.

    We're using 2DToolkit and Spine for our new Spider game. 2DToolkit recently added a feature called "PNG Atlases", which, unfortunately, is a gross hack designed to work around the limitation of PNGs being treated as uncompressed textures. The way it works it that the PNGs are saved to disk with phony ".bytes" extensions so that they can be referenced as "TextAssets" and then loaded into a texture at runtime as Matt describes above.

    Certainly it's the third party software provider's responsibility for making this stuff work properly, but at present, making this stuff work with textures in the editor is a bit of a mess. On top of that, Spine doesn't know how to deal with a Texture that is not actually a Texture, so at present, I am incapable of using Spine in conjunction with 2D Toolkit's PNG textures, resulting in 10s of MBs of textures in our project that are uncompressed in the final package.

    More about our situation:

    We're working on Spider: Rite of the Shrouded Moon, which is a sequel to the 2009 iPhone game Spider: The Secret of Bryce Manor. Spider is a very content heavy game, especially for mobile, as every level is composed of many unique art assets. The original Spider -- written in native Obj-C++ -- clocked in at about 95MB total package size (after all content updates). The new Spider currently has about 1/5 of its final planned content, and recently clocked in at 781MB installed (as reported by iTunes, and the compressed .ipa was 215MB). After going through the process of working with 2DToolkit's PNG Atlas feature (and cleaning up unnecessary references), and in spite of the limitations mentioned above, the package came down to 210MB installed / 154MB .ipa. If our content really does multiply by 5x, we're looking at a project approaching 1GB, and this is WITH the use of properly compressed PNGs. But without the 2DToolkit work-around or a custom code solution, our project could be in the 4-5GB range, which is simply unsustainable for a mobile game. We're quite aware of the fact that our game is going to be a big package, and that's OK, but for us there's simply no question that taking the massive savings in package size due to PNG compression is worth a couple of seconds of load time for every level.

    If Unity is serious about supporting native 2D moving forward (as one would assume from the features added in 4.3), this feature is absolutely necessary, and will benefit devs and users throughout the Unity ecosystem.

    Thanks for reading!
    David Kalina
    Tiger Style
     
    SvenK, DarekRusin, hessel_mm and 2 others like this.