2

I was trying to recreate the effect achieved by this code in the 2d context:

// frame background "repaint"
ctx.fillStyle = 'rgba(0,0,0,.08)';
ctx.fillRect( 0, 0, w, h );

// draw rest of frame

which essentially adds a "trail". An example can be seen here: http://codepen.io/towc/pen/mJzOWJ

I ended up learning that in webgl you can have similar "source-over" transparency by using the following methods:

gl.blendFunc( gl.SRC_ALPHA, gl.ONE );
gl.enable( gl.BLEND );

and yes, I'm not using any fancy shaders nor am I trying to achieve 3d semi-transparency, I just want a simple composition based on the alpha value of the source and the color values of the destination.

The problem with the above code is that each frame, it looks like whatever was in the canvas on the previous frame gets completely removed, so the semi-transparency can be seen in each frame, but not across frames, as in the case of the "trail" in the canvas.getContext('2d').

As a solution to the cross-frame semitransparency, I can always fall back to providing the current canvas frame as a texture and drawing it at the beginning of the new frame, as to have the blending act in the way I want it to.

But obviously this could all be avoided if there was a way to tell the canvas not to remove everything at each frame, which I only guess is the issue.

Here's what I've tried: https://jsfiddle.net/206Ltsgo/ After cross-frame semi-transparency, I should be able to get something like this: http://codepen.io/towc/pen/bNWyOq

The answer can include suggestions to libraries, but ultimately should be vanilla. If I made the wrong assumption about the issue, ideally the answer should state the actual issue first, and if any, provide a solution. If the only solution is actually to send a texture, it would be helpful to know if there are very fast/short/efficient ways of sending the canvas as the texture.

towc
  • 1,983
  • 2
  • 22
  • 36
  • Other similar questions or related answers include http://stackoverflow.com/questions/33327585/why-webgl-clear-draw-to-front-buffer and http://stackoverflow.com/questions/35493509/webgl-draw-in-event-handler-seems-to-clear-the-canvas, http://stackoverflow.com/questions/9491417/when-webgl-decide-to-update-the-display, http://stackoverflow.com/questions/11546642/why-does-webgl-canvas-turn-white-on-the-second-frame-when-alpha-is-masked, – gman Dec 27 '16 at 16:47
  • @gman I was eventually linked to the last answer you posted. I think it's still worth keeping this question, noting that it's linked to all of those others, as it covers more googling possibilities, given that this issue is explicable in so many ways. I don't mind if you don't change your mind, of course – towc Dec 27 '16 at 23:03
  • 1
    No problem, that's what duplication question mark is for . People can search, find your question phrased your way and be lead to an answer. – gman Dec 28 '16 at 02:04

1 Answers1

3

turns out the issue was effectively that on every frame, the drawingBuffer was cleared. This can be overwritten by adding an attribute when defining your gl, as this mdn page points out:

var gl = canvas.getContext( 'webgl', { preserveDrawingBuffer: true } );
towc
  • 1,983
  • 2
  • 22
  • 36