ImageSharp.Textures icon indicating copy to clipboard operation
ImageSharp.Textures copied to clipboard

Support for decoding `DXT1` with alpha

Open Crauzer opened this issue 2 years ago • 3 comments

DXT1 textures can "carry" alpha information using black pixels, which means that any pixel that is pure black has alpha of 0 and any other pixel has alpha 255.

I couldn't seem to find a way to set this behavior in the library. Here is an example of what it looks like when DXT1 textures aren't decoded with alpha (the textures in the image were decoded by this library and then converted to PNG using ImageSharp): image

Crauzer avatar Jan 16 '23 19:01 Crauzer

Might be a good idea to share a sample image that can be used for this?

dlemstra avatar Jan 16 '23 21:01 dlemstra

Here are 2 DXT1/BC1 files which both contain alpha information dxt1_examples.zip

DXT1example.dds is a file I created with photoshop by exporting it with BC1a format. _chunk_jungle_south_island_i_alpha_3dcuv_atlas_color.dds is a file from a game that I'm converting textures from.

dwFlags has a flag called DDPF_ALPHAPIXELS which is used when there is encoded alpha, the issue with it is that it is also as unreliable as the rest of the DDS format because it's not always set, as you can see in DXT1example.dds (the game texture does have it)

I think the best way to handle this would be to always decode to Rgba32 using the following logic:

  • If DDPF_ALPHAPIXELS is set or user sets a settings flag ShouldExpectAlpha, check if pixel is black, if it is then alpha will be set to 0, otherwise 255
  • By default, always set alpha to 255

Crauzer avatar Jan 16 '23 22:01 Crauzer

I don't know much about how the BCx compression works but I also believe that it is possible to set an alpha cutoff value which can be used to determine if a pixel should be transparent or not. This is used in various game engines and in blender. (The default seems to be 127 ?)

Crauzer avatar Jan 16 '23 22:01 Crauzer