| Name | |
| ARB_framebuffer_sRGB | |
| Name Strings | |
| GL_ARB_framebuffer_sRGB | |
| GLX_ARB_framebuffer_sRGB | |
| WGL_ARB_framebuffer_sRGB | |
| Contributors | |
| Herb (Charles) Kuta, Quantum3D | |
| Alain Bouchard, Matrox | |
| Brian Paul, Tungsten Graphics | |
| Daniel Vogel, Epic Games | |
| Eric Werness, NVIDIA | |
| Kiril Vidimce, Pixar | |
| Mark J. Kilgard, NVIDIA | |
| Pat Brown, NVIDIA | |
| Yanjun Zhang, S3 Graphics | |
| Jeremy Sandmel, Apple | |
| Jon Leech | |
| Adam Jackson, Red Hat | |
| Contact | |
| Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com) | |
| Notice | |
| Copyright (c) 2008-2013 The Khronos Group Inc. Copyright terms at | |
| http://www.khronos.org/registry/speccopyright.html | |
| Specification Update Policy | |
| Khronos-approved extension specifications are updated in response to | |
| issues and bugs prioritized by the Khronos OpenGL Working Group. For | |
| extensions which have been promoted to a core Specification, fixes will | |
| first appear in the latest version of that core Specification, and will | |
| eventually be backported to the extension document. This policy is | |
| described in more detail at | |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php | |
| Status | |
| Approved by the ARB on July 11, 2008 | |
| Version | |
| Date: September 19, 2019 | |
| Revision: 1.3 | |
| Number | |
| ARB Extension #46 | |
| Dependencies | |
| OpenGL 1.1 is required | |
| This extension is written against the OpenGL 2.0 (September 7, | |
| 2004) specification. | |
| WGL_EXT_extensions_string is required for WGL support. | |
| WGL_EXT_pixel_format is required for WGL support. | |
| ARB_color_buffer_float interacts with this extension. | |
| ARB_framebuffer_object is required. | |
| EXT_texture_sRGB interacts with this extension. | |
| ARB_draw_buffers interacts with this extension. | |
| Overview | |
| Conventionally, OpenGL assumes framebuffer color components are stored | |
| in a linear color space. In particular, framebuffer blending is a | |
| linear operation. | |
| The sRGB color space is based on typical (non-linear) monitor | |
| characteristics expected in a dimly lit office. It has been | |
| standardized by the International Electrotechnical Commission (IEC) | |
| as IEC 61966-2-1. The sRGB color space roughly corresponds to 2.2 | |
| gamma correction. | |
| This extension adds a framebuffer capability for sRGB framebuffer | |
| update and blending. When blending is disabled but the new sRGB | |
| updated mode is enabled (assume the framebuffer supports the | |
| capability), high-precision linear color component values for red, | |
| green, and blue generated by fragment coloring are encoded for sRGB | |
| prior to being written into the framebuffer. When blending is enabled | |
| along with the new sRGB update mode, red, green, and blue framebuffer | |
| color components are treated as sRGB values that are converted to | |
| linear color values, blended with the high-precision color values | |
| generated by fragment coloring, and then the blend result is encoded | |
| for sRGB just prior to being written into the framebuffer. | |
| The primary motivation for this extension is that it allows OpenGL | |
| applications to render into a framebuffer that is scanned to a monitor | |
| configured to assume framebuffer color values are sRGB encoded. | |
| This assumption is roughly true of most PC monitors with default | |
| gamma correction. This allows applications to achieve faithful | |
| color reproduction for OpenGL rendering without adjusting the | |
| monitor's gamma correction. | |
| New Procedures and Functions | |
| None | |
| New Tokens | |
| Accepted by the <attribList> parameter of glXChooseVisual and | |
| glXChooseFBConfig, and by the <attrib> parameter of glXGetConfig | |
| and glXGetFBConfigAttrib: | |
| GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 | |
| Accepted by the <piAttributes> parameter of | |
| wglGetPixelFormatAttribivEXT, wglGetPixelFormatAttribfvEXT, and | |
| the <piAttribIList> and <pfAttribIList> of wglChoosePixelFormatEXT: | |
| WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 | |
| Accepted by the <cap> parameter of Enable, Disable, and IsEnabled, | |
| and by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, | |
| and GetDoublev: | |
| FRAMEBUFFER_SRGB 0x8DB9 | |
| Additions to Chapter 2 of the 2.0 Specification (OpenGL Operation) | |
| None | |
| Additions to Chapter 3 of the 2.0 Specification (Rasterization) | |
| None | |
| Additions to Chapter 4 of the 2.0 Specification (Per-Fragment Operations | |
| and the Frame Buffer) | |
| DELETE the following sentence from section 4.1.8 (Blending) because | |
| it is moved to the new "sRGB Conversion" section: | |
| "Each of these floating-point values is clamped to [0,1] and | |
| converted back to a fixed-point value in the manner described in | |
| section 2.14.9." | |
| If ARB_color_buffer_float is supported, the following paragraph | |
| is modified to eliminate the fixed-point clamping and conversion | |
| because this behavior is moved to the new "sRGB Conversion" section. | |
| "If the color buffer is fixed-point, the components of the source | |
| and destination values and blend factors are clamped to [0, 1] | |
| prior to evaluating the blend equation, the components of the | |
| blending result are clamped to [0,1] and converted to fixed- | |
| point values in the manner described in section 2.14.9. If the | |
| color buffer is floating-point, no clamping occurs. The | |
| resulting four values are sent to the next operation." | |
| The modified ARB_color_buffer_float paragraph should read: | |
| "If the color buffer is fixed-point, the components of the source | |
| and destination values and blend factors are clamped to [0, 1] | |
| prior to evaluating the blend equation. If the color buffer is | |
| floating-point, no clamping occurs. The resulting four values are | |
| sent to the next operation." | |
| Replace the following sentence: | |
| "Destination (framebuffer) components are taken to be fixed-point | |
| values represented according to the scheme in section 2.14.9 (Final | |
| Color Processing), as are source (fragment) components." | |
| with the following sentences: | |
| "Destination (framebuffer) components are taken to be fixed-point | |
| values represented according to the scheme in section 2.14.9 (Final | |
| Color Processing). If FRAMEBUFFER_SRGB is enabled and the value | |
| of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer | |
| attachment corresponding to the destination buffer is SRGB (see | |
| section 6.1.3), the R | |
| G, and B destination color values (after conversion from fixed-point | |
| to floating-point) are considered to be encoded for the sRGB color | |
| space and hence need to be linearized prior to their use in blending. | |
| Each R, G, and B component is linearized by some approximation of | |
| the following: | |
| { cs / 12.92, cs <= 0.04045 | |
| cl = { | |
| { ((cs + 0.055)/1.055)^2.4, cs > 0.04045 | |
| where cs is the component value prior to linearization and cl is | |
| the result. Otherwise if FRAMEBUFFER_SRGB is disabled, or the | |
| value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is not SRGB, no | |
| linearization is performed. | |
| The resulting linearized R, G, and B and unmodified A values are | |
| recombined as the destination color used in blending computations. | |
| ADD new section 4.1.X "sRGB Conversion" after section 4.1.8 (Blending) | |
| and before section 4.1.9 (Dithering). With this new section added, | |
| understand the "next operation" referred to in the section 4.1.8 | |
| (Blending) to now be "sRGB Conversion" (instead of "Dithering"). | |
| "If FRAMEBUFFER_SRGB is enabled and the value of | |
| FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment | |
| corresponding to the destination buffer is SRGB (see section 6.1.3), | |
| the R, G, and B values after blending are converted into the non-linear | |
| sRGB color space by some approximation of the following: | |
| { 0.0, 0 <= cl | |
| { 12.92 * c, 0 < cl < 0.0031308 | |
| cs = { 1.055 * cl^0.41666 - 0.055, 0.0031308 <= cl < 1 | |
| { 1.0, cl >= 1 | |
| where cl is the R, G, or B element and cs is the result | |
| (effectively converted into an sRGB color space). | |
| If FRAMEBUFFER_SRGB is disabled or the value of | |
| FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is not SRGB, then | |
| cs = cl | |
| The resulting cs values for R, G, and B and the unmodified A form a | |
| new RGBA color value. If the color | |
| buffer is fixed-point, the components of this RGBA color value are | |
| clamped to [0,1] and then converted to a fixed-point value in the | |
| manner described in section 2.14.9. The resulting four values are | |
| sent to the subsequent dithering operation." | |
| Additions to Chapter 5 of the 2.0 Specification (Special Functions) | |
| None | |
| Additions to Chapter 6 of the 2.0 Specification (State and State Requests) | |
| None | |
| Additions to the OpenGL Shading Language specification | |
| None | |
| Additions to the GLX Specification | |
| If GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB is specified for glXChooseVisual or | |
| glXChooseFBConfig, it is treated as an exact match. If it is not specified, | |
| it is treated as GLX_DONT_CARE. Sorting of visuals and fbconfigs by | |
| GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB is undefined. | |
| Dependencies on ARB_color_buffer_float | |
| If ARB_color_buffer_float is not supported, ignore the edits to | |
| ARB_color_buffer_float language. | |
| Dependencies on EXT_texture_sRGB and ARB_framebuffer_object | |
| If EXT_texture_sRGB and ARB_framebuffer_object are both supported, the | |
| implementation should set the value of | |
| FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING to LINEAR when | |
| rendering to a color texture that is not one of the EXT_texture_sRGB | |
| introduced internal formats. An implementation can determine whether | |
| or not it will set the value of | |
| FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING to SRGB for the | |
| EXT_texture_sRGB introduced internal formats. Implementations are | |
| encouraged to allow sRGB update and blending when rendering to sRGB | |
| textures using ARB_framebuffer_object but this is not required. | |
| In any case, FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING should indicate | |
| whether or not sRGB update and blending is supported. | |
| Dependencies on ARB_draw_buffers, EXT_texture_sRGB, and ARB_framebuffer_object | |
| If ARB_draw_buffers, EXT_texture_sRGB, and ARB_framebuffer_object | |
| are supported and an application attempts to render to a set of | |
| color buffers where some but not all of the color buffers are SRGB | |
| capable, sRGB update and blending only apply to the color buffers | |
| that are actually sRGB-capable. | |
| GLX Protocol | |
| None. | |
| Errors | |
| Relaxation of INVALID_ENUM errors | |
| --------------------------------- | |
| Enable, Disable, IsEnabled, GetBooleanv, GetIntegerv, GetFloatv, | |
| and GetDoublev now accept FRAMEBUFFER_SRGB as allowed in the "New | |
| Tokens" section. | |
| New State | |
| Add to table 6.20 (Pixel Operations) | |
| Get Value Type Get Command Initial Value Description Sec. Attribute | |
| ---------------- ---- ----------- ------------- --------------- ----- ------------------- | |
| FRAMEBUFFER_SRGB B IsEnabled False sRGB update and 4.1.X color-buffer/enable | |
| blending enable | |
| New Implementation Dependent State | |
| None | |
| Issues | |
| 1) What should this extension be called? | |
| RESOLVED: ARB_framebuffer_sRGB. | |
| The "ARB_framebuffer" part indicates the extension is in | |
| the framebuffer domain and "sRGB" indicates the extension is | |
| adding a set of sRGB formats. This mimics the naming of the | |
| EXT_texture_sRGB extension that adds sRGB texture formats. | |
| The mixed-case spelling of sRGB is the established usage so | |
| "_sRGB" is preferred to "_srgb". The "s" stands for standard | |
| (color space). | |
| For token names, we use "SRGB" since token names are uniformly | |
| capitalized. | |
| 2) Should alpha be sRGB encoded? | |
| RESOLVED: No. Alpha remains linear. | |
| A rationale for this resolution is found in Alvy Ray's "Should | |
| Alpha Be Nonlinear If RGB Is?" Tech Memo 17 (December 14, 1998). | |
| See: ftp://ftp.alvyray.com/Acrobat/17_Nonln.pdf | |
| 3) Should the ability to support sRGB framebuffer update and blending | |
| be an attribute of the framebuffer? | |
| RESOLVED: Yes. It should be a capability of some pixel formats | |
| (mostly likely just RGB8 and RGBA8) that says sRGB blending can | |
| be enabled. | |
| This allows an implementation to simply mark the existing RGB8 | |
| and RGBA8 pixel formats as supporting sRGB blending and then | |
| just provide the functionality for sRGB update and blending for | |
| such formats. | |
| sRGB support for floating-point formats makes little sense | |
| (because floating-point already provide a non-linear distribution | |
| of precision and typically have considerably more precision | |
| than 8-bit fixed-point framebuffer components allow) and would | |
| be expensive to support. | |
| Requiring sRGB support for all fixed-point buffers means that | |
| support for 16-bit components or very small 5-bit or 6-bit | |
| components would require special sRGB conversion hardware. | |
| Typically sRGB is well-suited for 8-bit fixed-point components | |
| so we do not want this extension to require expensive tables | |
| for other component sizes that are unlikely to ever be used. | |
| Implementations could support sRGB conversion for any color | |
| framebuffer format but implementations are not required to | |
| (honestly nor are implementations like to support sRGB on anything | |
| but 8-bit fixed-point color formats). | |
| 4) Should there be an enable for sRGB update and blending? | |
| RESOLVED: Yes, and it is disabled by default. The enable only | |
| applies if a destination buffer's pixel format is capable | |
| of sRGB update and blending. Otherwise, the enable is silently | |
| ignored (similar to how the multisample enables are ignored when | |
| the pixel format lacks multisample supports). | |
| 5) How is sRGB blending done? | |
| RESOLVED: Blending is a linear operation so should be performed | |
| on values in linear spaces. sRGB-encoded values are in a | |
| non-linear space so sRGB blending should convert sRGB-encoded | |
| values from the framebuffer to linear values, blend, and then | |
| sRGB-encode the result to store it in the framebuffer. | |
| The destination color RGB components are each converted | |
| from sRGB to a linear value. Blending is then performed. | |
| The source color and constant color are simply assumed to be | |
| treated as linear color components. Then the result of blending | |
| is converted to an sRGB encoding and stored in the framebuffer. | |
| 6) What happens if GL_FRAMEBUFFER_SRGB is enabled (and | |
| GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is GL_SRGB), but | |
| GL_BLEND is not enabled? | |
| RESOLVED: The color result from fragment coloring (the source | |
| color) is converted to an sRGB encoding and stored in the | |
| framebuffer. | |
| 7) How are multiple render targets handled? | |
| RESOLVED: Render targets that are not sRGB-capable ignore the | |
| state of the GL_FRAMEBUFFER_SRGB enable for sRGB update and | |
| blending. Note that unlike EXT_framebuffer_sRGB, the | |
| sRGB-capable query may be performed on a per-color-attachment | |
| basis. | |
| 8) Should sRGB framebuffer support affect the pixel path? | |
| RESOLVED: No. | |
| sRGB conversion only applies to color reads for blending and | |
| color writes. Color reads for glReadPixels, glCopyPixels, | |
| or glAccum have no sRGB conversion applied. | |
| For pixel path operations, an application could use pixel maps | |
| or color tables to perform an sRGB-to-linear conversion with | |
| these lookup tables. | |
| 9) Can luminance (single color component) framebuffer formats | |
| support sRGB blending? | |
| RESOLVED: Yes, if an implementation chooses to advertise such | |
| a format and set the sRGB attribute for the format too. | |
| Implementations are not obliged to provide such formats. | |
| 10) Should all component sizes be supported for sRGB components or | |
| just 8-bit? | |
| RESOLVED: This is at the implementation's discretion since | |
| the implementation decides what pixel formats such support sRGB | |
| update and blending. | |
| It likely implementations will only provide sRGB-capable | |
| framebuffer configurations for configurations with 8-bit | |
| components. | |
| 11) What must be specified as far as how do you convert to and from | |
| sRGB and linear RGB color spaces? | |
| RESOLVED: The specification language needs to only supply the | |
| linear RGB to sRGB conversion (see section 4.9.X above). | |
| The sRGB to linear RGB conversion is documented in the | |
| EXT_texture_sRGB specification. | |
| For completeness, the accepted linear RGB to sRGB conversion | |
| (the inverse of the function specified in section 3.8.x) is as | |
| follows: | |
| Given a linear RGB component, cl, convert it to an sRGB component, | |
| cs, in the range [0,1], with this pseudo-code: | |
| if (isnan(cl)) { | |
| /* Map IEEE-754 Not-a-number to zero. */ | |
| cs = 0.0; | |
| } else if (cl > 1.0) { | |
| cs = 1.0; | |
| } else if (cl < 0.0) { | |
| cs = 0.0; | |
| } else if (cl < 0.0031308) { | |
| cs = 12.92 * cl; | |
| } else { | |
| cs = 1.055 * pow(cl, 0.41666) - 0.055; | |
| } | |
| The NaN behavior in the pseudo-code is recommended but not | |
| specified in the actual specification language. | |
| sRGB components are typically stored as unsigned 8-bit | |
| fixed-point values. If cs is computed with the above | |
| pseudo-code, cs can be converted to a [0,255] integer with this | |
| formula: | |
| csi = floor(255.0 * cs + 0.5) | |
| 12) Does this extension guarantee images rendered with sRGB textures | |
| will "look good" when output to a device supporting an sRGB | |
| color space? | |
| RESOLVED: No. | |
| Whether the displayed framebuffer is displayed to a monitor that | |
| faithfully reproduces the sRGB color space is beyond the scope | |
| of this extension. This involves the gamma correction and color | |
| calibration of the physical display device. | |
| 13) How does this extension interact with ARB_framebuffer_object? | |
| RESOLVED: ARB_framebuffer_object is required to provide the | |
| GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING query used to determine | |
| if the color texture image is capable of sRGB rendering. | |
| This query should be LINEAR for all texture internal formats | |
| other than sRGB internal formats such as those introduced by | |
| EXT_texture_sRGB. Implementations of this extension must be able | |
| to support sRGB update and blending of sRGB textures. | |
| 14) How is the constant blend color handled for sRGB framebuffers? | |
| RESOLVED: The constant blend color is specified as four | |
| floating-point values. Given that the texture border color can | |
| be specified at such high precision, it is always treated as a | |
| linear RGBA value. | |
| 15) How does glCopyTex[Sub]Image work with sRGB? Suppose we're | |
| rendering to a floating point pbuffer or framebuffer object and | |
| do CopyTexImage. Are the linear framebuffer values converted | |
| to sRGB during the copy? | |
| RESOLVED: No, linear framebuffer values will NOT be automatically | |
| converted to the sRGB encoding during the copy. If such a | |
| conversion is desired, as explained in issue 12, the red, green, | |
| and blue pixel map functionality can be used to implement a | |
| linear-to-sRGB encoding translation. | |
| 16) Should this extension explicitly specify the particular | |
| sRGB-to-linear and linear-to-sRGB conversions it uses? | |
| RESOLVED: The conversions are explicitly specified but | |
| allowance for approximations is provided. The expectation is | |
| that the implementation is likely to use a table to implement the | |
| conversions the conversion is necessarily then an approximation. | |
| 17) How does this extension interact with multisampling? | |
| RESOLVED: There are no explicit interactions. However, arguably | |
| if the color samples for multisampling are sRGB encoded, the | |
| samples should be linearized before being "resolved" for display | |
| and then recoverted to sRGB if the output device expects sRGB | |
| encoded color components. | |
| This is really a video scan-out issue and beyond the scope | |
| of this extension which is focused on the rendering issues. | |
| However some implementation advice is provided: | |
| The implementation sufficiently aware of the gamma correction | |
| configured for the display device could decide to perform an | |
| sRGB-correct multisample resolve. Whether this occurs or not | |
| could be determined by a control panel setting or inferred by | |
| the application's use of this extension. | |
| 18) Why is the sRGB framebuffer GL_FRAMEBUFFER_SRGB enable | |
| disabled by default? | |
| RESOLVED: This extension could have a boolean | |
| sRGB-versus-non-sRGB pixel format configuration mode that | |
| determined whether or not sRGB framebuffer update and blending | |
| occurs. The problem with this approach is 1) it creates may more | |
| pixel formation configurations because sRGB and non-sRGB versions | |
| of lots of existing configurations must be advertised, and 2) | |
| applicaitons unaware of sRGB might unknowingly select an sRGB | |
| configuration and then generate over-bright rendering. | |
| It seems more appropriate to have a capability for sRGB | |
| framebuffer update and blending that is disabled by default. | |
| This allows existing RGB8 and RGBA8 framebuffer configurations | |
| to be marked as sRGB capable (so no additional configurations | |
| need be enumerated). Applications that desire sRGB rendering | |
| should identify an sRGB-capable framebuffer configuration and | |
| then enable sRGB rendering. | |
| This is different from how EXT_texture_sRGB handles sRGB support | |
| for texture formats. In the EXT_texture_sRGB extension, textures | |
| are either sRGB or non-sRGB and there is no texture parameter | |
| to switch textures between the two modes. This makes sense for | |
| EXT_texture_sRGB because it allows implementations to fake sRGB | |
| textures with higher-precision linear textures that simply convert | |
| sRGB-encoded texels to sufficiently precise linear RGB values. | |
| Texture formats also don't have the problem enumerated pixel | |
| format descriptions have where a naive application could stumble | |
| upon an sRGB-capable pixel format. sRGB textures require | |
| explicit use of one of the new EXT_texture_sRGB-introduced | |
| internal formats. | |
| 19) How does sRGB and this extension interact with digital video | |
| output standards, in particular DVI? | |
| RESOLVED: The DVI 1.0 specification recommends "as a default | |
| position that digital moniotrs of all types support a color | |
| transfer function similar to analog CRT monitors (gamma=2.2) | |
| which makes up the majority of the compute display market." This | |
| means DVI output devices should benefit from blending in the | |
| sRGB color space just like analog monitors. | |
| 20) Why don't the new tokens and entry points in this extension have | |
| "ARB" suffixes like other ARB extensions? | |
| RESOLVED: Unlike most ARB extensions, this is a strict subset of | |
| functionality already approved in OpenGL 3.0. This extension | |
| exists only to support that functionality on older hardware that | |
| cannot implement a full OpenGL 3.0 driver. Since there are no | |
| possible behavior changes between the ARB extension and core | |
| features, source code compatibility is improved by not using | |
| suffixes on the extension. | |
| This does not apply to the GLX and WGL elements of this | |
| extension, since those elements are not part of a new core GLX | |
| or WGL release yet. | |
| 21) Where's the specification language for the GLX and WGL pixel | |
| format selection interface? | |
| TO BE DONE. The {GLX,WGL}_FRAMEBUFFER_SRGB_CAPABLE_ARB pixel | |
| format attributes are used to select default framebuffers which | |
| are sRGB-capable in the fairly obvious way, but this language | |
| was missing in the original EXT_framebuffer_sRGB and needs to be | |
| added here. | |
| Revision History | |
| Rev. Date Author Changes | |
| ---- -------- -------- ------------------------------------- | |
| 1.3 09/19/19 ajax Clarify GLX interaction. | |
| 1.2 08/11/08 jleech Use per-FBO-attachment state for | |
| sRGB-capable queries, rather then the | |
| EXT's single boolean query for the | |
| entire framebuffer. | |
| 1.1 08/08/08 jleech Remove ARB suffixes. | |
| 1 10/21/06 barthold Added revision history | |
| 0.4 10/20/06 mjk Added issue 19 | |
| 0.3 mjk Internal spec development. | |