game-icons / icons

All SVG icons available on https://game-icons.net
Other
1.05k stars 115 forks source link

transparent background #943

Open PeterSPrins opened 1 year ago

PeterSPrins commented 1 year ago

Hi, I just found this website and it looks very useful for my unity project. I have one Issue though. If I download An icon as a png with the icon itself being white and the background transparent, it saves the background as being 'black transparent'. this causes unity to draw a grey outline around the icon as it interpolates between the white foreground and the black transparent background. It would be better if the background would be white transparent in such cases.

Delapouite commented 1 year ago

Hi. I did not know that there could be various kind of transparency. Do you have any documentation ref about this behavior of PNG files? Thanks.

PeterSPrins commented 1 year ago

I'm having a hard time finding any documentation about this besides some forum posts: https://www.reddit.com/r/unity_tutorials/comments/pmtkh3/why_are_these_white_lines_appearing_when_the/ https://forum.unity.com/threads/photoshop-files-give-white-outline-on-transparent-textures.60508/

However I can explain some things as I understand them as a software engineer. I'm sure you know that colours in images are often represented as an rgb value, an intensity of red green and blue colours that together mix to form the colour that you see on the screen. Image files that add an option for transparency add a fourth 'colour' called alpha. This tells the computer how transparent the colour is from completely transparent at 0 to completely opaque at 255. So to represent an opaque white pixel you get r:255, g:255, b:255 and a:255. When representing a transparent pixel the file still saves all four of these values, so the transparent pixel still his a colour, for instance transparent white: r:255, g:255, b:255 and a:0.

Now this all works fine when you display the image at its native resolution. However, when you scale the image down there are multiple image pixels that fall within one screen pixel. Now some systems simply pick one of the image pixels to display on the screen pixel and there would be no problem. Unity however, mixes all the image pixels in the screen pixel by averaging each value, as this usually gets a better result. When you do this to transparent pixels on the other hand you create a problem at the border between for instance white opaque pixels and black transparent pixels. In this case the result of mixing these pixels will be a grey, partially see through colour. Making the transparent pixels the same rgb value along these borders as the opaque pixels solves this problem as the mixed pixels will still be white, just partially transparent.

Now in Unity you have an option to simply ignoring all invisible pixels when mixing pixels like this. However since this has to do a lot of extra checks it is a lot less efficient than simply taking the average.

tommyettinger commented 1 year ago

This can probably be done in a graphics editor by-hand (depending on how it handles alpha=0), but could also be automated. I have a script-like piece of Java code that I use for this purpose: https://github.com/tommyettinger/textratypist/blob/main/src/test/java/com/github/tommyettinger/textra/TransparencyProcessor.java#L123-L135 It's manually building a PNG file based on its file format, which most libraries hide from their users.

The key thing here is that it builds an all-lightest-white palette, and changes the transparency for each entry in the palette so all transparency (alpha) values exist and have white for the other channels. If the icon should be a different color, change all-white to all-that-other-color. If I edit a file this has produced in certain graphics editors, the RGB values for alpha=0 are disregarded, and I would need to run the script again.