DDS files in the game are premultiplied alpha, but extraction does not un-premultiply when making PNGs (premultiplied PNG is not even a thing but whatever)
Multiplying/Dividing the alpha is lossy and we can't really get an original PNG back that could be both loaded in PL and look right in an editor
Playlunky is premultiplying all images from mods, cause they are likely PNG and not premultiplied
Playlunky is also premultiplying the cached vanilla files it extracted when stitching entity sheets or sprite maps, which is bad and any unmodified parts get premultiplied twice in the end
Using any mods that custom sprite map to items.png will break all the other items because of 4
There might even be a feedback loop so files in the cache get premultiplied again and again
Solutions:
Modlunky could predivide alphas when extracting, but it's not going to look the same when premultiplying again
We could just say the extracted PNG files are premultiplied and anyone who uses very transparent parts as base for their mods is stupid
Playlunky definitely shouldn't divide or premultiply cached (vanilla) files ever, only premultiply user-provided files once before caching or stitching
Disabling premultiplication in PL will load extracted vanilla PNG files correctly, but this is obviously a useless feature
I tried to undo the premultiplication and then load the textures again in PL https://imgur.com/a/Z4ToeAS
I extracted the divided textures with this modification but nothing looks quite right either way...
def dds_to_png(data):
"""Takes a .DDS `Image` and returns .png data."""
img = Image.open(io.BytesIO(data))
px = img.load()
width, height = img.size
for i in range(width):
for j in range(height):
if px[i, j][3] != 0:
R = int(255.0 * px[i, j][0] / px[i, j][3] + 0.5)
G = int(255.0 * px[i, j][1] / px[i, j][3] + 0.5)
B = int(255.0 * px[i, j][2] / px[i, j][3] + 0.5)
a = px[i, j][3]
px[i, j] = (R, G, B, a)
new_data = io.BytesIO()
img.save(new_data, format="PNG")
return new_data.getvalue()
Thoughts from Discord:
Solutions:
I tried to undo the premultiplication and then load the textures again in PL https://imgur.com/a/Z4ToeAS I extracted the divided textures with this modification but nothing looks quite right either way...
Originally posted by @Dregu in https://github.com/spelunky-fyi/modlunky2/issues/304#issuecomment-1288104234