Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8587387
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T22:33:27+00:00 2026-06-11T22:33:27+00:00

What I’m trying to do is blend two canvases onto a single canvas for

  • 0

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.

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>

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?

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

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/

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T22:33:28+00:00Added an answer on June 11, 2026 at 10:33 pm

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

    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);
    

    to

    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;
    }
    

    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");
    

    Sample here:

    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>
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to render a haml file in a javascript response like so:
I'm trying to use string.replace('’','') to replace the dreaded weird single-quote character: ’ (aka
I'm trying to create an if statement in PHP that prevents a single post
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I used javascript for loading a picture on my website depending on which small
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
this is what i have right now Drawing an RSS feed into the php,
I am reading a book about Javascript and jQuery and using one of the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.