What performance improvements to expect from .basis texture / compressed texture

Hello,

I went through the documentation of compressed texture: Multi-Platform Compressed Textures - Babylon.js Documentation , and in particular .basis texture.

Before investigating further this topic I thought I might ask if on paper it is worth investigating.

My scene has one very large texture of 7000 x 7000 px, but is super simple with only a big mesh of 10000 vertices / faces that gets this texture applied to it. There is no light etc etc…

Besides advantage regarding texture size, RAM usage and CPU on loading, my question is do you think there will be significant performance improvements of the scene once loaded with this texture compressed instead of a JPG file ? Or once loaded on the GPU it is the same ?

Thanks.

Compressed texture are more gpu friendly as they are used compressed on GPU to. Caching, uploading and fetching might be faster to due to the reduced bandwith requirements:

Considering your use case of a unique texture, you could try and measure the cross device gain but I am not sure it would dramatically change your perf, it would still be better (though not significantly if you are bound somewhere else) but might lead to a reduced visual quality (artifacts) depending on the usage you have.

Ok many thanks for the feedback, I will update this topic when I try but I won’t priorize it for now. I guess the bottleneck is more on the mesh complexity.

1 Like

Just to chime in here, I’ve been doing experiments using .ktx textures, and in general the results of using compressed textures are pretty impressive. First of all, when a texture is not compressed, the GPU doing a lookup needs to traverse every pixel to find the uv position for the shader. In a very large image that’s going to be slow. And before it can do this, it needs to uncompress the texture from whatever compression scheme it’s using, such as .png or .jpg. This will then be uploaded to the GPU where it’s stored in both GPU and CPU. A .basis or .ktx file, however, will store the compressed versions only on the GPU, and they won’t be uncompressed at all. When it’s time to look up the texture in the shader, it can uncompress the data in 4x4 blocks, which is much faster. Also, as you pointed out, the memory footprint is much smaller on compressed formats. In my tests, a crunched DXT texture takes up just 25% of the GPU memory that an uncompressed one does. And as we know, it doesn’t matter if we use JPG because it all has to be uncompressed to send to the GPU either way, so compressed textures are faster to load. On my test, load times were reduced by 50%.

So I think it’s well worth the effort. I’m not going with .basis right now, only because it’s not as well supported and the tooling doesn’t have an npm library to help make it easier on Jenkins.

Hey @Alex_B , many thanks for the feedback … I’ll keep you posted when I give it a try !

basis is a bit different as it still requires some load time to convert to the actual gpu compressed format so load time might not be a big win.

But the runtime win will be there in a simple way as you do not need to yourself support all the different compressions.

1 Like

Thanks for that reminder. I saw the Binomial talk and their ultimate goal is to have the Basis decoder be implemented in GPU hardware instead of code, which would make that the clear winner, but you’re right that the current implementation is (I believe) that Basis transcodes into DTX, ASTC, etc based on the device, so it essentially works the same as Babylon’s check for associated extensions. Except that Basis then unpacks into that format on the fly so you only need one file. I think it’s better to pre-compress the textures as KTX files for now, but I haven’t done any benchmark tests to confirm that.

But it is 100% worth the time to use compressed textures over PNG and JPG files :slight_smile:

Quick update here, I tried with KTX (DTX) compressed texture. And I don’t see much improvement after everything is loaded vs a .png file.

That said the biggest improvement came from using power of two texture actually, as it was required for the compressed texture I then did the same for the png file. And it improves drastically the perfs.

I think this is a great demonstration of how much smaller compressed textures are:

http://toji.github.io/texture-tester/

Note that a Crunch compressed DXT1 file is even smaller than a JPG file. But look especially at the GPU memory footprint.

I once had to write this up so here was my explanation:

A square 4k image that’s 32-bit (8 bit per channel, RGBA) will use:

4096 * 4096 = 16,777,216 pixels
8 bits per channel * 4 channels = 32 bit = 4 bytes
4 * 16,777,216 = 67,108,864 bytes = 64 megabytes
And it needs to exist both on the GPU and in main memory.
A KTX file will be 64 bits per 4x4 pixels. (1024 * 1024) * 64 = 8.3 megabytes This also only exists in GPU

Yo @tdurand

What do you mean you did the same for png… What did you do to the PNG file that improved performance ???

Make it a power of two

Yes, I made the png a 8192x8192 file and it improved a lot performances.

And yes it is true, the DXT file is something like 3-4x smaller than the png I think…