Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Grey edges in sprites with transparent pixels

Discussion in 'Editor & General Support' started by Redden44, Nov 15, 2014.

  1. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Hi, I have a problem with my sprites which hold transparent pixels, when they are rendered, grey edges appear around them.

    I alredy did some research and apparently the problem lays in how photoshop handles the background of an image with transparent pixels (saving it as white) and when the image is rendered the pixels next a transparent area are mixed with white, creating this grey/white border.

    The solution given to this problem is to add an alpha channel, color the empty pixels around the image with the same colors of the pixels of the edges and then fill the background with a color to remove all the remaining empty pixels. It didn't work at all.

    I tried the flaming pear solidify method, the fringe+dilatate method, the solid color background method, I kept the layers separated, I merged the layers, I used a background layer called "Background", I imported the file as .psd, I used png, png 8, png 24, super png, save for web and none worked.

    In unity I'm using these settings:


    I changed them in every possible way and nothing worked, almost nothing..the only way to have those edges gone is to set the "Filter mode" to point; I don't like it though because the texture appear pixeled and I don't want that.

    Also I get this error too (which doesn't prevent the game to run), don't know if matters or not:
    importer.GetNPOTScale() == TextureImporter::kNPOTKeep
    UnityEditor.DockArea:OnGUI()

    What else, the sprites I'm using are multiple sprites, I tried 100x100 pixels and 200x200 pixels sprites, inside canvas of 1024x512 pixels, 512x512 pixels and 512x128 pixels.

    I create the sprites this way:
    I make a new ps file, lets say 100x100, RGB color 8 bit, background transparent or color and color profile sRGB IEC61966-2.1, square pixels.
    I paint the textures I need on different layers then I expand the canvas and move the sprites around it; at this point I try the methods I listed above, save and import the file by drag&drop from my save folder into unity.
    I select the image. set it like the screenshot above and attach the sprite I need to a prefab which I instantiate via script.
    This is the prefab:


    I think unity reads the alpha chennel correctly, because it removes the solid color from the sprite sheet and the sprite editor slices the single sprites perfectly.

    If I use a single sprite, not a sprite form a sprite sheet, I mean a single image with a single sprite with some transparency and a single photoshop layer (no solid background color) and I save it as a png without even create the alpha channel..guess what. it works, no grey edges at all..which could mean I'm doing something wrong with the sprite sheet since multiple sprites don't work and single sprite does work? I don't know T_T

    Please help me, thanks.
     
  2. peteorstrike

    peteorstrike

    Unity Technologies

    Joined:
    Oct 4, 2013
    Posts:
    116
    You're close with what's causing the issue - the problem is to do with the bilinear filtering itself, and how it works on Sprite Sheets.

    When using a Spite Sheet, it appears that Bilinear filtering will smooth across the boundary-edge of your sprites, including dead areas of the sprite sheet. So when it samples a pixel on the boundary-edge of your sprite, the filter sees a transparent pixel one side and a green one on the other and averages the two, creating your grey lines. As far as I can tell, the bilinear filtering isn't able to know what the texture colour underlying a transparent pixel is (as is used for correct matting in other uses of transparent images), as it's a process applied to the end-result texture. The reason point filtering doesn't cause this issue, is that there's no sample averaging occurring across multiple pixels, therefore any transparent pixel next to your sprite's boundary-edge pixel won't affect the end result.

    I believe the reason this doesn't happen on single sprites, is that Unity assumes either that whatever pixel is on the edge of a sprite carries on infinitely in that direction (so the bilinear filter would see green next to green) or that the sprite tiles infinitely in all directions.

    The easiest fix is probably to have an actual pixel bleed of 2 pixels, non-alpha'd, dilated from any non-transparent boundary-edge pixels of your sprites that will be cut by the Sprite Editor. If you cut the sprites as you did before, then this padding outside of your sprite should force the bilinear filtering to do thy bidding.
     
    Last edited: Nov 15, 2014
  3. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Do you mean like this?



    That's a 512x512 sprite sheet, with 200x200 sprites; I created the sprites, then the alpha channel and I used the flaming pear solidify B filter, which should do what you suggested I believe; it doesn't work.

    Here are the settings, the sprite editor and the result:



    If you didn't mean that, can you explain it again please? Thanks a lot.
     
  4. peteorstrike

    peteorstrike

    Unity Technologies

    Joined:
    Oct 4, 2013
    Posts:
    116
    Close! You need to bleed the alpha by a couple of pixels as well, though, and just cut your sprites as normal so that you'll be moving the sprite boundaries 'inside' the artwork. I've tried to knock up a little diagram if it helps:


    For png files, this just means make your art spread a little bit outside of where you intend to cut the sprite.

    The filter gets its info from the final pixel data on the sprite sheet, so it's not able to tell that an alpha'd out colour needs to be taken into consideration for the sampling. If it did it would sadly probably create more issues than it solved (black outlines of a character alpha'ing to white, as in your first example, and so on).
     
    UnityKen likes this.
  5. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    That worked! Thank you very much!

    May I ask you how did you avoid to bleed the wavy part? I had to duplicate the layer, bleed the copy, select and erase the unwanted part and merge the layers again.

    Also in this tutorial (http://docs.unity3d.com/Manual/HOWTO-alphamaps.html) they create the alpha without the bleed, isn't that wrong then? o_O

    Thanks again!
     
  6. peteorstrike

    peteorstrike

    Unity Technologies

    Joined:
    Oct 4, 2013
    Posts:
    116
    Hi @Redden44, really glad it helped!

    The tutorial is still technically correct, it's just that the sprite editor is a special use case as it's creating tiling assets from a larger texture - this means that the bilinear filtering acts across the edges of where you cut your sprite, which doesn't happen on regular textures. Because of this, you have to be extra mindful of what happens on the boundaries of where you cut your sprites.

    And yeah, I did my bleed manually (selected edge pixels, stretched off the boundaries by a couple of pixels), as it was quicker than installing the tool. Whatever works easiest for you, really!
     
  7. arham_jee

    arham_jee

    Joined:
    Nov 14, 2021
    Posts:
    1
    it also solved by Using wrap mode= clamp with filter mode bilinear or trilinear