04/03/2010 Using sRGB color space with OpenGL

sRGB is a non-linear color space that can be directly displayed by computer display devices. Another very popular color space is Adobe RGB often used in photography for its higher precision. sRGB and Adobe RGB color spaces define what actual color is a color code so that on all compatible outputs or supports, the color will look the same.

OpenGL defines sRGB textures (OpenGL 2.1) and sRGB framebuffers (OpenGL 3.0) to take advantage of the sRGB color space. sRGB provides an optimized use of each value of the storage range so that these values become more relevant for our eyes perception. A quality gain for zero extra storage.

OpenGL provides sRGB with 8 bits components and compressed sRGB data only. These formats are identified with GL_SRGB, GL_SRGB8, GL_SRGB_ALPHA, GL_SRGB8_ALPHA8, GL_COMPRESSED_SRGB and GL_COMPRESSED_SRGB_ALPHA. When the extension GL_EXT_texture_compression_s3tc is supported, the following format are supported: GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT and GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT. These formats are absolutely similar to the usual DXTC1, DXTC3 and DXTC5 but with sRGB sources.

The ARB has considered that less that 8 bits per pixel is not enough precision to make a non linear color space relevant for storage. The ARB has also considered that more than 8 bits per pixel is so much precision than sRGB isn't really useful. Another way to see this, is that less than 8 bits per pixel is not used anymore and more than 8 bits per pixels conversion to linear space would be too expensive to do on the hardware. Currently, we can expect the conversion to be implemented in GPUs with a lookup table of 256 values so that this conversion is almost free to perform. However, a table with 65536 values is a lot higher transistors cost. I would not be surprised to see sRGB16 OpenGL extension in the future.

With OpenGL 3.2 core profile, there is no 1 or 2 components sRGB textures. With OpenGL 3.2 compatibility profile we have some extra formats: GL_SLUMINANCE, GL_SLUMINANCE8_ALPHA8, GL_COMPRESSED_SLUMINANCE and GL_COMPRESSED_SLUMINANCE_ALPHA. One example where nVidia is right about "some deprecated OpenGL features might be useful" (minute 23).

When an alpha channel is used, the alpha channel ALWAYS remains linear. The texture format names use a separated token 'ALPHA' to show this difference between channels.

sRGB is not a linear color space. If we have 2 sRGB pixels A and B then A + B is not a valid operation. Each time a sRGB value is used for an operation, the value need to be converted to a linear color space value. To convert a 8 bits sRGB pixel to a linear RGB pixel, the graphics card might need 16 bits per channel to be lossless.

On the OpenGL pipeline we will find these conversions for three tasks: texel sampling, multisample resolution and blending. OpenGL gives control of these conversions only at blending stage with the calls glEnable(GL_FRAMEBUFFER_SRGB) and glDisable(GL_FRAMEBUFFER_SRGB). When enabled, the values are linearized prior to their use for blending. A lack of conversions will generally darken the framebuffer.

For texel fetch and multisample resolution, these conversions are performed automatically but the way it's performed is just a recommandation. For texel fetch, the recommantation is to perform the conversions to a linear space before the filtering. For the multisample resolution, the recommanration is to perform the conversions before the average.

sRGB textures are supported from GeForce 6 and Radeon 9***. sRGB framebuffers require a GeForce 8 or a Radeon HD 2***. Apple drivers doesn't support OpenGL 3.0 yet (in MacOS X 10.6.2) but supports GL_EXT_texture_sRGB and GL_EXT_framebuffer_sRGB for all cards that support sRGB color space. Intel drivers are also suposed to support both sRGB textures and framebuffers... I'm so sure either about S3. Chrome 4** supports sRGB textures and are suposed to support sRGB framebuffers because S3 claims that Chrome 4** are OpenGL 3 cards but GL_EXT/ARB_framebuffer_sRGB isn't in the extension list of the card.

Unfortunatly, OpenGL ES 1 and 2 don't provide any support of sRGB.

To get started with using sRGB with OpenGL, the last release of the OpenGL 3 Samples Pack contains a sample using a sRGB framebuffer object.

  • OpenGL and Direct3D support.
  • Compressed textures support.
  • Defines which color a set of values represent.
  • Same storage size than RGB for higher quality.
  • Great LDR format when use with HDR rendering.
  • Large support by tools (Photoshop, Lightroom, Paint Shop Pro, etc.) and hardware (GPUs, Cameras, Monitors, etc.).
  • Arithmetic operations are not correct without conversion to a linear format.
  • Lower precision than Adobe RGB.
< OpenGL Overload (GLO) announcement
Copyright Christophe Riccio 2002-2016 all rights reserved
Designed for Chrome 9, Firefox 4, Opera 11 and Safari 5