| Name |
| |
| KHR_blend_equation_advanced |
| |
| Name Strings |
| |
| GL_KHR_blend_equation_advanced |
| GL_KHR_blend_equation_advanced_coherent |
| |
| Contact |
| |
| Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) |
| |
| Notice |
| |
| Copyright (c) 2012-2015 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 and OpenGL ES Working Groups. 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 |
| |
| Contributors |
| |
| OpenGL ES Working Group in Khronos |
| Jeff Bolz, NVIDIA Corporation |
| Mathias Heyer, NVIDIA Corporation |
| Mark Kilgard, NVIDIA Corporation |
| Daniel Koch, NVIDIA Corporation |
| Rik Cabanier, Adobe |
| Slawek Grajewski, Intel |
| |
| Status |
| |
| Complete. |
| Ratified by the Khronos Board of Promoters on 2014/03/14. |
| |
| Version |
| |
| Last Modified Date: February 14, 2018 |
| Revision: 17 |
| |
| Number |
| |
| ARB Extension #174 |
| OpenGL ES Extension #168 |
| |
| Dependencies |
| |
| This extension is written against the OpenGL 4.1 Specification |
| (Compatibility Profile). |
| |
| This extension is written against the OpenGL Shading Language |
| Specification, Version 4.10 (Revision 6). |
| |
| OpenGL 2.0 is required (for Desktop). |
| |
| OpenGL ES 2.0 is required (for mobile). |
| |
| EXT_blend_minmax is required (for mobile). |
| |
| This extension interacts with OpenGL 4.0. |
| |
| This extension interacts with OpenGL 4.1 (Core Profile). |
| |
| This extension interacts with OpenGL 4.3 or later. |
| |
| This extension interacts with OpenGL ES 2.0. |
| |
| This extension interacts with OpenGL ES 3.0. |
| |
| This extension interacts with NV_path_rendering. |
| |
| Overview |
| |
| This extension adds a number of "advanced" blending equations that can be |
| used to perform new color blending operations, many of which are more |
| complex than the standard blend modes provided by unextended OpenGL. This |
| extension provides two different extension string entries: |
| |
| - KHR_blend_equation_advanced: Provides the new blending equations, but |
| guarantees defined results only if each sample is touched no more than |
| once in any single rendering pass. The command BlendBarrierKHR() is |
| provided to indicate a boundary between passes. |
| |
| - KHR_blend_equation_advanced_coherent: Provides the new blending |
| equations, and guarantees that blending is done coherently and in API |
| primitive order. An enable is provided to allow implementations to opt |
| out of fully coherent blending and instead behave as though only |
| KHR_blend_equation_advanced were supported. |
| |
| Some implementations may support KHR_blend_equation_advanced without |
| supporting KHR_blend_equation_advanced_coherent. |
| |
| In unextended OpenGL, the set of blending equations is limited, and can be |
| expressed very simply. The MIN and MAX blend equations simply compute |
| component-wise minimums or maximums of source and destination color |
| components. The FUNC_ADD, FUNC_SUBTRACT, and FUNC_REVERSE_SUBTRACT |
| multiply the source and destination colors by source and destination |
| factors and either add the two products together or subtract one from the |
| other. This limited set of operations supports many common blending |
| operations but precludes the use of more sophisticated transparency and |
| blending operations commonly available in many dedicated imaging APIs. |
| |
| This extension provides a number of new "advanced" blending equations. |
| Unlike traditional blending operations using the FUNC_ADD equation, these |
| blending equations do not use source and destination factors specified by |
| BlendFunc. Instead, each blend equation specifies a complete equation |
| based on the source and destination colors. These new blend equations are |
| used for both RGB and alpha components; they may not be used to perform |
| separate RGB and alpha blending (via functions like |
| BlendEquationSeparate). |
| |
| These blending operations are performed using premultiplied source and |
| destination colors, where RGB colors produced by the fragment shader and |
| stored in the framebuffer are considered to be multiplied by alpha |
| (coverage). Many of these advanced blending equations are formulated |
| where the result of blending source and destination colors with partial |
| coverage have three separate contributions: from the portions covered by |
| both the source and the destination, from the portion covered only by the |
| source, and from the portion covered only by the destination. Such |
| equations are defined assuming that the source and destination coverage |
| have no spatial correlation within the pixel. |
| |
| In addition to the coherency issues on implementations not supporting |
| KHR_blend_equation_advanced_coherent, this extension has several |
| limitations worth noting. First, the new blend equations are not |
| supported while rendering to more than one color buffer at once; an |
| INVALID_OPERATION will be generated if an application attempts to render |
| any primitives in this unsupported configuration. Additionally, blending |
| precision may be limited to 16-bit floating-point, which could result in a |
| loss of precision and dynamic range for framebuffer formats with 32-bit |
| floating-point components, and in a loss of precision for formats with 12- |
| and 16-bit signed or unsigned normalized integer components. |
| |
| New Procedures and Functions |
| |
| void BlendBarrierKHR(void); |
| |
| New Tokens |
| |
| Accepted by the <cap> parameter of Disable, Enable, and IsEnabled, and by |
| the <pname> parameter of GetIntegerv, GetBooleanv, GetFloatv, GetDoublev |
| and GetInteger64v: |
| |
| BLEND_ADVANCED_COHERENT_KHR 0x9285 |
| |
| Note: The BLEND_ADVANCED_COHERENT_KHR enable is provided if and only if |
| the KHR_blend_equation_advanced_coherent extension is supported. On |
| implementations supporting only KHR_blend_equation_advanced, this enable |
| is considered not to exist. |
| |
| Accepted by the <mode> parameter of BlendEquation and BlendEquationi: |
| |
| MULTIPLY_KHR 0x9294 |
| SCREEN_KHR 0x9295 |
| OVERLAY_KHR 0x9296 |
| DARKEN_KHR 0x9297 |
| LIGHTEN_KHR 0x9298 |
| COLORDODGE_KHR 0x9299 |
| COLORBURN_KHR 0x929A |
| HARDLIGHT_KHR 0x929B |
| SOFTLIGHT_KHR 0x929C |
| DIFFERENCE_KHR 0x929E |
| EXCLUSION_KHR 0x92A0 |
| |
| HSL_HUE_KHR 0x92AD |
| HSL_SATURATION_KHR 0x92AE |
| HSL_COLOR_KHR 0x92AF |
| HSL_LUMINOSITY_KHR 0x92B0 |
| |
| NOTE: These enums are not accepted by the <modeRGB> or <modeAlpha> |
| parameters of BlendEquationSeparate or BlendEquationSeparatei. |
| |
| |
| Additions to Chapter 2 of the OpenGL 4.1 Specification (OpenGL Operation) |
| |
| None. |
| |
| Additions to Chapter 3 of the OpenGL 4.1 Specification (Rasterization) |
| |
| None. |
| |
| Additions to Chapter 4 of the OpenGL 4.1 Specification (Per-Fragment |
| Operations and the Frame Buffer) |
| |
| Modify Section 4.1.8, Blending (p. 359). |
| |
| (modify the first paragraph, p. 361, allowing for new values in the |
| <mode> parameter) ... <modeRGB> and <modeAlpha> must be one of |
| FUNC_ADD, FUNC_SUBTRACT, FUNC_REVERSE_SUBTRACT, MIN, or MAX as listed |
| in Table 4.1. <mode> must be one of the mode values in Table 4.1, |
| or one of the blend equations listed in tables X.1 and X.2. ... |
| |
| (modify the third paragraph, p. 361, specifying minimum precision and |
| dynamic range for blend operations) ... Blending computations are treated |
| as if carried out in floating-point. For the equations in table 4.1, |
| blending computations will be performed with a precision and dynamic range |
| no lower than that used to represent destination components. For the |
| equations in table X.1 and X.2, blending computations will be performed |
| with a precision and dynamic range no lower than the smaller of that used |
| to represent destination components or that used to represent 16-bit |
| floating-point values as described in section 2.1.1. |
| |
| (add unnumbered subsection prior to "Dual Source Blending and Multiple |
| Draw Buffers", p. 363) |
| |
| Advanced Blend Equations |
| |
| The advanced blend equations are those listed in tables X.1 and X.2. When |
| using one of these equations, blending is performed according to the |
| following equations: |
| |
| R = f(Rs',Rd')*p0(As,Ad) + Y*Rs'*p1(As,Ad) + Z*Rd'*p2(As,Ad) |
| G = f(Gs',Gd')*p0(As,Ad) + Y*Gs'*p1(As,Ad) + Z*Gd'*p2(As,Ad) |
| B = f(Bs',Bd')*p0(As,Ad) + Y*Bs'*p1(As,Ad) + Z*Bd'*p2(As,Ad) |
| A = X*p0(As,Ad) + Y*p1(As,Ad) + Z*p2(As,Ad) |
| |
| where the function f and terms X, Y, and Z are specified in the table. |
| The R, G, and B components of the source color used for blending are |
| considered to have been premultiplied by the A component prior to |
| blending. The base source color (Rs',Gs',Bs') is obtained by dividing |
| through by the A component: |
| |
| (Rs', Gs', Bs') = |
| (0, 0, 0), if As == 0 |
| (Rs/As, Gs/As, Bs/As), otherwise |
| |
| The destination color components are always considered to have been |
| premultiplied by the destination A component and the base destination |
| color (Rd', Gd', Bd') is obtained by dividing through by the A component: |
| |
| (Rd', Gd', Bd') = |
| (0, 0, 0), if Ad == 0 |
| (Rd/Ad, Gd/Ad, Bd/Ad), otherwise |
| |
| When blending using advanced blend equations, we expect that the R, G, and |
| B components of premultiplied source and destination color inputs be |
| stored as the product of non-premultiplied R, G, and B components and the |
| A component of the color. If any R, G, or B component of a premultiplied |
| input color is non-zero and the A component is zero, the color is |
| considered ill-formed, and the corresponding component of the blend result |
| will be undefined. |
| |
| The weighting functions p0, p1, and p2 are defined as follows: |
| |
| p0(As,Ad) = As*Ad |
| p1(As,Ad) = As*(1-Ad) |
| p2(As,Ad) = Ad*(1-As) |
| |
| In these functions, the A components of the source and destination colors |
| are taken to indicate the portion of the pixel covered by the fragment |
| (source) and the fragments previously accumulated in the pixel |
| (destination). The functions p0, p1, and p2 approximate the relative |
| portion of the pixel covered by the intersection of the source and |
| destination, covered only by the source, and covered only by the |
| destination, respectively. The equations defined here assume that there |
| is no correlation between the source and destination coverage. |
| |
| |
| Mode Blend Coefficients |
| -------------------- ----------------------------------- |
| MULTIPLY_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = Cs*Cd |
| |
| SCREEN_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = Cs+Cd-Cs*Cd |
| |
| OVERLAY_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = 2*Cs*Cd, if Cd <= 0.5 |
| 1-2*(1-Cs)*(1-Cd), otherwise |
| |
| DARKEN_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = min(Cs,Cd) |
| |
| LIGHTEN_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = max(Cs,Cd) |
| |
| COLORDODGE_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = |
| 0, if Cd <= 0 |
| min(1,Cd/(1-Cs)), if Cd > 0 and Cs < 1 |
| 1, if Cd > 0 and Cs >= 1 |
| |
| COLORBURN_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = |
| 1, if Cd >= 1 |
| 1 - min(1,(1-Cd)/Cs), if Cd < 1 and Cs > 0 |
| 0, if Cd < 1 and Cs <= 0 |
| |
| HARDLIGHT_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = 2*Cs*Cd, if Cs <= 0.5 |
| 1-2*(1-Cs)*(1-Cd), otherwise |
| |
| SOFTLIGHT_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = |
| Cd-(1-2*Cs)*Cd*(1-Cd), |
| if Cs <= 0.5 |
| Cd+(2*Cs-1)*Cd*((16*Cd-12)*Cd+3), |
| if Cs > 0.5 and Cd <= 0.25 |
| Cd+(2*Cs-1)*(sqrt(Cd)-Cd), |
| if Cs > 0.5 and Cd > 0.25 |
| |
| DIFFERENCE_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = abs(Cd-Cs) |
| |
| EXCLUSION_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = Cs+Cd-2*Cs*Cd |
| |
| Table X.1, Advanced Blend Equations |
| |
| |
| When using one of the HSL blend equations in table X.2 as the blend |
| equation, the RGB color components produced by the function f() are |
| effectively obtained by converting both the non-premultiplied source and |
| destination colors to the HSL (hue, saturation, luminosity) color space, |
| generating a new HSL color by selecting H, S, and L components from the |
| source or destination according to the blend equation, and then converting |
| the result back to RGB. The HSL blend equations are only well defined |
| when the values of the input color components are in the range [0..1]. |
| In the equations below, a blended RGB color is produced according to the |
| following pseudocode: |
| |
| float minv3(vec3 c) { |
| return min(min(c.r, c.g), c.b); |
| } |
| float maxv3(vec3 c) { |
| return max(max(c.r, c.g), c.b); |
| } |
| float lumv3(vec3 c) { |
| return dot(c, vec3(0.30, 0.59, 0.11)); |
| } |
| float satv3(vec3 c) { |
| return maxv3(c) - minv3(c); |
| } |
| |
| // If any color components are outside [0,1], adjust the color to |
| // get the components in range. |
| vec3 ClipColor(vec3 color) { |
| float lum = lumv3(color); |
| float mincol = minv3(color); |
| float maxcol = maxv3(color); |
| if (mincol < 0.0) { |
| color = lum + ((color-lum)*lum) / (lum-mincol); |
| } |
| if (maxcol > 1.0) { |
| color = lum + ((color-lum)*(1-lum)) / (maxcol-lum); |
| } |
| return color; |
| } |
| |
| // Take the base RGB color <cbase> and override its luminosity |
| // with that of the RGB color <clum>. |
| vec3 SetLum(vec3 cbase, vec3 clum) { |
| float lbase = lumv3(cbase); |
| float llum = lumv3(clum); |
| float ldiff = llum - lbase; |
| vec3 color = cbase + vec3(ldiff); |
| return ClipColor(color); |
| } |
| |
| // Take the base RGB color <cbase> and override its saturation with |
| // that of the RGB color <csat>. The override the luminosity of the |
| // result with that of the RGB color <clum>. |
| vec3 SetLumSat(vec3 cbase, vec3 csat, vec3 clum) |
| { |
| float minbase = minv3(cbase); |
| float sbase = satv3(cbase); |
| float ssat = satv3(csat); |
| vec3 color; |
| if (sbase > 0) { |
| // Equivalent (modulo rounding errors) to setting the |
| // smallest (R,G,B) component to 0, the largest to <ssat>, |
| // and interpolating the "middle" component based on its |
| // original value relative to the smallest/largest. |
| color = (cbase - minbase) * ssat / sbase; |
| } else { |
| color = vec3(0.0); |
| } |
| return SetLum(color, clum); |
| } |
| |
| |
| Mode Result |
| -------------------- ---------------------------------------- |
| HSL_HUE_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = SetLumSat(Cs,Cd,Cd); |
| |
| HSL_SATURATION_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = SetLumSat(Cd,Cs,Cd); |
| |
| HSL_COLOR_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = SetLum(Cs,Cd); |
| |
| HSL_LUMINOSITY_KHR (X,Y,Z) = (1,1,1) |
| f(Cs,Cd) = SetLum(Cd,Cs); |
| |
| Table X.2, Hue-Saturation-Luminosity Advanced Blend Equations |
| |
| |
| Advanced blending equations are supported only when rendering to a single |
| color buffer using fragment color zero. If any non-NONE draw buffer uses |
| a blend equation found in table X.1 or X.2, the error INVALID_OPERATION is |
| generated by [[Compatibility Profile: Begin or any operation that |
| implicitly calls Begin (such as DrawElements)]] [[Core Profile and OpenGL |
| ES: DrawArrays and the other drawing commands defined in section 2.8.3]] |
| if: |
| |
| * the draw buffer for color output zero selects multiple color buffers |
| (e.g., FRONT_AND_BACK in the default framebuffer); or |
| |
| * the draw buffer for any other color output is not NONE. |
| |
| [[ The following paragraph applies to KHR_blend_equation_advanced only. ]] |
| |
| When using advanced blending equations, applications should split their |
| rendering into a collection of blending passes, none of which touch an |
| individual sample in the framebuffer more than once. The results of |
| blending are undefined if the sample being blended has been touched |
| previously in the same pass. The command |
| |
| void BlendBarrierKHR(void); |
| |
| specifies a boundary between passes when using advanced blend equations. |
| Any command that causes the value of a sample to be modified using the |
| framebuffer is considered to touch the sample, including clears, blended |
| or unblended primitives, and BlitFramebuffer copies. |
| |
| [[ The following paragraph applies to KHR_blend_equation_advanced_coherent |
| only. ]] |
| |
| When using advanced blending equations, blending is typically done |
| coherently and in primitive order. When an individual sample is covered |
| by multiple primitives, blending for that sample is performed sequentially |
| in the order in which the primitives were submitted. This coherent |
| blending is enabled by default, but can be enabled or disabled by calling |
| Enable or Disable with the symbolic constant BLEND_ADVANCED_COHERENT_KHR. |
| If coherent blending is disabled, applications should split their |
| rendering into a collection of blending passes, none of which touch an |
| individual sample in the framebuffer more than once. When coherent |
| blending is disabled, the results of blending are undefined if the sample |
| being blended has been touched previously in the same pass. The command |
| |
| void BlendBarrierKHR(void); |
| |
| specifies a boundary between passes when using advanced blend equations. |
| Any command that causes the value of a sample to be modified using the |
| framebuffer is considered to touch the sample, including clears, blended |
| or unblended primitives, and BlitFramebuffer copies. |
| |
| Advanced blending equations require the use of a fragment shader with a |
| matching "blend_support" layout qualifier. If the current blend equation |
| is found in table X.1 or X.2, and the active fragment shader does not |
| include the layout qualifier matching the blend equation or |
| "blend_support_all_equations", the error INVALID_OPERATION is generated by |
| [[Compatibility Profile: Begin or any operation that implicitly calls |
| Begin (such as DrawElements)]] [[Core Profile and OpenGL ES: DrawArrays |
| and the other drawing commands defined in section 2.8.3]] The set of |
| layout qualifiers supported in fragment shaders is specified in sectino |
| 4.3.8.2 of the OpenGL Shading Language Specification. |
| |
| |
| Additions to Chapter 5 of the OpenGL 4.1 Specification (Special Functions) |
| |
| None. |
| |
| Additions to Chapter 6 of the OpenGL 4.1 Specification (State and |
| State Requests) |
| |
| None. |
| |
| Additions to Appendix A of the OpenGL 4.1 Specification (Invariance) |
| |
| None. |
| |
| Additions to the AGL/GLX/WGL/EGL Specifications |
| |
| None. |
| |
| Additions to the OpenGL Shading Language Specification, Version 4.10 |
| |
| Including the following line in a shader can be used to control the |
| language features described in this extension: |
| |
| #extension GL_KHR_blend_equation_advanced : <behavior> |
| |
| where <behavior> is as specified in section 3.3. |
| |
| A new preprocessor #define is added to the OpenGL Shading Language: |
| |
| #define GL_KHR_blend_equation_advanced 1 |
| |
| Modify Section 4.3.8.2, Output Layout Qualifiers, p. 47 |
| |
| (add to the end of the section, p. 50) |
| |
| Fragment shaders additionally support the following layout qualifiers, |
| specifying a set of advanced blend equations supported when the fragment |
| shader is used. These layout qualifiers are only permitted on the |
| interface qualifier out, and use the identifiers specified in the "Layout |
| Qualifier" column of Table X.3. |
| |
| If a layout qualifier in Table X.3 is specified in the fragment shader, |
| the fragment shader may be used with the corresponding advanced blend |
| equation in the "Blend Equation(s) Supported" column. Additionally, the |
| special qualifier "blend_support_all_equations" indicates that the shader |
| may be used with any advanced blending equation supported by the OpenGL |
| Specification. It is not an error to specify more than one of these |
| identifiers in any fragment shader. Specifying more than one qualifier or |
| "blend_support_all_equations" means that the fragment shader may be used |
| with multiple advanced blend equations. Additionally, it is not an error |
| to specify any single any of these layout qualifiers more than once. |
| |
| Layout Qualifier Blend Equation(s) Supported |
| ------------------------ ------------------------------ |
| blend_support_multiply MULTIPLY_KHR |
| blend_support_screen SCREEN_KHR |
| blend_support_overlay OVERLAY_KHR |
| blend_support_darken DARKEN_KHR |
| blend_support_lighten LIGHTEN_KHR |
| blend_support_colordodge COLORDODGE_KHR |
| blend_support_colorburn COLORBURN_KHR |
| blend_support_hardlight HARDLIGHT_KHR |
| blend_support_softlight SOFTLIGHT_KHR |
| blend_support_difference DIFFERENCE_KHR |
| blend_support_exclusion EXCLUSION_KHR |
| blend_support_hsl_hue HSL_HUE_KHR |
| blend_support_hsl_saturation HSL_SATURATION_KHR |
| blend_support_hsl_color HSL_COLOR_KHR |
| blend_support_hsl_luminosity HSL_LUMINOSITY_KHR |
| blend_support_all_equations /all blend equations/ |
| |
| Table X.3, Fragment Shader Output Layout Qualifiers for Blend Support |
| |
| A draw-time error will be generated in the OpenGL API if an application |
| attempts to render using an advanced blending equation without having a |
| matching layout qualifier specified in the active fragment shader. |
| |
| GLX Protocol |
| |
| !!! TBD |
| |
| Dependencies on OpenGL 4.0 |
| |
| If OpenGL 4.0 is not supported, references to the BlendEquationi API should |
| be removed. |
| |
| Dependencies on OpenGL 4.1 (Core Profile) |
| |
| This extension throws an INVALID_OPERATION when Begin is called if advanced |
| blend equations are used in conjunction with multiple draw buffers. For |
| the core profile of OpenGL 4.1 (and other versions of OpenGL), there is no |
| Begin command; instead, the error is thrown by other rendering commands |
| such as DrawArrays. The language in this specification documenting the |
| error has separate versions for the core and compatibility profiles. |
| |
| Dependencies on OpenGL 4.3 or later (any Profile) |
| |
| References to Chapter 4 are replaced with references to Chapter 17 (Writing |
| Fragments and Samples to the Framebuffer). |
| References to section 4.1.8 are replaced with references to section 17.3.8. |
| References to Table 4.1 are replace with references to Table 17.1. |
| References to section 2.1.1 are replaced with references to section 2.3.3. |
| |
| Dependencies on OpenGL ES 2.0 |
| |
| If unextended OpenGL ES 2.0 is supported, references to BlendEquationi, |
| BlendEquationSeparatei, GetInteger64v, and GetDoublev should be ignored. |
| |
| Ignore any references to multiple draw buffers if EXT_draw_buffers or |
| NV_draw_buffers is not supported. |
| |
| Dependencies on EXT_blend_minmax |
| |
| Requires EXT_blend_minmax on OpenGL ES 2.0 implementations and references |
| to MIN and MAX should be replace by references to MIN_EXT and MAX_EXT as |
| introduced by that extension. |
| |
| Dependencies on OpenGL ES 3.0 |
| |
| If unextended OpenGL ES 3.0 is supported, references to BlendEquationi, |
| BlendEquationSeparatei, and GetDoublev should be ignored. |
| |
| Dependencies on NV_path_rendering |
| |
| When NV_path_rendering is supported, covering geometry generated by the |
| commands CoverFillPathNV, CoverFillPathInstancedNV, CoverStrokePathNV, and |
| CoverStrokePathInstancedNV will automatically be blended coherently |
| relative to previous geometry when using the blend equations in this |
| extension. This guarantee is provided even on implementations supporting |
| only NV_blend_equation_advanced. |
| |
| Insert the following language after the discussion of the |
| BlendBarrierKHR() command for both extensions: |
| |
| [[ For KHR_blend_equation_advanced only: ]] |
| |
| The commands CoverFillPathNV, CoverFillPathInstancedNV, |
| CoverStrokePathNV, and CoverStrokePathInstancedNV are considered to |
| start a new blending pass, as though BlendBarrierKHR were called prior |
| to the cover operation. If a cover primitive is followed by subsequent |
| non-cover primitives using advanced blend equations and touching the |
| same samples, applications must call BlendBarrierKHR after the cover |
| primitives to ensure defined blending results. |
| |
| [[ For KHR_blend_equation_advanced_coherent, the language immediately |
| above should be used, but the first sentence should be prefixed with |
| "When coherent blending is disabled, ...". ]] |
| |
| |
| Errors |
| |
| If any non-NONE draw buffer uses a blend equation found in table X.1 or |
| X.2, the error INVALID_OPERATION is generated by Begin or any operation |
| that implicitly calls Begin (such as DrawElements) if: |
| |
| * the draw buffer for color output zero selects multiple color buffers |
| (e.g., FRONT_AND_BACK in the default framebuffer); or |
| |
| * the draw buffer for any other color output is not NONE. |
| |
| New State |
| Initial |
| Get Value Type Get Command Value Description Sec Attribute |
| -------------------- ---- ------------ ------------ ------------------------ ----- ------------ |
| BLEND_ADVANCED_ B IsEnabled TRUE are advanced blending 4.1.8 color-buffer |
| COHERENT_KHR equations guaranteed to |
| be evaluated coherently? |
| |
| Note: The BLEND_ADVANCED_COHERENT_KHR enable is provided if and only if |
| the KHR_blend_equation_advanced_coherent extension is supported. On |
| implementations supporting only KHR_blend_equation_advanced, this enable |
| is considered not to exist. |
| |
| New Implementation Dependent State |
| |
| None. |
| |
| Issues |
| |
| Note: These issues apply specifically to the definition of the |
| KHR_blend_equation_advanced specification, which was derived from the |
| extension NV_blend_equation_advanced. The issues from the original |
| NV_blend_equation_advanced specification have been removed, but can be |
| found (as of August 2013) in the OpenGL Registry at: |
| |
| http://www.opengl.org/registry/specs/NV/blend_equation_advanced.txt |
| |
| (0) How does this extension differ from the NV_blend_equation_advanced |
| extension for OpenGL and OpenGL ES? |
| |
| RESOLVED: A number of features have been removed from |
| NV_blend_equation_advanced, including: |
| |
| * The BlendParameterivNV API has been removed, and with it, the |
| BLEND_PREMULTIPLIED_SRC_NV and BLEND_OVERLAP_NV parameters. The spec |
| has been refactored to assume premultipled source colors and |
| uncorrelated source and destination coverage. |
| |
| * A number of less commonly used blend modes have been removed, |
| including: |
| |
| - certain "X/Y/Z" blending modes supported by few, if any, standards |
| (INVERT, INVERT_RGB_NV, LINEARDODGE_NV, LINEARBURN_NV, |
| VIVIDLIGHT_NV, LINEARLIGHT_NV, PINLIGHT_NV, HARDMIX_NV) |
| |
| - various versions of additive and subtractive modes (PLUS_NV, |
| PLUS_CLAMPED_NV, PLUS_CLAMPED_ALPHA_NV, PLUS_DARKER_NV, MINUS_NV, |
| MINUS_CLAMPED_NV) |
| |
| - other uncommon miscellaneous modes (CONTRAST_NV, INVERT_OVG_NV, |
| RED, GREEN, BLUE) |
| |
| Additionally, this extension adds blending support layout qualifiers to |
| the fragment shader (qualifying "out"). Each fragment shader can |
| specify a set of advanced blend equations that can be used when it is |
| active. For example: |
| |
| layout(blend_support_hardlight, blend_support_softlight) out; |
| |
| specifies that the HARDLIGHT_KHR and SOFTLIGHT_KHR equations are allowed |
| when using the shader. A draw-time error will be generated if an |
| advanced blend equation is enabled in the API and a matching layout |
| qualifier is not specified in the active fragment shader. |
| |
| (1) What should we do about the BLEND_PREMULTIPLIED_SRC_NV blend parameter |
| from NV_blend_equation_advanced? |
| |
| RESOLVED: Remove this parameter for simplicity. All equations in this |
| extension assume that the source and destination colors are both |
| premultiplied. |
| |
| (2) What should we do about the BLEND_OVERLAP_NV blend parameter from |
| NV_blend_equation_advanced? |
| |
| RESOLVED: Remove this parameter for simplicitly. All equations in this |
| extension assume an UNCORRELATED_NV overlap mode. Blending using the |
| UNCORRELATED_NV overlap mode is usually mathematically simpler than |
| blending using the DISJOINT_NV or CONJOINT_NV modes. |
| |
| (3) What set of "complex" blending equations should we support in this |
| extension? |
| |
| RESOLVED: During standardization of this extensions, the set of |
| equations provided in this extension has been reduced to a smaller |
| subset for simplicitly. The remaining equations are typically found in |
| a wide collection of compositing standards. In particular, the |
| standarization process removed several classes of blend equations from |
| the NV_blend_equation_advanced, as described in "differences" issue (0) |
| above. |
| |
| (4) Should we support the "Porter-Duff" blend equations (e.g., |
| SRC_OVER_NV) from NV_blend_equation_advanced? |
| |
| RESOLVED: All of these blend equations should be supportable in |
| unextended OpenGL ES 3.0, and have been removed for simplicity. The |
| primary rationale for this decision is to reduce the number of internal |
| paths required by the driver; some implementations may have separate |
| paths for traditional OpenGL blending and for the new advanced blending |
| equations. Redirecting "simple" advanced blending equations to |
| traditional fixed-function blending hardware may involved more driver |
| implementation work and may have different performance characteristics |
| than other "complex" blending equations. |
| |
| This approach does mean that an application wanting to use both |
| Porter-Duff blend equations and advanced blending equations provided by |
| this extension will need GL_to program blending somewhat differently |
| when using the Porter-Duff equations: |
| |
| if (isPorterDuff(equation)) { |
| glBlendEquation(GL_FUNC_ADD); // enable sf*S+df*D blending |
| glBlendFunc(srcFactor, dstFactor); // and program blend factors |
| } else { |
| glBlendEquation(equation); // advanced eqs. don't use BlendFunc |
| } |
| |
| (5) Should we impose any requirements on fragment shaders when used in |
| conjunction with advanced blend equations? |
| |
| RESOLVED: Yes. This extension adds fragment shader layout qualifiers |
| allowing individual shaders to specify that they will be used with one |
| or multiple advanced blending equations. When using an advanced |
| blending equation from this extension, it is necessary to use a fragment |
| shader with a matching layout qualifier. A draw-time error will be |
| generated if the current fragment shader doesn't include a layout |
| qualifier matching the current advanced blending mode. |
| |
| The rationale for this decision is that some implementations of this |
| extension may require special fragment shader code when using advanced |
| blending equations, and may perhaps perform the entire blending |
| operation in the fragment shader. Knowing the set of blending equations |
| that a fragment shader will be used with at compile time may reduce the |
| extent of run-time fragment shader re-compilation when the shader is |
| used. |
| |
| Note that NV_blend_equation_advanced doesn't include layout qualifiers |
| or the draw-time error specified here. |
| |
| (6) How do we handle coherency when a fragment is hit multiple times? |
| |
| RESOLVED: In this extension, blending equations will be done coherently |
| and in primitive order by default, as is the case with traditional |
| blending in OpenGL and OpenGL ES. |
| |
| The NVIDIA extension provides two separate extension string entries: |
| |
| * NV_blend_equation_advanced |
| * NV_blend_equation_advanced_coherent |
| |
| Exposing the former without the latter signals that the implementation |
| can support blending with these equations, but is unable to ensure that |
| fragments are blended in order when the same (x,y) is touched multiple |
| times. To ensure coherent results and proper ordering using the |
| non-coherent version of the extension, an application must separate its |
| rendering into "passes" that touch each (x,y) at most once, and call |
| BlendBarrierNV between passes. There are important use cases (e.g., |
| many path rendering algorithms) where this limitation isn't too |
| restrictive, and NVIDIA chose to expose the non-coherent version to |
| allow the functionality to be used on a larger set of GPUs. |
| |
| This extension is functionally comparable to an implementation of the |
| NVIDIA extension exposing both strings, where coherent behavior is |
| enabled by default. NV_blend_equation_advanced_coherent and this |
| extension both provide the ability to opt out of this automatic |
| coherence by disabling BLEND_ADVANCED_COHERENT_KHR and using |
| BlendBarrierKHR manually. This could theoretically result in higher |
| performance -- see issue (32) of the NVIDIA extension for more |
| discussion. |
| |
| (7) How should the blend equations COLORDODGE_KHR and COLORBURN_KHR be |
| expressed mathematically? |
| |
| RESOLVED: NVIDIA changed the definition of these equations after the |
| NV_blend_equation_advanced spec was originally published, as discussed |
| below. These changes add new special cases to the COLORDODGE_KHR and |
| COLORBURN_KHR equations that are found in newer compositing standard |
| specifications and in a number of implementations of old and new |
| standards. They believe that the omission of the special case in other |
| older specifications is a bug. They have no plans to add new blend |
| equation tokens to support "equivalent" modes without the new special |
| case. We are adopting the same approach in this extension. |
| |
| Note, however, that older versions of this extension and older NVIDIA |
| drivers implementing it will lack these special cases. A driver update |
| may be required to get the new behavior. |
| |
| There is some disagreement in different published specifications about |
| how these two blend equations should be handled. At the time the NVIDIA |
| extension was initially developed, all specifications they found that |
| specified blending equations mathematically (see issue 28 of |
| NV_blend_equation_advanced) were written the same way. Since then, they |
| discovered that newer working drafts of the W3C Compositing and Blending |
| Level 1 specification (for CSS and SVG) express "color-burn" as follows |
| (translated to our nomenclature): |
| |
| if (Cd == 1) // their Cb (backdrop) is our Cd (destination) |
| f(Cs,Cd) = 1 // their B() is our f() |
| else if (Cs == 0) |
| f(Cs,Cd) = 0 |
| else |
| f(Cs,Cd) = 1 - min(1, (1-Cd)/Cs) |
| |
| http://www.w3.org/TR/2013/WD-compositing-1-20131010/ |
| #blendingcolorburn |
| |
| Earlier versions of the same W3C specification, an older SVG compositing |
| draft specification, the Adobe PDF specification (and the ISO 32000-1 |
| standard), and the KHR_advanced_blending extension to OpenVG all specify |
| the following equation without the initial special case: |
| |
| if (Cs == 0) |
| f(Cs,Cd) = 0 |
| else |
| f(Cs,Cd) = 1 - min(1, (1-Cd)/Cs) |
| |
| http://www.w3.org/TR/2012/WD-compositing-20120816/ |
| #blendingcolorburn |
| http://www.w3.org/TR/2011/WD-SVGCompositing-20110315/ |
| http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/ |
| pdfs/pdf_reference_1-7.pdf |
| http://www.khronos.org/registry/vg/extensions/KHR/ |
| advanced_blending.txt |
| |
| For the Adobe PDF specification, the corrected blend equations are |
| published in an Adobe supplement to ISO 32000-1 and are expected to be |
| accepted in a future version of the standard: |
| |
| http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/ |
| devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf |
| |
| The author's understanding is that multiple shipping implementations of |
| these blending modes implement the special case for "Cd==1" above, |
| including various Adobe products and the open-source Ghostscript |
| project. |
| |
| We believe that the extra special case in this specification is |
| consistent with the physical model of color burning. Burning is |
| described in |
| |
| http://en.wikipedia.org/wiki/Dodging_and_burning |
| |
| as making a print with normal exposure, and then adding additional |
| exposure to darken the overall image. In the general equation: |
| |
| 1 - min(1, (1-Cd)/Cs) |
| |
| Cs operates as a sort of fudge factor where a value of 1.0 implies no |
| additional exposure time and 0.0 implies arbitrarily long additional |
| exposure time, where the initial amount of exposure (1-Cd) is multiplied |
| by 1/Cs and then clamped to maximum exposure by the min() operation. |
| The Cd==1 special case here implies that we get zero exposure in the |
| initial print, since 1-Cd==0. No amount of extra exposure time will |
| generate any additional exposure. This would imply that the final |
| result should have zero exposure and thus a final f() value of 1. This |
| matches the initial special case. Without that special case, we would |
| hit the second special case if Cs==0 (infinite exposure time), which |
| would yield an incorrect final value of 0 (full exposure). |
| |
| A similar issue applies to COLORDODGE_KHR, where some specifications |
| include a special case for Cb==0 while others do not. We have added a |
| special case there as well. |
| |
| (8) The NV_blend_equation_advanced extension has two variants: |
| NV_blend_equation_advanced and NV_blend_equation_advanced_coherent. |
| Some implementations of that extension are not capable of performing |
| fully coherent blending when samples are touched more than once |
| without a barrier, and may expose only the former. Should we follow |
| this pattern here or support only the "coherent" variant? |
| |
| RESOLVED: Yes. The working group originally decided to support only |
| the "coherent" variant (revision 4) for simplicity but later decided to |
| support both extension string entries as some implementations on both |
| OpenGL and OpenGL ES are unable to support the "coherent" variant. |
| Applications not wanting to manage coherency manually should look for |
| the KHR_blend_equation_advanced_coherent extension and ignore |
| KHR_blend_equation_advanced. |
| |
| (9) We don't permit the use of advanced blend equations with multiple draw |
| buffers. Should we produce compile-, link-, or draw-time errors if we |
| encounter a shader that includes both (a) one or more layout |
| qualifiers indicating that the shader wants to use advanced blending |
| and (b) a color output with a location other than zero? |
| |
| RESOLVED: No. |
| |
| In the current extension, there is a draw-time error generated if you |
| try to use one of the new blend equations with multiple color targets |
| (glDrawBuffers with a count > 1). With this restriction, any "extra" |
| fragment shader color outputs could never be successfully blended into |
| the framebuffer with one of these equations. |
| |
| When only one draw buffer is enabled when using a shader with multiple |
| outputs, "extra" outputs will simply be dropped and have no effect on |
| the framebuffer. You can already do this in unextended OpenGL and |
| OpenGL ES without generating an error. We didn't feel that the value of |
| such a warning/error justifies the draw-time overhead needed to detect |
| and report such a condition. |
| |
| Since this extension requires that you declare the intent to use |
| advanced blending using layout qualifers, it is possible to identify a |
| shader that may want to use "extra" color outputs with advanced blending |
| at compile time, with no draw-time overhead. We decided not to treat |
| this condition as an error for several reasons: |
| |
| - Advanced blending layout qualifiers don't require that blending |
| actually be enabled. Multiple draw buffers with multiple outputs |
| work just fine in that case. |
| |
| - If we treated this condition as an error and a future extension |
| relaxed the DrawBuffers restriction, it would be necessary to also |
| add a GLSL language feature to disable the now-undesirable error. |
| |
| (10) What happens when converting a premultiplied color with an alpha of |
| zero to a non-premultiplied color? |
| |
| RESOLVED: We specify that a premultiplied color of (0,0,0,0) should |
| produce non-premultiplied (R,G,B) values of (0,0,0). A premultiplied |
| color with an alpha of zero and a non-zero R, G, or B component is |
| considered to be ill-formed and will produce undefined blending results. |
| |
| For a non-premultiplied color (R',G',B',A'), the corresponding |
| premultiplied color (R,G,B,A) should satisfy the equation: |
| |
| (R,G,B,A) = (R'*A', G'*A', B'*A', A') |
| |
| If the alpha of a non-premultiplied color is zero, the corresponding |
| premultiplied color (R,G,B,A) should be (0,0,0,0). |
| |
| We specify that ill-formed premultiplied colors produce undefined |
| blending results to enable certain performance optimizations. In many |
| of these blending equations, the alpha component used as a denominator |
| to compute the non-premultiplied color ends up being multiplied by the |
| same alpha component in the coverage, resulting in cancellation. For |
| example, implementations may want to substitute a premultiplied |
| destination color into the last term of the basic blend equation: |
| |
| R = f(Rs',Rd')*p0(As,Ad) + Y*Rs'*p1(As,Ad) + Z*Rd'*p2(As,Ad) |
| = ... + Z*Rd'*(Ad*(1-As)) |
| = ... + Z*(Rd'*Ad)*(1-As) |
| = ... + Z* Rd * (1-As) |
| |
| This substitution would be invalid for ill-formed premultiplied |
| destination colors. We choose to specify undefined results for invalid |
| input colors rather than requiring implementations to skip such |
| optimizations or include logic to check for zero alpha values for each |
| input. |
| |
| (11) For "HSL" blend equations, the blend equation involves a clipping |
| step where colors may be "clipped" if the blend would produce |
| components are outside the range [0,1]. Are there inputs where this |
| blend could produce ill-defined or nonsensical results? |
| |
| RESOLVED: Yes, the results of HSL blend equations are undefined if the |
| input colors have components outside the range [0,1]. Even if the input |
| colors are in-range, the basic color adjustment done in these blends |
| could produce result components outside the range [0,1]. To compensate, |
| the ClipColor() function in the specification interpolates the result |
| color and a greyscale value that matches the luminance of the result. |
| The math for the clipping operation assumes the luminance of the result |
| color is in the range [0,1]. If that isn't the case, the clipping |
| operation could result in a divide by zero (when all result components |
| have the same out-of-bounds value) or perform an otherwise nonsensical |
| computation. |
| |
| |
| Revision History |
| |
| Revision 17, February 14, 2018 |
| |
| Fix ClipColor() equation where in the "if (maxcol > 1.0)" body the |
| "(color-lum)*lum" term should have been "(color-lum)*(1-lum)". Also |
| add new issue 11 for the case where the inputs to SetLum() are outside |
| the range [0..1] and could cause a divide-by-zero in ClipColor(). |
| |
| Revision 16, April 16, 2016 (from a September 30, 2014 edit that wasn't |
| published) |
| |
| Fix incorrectly specified color clamping in the HSL blend modes. |
| |
| Revision 15, May 9, 2015 |
| |
| Renumber as OpenGL ARB extension instead of vendor extension, by |
| symmetry with other KHR Khronos-approved extensions. Add copyright |
| notice. |
| |
| Revision 14, March 14, 2014 |
| |
| Cast as KHR extension. |
| |
| Revisions 12 and 13, March 5, 2014 |
| |
| For non-coherent blending, clarify that all writes to a sample are |
| considered to "touch" that sample and require a BlendBarrierKHR call |
| before blending overlapping geometry. Clears, non-blended geometry, and |
| copies by BlitFramebuffer or TexSubImage are all considered to "touch" a |
| sample (bug 11738). Specify that non-premultiplied values corresponding |
| to ill-conditioned premultiplied colors such as (1,1,1,0) are undefined |
| (bug 11739). Add issue (10) related to the ill-conditioned |
| premultiplied color issue. |
| |
| Revision 11, January 30, 2014 |
| |
| Cast as OES extension. |
| |
| Revision 10, January 22, 2014 |
| |
| Add issue (9), where we decided not to add compile- or link-time errors |
| when using both advanced blending and multiple color outputs (bug |
| 11468). |
| |
| Revision 9, January 2, 2014 |
| |
| Fix typo in issue (0). |
| |
| Revision 8, November 6, 2013 |
| |
| Restore support for non-coherent-only implementations that was removed |
| in revision 4. Fix the language about non-coherent blending to specify |
| that results are undefined only if an individual *sample* is touched |
| more than once (instead of *pixel*). Minor language tweaks to use |
| "equations" consistently, instead of sometimes using "modes". |
| |
| Revision 7, October 21, 2013 |
| |
| Add a reference to the Adobe supplement to ISO 32000-1, which includes |
| the corrected equations for COLORDODGE_NV and COLORBURN_NV. Move |
| "NVIDIA Implementation Details" down a bit in the spec. |
| |
| Revision 6, October 16, 2013 |
| |
| Add new special cases for COLORDODGE_KHR and COLORBURN_KHR, as described |
| in issue (7). Mark issue (7) as resolved. |
| |
| Revision 5, October 15, 2013 |
| |
| Remove Porter-Duff blend equations from the specification (issue 4). |
| Add a Draw-time error if an advanced blending equation is used without |
| specifying a matching layout qualifier in the fragment shader (issue 5). |
| |
| Add issues for the spec issues discussed during standardization in |
| Khronos. Remove OpenGL ES 2.0 and 3.0 interactions dealing with |
| handling tokens present in OpenGL but not the core OpenGL ES |
| specification, since the relevant equations (ZERO and XOR) have been |
| removed. |
| |
| Revision 4, September 6, 2013 |
| |
| Removed support for non-coherent-only implementations. Implementations |
| that could support NV_blend_equation_advanced (app-managed coherency |
| only) but not NV_blend_equation_advanced_coherent will be unable to |
| support this extension. |
| |
| Revision 3, August 19, 2013 |
| |
| Fixed typos in the OpenGL ES 2.0 and 3.0 interactions section of |
| NV_blend_equation_advanced. |
| |
| Revision 2, August 13, 2013 |
| |
| Removed issues from the original NV_blend_equation_advanced |
| specification. Rename "NV" prefixes and suffixes to "XXX" since the |
| future status of this extension is unknown. Remove the |
| BlendParameterivNV function and the BLEND_PREMULTIPLIED_SRC_NV and |
| BLEND_OVERLAP_NV parameters. Source colors are assumed to be |
| premultiplied. The source and destination pixel coverage, derived from |
| their respective alpha components, is assumed to be uncorrelated. |
| Removed the miscellaneous blend modes (PLUS_NV, PLUS_CLAMPED_NV, |
| PLUS_CLAMPED_ALPHA_NV, PLUS_DARKER_NV, MINUS_NV, MINUS_CLAMPED_NV, |
| CONTRAST_NV, INVERT_OVG_NV, RED, GREEN, BLUE) from Table X.4 of |
| NV_blend_equation_advanced. Removed some of the less common "X/Y/Z" |
| blend modes (INVERT, INVERT_RGB_NV, LINEARDODGE_NV, LINEARBURN_NV, |
| VIVIDLIGHT_NV, LINEARLIGHT_NV, PINLIGHT_NV, HARDMIX_NV). Add layout |
| qualifiers to the OpenGL Shading Language to indicate the set of |
| advanced blend equations are supported with a particular fragment |
| shader; using blend equations not identified in the current fragment |
| shader result in undefined blending results. |
| |
| Revision 1, August 13, 2013 |
| |
| Forked the original NV_blend_equation_advanced specification. |