I’d really like a crunched single channel texture option like Alpha8 or R8.
My use case is the WebGL client downloads many assetbundles that need to be as small as possible. I wrote a shader for that to use single channel textures as a mask for effects, and I thought that using Alpha8 would give me a tiny texture, but then realized it didn’t support compression and was actually 7 times larger than a full DXT5 crunched texture of the same resolution!
From more research on the subject, it looks like this is not supported at the hardware level and would need to be decoded on the CPU before sending to the GPU… I find this acceptable since the download is what I need to optimize in this case.
A DXT5 and Alpha8 or R8 texture are identical in size, both in the build and on the GPU. They all use 8 bits per pixel, though they will get compressed a bit via LZMA or LZ4 compression if it’s enabled. The bad news is images don’t generally compress well with those compression types. Crunched DXT5 textures have an added layer of compression for builds that gets decompressed on the CPU before being uploaded to the GPU. The compression done works well with image data, so it’s much better than straight LZMA.
However the cheapest way in terms of build size to do a single channel texture for WebGL would be to store it as a PNG file and load it at runtime using Resource.Load, or a WWW request.
You can then copy a single channel the Texture2D created into an Alpha8 or R8 texture you actually use so you’re not uploading an uncompressed RGB or RGBA texture to the GPU.
Or use the 3 or 4 channel packed Crunched DXT trick @neoshaman mentioned and save yourself some headache (at the cost of a lot more compression artifacts).
I have thought about other ways to go about this like you guys have suggested. I suggested this feedback for the least pain from a developer/artist point of view, where the artist just creates the mask in photoshop, imports it into Unity, hooks up the reference in the material, and builds the bundle. I’d be happy to write the compression/decompression algorithm myself if Unity provided that option with the texture import.
Well, Crunch is a specific file format and toolset by someone outside of Unity specifically for compressing DXT5 textures initially, and expanded to DXT1 and eventually ETC textures later. It’s also a dead project, and Unity is unlikely to try to continue any work on it.
The author of Crunch moved to working on the Basis format which is intended as a universal compressed file format. Like Crunch it is highly compressed on disk and decompressed directly into GPU friendly formats. The big difference is a single Basis file can decompress into different GPU formats depending on the platform. So you could have a single .basis file and it’d decompress into DXT5 on PC, and ETC or ASTC on mobile. Unity hasn’t said if they’ll be supporting Basis or not, though it is something they’ve said they’re looking at. Technically it’d be possible to support Basis yourself by writing your own importer, but it would definitely affect the work flow of your artists as you would need an additional re-export step.
If they do add support for Basis, another option you could use would be BC4. It’s a single channel format that is essentially the DXT5 alpha channel by itself. Until then a Cruch DXT5 will still probably be smaller in the build than using a BC4 since that’ll be 4 bits per pixel, and Crunch can get the 8 bits per pixel DXT5 down to 2~4 bits per pixel.