Hello. I’m getting dxt1 blocks with flipped endpoints (binary alpha) when selecting BC1 as the encoding format (which is supposed to discard alpha). This happens if the src image is 32bit and has alpha. If the src pixel either has a=0 or a=255 we’re good (we get a properly ordered no-alpha block), but not otherwise?
In the image I’ve coloured the incorrect pixels red.
The decoder is a software decoder (bcdec/iOrange) and the pixel format in top right of the screenshot (BC1DX1A) is determined via a different codepath that quickly inspects the blocks, but they both seem to agree they exist ;)
The file BC1DXT1_AlphaOnlyWhy_Modern.dds was generated from TacentTestPattern.tga using TextureToolsExporter 2021.2.0, BC1, Normal Quality, DX10 header. Both images are available here:
I think we get a slightly less accurate colour encoding for those blocks because of this.
In any case, I’m currently generating the BC1 test images from 24bit source, which works fine. Just thought it was worth bringing the issue up.
Thank you for finding this bug! I managed to find the root cause, and it’ll be fixed in the next release. Specifically, this can happen for a 4x4 block when all of the following are true:
BC1 is enabled
The CPU compressor is being used (the CUDA compressor does not have this issue)
The block has some semitransparent pixels, where not all the pixels have the same RGBA value (this is why the blocks that only cover fully transparent areas aren’t affected)
The block can be compressed with a lower root mean square error with the 3-entry + transparency palette than with the 4-entry opaque palette.
A workaround until the next release is to set the alpha channel to 1.0f (255). Setting the Image Options > Scale and Bias Output > Alpha > Bias slider to 1.0, or adding --bias-a 1.0 to the nvtt_export command line should do the trick!
Hi Neil. Thanks for figuring it out – and for the workaround forcing the alpha to full with the bias.
Your note regarding the error is the most interesting because, well, it’s the least intuitive! I think I can see how this might happen … if the average value between 2 end-points (the binary alpha case with 3 colours) closely matches a colour in the block, a fourth colour (2 interpolants between the end-points) would push the colours away from the average… increasing the error. In any case, glad it’s fixed. Doesn’t sound like it was easy to track down ;)