primers
JavaScript WebGL uses image confusion to mention two images stacked on top of each other. By default, even if there is a transparent area, it is not visible through. Now let’s look at the transparent processing.
-
My GitHub
About the transparent
Speaking of transparency, Alpha channel is responsible for color coding. Transparency is stored in the following ways:
-
Premultiplied Alpha: color information stored will multiply the transparent information with RGB, for example, RGB is (1, 1, 1) and transparency is 0.5, then stored as: (0.5, 0.5, 0.5, 0.5).
-
Non-premultiplied Alpha: RGB and transparent information are stored separately without multiplying. For example, RGB is (1, 1, 1) and transparency is 0.5, then stored as: (1, 1, 1, 0.5)
WebGL texture preprocessing uses the pixelStorei method to specify color transparency. If you want to use Premultiplied Alpha:
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
Copy the code
One approach to WebGL transparency is to use alpha blending.
Alpha blending
Alpha blending is the process of mixing the colors of more than two objects using the alpha value (A in RGBA). In this scenario, multiple textures are drawn with overlapping areas. Assume that texture C is drawn first, and then texture D, where texture D is the source color and texture C is the destination color.
To use this feature, first enable:
gl.enable(gl.BLEND);
Copy the code
Then specify the mixing methods as follows:
-
blendEquation
-
blendEquationSeparate
-
blendFunc
-
blendFuncSeparate
blendEquation
void blendEquation(enum mode)
Copy the code
Mode can be:
-
FUNC_ADD: Adds the source color component to the target color component.
-
FUNC_SUBTRACT: Source color component minus target color component.
-
FUNC_REVERSE_SUBTRACT: Target color component minus source color component.
This method only specifies the blending method, which needs to be used in conjunction with the blendFunc or blendFuncSeparate methods to see the final effect. Take a look at the pseudo-code logic at the bottom of this article to make sense.
Here’s an example.
blendEquationSeparate
void blendEquationSeparate(enum modeRGB, enum modeAlpha)
Copy the code
The two values of this method are the same as those of the blendEquation method, except that the color is separated into RGB and A.
blendFunc
void blendFunc(enum sfactor, enum dfactor);
Copy the code
-
Sfactor: constant, the weight factor of the source color in the mixed color, with one more value than dfactor SRC_ALPHA_SATURATE.
-
Dfactor: constant, the weight factor of the target color in the mixed color.
The calculation method of mixed colors is as follows:
Blended color = source color * sfactor + target color * dfactorCopy the code
Here the calculation is for each color component, below set S code source color, D represents the target color, each component is represented by lowercase RGBA, let’s look at the weight factor part of the constant value:
constant | R component | G component | B component | A component |
---|---|---|---|---|
ZERO | 0 | 0 | 0 | 0 |
ONE | 1 | 1 | 1 | 1 |
SRC_COLOR | S.r | S.g | S.b | S.a |
ONE_MINUS_SRC_COLOR | (1-S.r) | (1-S.g) | (1-S.b) | (1-S.a) |
DST_COLOR | D.r | D.g | D.b | D.a |
ONE_MINUS_DST_COLOR | (1-D.r) | (1-D.g) | (1-D.b) | (1-D.a) |
SRC_ALPHA | S.a | S.a | S.a | S.a |
ONE_MINUS_SRC_ALPHA | (1-S.a) | (1-S.a) | (1-S.a) | (1-S.a) |
DST_ALPHA | D.a | D.a | D.a | D.a |
ONE_MINUS_DST_ALPHA | (1-D.a) | (1-D.a) | (1-D.a) | (1-D.a) |
BlendColor (red, green, blue, alpha)
constant | R component | G component | B component | A component |
---|---|---|---|---|
CONSTANT_COLOR | red | green | blue | alpha |
ONE_MINUS_CONSTANT_COLOR | (1-red) | (1-green) | (1-blue) | (1-alpha) |
CONSTANT_ALPHA | alpha | alpha | alpha | alpha |
ONE_MINUS_CONSTANT_ALPHA | (1-alpha) | (1-alpha) | (1-alpha) | (1-alpha) |
If you don’t use blendColor to specify the component, you can also use these constants because there is a default value:
gl.getParameter(gl.BLEND_COLOR) // By default, the corresponding components are 0
Copy the code
SRC_ALPHA_SATURATE: SRC_ALPHA_SATURATE
constant | R component | G component | B component | A component |
---|---|---|---|---|
SRC_ALPHA_SATURATE | min(S.a, 1-D.a) | min(S.a, 1-D.a) | min(S.a, 1-D.a) | 1 |
Here are some examples:
-
There is no example using the blendColor method.
-
An example with the blendColor method.
blendFuncSeparate
void blendFuncSeparate(enum srcRGB, enum dstRGB, enum srcAlpha, enum dstAlpha)
Copy the code
This method takes the same value as the blendFunc method, except that the color is separated into RGB and A.
The resources
-
Texture Maps
-
Texture Mapping Using Images
-
WebGL and Alpha
-
Transparency (and Alpha Blending)
-
WEBGL, BLENDING, AND WHY YOU’RE PROBABLY DOING IT WRONG
Recently I saw Ron’s Gone Wrong, which told a heartwarming story that reminded me of Big Hero 6.