Color spaces, gamma and image enhancement

前端 未结 3 1992
一个人的身影
一个人的身影 2021-01-31 00:24

Color space. Well, everybody knows about RGB: three values normalized in the range [0.0,1.0], which have the meaning of the intensity of the color components Red Green

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-31 00:58

    Unfortunately OpenGL by itself doesn't define a colour space. It's just defined that the RGB values passed to OpenGL form a linear vector space. The values of the rendered framebuffer are then sent to the display device as they are. OpenGL just passes through the value.

    Gamma services two purposes:

    • Sensory perception is nonlinear
    • In the old days, display devices had a nonlinear response

    The gamma correction is used to compensate for both.

    The transformation is just "linear value V to some power Gamma", i.e. y(v) = v^gamma

    Colorspace transformations involve the complete chain from input values to whats sent to the display, so this includes the gamma correction. This also implies that you should not manipulate the gamma ramp youself.

    For a long time the typical Gamma value used to be 2.2. However this caused some undesireable quantisation of low values, so Adobe introduced a new colour space, called sRGB which has a linear part for low values and a powerfunction with exponential ~2.3 for the higher values. Most display devices these days use sRGB. Also most image files these days are in sRGB.

    So if you have a sRGB image, and display it as-is on a sRGB display device with a linear gamma ramp configured on the device (i.e. video driver gamma=1) you're good by simply using sRGB texturing and framebuffer and not doing anything else.

    EDIT due to comments

    Just to summarize:

    • Use a ARB_framebuffer_sRGB framebuffer, so that the results of the linear OpenGL processing are properly color transformed by the driver http://www.opengl.org/registry/specs/ARB/framebuffer_sRGB.txt

    • Linearize all colour inputs to OpenGL

    • Textures in sRGB colour space should be passed through EXT_texture_sRGB http://www.opengl.org/registry/specs/EXT/texture_sRGB.txt

    • Don't gamma correct the output values (the sRGB format framebuffer will take care of this)

    If your system does not support sRGB framebuffers:

    • Set a linear colour ramp on your display device.

      • Windows http://msdn.microsoft.com/en-us/library/ms536529(v=vs.85).aspx
      • X11 can be done though xgamma http://www.xfree86.org/current/xgamma.1.html
    • create (linear) framebuffer objects, to linear rendering in the framebuffer object. The use of a FBO is, to properly to blending, which only works in linear colour space.

    • draw the final render result from the FBO to the window using a fragment shader that applies the desired colour (gamma and other) corrections.

提交回复
热议问题