Search Unity

Question In linear color space, how to turn off gamma correction processing when writing to the framebuffer

Discussion in 'Shaders' started by hakukou, Mar 28, 2023.

  1. hakukou

    hakukou

    Joined:
    Mar 16, 2020
    Posts:
    6
    I work for a display manufacturer and there is a demand in our products. It is to store some description information in the first line of the framebuffer as a line of information. After the second line, the normal rendered color, which is the RGB information for each pixel. But when I use URP and HDRP, if the color space I use is linear space, when I append the information line in the post-processing and put the result into the framebuffer, Unity will Gamma correct the data of the first line, resulting in data errors, and the display side receives the wrong information data. Is there any way to turn off the last step in linear mode to avoid performing gamma correction when writing to the framebuffer.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    There's no way to turn this off. But there are ways around it.

    The main method would be to apply the sRGB to linear conversion to the data values you're appending to the image, that way when the image is converted from linear to sRGB you'll get the originally intended values you wanted.

    The alternative is to use a coroutine with a
    yield return new WaitForEndOfFrame();
    that you wait for before bliting your data to the image. AFAIK the framebuffer at that point should be after the sRGB conversion step.
     
  3. hakukou

    hakukou

    Joined:
    Mar 16, 2020
    Posts:
    6
    Thank you for your answer. The first method, which I have tried, but there will be accuracy problems. An integer between 0-255, after doing a linear conversion, a decimal number is obtained, due to precision problems, after unity's automatic sRGB conversion, a small error occurs with the original integer. The second way, I'll test it and see if it works.
     
  4. hakukou

    hakukou

    Joined:
    Mar 16, 2020
    Posts:
    6
    I found a way. It turns out that the automatic sRGB conversion is performed when the FragmentShader is output, and is not directly related to the FrameBuffer. I just need to be in the last step of Blit(...shaderMat), use GL.sRGBWrite = false; That's it
     
    bgolus likes this.
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You can work around the precision problem by using
    (integer value + 0.5) / 255.0
    , and use the accurate conversion. The built in functions for it are approximations.

    But I’m glad you found a solution!