SixLabors / ImageSharp.Textures

Texture loading and manipulation library
Apache License 2.0
61 stars 13 forks source link

Support for decoding `DXT1` with alpha #14

Open Crauzer opened 1 year ago

Crauzer commented 1 year ago

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

dlemstra commented 1 year ago

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

Crauzer commented 1 year ago

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:

Crauzer commented 1 year ago

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 ?)