How can I reduce the on-disk size of my lossless textures?

Hi, I’m curious to understand my different high-level options when it comes to reducing lossless texture size to not deal with giant RGBA32 textures. This is for mobile devices in particular. These textures are taking up hundreds and hundreds of MB for me, and every new background is at least 12mb. Here are some strategies I can think of, without resorting to lossy textures (some textures include text, all are actual pixel data for the screen) or reducing the texture size and upsampling.

Simple, universal strategies:

  • Use a .png, unpack it at runtime
  • Use LZ4 compression in the .unity3d file (due to the lazy decompression of LZ4 blocks, do people try to also preemptively decompress stuff they’ll need later in real-time?)

Specialized ones, that seem more cumbersome to implement/maintain:

  • For a texture that is one big solid color background with some small item in the middle, store the item’s texture separately since as a much smaller texture and use a solid texture behind it
  • For a texture that is just different shades of a specific blue-green color (e.g. a gradient), use a solid texture of that color (programatically defined), along with a texture of just alpha values, and a white texture behind it
  • For a texture that consists of a small object on top of an existing texture, programatically render the small object on top of existing texture (will the .resS file just de-duplicate the data between the two textures anyways?)

What are people’s thoughts? Is there a strategy here I should generally default to?

There’s a reason why lossy compression exists. Try playing with the various options to see which kind of “loss” you can live with. The size increase is well worth it. Like 5-10 times quite easily.

Or change to 16-bit color data formats, making it half the size. That’s also “lossy” of sorts and works best if the art was created with 16 bit as the target to begin with but may work for you too (but not with gradients, at least not without dithering).

Definitely don’t use a fullscreen image just to have a background for something. Solid colors can easily be created with a 2x2 texture and gradients with very little coding (a quad with vertex colors for instance). I believe there’s even options for that via GUI canvas stuff.

If you want truly lossless textures at minimal data size, you have to generate them either procedurally or use vector graphics. There are C# libraries that can render svg files to an image, for example. You would only have to do it once at load time.

Might also be worth looking into crunch compression. Not lossless, but it was designed for textures: https://blog.unity.com/technology/updated-crunch-texture-compression-library