Search Unity

Save Normal, Occlusion, Metallic Texture maps in Linear space?

Discussion in 'General Graphics' started by SuperUltraHyper, Jan 17, 2016.

  1. SuperUltraHyper

    SuperUltraHyper

    Joined:
    Sep 7, 2015
    Posts:
    112
    As the title suggests, Should I be saving out all of my textures in linear space? (Albedo, Normal, Occlusion, and Metallic)
    Obviously the Albedo needs to be in linear space but there is not other information on the subject.

    Is there documentation I have missed?

    Thanks!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Albedo should be sRGB, not linear. It should be noted that for the most part it's not how they're saved but how they're created eventually read. The image formats themselves don't usually have a concept of if they data they hold should be considered sRGB or linear. However it's usually pretty easy to know which is going to be wanted / needed. If the image is holding a color or some value you're going to be seeing directly (like albedo or specular color, or even occlusion) then it should be sRGB, if it holds data that is going to be interpreted then most likely it should be linear. Metallic is an odd one because it's technically "data", but but for ease of use they expect sRGB textures, that and what "halfway between dielectric and metal" looks like is kind of arbitrary; in the real world things are 100% one or the other.

    Albedo, metallic, specular and occlusion are sRGB. Normals and smoothness are linear.
     
    Jemster3D likes this.
  3. SuperUltraHyper

    SuperUltraHyper

    Joined:
    Sep 7, 2015
    Posts:
    112
    I should have mentioned, I am using linear space in Unity. Albedo diffidently needs to be in linear space. (Converted to RGB 32bit / Channel and Saved from Photoshop as a DXT1/5 ) After testing it appears that the Normal needs to be saved as 8bit / channel and to a standard DXT5_NM.

    I as for the Occlusion and Metallic textures... Keep them as 8/bit or convert them to 32bit before saving the DXT. This is the question as it isn't as obvious to me what is correct simply from viewing it.

    Thanks for any clarification that can be provided!
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Albedo should be sRGB, not linear. This is true even when the rendering mode is linear!

    The difference between linear and gamma rendering is in how lighting falloff is calculated. Color textures are converted back and forth between linear and gamma space automatically for the rendering color space depending on if they're marked as sRGB or not.

    DXT1 is an 24 bit, 8 bit per channel format (actually, it's 16 bit, 5:6:5 bpc internally for the color table it uses, but the interpolated output is 24 bit, 8 bpc), and if you read an 8 bpc color without using sRGB the results will have significant banding in the darker areas. It's also important to note that Unity does not support using >8 bpc texture formats in most shaders and by default it converts all textures to some form of 8bpc (DXT1, DXT5, RGBA32 A8) or optionally a 16 bit format (RGB16 5:6:5 bpc or RGBA16 4:4:4:4). You can start with a 16 bpc or 32 bpc texture but it'll just crush them down to 8bpc or less. Even imported HDR formats are converted to a DXT5 RGBM where the final color is 8.0 * color.a * color.rgb. Generally with Unity you just want to have and work with 24 or 32 bit (8bpc) .tga, .psd, or .png files that Unity will convert to a DXT1 or DXT5 for you rather than doing so ahead of time.

    Normals are linear, but again Unity will handle the conversion of these. Your normal map generation tool of choice will happily spit out normals in whatever texture format you want, and if they're worth anything will do so in linear space regardless of whatever settings you have the program set to render other things in. Unity will take the 24 or 32 bit (8bpc) texture and convert them to a DXT5_NM by default as you surmised, though you can optionally use an uncompressed RGBA32 or RGBA16 for quality reasons.

    For metallic textures the assumption they're making is that you're authoring these in a graphics program that's using an 8 bpc sRGB, but you can do these in linear if you want. It's kind of irrelevant as it's just data. However specular color does need to be sRGB as it's a color and uses the same slot as metallic and Unity's default behavior is to treat all textures as sRGB so they just assume that's what you're going to do. The slider for metallic in the standard shader when you don't have a texture is in sRGB / gamma space so that "0.5" is the equivalent of 127/255 in sRGB (~0.2) and not 127/255 in linear because of this.

    For occlusion, there's no physical basis for how this is generated. It's a reasonable approximation that's mainly up to the artist, but one that's likely going to be done in 8bpc sRGB either in greyscale or as a 24 or 32 bit image. Regardless the default behavior for Unity is to treat it as sRGB and convert it into a 24 bit sRGB DXT1 as the way this is used is as a color multiplier over the ambient light. If it was linear it would have banding.
     
    Jemster3D likes this.
  5. SuperUltraHyper

    SuperUltraHyper

    Joined:
    Sep 7, 2015
    Posts:
    112
    I think there are some conceptual issues in our conversation related to my understanding of textures in linear vs gamma space. This is what I can tell you:

    1) My Unity project is in Gamma space and everything looks correct.
    2) I author all of my textures normally in Photoshop as I have done for years.
    2) I switch to linear space in Unity
    3) The project looks completely washed out.
    4) Open Photoshop, open each Albedo texture source file, convert to 32bpc (Image-->Mode-->32bit) and save out a .DDS (DXT) of the image.
    5) The Unity Project is in Linear Space and everything looks correct again / not washed out.

    Are my DDS files not in Linear space? They are much darker when viewing them in Photoshop.

    Thanks!