Alpha blending

A fragment is eligible for alpha blending if it has passed the depth test. However, when depth testing is disabled, all fragments are eligible for alpha blending.

Alpha blending is enabled using the following line of code:

gl.enable(gl.BLEND);

For each eligible fragment the alpha blending operation reads the color present in the frame buffer for those fragment coordinates and creates a new color that is the result of a linear interpolation between the color previously calculated in the fragment shader (gl_FragColor) and the color already present in the frame buffer.

Note

Alpha blending is disabled by default in WebGL.

Blending function

With blending enabled, the next step is to define a blending function. This function will determine how the fragment colors coming from the object we are rendering (source) will be combined with the fragment colors already present in the frame buffer (destination).

We combine source and destination as follows:

Color Output = S * sW + D * dW

Here,

  • S: source color
  • D: destination color
  • sW: source scaling factor
  • dW: destination scaling factor
  • S.rgb: rgb components of the source color
  • S.a: alpha component of the source color
  • D.rgb: rgb components of the destination color
  • D.a: alpha component of the destination color

It is very important to notice here that the rendering order will determine what the source and the destination fragments are in the previous equations. Following the example from the previous section, if the sphere is rendered first, then it will become the destination of the blending operation because the sphere fragments will be already stored in the frame buffer when the cone is rendered. In other words, alpha blending is a non-commutative operation with respect to the rendering order.

Blending function

Separate blending functions

It is also possible to determine how the RGB channels are going to be combined independently from the alpha channels. For that, we use the gl.blendFuncSeparate function.

We define two independent functions this way:

Color output = S.rgb * sW.rgb + D.rgb * dW.rgb
Alpha output = S.a * sW.a + D.a * dW.a

Here,

  • sW.rgb: source scaling factor (only rgb)
  • dW.rgb: destination scaling factor (only rgb)
  • sW.a: source scaling factor for the source alpha value
  • dW.a: destination scaling factor for the destination alpha value

Then we could have something as follows:

Color output = S.rgb * S.a + D.rbg * (1 - S.a)
Alpha output = S.a * 1 + D.a * 0

This would be translated into code as:

gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ZERO)

This particular configuration is equivalent to our previous case where we did not separate the functions. The parameters for the gl.blendFuncSeparate function are the same as that can be passed to gl.blendFunc. As stated before, you will find the complete list later in this section.

Blend equation

We could have the case where we do not want to interpolate the source and destination fragment colors by scaling them and adding them as shown before. It could be the case where we want to subtract one from the other. In that case, WebGL provides the gl.blendEquation function. This function receives one parameter that determines the operation on the scaled source and destination fragment colors.

gl.blendEquation(gl.FUNC_ADD) will correspond to:

Color output = S * sW + D *dW

While gl.blendEquation(gl.FUNC_SUBTRACT) corresponds to:

Color output = S * sW - D *dW

There is a third option: gl.blendEquation(gl.FUNC_REVERSE_SUBTRACT) that corresponds to:

Color output = D* dw S*sW

As it is expected, it is also possible to define the blending equation separately for the RGB channels and for the alpha channel. For that, we use the gl.blendEquationSeparate function.

Blend color

WebGL provides the scaling factors gl.CONSTANT_COLOR and gl.ONE_MINUS_CONSTANT_COLOR. These scaling factors can be used with gl.blendFunc and with gl.blendFuncSeparate. However, we need to establish beforehand what the blend color is going to be. We do so by invoking gl.blendColor.

WebGL alpha blending API

The following table summarizes the WebGL functions that are relevant to performing alpha blending operations:

WebGL Function

Description

gl.enable|disable (gl.BLEND)

Enable/disable blending

gl.blendFunc (sW, dW)

Specify pixel arithmetic. Accepted values for sW and dW are: ZERO

ONE

SRC_COLOR

DST_COLOR

SRC_ALPHA

DST_ALPHA

CONSTANT_COLOR

CONSTANT_ALPHA

ONE_MINUS_SRC_ALPHA

ONE_MINUS_DST_ALPHA

ONE_MINUS_SRC_COLOR

ONE_MINUS_DST_COLOR

ONE_MINUS_CONSTANT_COLOR

ONE_MINUS_CONSTANT_ALPHA

In addition, sW can also be SRC_ALPHA_SATURATE

gl.blendFuncSeparate(sW_rgb, dW_rgb, sW_a, dW_a)

Specify pixel arithmetic for RGB and alpha components separately

gl.blendEquation(mode)

Specify the equation used for both the RGB blend equation and the alpha blend equation. Accepted values for mode are:

gl.FUNC_ADD

gl.FUNC_SUBTRACT

gl.FUNC_REVERSE_SUBTRACT

gl.blendEquationSeparate(modeRGB, modeAlpha)

Set the RGB blend equation and the alpha blend equation separately

gl.blendColor ( red, green, blue, alpha)

Set the blend color

gl.getParameter(pname)

Just like with other WebGL variables, it is possible to query blending parameters using gl.getParameter.

Relevant parameters are:

gl.BLEND

gl.BLEND_COLOR

gl.BLEND_DST_RGB

gl.BLEND_SRC_RGB

gl.BLEND_DST_ALPHA

gl.BLEND_SRC_ALPHA

gl.BLEND_EQUATION_RGB

gl.BLEND_EQUATION_ALPHA

Alpha blending modes

Depending on the parameter selection for sW and dW we can create different blending modes. In this section we are going to see how to create additive, subtractive, multiplicative, and interpolative blending modes. All blending modes depart from the already known formula:

Color output = S * (sW) + D * dW

Additive blending

Additive blending simply adds the colors of the source and destination fragments, creating a lighter image. We obtain additive blending by writing:

gl.blendFunc(gl.ONE, gl.ONE);

This assigns the weights for source and destination fragments sW and dW to 1. The color output will be:

Color output = S * 1 + D * 1
Color output = S + D

Since each color channel is in the [0, 1] range, this blending will clamp all values over 1. When all channels are 1 this results in a white color.

Subtractive blending

Similarly, we can obtain subtractive blending by writing:

gl.blendEquation(gl.FUNC_SUBTRACT);
gl.blendFunc(gl.ONE, gl.ONE);

This will change the blending equation to:

Color output = S * (1) - D * (1)
Color output = S - D

Any negative values will be simply shown as zero. When all channels are negative this results in black color.

Multiplicative blending

We obtain multiplicative blending by writing:

gl.blendFunc(gl.DST_COLOR, gl.ZERO);

This will be reflected in the blending equation as:

Color output = S * (D) + D * (0)
Color output = S * D

The result will be always a darker blending.

Interpolative blending

If we set sW to S.a and dW to 1-S.a then:

Color output = S * S.a + D *(1-S.a)

This will create a linear interpolation between the source and destination color using the source alpha color S.a as the scaling factor. In code, this is translated as:

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

Interpolative blending allows us to create a transparency effect as long as the destination fragments have passed the depth test. This implies that the objects need to be rendered from back to front.

In the next section you will play with different blending modes on a simple scene constituted by a cone and a sphere.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.13.201