JavaScript EditorFree JavaScript Editor     Ajax Editor 



Main Page
Previous Page
Next Page

19.6. Blend Modes

With the expressiveness of a high-level language, it is easy to combine, or blend, two images in a variety of ways. Both images can be stored in texture memory, or one can be in texture memory and one can be downloaded by the application with glDrawPixels. For example, here's a fragment shader that adds together two images:

uniform sampler2D BaseImage;
uniform sampler2D BlendImage;
uniform float Opacity;

void main (void)
{
    vec4 base  = texture2D(BaseImage, gl_TexCoord[0].xy);
    vec4 blend = texture2D(BlendImage, gl_TexCoord[0].xy);

    vec4 result = blend + base;
         result = clamp(result, 0.0, 1.0);

    gl_FragColor = mix(base, result, Opacity);
}

The following sections contain snippets of OpenGL shader code that perform pixel-by-pixel blending for some of the common blend modes. In each case,

  • base is a vec4 containing the RGBA color value from the base (original) image.

  • blend is a vec4 containing the RGBA color value from the image that is being blended into the base image.

  • result is a vec4 containing the RGBA color that results from the blending operation.

  • If it's needed in the computation, white is a vec4 containing (1.0, 1.0, 1.0, 1.0).

  • If it's needed in the computation, lumCoeff is a vec4 containing (0.2125, 0.7154, 0.0721, 1.0).

  • As a final step, base and result are combined by use of a floating-point value called Opacity, which determines the contribution of each.

There is no guarantee that the results of the code snippets provided here will produce results identical to those of your favorite image editing program, but the effects should be similar. The OpenGL shader code for the various blend modes is based on information published by Jens Gruschel in his article Blend Modes, available at http://www.pegtop.net/delphi/blendmodes. Unless otherwise noted, the blend operations are not commutative (you will get different results if you swap the base and blend images).

Results of the blend mode shaders are shown in Color Plate 34.

19.6.1. Normal

NORMAL is often used as the default blending mode. The blend image is placed over the base image. The resulting image equals the blend image when the opacity is 1.0 (i.e., the base image is completely covered). For opacities other than 1.0, the result is a linear blend of the two images based on Opacity.

result = blend;

19.6.2. Average

The AVERAGE blend mode adds the two images and divides by two. The result is the same as NORMAL when the opacity is set to 0.5. This operation is commutative.

result = (base + blend) * 0.5;

19.6.3. Dissolve

In the DISSOLVE mode, either blend or base is chosen randomly at every pixel. The value of Opacity is used as a probability factor for choosing the blend value. Thus, as the opacity gets closer to 1.0, the blend value is more likely to be chosen than the base value. If we draw the image as a texture on a rectangular polygon, we can use the texture coordinate values as the argument to noise1D to provide a value with which we can select in a pseudorandom, but repeatable, way. We can apply a scale factor to the texture coordinates to obtain noise of a higher frequency and give the appearance of randomness. The value returned by the noise function is in the range [-1,1] so we add 1 and multiply by 0.5 to get it in the range [0,1].

float noise = (noise1(vec2(gl_TexCoord[0] * noiseScale)) + 1.0) * 0.5;
result = (noise < Opacity) ? blend : base;

19.6.4. Behind

BEHIND chooses the blend value only where the base image is completely transparent (i.e., base.a = 0.0). You can think of the base image as a piece of clear acetate, and the effect of this mode is as if you were painting the blend image on the back of the acetateonly the areas painted behind transparent pixels are visible.

result = (base.a == 0.0) ? blend : base;

19.6.5. Clear

CLEAR always uses the blend value, and the alpha value of result is set to 0 (transparent). This blend mode is more apt to be used with drawing tools than on complete images.

result.rgb = blend.rgb;
result.a   = 0.0;

19.6.6. Darken

In DARKEN mode, the two values are compared, and the minimum value is chosen for each component. This operation makes images darker because the blend image can do nothing except make the base image darker. A blend image that is completely white (RGB = 1.0, 1.0, 1.0) does not alter the base image. Regions of black (0, 0, 0) in either image cause the result to be black. It is commutativethe result is the same if the blend image and the base image are swapped.

result = min(blend, base);

19.6.7. Lighten

LIGHTEN can be considered the opposite of DARKEN. Instead of taking the minimum of each component, we take the maximum. The blend image can therefore never do anything but make the result lighter. A blend image that is completely black (RGB = 0, 0, 0) does not alter the base image. Regions of white (1.0, 1.0, 1.0) in either image cause the result to be white. The operation is commutative because swapping the two images does not change the result.

result = max(blend, base);

19.6.8. Multiply

In MULTIPLY mode, the two values are multiplied together. This produces a darker result in all areas in which neither image is completely white. White is effectively an identity (or transparency) operator because any color multiplied by white will be the original color. Regions of black (0, 0, 0) in either image cause the result to be black. The result is similar to the effect of stacking two color transparencies on an overhead projector. This operation is commutative.

