From b194394cfded43f52117adf01aa939beca95ee9f Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Tue, 28 Jan 2020 21:05:33 -0500 Subject: [PATCH 1/3] Set PenSkin silhouette data directly --- src/PenSkin.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/PenSkin.js b/src/PenSkin.js index fe5ae58a..ef457bd6 100644 --- a/src/PenSkin.js +++ b/src/PenSkin.js @@ -109,6 +109,12 @@ class PenSkin extends Skin { /** @type {boolean} */ this._silhouetteDirty = false; + /** @type {Uint8Array} */ + this._silhouettePixels = null; + + /** @type {ImageData} */ + this._silhouetteImageData = null; + /** @type {object} */ this._lineOnBufferDrawRegionId = { enter: () => this._enterDrawLineOnBuffer(), @@ -597,6 +603,9 @@ class PenSkin extends Skin { gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); + this._silhouettePixels = new Uint8Array(Math.floor(width * height * 4)); + this._silhouetteImageData = this._canvas.getContext('2d').createImageData(width, height); + this._silhouetteDirty = true; } @@ -634,24 +643,17 @@ class PenSkin extends Skin { // Render export texture to another framebuffer const gl = this._renderer.gl; - const bounds = this._bounds; - this._renderer.enterDrawRegion(this._toBufferDrawRegionId); // Sample the framebuffer's pixels into the silhouette instance - const skinPixels = new Uint8Array(Math.floor(this._canvas.width * this._canvas.height * 4)); - gl.readPixels(0, 0, this._canvas.width, this._canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, skinPixels); + gl.readPixels( + 0, 0, + this._canvas.width, this._canvas.height, + gl.RGBA, gl.UNSIGNED_BYTE, this._silhouettePixels + ); - const skinCanvas = this._canvas; - skinCanvas.width = bounds.width; - skinCanvas.height = bounds.height; - - const skinContext = skinCanvas.getContext('2d'); - const skinImageData = skinContext.createImageData(bounds.width, bounds.height); - skinImageData.data.set(skinPixels); - skinContext.putImageData(skinImageData, 0, 0); - - this._silhouette.update(this._canvas, true /* isPremultiplied */); + this._silhouetteImageData.data.set(this._silhouettePixels); + this._silhouette.update(this._silhouetteImageData, true /* isPremultiplied */); this._silhouetteDirty = false; } From 90b8f15d8c20b6484d93a837da9a2999aa70b848 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Tue, 4 Feb 2020 22:32:04 -0500 Subject: [PATCH 2/3] Un-premultiply extracted drawables --- src/RenderWebGL.js | 3 ++- src/ShaderManager.js | 5 +++++ src/shaders/sprite.frag | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 56c7c49d..6f1c9867 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 a71ef2d2..4fb3da5f 100644 --- a/src/ShaderManager.js +++ b/src/ShaderManager.js @@ -158,6 +158,11 @@ ShaderManager.DRAW_MODE = { */ default: 'default', + /** + * Un-premultiply 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 13fe19de..b271fd28 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. From a427461467290afb61eb6e4e46d9ffa3ecb75b24 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Thu, 26 Mar 2020 23:01:18 -0400 Subject: [PATCH 3/3] Clarify draw mode comments --- src/ShaderManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ShaderManager.js b/src/ShaderManager.js index 4fb3da5f..3f0bc613 100644 --- a/src/ShaderManager.js +++ b/src/ShaderManager.js @@ -154,12 +154,12 @@ ShaderManager.EFFECTS = Object.keys(ShaderManager.EFFECT_INFO); */ ShaderManager.DRAW_MODE = { /** - * Draw normally. + * Draw normally. Its output will use premultiplied alpha. */ default: 'default', /** - * Un-premultiply alpha. Useful for reading pixels from GL into an ImageData object. + * Draw with non-premultiplied alpha. Useful for reading pixels from GL into an ImageData object. */ straightAlpha: 'straightAlpha',