如何在画布上实时使用乘法混合模式? [英] How can I use the multiply blend mode on a canvas in real time?

查看:322
本文介绍了如何在画布上实时使用乘法混合模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

修改始于2016年:multiply值实现为 globalCompositeOperation






基本上,我有两个画布(一个是不可见的画布用于绘图),我想使用乘法混合模式将不可见的画布混合到可见的画布上。



Context.globalCompositeOperation 不包括乘法(但我认为应该使用 imageData 手动混合画布太慢了(我需要能够在60fps做到这一点)。



方法我可以使用来混合画布?我相信这可以使用 WebGL 完成,但我没有使用它的经验。

解决方案

WebGL混合模式不包括乘法(源和目标)。但是,您可以使用WebGL的渲染到纹理功能高效地执行乘法运算:


  1. 让可视画布成为WebGL画布。 / li>
  2. 创建两个纹理;

  3. 将不可见画布内容呈现为源纹理;这可以通过直接使用WebGL绘制操作(不使用额外的画布)或通过将2D不可见画布的内容上传到纹理(这是一个内置操作)来完成:

      var sourceTexture = gl.createTexture()
    gl.bindTexture(gl.TEXTURE_2D,sourceTexture)
    gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA ,gl.RGBA,gl.UNSIGNED_BYTE,sourceCanvas)
    // ...还设置纹理过滤器 - 请参阅任何WebGL教程...

  4. 实际可见的画布,使用片段着色器乘以源和目标纹理。这里的技术是用于后处理效果的技术 - 我建议您查找这样的教程或简单示例。简单来说,要将片段着色器应用于整个画布,您需要绘制一个全屏四边形 - 覆盖整个视口的几何图形。顶点着色器是微不足道的,片段着色器将是:

      varying vec2 texCoord; 
    uniform sampler2D sourceTexture;
    uniform sampler2D destTexture;
    void main(void){
    gl_FragColor = texture2D(sourceTexture,texCoord)* texture2D(destTexture,texCoord);
    }


每帧多次重叠乘法混合,那么如果没有超过,例如8,您可以扩展上述过程以乘以几个纹理;如果有很多,你将需要做多个阶段的乘以两个纹理,同时渲染到第三个,然后交换角色。



如果你想要一个更具体的答案,那么请展开您的问题,并提供有关您将多少图形加在一起的详细信息。


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.

解决方案

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:

  1. Let your visible canvas be a WebGL canvas.
  2. Create two textures; call them "source" and "destination".
  3. 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...
    

  4. Render the other content to be multiplied to the "destination" texture.

  5. 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.

这篇关于如何在画布上实时使用乘法混合模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