I am getting a white line around the visible part of some pngs I am using. I have tried several different shaders but the white artifacts do not go away. How can I fix this?
The reason for this is due to how the texture image was authored, combined with the filtering that most 3d engines use when textures are displayed at different sizes on screen.
Your image may have coloured areas which are completely opaque, coloured areas which are partially transparent, and areas which are completely transparent. However, the areas where your alpha channel is completely transparent (0% opacity) actually still have a colour value too. In PNGs (or at least, the way Photoshop exports PNGs) seems to default to using white for the completely transparent pixels. With other formats or editors, this may be black. Both are equally undesirable when it comes to use in a 3d engine.
You may think, "why is the white colour a problem if it's completely transparent?". The problem occurs because when your texture appears on screen, it's usually either upscaled or downscaled depending whether the pixels in the texture's image are appearing larger or smaller than actual size. For the downsizing, a series of downscaled versions get created during import. These downscaled versions get used when the texture is displayed at smaller sizes or steeper angles in relation to the view, and is intended to improve visual quality and make rendering faster. This process is called "mip-mapping" - read more about mip-mapping here. For upscaling, simple bilinear interpolation is normally used.
The scaled versions are usually created using simple bilinear interpolation, which means that the transparent pixels are mixed with the neighbouring visible pixels. With the mipmaps, for each smaller level, the problem with the invisible mixing with the visible pixel colours increases (with the result that your nasty white edges become more apparent at further distances away).
The solution is to ensure that these completely transparent pixels have a colour value which matches their neighbouring visible pixels, so that when the interpolation occurs, the colour 'bleed' from the invisible pixels is of the appropriate colour.
To solve this (in Photoshop) I always use the free "Solidify" tool from the Flaming Pear Free Plugins pack, like this:
- Download and install the Flaming Pear "Free Plugins" pack (near the bottom of that list)
- Open your PNG in photoshop.
- Go to Select -> Load Selection and click OK.
- Go to Select -> Save Selection and click OK. This will create a new alpha channel.
- Now Deselect all (Ctrl-D or Cmd-D)
- Select Filter -> Flaming Pear -> Solidify B
Your image will now appear to be entirely made of solid colour, with no transparent areas, however your transparency information is now stored in an explicit alpha channel, which you can view and edit by selecting it in the channels palette.
Now re-save your image, and you should find your white fuzzies have dissappeared!
The problem has nothing to do with mipmapping, actually. Allow me to illustrate:
What's going on in the first panel is that bilinear filtering is causing the pixels to be blended between black and the background color. So the transparency is blending from 0% to 100%. This is all well and good, except the default color for transparent pixels in Photoshop is white, and there's no way to change that. So the pixels are also being blended from black to white. Therefore all the in-between areas are partially transparent shades of gray. As you can see, turning off mipmaps doesn't do a thing to help--it's not causing the problem in the first place.
In the second panel, turning off bilinear filtering fixes the interpolation problem. (While introducing a blockiness problem, but that's besides the point here.) Most of the pixels are either 100% solid or 100% transparent, giving no chance for the white background to show up. However, the diagonal cut is done with anti-aliasing, so some of the pixels there are partially transparent. Again, this allows the white background to show through.
In the third panel, an alpha channel has been made and the shape pasted into it, and the background is just filled with solid black. Now, the bilinear filtering is blending the transparency from 0% to 100%, and the pixels are all black (including the transparent areas), so the problem is completely eliminated.
The fourth panel shows that the black background also fixed the issue with the antialiased diagonal cut.
It's actually possible in some cases to use plain transparency (no separate alpha channel) and eliminate the white fringes. Namely, when saving .png files for the web in Photoshop, you can specify the matte color. If your texture is primarily one color, use this for the matte color and bingo, problem solved. (Except you have to export for the web as .png and can't use the texture in .psd format, which is a bit of a pain if you make changes.)
The solution is as described in the other answers: don't use transparency, use a separate alpha channel, and extend colors in the texture outward into transparent areas by one pixel (or more).
Note that there's a bug/quirk/something where sometimes the alpha channel won't show up in Unity for some reason. If this happens, you must have an actual background layer in Photoshop (labeled Background)--simply filling in a layer with solid color isn't always enough.
You can try using transparent cutout shaders, they have alpha cutoff sliders, so you can use them to specify what alpha sould be preserved as transparent.
Another option is modifying the PNG with this PS technnique:
This way you shouldn't have those nasty white edges.
Well, I had the same problem (sort of) and I'm pretty much a noob here, but I'll offer what solved it for me - setting the texture wrap mode to "clamp" instead of "repeat". I'm guessing it is related to this: http://answers.unity3d.com/questions/7893/getting-rid-of-dirt-on-edge-of-plane-texture
This can also happen in areas of partial transparency where no background color is present, particularly with PNGs, so it is always important to follow Duck's instructions in creating a solid background color.
This also means you should create an alpha channel for the file, rather than simply rely on the default opacity (otherwise instead of 50% red, you will end up with more of a pink shade).
In photoshop, this can be done easily by duplicating all the layers, merging them, and overlaying white. Combine this with a black background layer, and copy this into an alpha channel.
For what it’s worth Gimp will do a great job. 1) Create new image with Advanced Transparent Background. 2) Paint your grass (I like using lighter gray tones and letting Unity fill in the Healthy/Worn colors. Do NOT save as psd but use png. Use defaults on save.
Сan try this…
PNG to TGA: remove artifacts from the transparent textures.
In Unity 4.2.1f check Alpha is Transparency in Advance Texture Type
but do you save a psd or a new png ?
For me the answer for your question is :
If your png file created in photoshop have a transparency layer like this:
You need to create a new layer above, like this:
This “background” can not have transparency. Now create a selection of your main layer ( ctrl + click or cmd + click(MAC)), go to Channels tab and add a alpha channel with this selection.
Ok now you can export to png.
if you texture is more complex then one color, you can use the Alpha Utility to inflate many times the texture. “Download”
Don’t forget to add a back layer full painted.
Works for me!
Hello to all, I would bring my experience.
I made 2D texture using Illustrator exporting in PNG with transparent background.
I get some of them with white border inside Unity, depending from the image, but i found solution: before export, in Illustrator select all then convert all strokes to path using Object > Path > Outline path (I’m not sure about the command name because I’m using an Italian version of Illustrator at the moment).
After conversion, export as usual in PNG and Unity will show it fine.
I hope this can help someone.
P.S. I use uncompressed texture for 2D of course.