Search Unity

GetPixel not getting correct color for PSD and PNG. TARGA ok

Discussion in 'iOS and tvOS' started by friken, Jul 14, 2009.

  1. friken

    friken

    Joined:
    May 1, 2009
    Posts:
    84
    Context: iphone unity though I'm pretty sure this would affect non iphone as well. 2D engine using texture mapped planes, no lighting, particle-alphablended.

    I am using GetPixel() for a 2d pixel perfect collision and using different colors to denote different collision types. It works really well but I'm having an issue with Unity not returning the correct RGB. As a test I created a texture in photoshop of rgb 128,128,128. A quick calculator of it 128/255=0.5019 (Unity 0-1 float for color). The getpixel returns 0.42 or 109 in 0-255 notation. I get this result if the file is PSD or PNG. I tried a targa thinking maybe it is the file itself and it worked Unity returns 128 (0.5019).

    Any idea why this would be? How to fix it? I can't use taga as I need 32bit with alpha. Ideally I'd like to use png as it maintains a better AA for transparancy (aas against edge color instead of white like psds do.
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    There are two potential reasons:

    1. You didn't disable compression. Texture compression is a destructive process and will not retain the color

    2. The texture is set to be 16bit, in this case it won't retain its color as well (keep in mind that 32bit textures are less efficient)
     
  3. friken

    friken

    Joined:
    May 1, 2009
    Posts:
    84
    thanks for the quick response. I wish it were either of the things you suggest. The import is set to uncompressed RGBA32 and the file in photoshop is set to RGB 8bitperchannel 32bit total.

    Interesting test I just tried is saved as indexed color 8bit in photoshop and unity did correctly import that and I get the correct getpixel value. I don't want to dither everything down to indexed 8bit though as I wouldn't be able to keep the AA edges of my sprites and unity is going to use the 32bit uncompressed memory anyway so there isn't even a savings to make sprites look like crap :)
     
  4. friken

    friken

    Joined:
    May 1, 2009
    Posts:
    84
    to recreate this issue:

    1. create a psd or png and fill the whole graphic with rgb 128,128,128.
    2. import using rgba32 uncompressed
    3. check the getpixel checkbox on import to allow getpixel
    4. put the texture on a material and set it to particle/alphablended.
    5. call
    Code (csharp):
    1.  
    2. var tex : Texture2D;
    3. tex = sprite.m_manager.material.GetTexture("_MainTex");
    4. var clr : Color = tex.GetPixel(0,0);
    5.  
    results: for a psd or png file unity returns 0.427 (109 RGB). If the file format is gif or targa unity returns the correct value of 128
     
  5. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Did you try what happens if oyu don't generate mipmaps?
    because on lower mip levels, the color would mix too.
     
  6. Adam-Mechtley

    Adam-Mechtley

    Administrator

    Joined:
    Feb 5, 2007
    Posts:
    290
    Hi,

    This is probably a problem of gamma or color profile saved in the file. Save the tga AND the psd in the project and look at them in inspector. Can you see a slight difference between them?
     
  7. friken

    friken

    Joined:
    May 1, 2009
    Posts:
    84
    Dreamora, thanks for the input. I should have added that tidbit to my first post. We do not use mipmaps and always uncheck the "generate mipmaps" import option as this is for a 2d game.

    Adam, I think you are onto something as I have done the test you described, saving the same graphic as a psd and tga. When importing both the hue is shifted slightly, the psd is a darker grey even in the inspector. Either Unity is importing it incorrectly or something in photoshop is saving incorrect color profile info in a psd and not a tga that is shifting the color when unity loads it.

    I'll look around photoshop again to see if I can find any setting to preserve colors correctly. My end goal is to have the photoshop color picker match Unity GetPixel... doesn't seem like too much to ask for :)

    One other note, is if I reload a previously imported file from unity to photoshop, Unity has not done anything to the file itself and photoshop does still read the color correctly as 128,128,128.
     
  8. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Its actually neither of your two "possible causes"

    TGA just does not transport any color profile, just the plain data, while PSD (and PNG) contains the color profile and unity uses it.

    The data thats stored is in both cases correct, but the data you get in Unity is the result of the data + profile.

    I think there is a "does nothing" profile floating around that could be used
     
  9. friken

    friken

    Joined:
    May 1, 2009
    Posts:
    84
    Thanks guys, I have been able to confirm that photoshop is embedding a color profile into psd and png. I found a setting for psd saving to not include that profile and I then get the correct, unaltered color value. I am still trying to get png working but there isn't an option on saving to not include color profile. I will need to figure out in photoshop how to always use a 'do nothing' profile.... I'm still scratching my head though on why there would ever be a default color profile that whacks colors for you.

    thanks again. I'll post here where the setting is or where to DL a do nothing profile when I find it.
     
  10. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    why the color profile: Because Photoshop's main purpose aren't games, its print and digital media, where you use profiles that will ensure that the color look the same on the target media as they do on your screen for example.

    without color profile you would waste dozens of hours to correct colors and if it is a movie or print media, that time is just not present.
     
  11. friken

    friken

    Joined:
    May 1, 2009
    Posts:
    84
    I found the setting in PS cs4 to not use a color profile. When creating a new file, click advanced and set color profile to "Do not manage colors". If you have an existing file that already has a default color profile, click edit/assignprofile and set it to not manage colors.

    This done, Unity is now matching exactly with the rgb values pulled from PS.