BC Compression from one to other

Started by
8 comments, last by Alundra 9 years, 10 months ago

Hi all,

I'm working on compression of image in my engine.

When change from BC3 to BC1, you must convert BC3 to RGBA then RGBA to BC1 ?

It an example but the question is for all BC compression format.

Thanks for the help

Advertisement
You convert the source image to BC3 or BC1.
Or you make a very trivial tool that can do the alpha-channel conversion directly.
Or you take the loss and don’t convert.

If you have BC* and you convert to RGBA, some tools can convert the color channel back to BC* reliably in most cases, but you never have that guarantee, and the quality never increases compared to the original BC* image.
Additionally, if the image has alpha below the cut-off limit, the conversion will always be severely lossy, as the color channel for that block is encoded with 3 colors instead of 4.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

I think that if you try to support an optimised conversion path from any texture format your engine supports to any other, you will quickly run into a combinatorial explosion. Basically, it's a waste of time, just implement conversion from RGBA to your supported formats and possibly back again.

If you end up with some special case that you need to do fast conversion from one compressed format to another at runtime, then I would add that only when it becomes necessary. Your example for BC1 to BC3 (and back again) would probably be pretty trivial to implement (the colour blocks are more or less the same, the only difference is the alpha encoding system), but I wouldn't actually implement it unless it becomes very necessary, and I have trouble imagining any circumstances where it would be necessary.

Let it be noted that this is not terribly ideal, though it may be useful.

Whenever it is a possibility you want to convert directly from the source RGBA (for example) image, directly to the compressed format you will need. Lossy compression like BC throw away color information at each conversion, so if you go from one form of BC to another form of BC, some amount of color information is lost twice, compounding the loss of image quality. In some cases, where you're going from a form of BC with greater color fidelity to one with lower color fidelity (in other words, from greater bits-per-pixel to fewer), the difference may be negligable -- an example of this is if you want to use a relatively high bpp BC format image in your download package to reduce its size, but then you might want to compress it even further at runtime in order to optimize for a specific platform or GPU. Otherwise, its always best to go from source image directly to the final format if you can, and its basically never a good idea to go from a lesser bpp BC format to a higher bpp one because you will always suffer the poor image quality of the lesser bpp format -- the only real exception to this is if you can inflate, say, full-fidelity alpha from a stored or computed mask that wasn't in/accommodated by the original BC format.

As far as mechanics goes, yes you probably want to convert back to RGBA (or some other full-fat representation) as an intermediary, then convert that to the target format to avoid the combinatorial explosion that C0lumbo points out. Use that strategy as your basis, and if there are particular source/target conversion pairs that are especially worth optimizing, you can do that too. If you're coding in C++, template specialization would be a good way of combining those general and optimized strategies in a way that presents a consistent interface to client code.

throw table_exception("(? ???)? ? ???");

if you go from one form of BC to another form of BC, some amount of color information is lost twice

This is not strictly true. I very slightly hit on this, but because the colors from the first BC* compression have already been quantized to the 4 colors available to each block, the second routine is likely to pick the same 2 key colors as in the first BC* routine.
A compressor can miss, so there is no guarantee of this happening, but also no guarantee it won’t (unless you go from BC* to BC1 with alpha below the cut-off).
So a better way to say it is that color information might be lost twice.

I do know for a fact it is not guaranteed because I discovered that one of the textures I had on one of my test models was actually an RGB convert from a BC format (I got it free online but someone probably ripped it from a game and used a cheap texture-extraction method).
After converting it back to BC* via The Compressonator an image compare showed 0 difference. It was able to find every single key color for every single block on the image. This time…

Still, the message is: Don’t do that if possible.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Thanks for all messages.

It's because I have a class "Image" with "LoadFromFile" who loads dds,png,tga,psd and other formats and that end to be BC or RGBA8 or RGBA32.

In the class I have a function "ChangeFormat( const TImageFormat& )" and it's here the question was from.

The easier way but maybe not the best sounds to convert from RGBA then the new BC format.

if you go from one form of BC to another form of BC, some amount of color information is lost twice

This is not strictly true. I very slightly hit on this, but because the colors from the first BC* compression have already been quantized to the 4 colors available to each block, the second routine is likely to pick the same 2 key colors as in the first BC* routine.
A compressor can miss, so there is no guarantee of this happening, but also no guarantee it won’t (unless you go from BC* to BC1 with alpha below the cut-off).
So a better way to say it is that color information might be lost twice.

I do know for a fact it is not guaranteed because I discovered that one of the textures I had on one of my test models was actually an RGB convert from a BC format (I got it free online but someone probably ripped it from a game and used a cheap texture-extraction method).
After converting it back to BC* via The Compressonator an image compare showed 0 difference. It was able to find every single key color for every single block on the image. This time…

Still, the message is: Don’t do that if possible.


L. Spiro

Yes, I probably worded it imprecisely. The color information is lost once, and its not present to be considered the second time around. But because of how the BC formats work, you wouldn't end up with different color values unless it's affected by alpha as you say, and I would think pre-multiplied alpha in particular.

throw table_exception("(? ???)? ? ???");

Is it possible to generate mipmaps of BC data without convert it back to RGBA and make a dynamic array and resize each time until 1x1 is reached ?

No.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Ok that answer a question.

Still one about that is the BC6H format, MSDN says it's half float but to convert to BC6H, the original input is an array of float ?

When you convert a BC6H, the output is an array of float ?

Since this format uses float, it has to be converted with correct endian right ?

Thanks

This topic is closed to new replies.

Advertisement