diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 56c7c49..6f1c986 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -1124,7 +1124,8 @@ class RenderWebGL extends EventEmitter { gl.clear(gl.COLOR_BUFFER_BIT); try { gl.disable(gl.BLEND); - this._drawThese([drawableID], ShaderManager.DRAW_MODE.default, projection, + // ImageData objects store alpha un-premultiplied, so draw with the `straightAlpha` draw mode. + this._drawThese([drawableID], ShaderManager.DRAW_MODE.straightAlpha, projection, {effectMask: ~ShaderManager.EFFECT_INFO.ghost.mask}); } finally { gl.enable(gl.BLEND); diff --git a/src/ShaderManager.js b/src/ShaderManager.js index a71ef2d..3f0bc61 100644 --- a/src/ShaderManager.js +++ b/src/ShaderManager.js @@ -154,10 +154,15 @@ ShaderManager.EFFECTS = Object.keys(ShaderManager.EFFECT_INFO); */ ShaderManager.DRAW_MODE = { /** - * Draw normally. + * Draw normally. Its output will use premultiplied alpha. */ default: 'default', + /** + * Draw with non-premultiplied alpha. Useful for reading pixels from GL into an ImageData object. + */ + straightAlpha: 'straightAlpha', + /** * Draw a silhouette using a solid color. */ diff --git a/src/shaders/sprite.frag b/src/shaders/sprite.frag index 13fe19d..b271fd2 100644 --- a/src/shaders/sprite.frag +++ b/src/shaders/sprite.frag @@ -210,6 +210,11 @@ void main() #endif // DRAW_MODE_colorMask #endif // DRAW_MODE_silhouette + #ifdef DRAW_MODE_straightAlpha + // Un-premultiply alpha. + gl_FragColor.rgb /= gl_FragColor.a + epsilon; + #endif + #else // DRAW_MODE_lineSample gl_FragColor = u_lineColor * clamp( // Scale the capScale a little to have an aliased region.