Texture atlas composed of basis compressed images

Is it possible to create a texture atlas that is composed of basis compressed images that would be usable by THREE, while still getting some memory savings on the GPU? If this is possible, how much memory would be saved?

Context: I have a bunch of images that are all already individually basis compressed. I also am currently constructing atlases on my server using uncompressed images, and then basis compressing the entire atlas. I’d like to move the atlas creation to the client. I know that it is possible to use render targets to create an atlas texture directly in THREE using uncompressed images. However, the output atlas is also uncompressed, which dramatically increases the memory load on my client GPU. I’m looking for ways to generate atlases on the client but retain the memory savings inherent to using basis compressed images.

Generating Basis-compressed textures on the client will be very slow and lossy — decoding, merging, and then re-compressing. three.js doesn’t provide tools to do this, but you can find WASM implementations in Basis Universal or KTX-Software. I don’t think two Basis textures can be merged without lossily re-compressing them both, but you could ask at the Basis repository to be sure.

In general the idea is to do compression offline, and here that would mean also generating the texture atlas offline.

Thanks for the reply.

I figured that there’s no world where we pursue decoding, merging, and recompressing. Either we do it all on the backend, or we find a way to merge basis textures (if that is possible).

(For completion, we COULD send the client uncompressed files and basis compress them client side, but I don’t think it would make a lot of sense for our use case; still, thanks for the links to the WASM binaries)

Just to compile some more of my team’s research, we did find a webgl api call (WebGLRenderingContext.compressedTexSubImage2D() - Web APIs | MDN) that allows for handling a subrectangle of a compressed texture, which could possibly be used for generating atlases?

There are some THREE examples of partial texture updates using uncompressed textures, e.g. three.js webgl - texture - partial update but I don’t know if this would work with compressed textures as well

Also, started a thread here (Merging multiple basis compressed images · Issue #302 · BinomialLLC/basis_universal · GitHub) on the basisu repo

Ah that’s a great point – you don’t necessarily need to merge the Basis-compressed data, because KTX2Loader will be transcoding it to something some target format with the client device anyway, like ASTC or ETC2. So something like this could work:

  1. allocate a 4K ETC2-compressed texture in GPU memory
  2. transcode N textures to ETC2
  3. upload each of the N textures to specified regions of the atlas

The target formats will depend on the device — see the two developer guides below for details on that:

1 Like