WebGL blit texture to canvas

2019-07-21 07:56发布

问题:

What is the cleanest way of blitting a texture to the HTML canvas in WebGL. I could see setting up an orthographic projection and rendering a textured quad, but is there a cleaner way?

回答1:

What to mean "blitting a texture to the HTML5 Canvas"? Do you mean just drawing a texture 1x1 pixel to the canvas? No need for a orthographic projection. The simplest thing is either make a unit quad and scale or make a quad in pixel coords and draw.

Here's the pixel coord quad shader

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

   v_texCoord = a_texCoord;
}

That example is from here. (http://games.greggman.com/game/webgl-image-processing/)

The scale offset of a unit quad version would be

attribute vec2 a_position;
attribute vec2 a_texCoord;

uniform vec2 u_offset;
uniform vec2 u_scale;

varying vec2 v_texCoord;

void main() {
   gl_Position = vec4(a_position * u_scale + u_offset, 0, 1);

   v_texCoord = a_texCoord;
}

Finally in either case you can simplify the code by using 3x3 matrix math

attribute vec2 a_position;

uniform mat3 u_matrix;

void main() {
  // Multiply the position by the matrix.
  gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);
}

And just set the matrix. You can use either a unit quad (adding scale matrix to enlarge it pixels) or use pixels.

A matrix of

[
  2 / canvasWidth, 0, 0,
  0, -2 / canvasHeight, 0,
  -1, 1, 1
]

Will convert from pixels to clipspace. A matrix of

[
  imageWidth, 0, 0,
  0, imageHeight, 0,
  0, 0, 1
]

Will convert from a unit quad to the size of your image.

Going into all the matrix math seems like too much for this answer but if you're interested you can find it here See http://games.greggman.com/game/webgl-2d-matrices/