WebGL's blend modes do not include multiplication (of the source and destination), either. However, you can perform the multiply operation efficiently using WebGL's render-to-texture capabilities:
- Let your visible canvas be a WebGL canvas.
- Create two textures; call them "source" and "destination".
Render your invisible-canvas content to the "source" texture; this can be done either using WebGL drawing operations directly (using no extra canvas) or by uploading your 2D invisible canvas's contents to the texture (this is a built-in operation):
var sourceTexture = gl.createTexture()
gl.bindTexture(gl.TEXTURE_2D, sourceTexture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, sourceCanvas)
// ...also set texture filters — see any WebGL tutorial...
Render the other content to be multiplied to the "destination" texture.
Finally, targeting the actual visible canvas, use a fragment shader to multiply the "source" and "destination" textures. The techniques here are those used for post-processing effects — I recommend looking up such a tutorial or simple example. Briefly, to apply a fragment shader to the entire canvas, you draw a full-screen quad - geometry that covers the entire viewport. The vertex shader is trivial, and the fragment shader would be like:
varying vec2 texCoord;
uniform sampler2D sourceTexture;
uniform sampler2D destTexture;
void main(void) {
gl_FragColor = texture2D(sourceTexture, texCoord) * texture2D(destTexture, texCoord);
}
If you want to do multiple overlapping multiply-blends per frame, then if there are no more than, say, 8, you can expand the above procedure to multiply several textures; if there are lots, you will need to do multiple stages of multiplying two textures while rendering to a third and then exchanging the roles.
If you would like a more specific answer, then please expand your question with more details on how many, and what kind of, graphics you are multiplying together.