Search Unity

16-bit PNG shows considerable banding

Discussion in 'Editor & General Support' started by Daerst, Apr 19, 2018.

  1. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    Hi there,

    I've hand-painted a terrain in Unity and now want to use its height map as a texture in a shader. I have exported the terrain as 16 bit RAW, imported it in Photoshop and saved as 16 bit PNG. When I reopen this file in Photoshop, it looks the same, so I assume nothing went wrong during this process.

    Now I want to import this PNG file in Unity without losing precision. Here are the import settings I chose:
    upload_2018-4-19_12-51-8.png

    Using the texture in a shader shows considerable banding. RenderDoc correctly reports the texture format as R16G16B16A16_FLOAT. Here's a contrast-stretched screenshot from RenderDoc:
    upload_2018-4-19_12-52-9.png

    The brightest value you see here is 0.04706, the second-brightest is 0.04315. The difference is 0.00391, which is suspiciously close to 1/256 = 0.00390625. For comparison, here is the same file, similar region in Photoshop, with the same contrast-stretching applied:
    upload_2018-4-19_12-58-37.png

    How can I make Unity import my 16 bit PNG with full precision? Bonus points for an R16 result instead of the excessive 4 channels.

    Tested in Unity 2017.1.1f1 and 2018.1.0b11. Same problem for TIFFs.

    Thanks!
    Daerst
     
    Last edited: Apr 19, 2018
  2. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    Gradients do tend to band on 16 bit. The only solution I have found is more bits. RGB 24 bit if no transparency, RGBA 32 bit if there is transparency.
     
  3. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    The formats you mentioned use only 8 bits per channel, so they don't help.

    If I import a 16 or 32 bit (per channel) image as either of the mentioned formats (RGBA Half, RGB24, RGBA32), I'm seeing the same banding all the time and RenderDoc shows no more than 256 distinct colors.
     
    Last edited: Apr 19, 2018
  4. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,269
    I think there is mix up on bits here - 16bit raw is 16bit per channel RGB?
    16bit PNG greyscale would be equivalent I guess
    24/32bit png is normally 4bit per channel for each of RGBA.

    RGBA half is an HDR format with 16bit float per color channel, RGB24 and RGBA32 are both 8bit per channel.

    Finally if your render/screen buffer and/or shaders work on 8bits per channel you will still get banding.
    One option is to dither your images
     
  5. unity_D2JaUXOTIn_2xQ

    unity_D2JaUXOTIn_2xQ

    Joined:
    Mar 8, 2018
    Posts:
    4
    For future views: Unity doesn't support 16 bit/channel PNG's so banding occurs because it is just 8bit after import.
    Shaders will most definitely not be the problem that causes banding.
     
  6. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    True, the only solution for now is converting to EXR or HDR.