When to use basis texture?

Is there any thumb of rule on when and how to use basis texture? I have some of textures varying from 100kb to 1mb sizes. I mean I can convert all of them in basis format but will it improve rendering or is it overkill for small textures? Or maybe I just don’t know how basis textures work. It’ll be helpful if anyone can explain me this.

Thank you.

Regardless of the size (KB or MB) of your textures, the space they require in GPU memory depends mainly on their resolution, because they’re decompressed before GPU upload. One 4K texture is going to require about 90 MB (4096 * 4096 * 4 * 1.33) of GPU memory, and will probably take a noticeable amount of time to upload to the GPU as a result. If you find that your application freezes the first time it shows a texture, that’s typically why. By contrast the size of a KTX2/Basis texture might be the same on disk, but it will be much smaller in GPU memory because it remains compressed.

If your textures don’t take up much memory anyway, and the texture upload times aren’t noticeable, then spending time compressing the textures with KTX2/Basis may not be necessary. If you have multiple high-resolution textures it’s probably worth considering it.

6 Likes

More details:

2 Likes

ohhhhh, thanks for reply.
My screen is not freezing, maybe because I am loading and uploading texture on gpu before hand. So if I use basis format it’ll reduce the loading time, right? I mean the how much it’ll reduce the loading time is still depend on resolution of textures. I will not see much of a difference in loading time if I convert the textures of low resolutions into basis format, right?

I have a around the 10 textures of 2k resolution and other are small textures, so it makes sense to only use basis for those 2k textures.

Thanks again :slight_smile:

I would suggest using ktx (basis) for all textures, it simplifies your pipeline - you don’t have to use two different texture types.

Compressing smaller textures will yield smaller proportional gains - yes, but those gains will still be there. What @donmccurdy said:

this is slightly incorrect, it is technically true that it takes some time to upload a texture to the GPU, but the larger part is spent in “decode”. That is, when you try to upload, say a PNG as a texture to the GPU - it will first be decoded (decompressed), PNG is a fairly complex format to decode and a 4k image might take ~200ms to decode, actual upload of 90Mb of data to the GPU will be trivial by comparison, taking only around 5ms.

What @donmccurdy said about reducing this “freezing” is true though, since KTX textures are not decoded before upload. So you end up uploading typically 4x less data, so instead of say 90Mb, you upload only 22.5Mb, but you also don’t pay the decoding cost.

On top of that, compressed textures typically come with their own mipmaps, this further saves your GPU time to build those mipmaps.

On top of that, compressed textures run faster, what I mean by this is that sampling a compressed texture in the shader will be a few cycles faster than a normal texture, because hardware is optimized for that and compressed texture takes less space, so you’ll have more texture cache hits.

On top of that, since compressed textures take less space on the GPU, you can put more texture data on the GPU to use in the same scene before you start seeing any performance issues due to memory issue, also around 4x more (assuming your compressed textures take 4x space).

Compressed textures are not “free” though, and the biggest thing to watch out for is the compression artifacts, when you look at a poorly compressed JPG image - you will see colors being slightly off in some places and curved lines broken into blocky smudges. Compressed textures work in much the same way as JPG compression, so you can expect to see similar artifacts. Usually this is not a problem as long as you’re aware of it ahead of time and use proper compression settings.

Back to your question.

If you have a lot of small textures (256 resolution or less) - I recommend using a texture atlas. It’s not about compression, but more about avoiding texture switching, which is a significant cost overhead in its own right. You can find a lot of information on texture atlases here on the forum if you’re interested.

7 Likes

Wow, thanks for such a detailed reply. :slight_smile:

1 Like

ktx2 is good for online game play experience, but encoding takes too much time or significant file size, according to ktx2 profile.

I wonder if there’s another alternative, that can be used to encode and decode with quite fair performance.

Are you referring to compressing the textures from PNG/JPEG to KTX2? If so, this should be done offline and not in the application. It is slow, but that’s kind of the nature of the GPU formats. Some of the KTX2 encoders are faster than others, depending on what you’re doing.

If you’re referring to transcoding the KTX2 files into a GPU-native texture format, then I’m surprised it’s slow enough to be a problem (it does run on Web Workers). But if you needed to avoid that, the alternative is to sh ip the GPU-native texture formats directly. This requires creating several versions of each texture, to be used on different devices.

1 Like

Thanks for the reply.

I know it’s not the best place to ask this, but ktx2 might not be a good choice if we want to create a texture on live and transfer it to another location, due to the slow encoding speed – yes, it’s the scenario of compressing image/png to ktx2.

Another alternatives are customized jpeg with alpha enabled (hardware accelerated encoding/decoding available, using javascript), webp (small bandwidth with same level of encoding/decoding speed with png). DDS, PVR might have the same problem with ktx2 for this scenario.

So I’m wondering if there’s other alternative compressed formats, which are not VERY slow to encode.

Update: Stuck with the KTX2 with UASTC format, fastest profile. It gave me same output size, and 0.2s for encoding per 4k texture, which is reasonable even for online texture baking.