javascript - 如何在 Canvas 上实时使用多重混合模式?

标签 javascript html canvas webgl

自 2016 年起编辑:为 globalCompositeOperation 实现“乘法”值.性能对于实时图形来说绰绰有余。


本质上,我有两个 Canvas (一个是用于绘图的不可见 Canvas ),我想使用多重混合模式将不可见 Canvas 混合到可见 Canvas 上。

Context.globalCompositeOperation 不包括 multiply(虽然它应该,在我看来)并且使用 imageData 手动混合 Canvas 太慢(我需要能够以 60fps 的速度执行此操作)。

我可以使用任何更快的方法来混合 Canvas 吗?我相信这可以使用 WebGL 来完成,但我没有使用它的经验。

最佳答案

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

  1. 让您的可见 Canvas 成为 WebGL Canvas 。
  2. 创建两个纹理;称它们为“来源”和“目的地”。
  3. 将您的不可见 Canvas 内容渲染到“源”纹理;这可以通过直接使用 WebGL 绘图操作(不使用额外的 Canvas )或通过将 2D 不可见 Canvas 的内容上传到纹理(这是内置操作)来完成:

    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. 将要相乘的其他内容渲染到“目标”纹理。

  5. 最后,针对实际的可见 Canvas ,使用片段着色器将“源”和“目标”纹理相乘。这里的技术是用于后处理效果的技术——我建议查找 such a tutorial或简单的例子。简而言之,要将片段着色器应用于整个 Canvas ,您可以绘制一个全屏四边形 - 覆盖整个视口(viewport)的几何体。顶点着色器很简单,片段着色器就像:

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

如果你想每帧做多个重叠乘法混合,那么如果不超过,比如说,8,你可以扩展上面的过程来乘以几个纹理;如果有很多,您将需要执行多个阶段,将两个纹理相乘,同时渲染到第三个纹理,然后交换 Angular 色。

如果您想要更具体的答案,请扩展您的问题,详细说明您要将多少个图形以及哪种图形相乘。

关于javascript - 如何在 Canvas 上实时使用多重混合模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11595694/

相关文章:

javascript - 如何在另一个元素的顶部显示导航

javascript - 如何使 2 个 Angular 列表在 html 表中彼此相邻显示

javascript - HTML Canvas 元素创建不需要的白色边框

javascript - 替换javascript中的类值

javascript - 为带有内容的 div 创建自动滚动时遇到问题

javascript - 两个 div 上的两个不同的 OnClick,一个在另一个之上

javascript - 如何使用 jQuery 系统地更改 Twitter.com 上所有头像图像的 src 属性?

javascript - 模拟背景大小 : cover in canvas

javascript - 使用 canvas.toDataURL 时如何设置 crossOrigin 属性?

javascript - Reactjs/Semantic Ui 在 map 中添加 if 条件