• <legend id='HFH1u'><style id='HFH1u'><dir id='HFH1u'><q id='HFH1u'></q></dir></style></legend>
          <bdo id='HFH1u'></bdo><ul id='HFH1u'></ul>

      1. <tfoot id='HFH1u'></tfoot>

        <small id='HFH1u'></small><noframes id='HFH1u'>

        <i id='HFH1u'><tr id='HFH1u'><dt id='HFH1u'><q id='HFH1u'><span id='HFH1u'><b id='HFH1u'><form id='HFH1u'><ins id='HFH1u'></ins><ul id='HFH1u'></ul><sub id='HFH1u'></sub></form><legend id='HFH1u'></legend><bdo id='HFH1u'><pre id='HFH1u'><center id='HFH1u'></center></pre></bdo></b><th id='HFH1u'></th></span></q></dt></tr></i><div id='HFH1u'><tfoot id='HFH1u'></tfoot><dl id='HFH1u'><fieldset id='HFH1u'></fieldset></dl></div>

        使用 WebGL 将两个画布混合到一个上

        Blend two canvases onto one with WebGL(使用 WebGL 将两个画布混合到一个上)
        <i id='3wyTT'><tr id='3wyTT'><dt id='3wyTT'><q id='3wyTT'><span id='3wyTT'><b id='3wyTT'><form id='3wyTT'><ins id='3wyTT'></ins><ul id='3wyTT'></ul><sub id='3wyTT'></sub></form><legend id='3wyTT'></legend><bdo id='3wyTT'><pre id='3wyTT'><center id='3wyTT'></center></pre></bdo></b><th id='3wyTT'></th></span></q></dt></tr></i><div id='3wyTT'><tfoot id='3wyTT'></tfoot><dl id='3wyTT'><fieldset id='3wyTT'></fieldset></dl></div>
      2. <tfoot id='3wyTT'></tfoot>

            <bdo id='3wyTT'></bdo><ul id='3wyTT'></ul>
              <tbody id='3wyTT'></tbody>
          • <small id='3wyTT'></small><noframes id='3wyTT'>

                <legend id='3wyTT'><style id='3wyTT'><dir id='3wyTT'><q id='3wyTT'></q></dir></style></legend>
                • 本文介绍了使用 WebGL 将两个画布混合到一个上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我要做的是将两个画布混合到一个画布上,用于我正在创建的绘图应用程序.我非常了解 Javascript,但我真的不知道从哪里开始使用 WebGL,而且由于这不是一项非常艰巨的任务,我假设如果我不使用它会产生更快的处理速度另一个库,例如 Three.js 或其他类似的库.

                  What I'm trying to do is blend two canvases onto a single canvas for a drawing app I am creating. I know Javascript very well, but I really don't have any clue where to start with WebGL and since it isn't a very hard task to do, I'm assuming it would be yield quicker processing speeds if I don't use another library like Three.js or others of that sort.

                  我已经拥有的是用户将要绘制的画布(我们称它们为画布 A 和 B),它们都是隐藏的,而画布 C 正在显示.

                  What I already have are canvases that the user will be drawing on (Let's call them canvas A and B) which are both hidden and canvas C which is being shown.

                  <canvas id='C' width=800 height=600></canvas>
                  
                  <canvas id='A' width=800 height=600 style='display:none'></canvas>
                  <canvas id='B' width=800 height=600 style='display:none'></canvas>
                  

                  我已经完成了主绘图应用程序,供用户选择要在其上绘制的图层并在其上绘图,但是我如何能够使用 WebGL 使用某种混合模式将两个图层混合在一起(即:乘) 当用户继续使用 WebGL 编辑画布?

                  I already have the main drawing app done for the user to pick the layer to draw on and to draw on it, but how would I be able to use WebGL to blend the two layers together using some blend mode (ie: multiply) as the user continues to edit the canvases using WebGL?

                  起初我尝试在这里关注其他帖子:https://stackoverflow.com/a/11596922/1572938但我很困惑.

                  At first I tried following the other post here: https://stackoverflow.com/a/11596922/1572938 but I got confused.

                  如果有人想填补我的 jsfiddle 上的空白,那将非常有效!http://jsfiddle.net/W3fVV/1/

                  If someone wants to fill in the gaps on my jsfiddle for the other post that would work very well! http://jsfiddle.net/W3fVV/1/

                  推荐答案

                  这里有一个用图片绘制的例子:https://webglfundamentals.org/webgl/lessons/webgl-image-processing.html

                  There's an example of drawing with images here: https://webglfundamentals.org/webgl/lessons/webgl-image-processing.html

                  WebGL 不关心源是图像、画布还是视频.所以改变样本从

                  WebGL doesn't care if the sources are images, canvases or video. So change the samples from

                  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, someImage);
                  

                  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, someCanvas);
                  

                  然后编写一个片段着色器来混合这两个纹理

                  Then write a fragment shader to blend the 2 textures as in

                  precision mediump float;
                  
                  // our 2 canvases
                  uniform sampler2D u_canvas1;
                  uniform sampler2D u_canvas2;
                  
                  // the texCoords passed in from the vertex shader.
                  // note: we're only using 1 set of texCoords which means
                  //   we're assuming the canvases are the same size.
                  varying vec2 v_texCoord;
                  
                  void main() {
                       // Look up a pixel from first canvas
                       vec4 color1 = texture2D(u_canvas1, v_texCoord);
                  
                       // Look up a pixel from second canvas
                       vec4 color2 = texture2D(u_canvas2, v_texCoord);
                  
                       // return the 2 colors multiplied
                       gl_FragColor = color1 * color2;
                  }
                  

                  您需要设置这 2 个纹理并告诉您的 GLSL 程序您将它们放在哪些纹理单元上.

                  You'll need to setup the 2 textures and tell your GLSL program which texture units you put them on.

                  function setupTexture(canvas, textureUnit, program, uniformName) {
                     var tex = gl.createTexture();
                  
                     updateTextureFromCanvas(tex, canvas, textureUnit);
                  
                     // Set the parameters so we can render any size image.
                     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
                     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
                     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
                     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
                  
                     var location = gl.getUniformLocation(program, uniformName);
                     gl.uniform1i(location, textureUnit);
                  }
                  
                  function updateTextureFromCanvas(tex, canvas, textureUnit) {
                    gl.activeTexture(gl.TEXTURE0 + textureUnit);
                    gl.bindTexture(gl.TEXTURE_2D, tex);
                    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
                  }
                  
                  var tex1 = setupTexture(canvas1, 0, program, "u_canvas1");
                  var tex2 = setupTexture(canvas2, 1, program, "u_canvas2");
                  

                  示例:

                  function main() {
                    var canvas1 = document.getElementById("canvas1");
                    var canvas2 = document.getElementById("canvas2");
                    var ctx1 = canvas1.getContext("2d");
                    var ctx2 = canvas2.getContext("2d");    
                    ctx1.fillStyle = "purple";
                    ctx1.arc(64, 64, 30, 0, Math.PI * 2, false);
                    ctx1.fill();
                    ctx2.fillStyle = "cyan";
                    ctx2.fillRect(50, 10, 28, 108);
                      
                    // Get A WebGL context
                    var canvas = document.getElementById("webgl");
                    var gl = canvas.getContext("webgl");
                    if (!gl) {
                      return;
                    }
                  
                    // setup GLSL program
                    var program = twgl.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
                    gl.useProgram(program);
                  
                    // look up where the vertex data needs to go.
                    var positionLocation = gl.getAttribLocation(program, "a_position");
                    var texCoordLocation = gl.getAttribLocation(program, "a_texCoord");
                  
                    // provide texture coordinates for the rectangle.
                    var texCoordBuffer = gl.createBuffer();
                    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
                    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
                        0.0,  0.0,
                        1.0,  0.0,
                        0.0,  1.0,
                        0.0,  1.0,
                        1.0,  0.0,
                        1.0,  1.0]), gl.STATIC_DRAW);
                    gl.enableVertexAttribArray(texCoordLocation);
                    gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);
                  
                    // lookup uniforms
                    var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
                  
                    // set the resolution
                    gl.uniform2f(resolutionLocation, canvas1.width, canvas1.height);
                  
                    // Create a buffer for the position of the rectangle corners.
                    var buffer = gl.createBuffer();
                    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
                    gl.enableVertexAttribArray(positionLocation);
                    gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
                  
                    // Set a rectangle the same size as the image.
                    setRectangle(gl, 0, 0, canvas.width, canvas.height);
                      
                      function setupTexture(canvas, textureUnit, program, uniformName) {
                         var tex = gl.createTexture();
                  
                         updateTextureFromCanvas(tex, canvas, textureUnit);
                  
                         // Set the parameters so we can render any size image.
                         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
                         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
                         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
                         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
                        
                         var location = gl.getUniformLocation(program, uniformName);
                         gl.uniform1i(location, textureUnit);
                      }
                  
                      function updateTextureFromCanvas(tex, canvas, textureUnit) {
                        gl.activeTexture(gl.TEXTURE0 + textureUnit);
                        gl.bindTexture(gl.TEXTURE_2D, tex);
                        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
                      }
                  
                      var tex1 = setupTexture(canvas1, 0, program, "u_canvas1");
                      var tex2 = setupTexture(canvas2, 1, program, "u_canvas2");
                  
                    // Draw the rectangle.
                    gl.drawArrays(gl.TRIANGLES, 0, 6);
                  }
                  
                  function setRectangle(gl, x, y, width, height) {
                    var x1 = x;
                    var x2 = x + width;
                    var y1 = y;
                    var y2 = y + height;
                    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
                       x1, y1,
                       x2, y1,
                       x1, y2,
                       x1, y2,
                       x2, y1,
                       x2, y2]), gl.STATIC_DRAW);
                  }
                  
                  main();

                  canvas {
                      border: 2px solid black;
                      width: 128px;
                      height: 128px;
                  }

                  <script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
                  <!-- vertex shader -->
                  <script id="2d-vertex-shader" type="x-shader/x-vertex">
                  attribute vec2 a_position;
                  attribute vec2 a_texCoord;
                  
                  uniform vec2 u_resolution;
                  
                  varying vec2 v_texCoord;
                  
                  void main() {
                     // convert the rectangle from pixels to 0.0 to 1.0
                     vec2 zeroToOne = a_position / u_resolution;
                  
                     // convert from 0->1 to 0->2
                     vec2 zeroToTwo = zeroToOne * 2.0;
                  
                     // convert from 0->2 to -1->+1 (clipspace)
                     vec2 clipSpace = zeroToTwo - 1.0;
                  
                     gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
                  
                     // pass the texCoord to the fragment shader
                     // The GPU will interpolate this value between points.
                     v_texCoord = a_texCoord;
                  }
                  </script>
                  <!-- fragment shader -->
                  <script id="2d-fragment-shader" type="x-shader/x-fragment">
                      precision mediump float;
                  
                      // our 2 canvases
                      uniform sampler2D u_canvas1;
                      uniform sampler2D u_canvas2;
                  
                      // the texCoords passed in from the vertex shader.
                      // note: we're only using 1 set of texCoords which means
                      //   we're assuming the canvases are the same size.
                      varying vec2 v_texCoord;
                  
                      void main() {
                           // Look up a pixel from first canvas
                           vec4 color1 = texture2D(u_canvas1, v_texCoord);
                  
                           // Look up a pixel from second canvas
                           vec4 color2 = texture2D(u_canvas2, v_texCoord);
                  
                           // return the 2 colors multiplied
                           gl_FragColor = color1 * color2;
                      }
                  </script>
                  <!-- fragment shader -->
                  <script id="aa2d-fragment-shader" type="x-shader/x-fragment">
                  precision mediump float;
                  
                  // our texture
                  uniform sampler2D u_canvas1;
                  uniform sampler2D u_canvas2;
                  
                  // the texCoords passed in from the vertex shader.
                  varying vec2 v_texCoord;
                  
                  void main() {
                     gl_FragColor = texture2D(u_canvas1, v_texCoord);
                  }
                  </script>
                  <canvas id="canvas1" width="128" height="128"></canvas>
                  <canvas id="canvas2" width="128" height="128"></canvas>
                  <canvas id="webgl" width="128" height="128"></canvas>

                  这篇关于使用 WebGL 将两个画布混合到一个上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  How to make rooftext effect and valley text effect in HTML5 (or Fabric.js)(如何在 HTML5(或 Fabric.js)中制作屋顶文字效果和山谷文字效果)
                  Draw border around nontransparent part of image on canvas(在画布上的图像不透明部分周围绘制边框)
                  dragging and resizing an image on html5 canvas(在 html5 画布上拖动图像并调整其大小)
                  What#39;s the difference between a boolean as primitive and a boolean as property of an object?(作为原始对象的布尔值和作为对象属性的布尔值有什么区别?)
                  I want to do animation of an object along a particular path(我想沿特定路径对对象进行动画处理)
                  How to upload image into HTML5 canvas(如何将图像上传到 HTML5 画布中)

                    <tbody id='OCRwJ'></tbody>

                  <small id='OCRwJ'></small><noframes id='OCRwJ'>

                      <tfoot id='OCRwJ'></tfoot>
                      <legend id='OCRwJ'><style id='OCRwJ'><dir id='OCRwJ'><q id='OCRwJ'></q></dir></style></legend>
                          • <bdo id='OCRwJ'></bdo><ul id='OCRwJ'></ul>
                            <i id='OCRwJ'><tr id='OCRwJ'><dt id='OCRwJ'><q id='OCRwJ'><span id='OCRwJ'><b id='OCRwJ'><form id='OCRwJ'><ins id='OCRwJ'></ins><ul id='OCRwJ'></ul><sub id='OCRwJ'></sub></form><legend id='OCRwJ'></legend><bdo id='OCRwJ'><pre id='OCRwJ'><center id='OCRwJ'></center></pre></bdo></b><th id='OCRwJ'></th></span></q></dt></tr></i><div id='OCRwJ'><tfoot id='OCRwJ'></tfoot><dl id='OCRwJ'><fieldset id='OCRwJ'></fieldset></dl></div>