result = blend * base;

19.6.9. Screen

SCREEN can be thought of as the opposite of MULTIPLY because it multiplies the inverse of the two input values. The result of this multiplication is then inverted to produce the final result. Black is effectively an identity (or transparency) operator because any color multiplied by the inverse of black (i.e., white) will be the original color. This blend mode is commutative.

result = white - ((white - blend) * (white - base));

19.6.10. Color Burn

COLOR BURN darkens the base color as indicated by the blend color by decreasing luminance. There is no effect if the blend value is white. This computation can result in some values less than 0, so truncation may occur when the resulting color is clamped.

result = white - (white - base) / blend;

19.6.11. Color Dodge

COLOR DODGE brightens the base color as indicated by the blend color by increasing luminance. There is no effect if the blend value is black. This computation can result in some values greater than 1, so truncation may occur when the result is clamped.

result = base / (white - blend);

19.6.12. Overlay

OVERLAY first computes the luminance of the base value. If the luminance value is less than 0.5, the blend and base values are multiplied together. If the luminance value is greater than 0.5, a screen operation is performed. The effect is that the base value is mixed with the blend value, rather than being replaced. This allows patterns and colors to overlay the base image, but shadows and highlights in the base image are preserved. A discontinuity occurs where luminance = 0.5. To provide a smooth transition, we actually do a linear blend of the two equations for luminance in the range [0.45,0.55].

float luminance = dot(base, lumCoeff);
if (luminance < 0.45)
    result = 2.0 * blend * base;
else if (luminance > 0.55)
    result = white - 2.0 * (white - blend) * (white - base);
else
{
    vec4 result1 = 2.0 * blend * base;
    vec4 result2 = white - 2.0 * (white - blend) * (white - base);
    result = mix(result1, result2, (luminance - 0.45) * 10.0);
}

19.6.13. Soft Light

SOFT LIGHT produces an effect similar to a soft (diffuse) light shining through the blend image and onto the base image. The resulting image is essentially a muted combination of the two images.

result = 2.0 * base * blend + base * base - 2.0 * base * base * blend;

19.6.14. Hard Light

HARD LIGHT mode is identical to OVERLAY mode, except that the luminance value is computed with the blend value rather than the base value. The effect is similar to shining a harsh light through the blend image and onto the base image. Pixels in the blend image with a luminance of 0.5 have no effect on the base image. This mode is often used to produce embossing effects. The mix function provides a linear blend between the two functions for luminance in the range [0.45,0.55].

float luminance = dot(blend, lumCoeff);
if (luminance < 0.45)
    result = 2.0 * blend * base;
else if (luminance > 0.55)
    result = white - 2.0 * (white - blend) * (white - base);
else
{
    vec4 result1 = 2.0 * blend * base;
    vec4 result2 = white - 2.0 * (white - blend) * (white - base);
    result = mix(result1, result2, (luminance - 0.45) * 10.0);
}

19.6.15. Add

In the ADD mode, the result is the sum of the blend image and the base image. Truncation may occur because resulting values can exceed 1.0. The blend and base images can be swapped, and the result will be the same.

result = blend + base;

19.6.16. Subtract

SUBTRACT subtracts the blend image from the base image. Truncation may occur because resulting values may be less than 0.

result = base - blend;

19.6.17. Difference

In the DIFFERENCE mode, the result is the absolute value of the difference between the blend value and the base value. A result of black means the two initial values were equal. A result of white means they were opposite. This mode can be useful for comparing images because identical images produce a completely black result. An all-white blend image can be used to invert the base image. Blending with black produces no change. Because of the absolute value operation, this blend mode is commutative.

result = abs(blend - base);

19.6.18. Inverse Difference

The INVERSE DIFFERENCE blend mode performs the "opposite" of DIFFERENCE. Blend values of white and black produce the same results as for DIFFERENCE (white inverts and black has no effect), but colors in between white and black become lighter instead of darker. This operation is commutative.

result = white - abs(white - base - blend);

19.6.19. Exclusion

EXCLUSION is similar to DIFFERENCE, but it produces an effect that is lower in contrast (softer). The effect for this mode is in between the effects of the DIFFERENCE and INVERSE DIFFERENCE modes. Blending with white inverts the base image, blending with black has no effect, and colors in between become gray. This is also a commutative blend mode.

result = base + blend - (2.0 * base * blend);

19.6.20. Opacity

In OPACITY mode, an opacity value in the range [0,1] can also specify the relative contribution of the base image and the computed result. The result value from any of the preceding formulas can be further modified to compute the effect of the opacity value as follows:

finalColor = mix(base, result, Opacity);


Previous Page
Next Page




JavaScript EditorAjax Editor     JavaScript Editor