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.
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 colorD:
destination colorsW:
source scaling factordW:
destination scaling factorS.rgb:
rgb components of the source colorS.a:
alpha component of the source colorD.rgb:
rgb components of the destination colorD.a:
alpha component of the destination colorIt 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.
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 valuedW.a:
destination scaling factor for the destination alpha valueThen 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.
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.
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
.
The following table summarizes the WebGL functions that are relevant to performing alpha blending operations:
WebGL Function |
Description |
---|---|
|
Enable/disable blending |
|
Specify pixel arithmetic. Accepted values for
In addition, |
|
Specify pixel arithmetic for RGB and alpha components separately |
|
Specify the equation used for both the RGB blend equation and the alpha blend equation. Accepted values for
|
|
Set the RGB blend equation and the alpha blend equation separately |
|
Set the blend color |
|
Just like with other WebGL variables, it is possible to query blending parameters using Relevant parameters are:
|
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 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.
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.
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.
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.
3.129.13.201