Edit as of 2016: The "multiply" value is implemented for globalCompositeOperation. The performance is more than sufficient for real-time graphics.
Essentially, I have two canvases (one is an invisible canvas used for drawing) and I want to blend the invisible canvas onto the visible one with the multiply blend mode.
Context.globalCompositeOperation
does not include multiply (though it should, in my opinion) and using imageData
to manually blend the canvases is too slow (I need to be able to do this at 60fps).
Is there any faster method I could use to blend the canvases? I believe this could be done using WebGL, but I have no experience using it.
Edit as of 2016: The "multiply" value is implemented for globalCompositeOperation. The performance is more than sufficient for real-time graphics.
Essentially, I have two canvases (one is an invisible canvas used for drawing) and I want to blend the invisible canvas onto the visible one with the multiply blend mode.
Context.globalCompositeOperation
does not include multiply (though it should, in my opinion) and using imageData
to manually blend the canvases is too slow (I need to be able to do this at 60fps).
Is there any faster method I could use to blend the canvases? I believe this could be done using WebGL, but I have no experience using it.
Share Improve this question edited Jul 14, 2016 at 11:02 nondefault asked Jul 21, 2012 at 20:42 nondefaultnondefault 3773 silver badges14 bronze badges1 Answer
Reset to default 6WebGL'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 remend 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.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745151432a4613886.html
评论列表(0条)