7

I have a <canvas> element which is written to by an external library. I wish to apply a "post-production" effect to this canvas: I want to map a function (r,g,b,a) -> (r,g,b,a) over every pixel before it is finally displayed.

I know that the external library writes to a 2D context obtained from the <canvas> element. I also know that the transformation I'm asking for is a "pixel shader" or "fragment shader". I know I will need a webgl context to apply such a shader. I am told by this answer that a canvas cannot have multiple contexts at the same time, so I am not sure this approach is possible.

Another approach I considered is to capture the output of the canvas as a stream, and write it to a new canvas with my transformation applied. However, this feature only exists in bleeding-edge Firefox.

Is it possible to apply a fragment shader to canvas output? If so, how?

Community
  • 1
  • 1
jameshfisher
  • 34,029
  • 31
  • 121
  • 167
  • you don't have to use `captureStream()`, `CanvasContext2D.drawImage()` method does accept an other canvas as imageSource. You would then just have to create an other canvas element, and `drawImage(yourActualCanvas, 0, 0)` on it. If the canvas drawn is not tainted, you can call the `getImageData()` of the canvas to do your pixel transformation, or you may also find your happiness into [`globalCompositeOperation`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) which are way faster ! – Kaiido Dec 24 '15 at 02:16
  • Here is an example : http://jsfiddle.net/an0ajbfw/ – Kaiido Dec 24 '15 at 02:27

1 Answers1

8

You can copy a 2D canvas to a WebGL texture and render that texture to a WebGL canvas with whatever fragment shader you design.

There's plenty of examples on stack overflow of using a canvas as the source data for a texture

How Do I Use an HTML5 Canvas as a WebGL Texture

how to get texture in webgl?without Canvas.toDataUrl()

Blend two canvases onto one with WebGL

WebGL blit texture to canvas

Community
  • 1
  • 1
gman
  • 100,619
  • 31
  • 269
  • 393