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

Question How to correctly sample HDR cubemap?

Discussion in 'Shaders' started by pensionerov, May 7, 2021.

  1. pensionerov

    pensionerov

    Joined:
    Mar 13, 2018
    Posts:
    12
    Hi everyone,

    Unity default skybox shader samples a cubemap like this
    Code (CSharp):
    1. half4 tex = texCUBE (_Tex, i.texcoord);
    2. half3 c = DecodeHDR (tex, _Tex_HDR);
    What does DecodeHDR do? When should I use it? Does unity populate _##_HDR for all textures in materials or the ones I bind using SetGlobalTexture?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    It decodes HDR (High Dynamic Range) textures that have been stored in RGBM or dLDR format. HDR a texture with values ">1.0". What is RGBM and dLDR?
    https://docs.unity3d.com/Manual/Lightmaps-TechnicalInformation.html
    And this is the code for that function.
    data
    is the texture color value,
    decodeInstructions
    is the
    *_HDR
    for that texture.
    Code (CSharp):
    1. // Decodes HDR textures
    2. // handles dLDR, RGBM formats
    3. inline half3 DecodeHDR (half4 data, half4 decodeInstructions)
    4. {
    5.     // Take into account texture alpha if decodeInstructions.w is true(the alpha value affects the RGB channels)
    6.     half alpha = decodeInstructions.w * (data.a - 1.0) + 1.0;
    7.  
    8.     // If Linear mode is not supported we can skip exponent part
    9.     #if defined(UNITY_COLORSPACE_GAMMA)
    10.         return (decodeInstructions.x * alpha) * data.rgb;
    11.     #else
    12.     #   if defined(UNITY_USE_NATIVE_HDR)
    13.             return decodeInstructions.x * data.rgb; // Multiplier for future HDRI relative to absolute conversion.
    14.     #   else
    15.             return (decodeInstructions.x * pow(alpha, decodeInstructions.y)) * data.rgb;
    16.     #   endif
    17.     #endif
    18. }
    Whenever you might use a pre-computed HDR texture, either one generated by Unity (i.e.: lightmaps, reflection probes), or imported from an external source (.hdr or .exr image for custom reflection probes, or sky boxes), but are using non-HDR texture formats. That can be either due to the platform not supporting them (ie: mobile), or you manually selecting a non-HDR texture format on that texture's import settings.

    Yes. If there's an
    *_HDR
    for a texture that's being used by that shader, Unity will fill it out with the required data. For non-HDR or native-HDR images it'll be values that will have no affect on the texture (
    float4(1.0, 1.0, 1.0, 0.0)
    ), and on HDR images it'll be the values to decode it from the current format for the current color space.


    Note: HDR Render Textures don't need to be decoded because they're already guaranteed to be in a native-HDR format. Even on mobile.
     
    NuclearCookieTF likes this.
  3. pensionerov

    pensionerov

    Joined:
    Mar 13, 2018
    Posts:
    12
    Thank you very much @bgolus! Though it's the first time you answer my question directly, your posts on this forum are absolutely invaluable source of information and helped me immensely.
     
    Last edited: May 8, 2021
  4. moranBoar

    moranBoar

    Joined:
    Dec 14, 2018
    Posts:
    6

    I have tried DecodeHDR in compute shader. But it seems that Unity does not fill the
    *_HDR
    variable for me in compute shader. All the decoded data were 0, because of the default value 0 in
    *_HDR
    variable without Unity's feeding. if I set
    *_HDR
    as half4(1,1,1,1), the values extracted from HDR map were truncated.(max to 1)

    May I ask is there any other method to get decoded HDR value from map in compute shader?
     
    zdart03 likes this.
  5. bunp

    bunp

    Joined:
    Feb 21, 2019
    Posts:
    66
    I am using unity shadergraph and I am trying to write a custom node that will decode an HDR texture I am passing in, but no matter what I do I can't find the syntax or methods to make it work. Can you point me in the right direction?

    Code (CSharp):
    1. inline float4 SampleHDRTexture2D(UnityTexture2D _tex, UnitySamplerState ss, float2 uv)
    2. {
    3.     //somehow decode
    4.     return color;
    5. }
    Is it even possible to extract HDR values from SAMPLE_TEXTURE2D?