VK_FORMAT_BC2_UNORM_BLOCK - what is it exactly?

Hello guys,

I’m dealing with textures at the moment in my project and got them working.
At the moment I’m looking trough my code and looking in the internet for possible ways to handle objects different and so on…
Here is my problem. I can’t get my head around the flag VK_FORMAT_BC2_UNORM_BLOCK. The explanation in the documentation is not enough for me to really understand it.

My problem is that it says. It is a 128-bit structure and it is divided into 64-bit colorData and 64-bit alphaColor. The result will be 4x4 = 16 colored Pixel. That means 128bit / 16 = 8bit per pixel for all channels. There are 4bit left for all colors and 4bit for the alpha?

I’m not getting anywhere. I never had to deal with something like that so far. Please help me to be able to integrate my own TextureLoader…

Thanks so much in advance!

.black

My problem is that it says. It is a 128-bit structure and it is divided into 64-bit colorData and 64-bit alphaColor. The result will be 4x4 = 16 colored Pixel. That means 128bit / 16 = 8bit per pixel for all channels. There are 4bit left for all colors and 4bit for the alpha?

Basically, yes.

The general idea of all block-based compression formats is that they take an image and divide it into pixel blocks of some size. S3TC (where BC2 comes from) always uses a block size of 4x4 pixels.

Each block of pixels is compressed into a data packet of a fixed byte size. BC2 (aka: DXT3) uses a size of 128-bits or 16 bytes.

How exactly it does that is a matter for the particular compression format. I’ll describe the general S3TC idea, but other block formats work in similar ways.

S3TC blocks contain two color values. Of course, there are 16 actual pixels in the block, so that’s not enough colors. The color for a particular pixel is computed as a linear interpolation between the two color values. And therefore, each pixel’s “value” in the block is simply a (2-bit) number describing how much interpolation to use. Two 16-bit colors plus 16 2-bit interpolation values yields 64 bits.

The quality of compression in S3TC is therefore a function of how rapidly colors change within a block and how clever the compressor is at selecting the two colors, so that the result looks “close enough” to being right. Modern compressors are pretty good at this, and for large textures (which generally don’t have rapidly changing colors, since they’re large) it works quite well.

BC2 works as I described for the color. For the alpha, BC2 is really just a 4-bit alpha. So that means 16 pixels with 4-alpha bits per pixel = 64-bits.

I’m not getting anywhere. I never had to deal with something like that so far.

It is not your job to “deal with it”. Doing S3TC compression is a complicated thing that requires deep knowledge of image analysis and compression techniques. And unless you’re an expert in the field, you’re not going to beat existing compressors.

Nor is it your job to decompress S3TC images. The whole point of a compressed texture is that Vulkan can read it without you having to decompress it.

So unless you’re doing something very special, your job as a user of Vulkan is to use some tool to generate a compressed image from an uncompressed one, then simply read it from a file (DDS or maybe KTX if you want to use something esoteric) and send it to Vulkan as is. Vulkan will handle the rest.

The only time you might need to adjust a compressed image is to flip it vertically. Which is a complicated process that requires intimate knowledge of the specific format.

Thank you Alfonse Reinheart for that deep dive into texturing. My situation ist now following. The problem that I have at the moment that I can’t push raw data like a stack of floats directly to the gpu in the order RGBA. Actually I’m bound using that ktx format. It works well, but if there is a direct way using that memory I would prefer that. I don’t know how to do that… Can u advice a method for doing that or is it impossible?

I don’t understand what pushing “a stack of floats directly to the gpu in the order RGBA” has to do with compressed textures. I’m fairly sure that KTX supports floating-point images too.

It’s also not clear why you are unable to just pass your data to the GPU. The image formats are meticulously detailed in the Vulkan specification.