From 99ff2ba11ec9cc68f29d8d16066fedf286820626 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Fri, 2 Aug 2019 03:12:55 -0400 Subject: [PATCH 1/7] Fix touching color check for background color --- src/RenderWebGL.js | 82 +++++++++++++++++++++++++++++++++-------- src/ShaderManager.js | 7 +++- src/shaders/sprite.frag | 14 ++++++- src/shaders/sprite.vert | 3 ++ 4 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 364009f50..37451d7fd 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -182,9 +182,23 @@ class RenderWebGL extends EventEmitter { /** @type {function} */ this._exitRegion = null; + /** @type {object} */ + this._backgroundDrawRegionId = { + enter: () => this._enterDrawBackground(), + exit: () => this._exitDrawBackground() + }; + /** @type {Array.} */ this._snapshotCallbacks = []; + /** @type {Array} + * @readonly */ + this._backgroundColor4f = [0, 0, 0, 0]; + + /** @type {Uint8ClampedArray} + * @readonly */ + this._backgroundColor3b = new Uint8ClampedArray(3); + this._createGeometry(); this.on(RenderConstants.Events.NativeSizeChanged, this.onNativeSizeChanged); @@ -244,7 +258,12 @@ class RenderWebGL extends EventEmitter { * @param {number} blue The blue component for the background. */ setBackgroundColor (red, green, blue) { - this._backgroundColor = [red, green, blue, 1]; + this._backgroundColor4f = [red, green, blue, 1]; + + this._backgroundColor3b[0] = red * 255; + this._backgroundColor3b[1] = green * 255; + this._backgroundColor3b[2] = blue * 255; + } /** @@ -623,7 +642,7 @@ class RenderWebGL extends EventEmitter { twgl.bindFramebufferInfo(gl, null); gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); - gl.clearColor.apply(gl, this._backgroundColor); + gl.clearColor.apply(gl, this._backgroundColor4f); gl.clear(gl.COLOR_BUFFER_BIT); this._drawThese(this._drawList, ShaderManager.DRAW_MODE.default, this._projection); @@ -739,12 +758,20 @@ class RenderWebGL extends EventEmitter { */ isTouchingColor (drawableID, color3b, mask3b) { const candidates = this._candidatesTouching(drawableID, this._visibleDrawList); - if (candidates.length === 0) { + + let bounds; + if (colorMatches(color3b, this._backgroundColor3b, 0)) { + // If the color we're checking for is the background color, don't confine the check to + // candidate drawables' bounds--since the background spans the entire stage, we must check + // everything that lies inside the drawable. + bounds = this._touchingBounds(drawableID); + } else if (candidates.length === 0) { + // If not checking for the background color, we can return early if there are no candidate drawables. return false; + } else { + bounds = this._candidatesBounds(candidates); } - const bounds = this._candidatesBounds(candidates); - const maxPixelsForCPU = this._getMaxPixelsForCPU(); const debugCanvasContext = this._debugCanvas && this._debugCanvas.getContext('2d'); @@ -805,6 +832,19 @@ class RenderWebGL extends EventEmitter { } } + _enterDrawBackground () { + const gl = this.gl; + const currentShader = this._shaderManager.getShader(ShaderManager.DRAW_MODE.background, 0); + gl.disable(gl.BLEND); + gl.useProgram(currentShader.program); + twgl.setBuffersAndAttributes(gl, currentShader, this._bufferInfo); + } + + _exitDrawBackground () { + const gl = this.gl; + gl.enable(gl.BLEND); + } + _isTouchingColorGpuStart (drawableID, candidateIDs, bounds, color3b, mask3b) { this._doExitDrawRegion(); @@ -816,15 +856,8 @@ class RenderWebGL extends EventEmitter { gl.viewport(0, 0, bounds.width, bounds.height); const projection = twgl.m4.ortho(bounds.left, bounds.right, bounds.top, bounds.bottom, -1, 1); - let fillBackgroundColor = this._backgroundColor; - - // When using masking such that the background fill color will showing through, ensure we don't - // fill using the same color that we are trying to detect! - if (color3b[0] > 196 && color3b[1] > 196 && color3b[2] > 196) { - fillBackgroundColor = [0, 0, 0, 255]; - } - - gl.clearColor.apply(gl, fillBackgroundColor); + // Clear the query buffer to fully transparent. This will be the color of pixels that fail the stencil test. + gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); let extraUniforms; @@ -836,6 +869,9 @@ class RenderWebGL extends EventEmitter { } try { + // Using the stencil buffer, mask out the drawing to either the drawable's bounds + // or pixels of the drawable which match the mask color, depending on whether a mask color is given. + // Masked-out pixels will not be checked. gl.enable(gl.STENCIL_TEST); gl.stencilFunc(gl.ALWAYS, 1, 1); gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); @@ -856,12 +892,25 @@ class RenderWebGL extends EventEmitter { gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); gl.colorMask(true, true, true, true); + // Draw the background as a quad. Drawing a background with gl.clear will not mask to the stenciled area. + this.enterDrawRegion(this._backgroundDrawRegionId); + + const uniforms = { + u_backgroundColor: this._backgroundColor4f + }; + + const currentShader = this._shaderManager.getShader(ShaderManager.DRAW_MODE.background, 0); + twgl.setUniforms(currentShader, uniforms); + twgl.drawBufferInfo(gl, this._bufferInfo, gl.TRIANGLES); + + // Draw the candidate drawables on top of the background. this._drawThese(candidateIDs, ShaderManager.DRAW_MODE.default, projection, {idFilterFunc: testID => testID !== drawableID} ); } finally { gl.colorMask(true, true, true, true); gl.disable(gl.STENCIL_TEST); + this._doExitDrawRegion(); } } @@ -880,7 +929,8 @@ class RenderWebGL extends EventEmitter { } for (let pixelBase = 0; pixelBase < pixels.length; pixelBase += 4) { - if (colorMatches(color3b, pixels, pixelBase)) { + // Transparent pixels are masked (either by the drawable's bounds or color mask). + if (pixels[pixelBase + 3] !== 0 && colorMatches(color3b, pixels, pixelBase)) { return true; } } @@ -1204,7 +1254,7 @@ class RenderWebGL extends EventEmitter { gl.viewport(0, 0, bounds.width, bounds.height); const projection = twgl.m4.ortho(bounds.left, bounds.right, bounds.top, bounds.bottom, -1, 1); - gl.clearColor.apply(gl, this._backgroundColor); + gl.clearColor.apply(gl, this._backgroundColor4f); gl.clear(gl.COLOR_BUFFER_BIT); this._drawThese(this._drawList, ShaderManager.DRAW_MODE.default, projection); diff --git a/src/ShaderManager.js b/src/ShaderManager.js index 8c59d3b7d..37c24346d 100644 --- a/src/ShaderManager.js +++ b/src/ShaderManager.js @@ -176,7 +176,12 @@ ShaderManager.DRAW_MODE = { /** * Draw a line with caps. */ - line: 'line' + line: 'line', + + /** + * Draw the background in a certain color. Must sometimes be used instead of gl.clear. + */ + background: 'background' }; module.exports = ShaderManager; diff --git a/src/shaders/sprite.frag b/src/shaders/sprite.frag index b65fe11a0..8ee6814f3 100644 --- a/src/shaders/sprite.frag +++ b/src/shaders/sprite.frag @@ -40,6 +40,10 @@ uniform float u_lineLength; uniform vec4 u_penPoints; #endif // DRAW_MODE_line +#ifdef DRAW_MODE_background +uniform vec4 u_backgroundColor; +#endif // DRAW_MODE_background + uniform sampler2D u_skin; varying vec2 v_texCoord; @@ -110,7 +114,7 @@ const vec2 kCenter = vec2(0.5, 0.5); void main() { - #ifndef DRAW_MODE_line + #if !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background)) vec2 texcoord0 = v_texCoord; #ifdef ENABLE_mosaic @@ -216,7 +220,9 @@ void main() gl_FragColor.rgb /= gl_FragColor.a + epsilon; #endif - #else // DRAW_MODE_line + #endif // !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background)) + + #ifdef DRAW_MODE_line // Maaaaagic antialiased-line-with-round-caps shader. // "along-the-lineness". This increases parallel to the line. @@ -235,4 +241,8 @@ void main() // the closer we are to the line, invert it. gl_FragColor = u_lineColor * clamp(1.0 - line, 0.0, 1.0); #endif // DRAW_MODE_line + + #ifdef DRAW_MODE_background + gl_FragColor = u_backgroundColor; + #endif } diff --git a/src/shaders/sprite.vert b/src/shaders/sprite.vert index 90ae4ca5c..c70646c31 100644 --- a/src/shaders/sprite.vert +++ b/src/shaders/sprite.vert @@ -60,6 +60,9 @@ void main() { // Apply view transform position *= 2.0 / u_stageSize; gl_Position = vec4(position, 0, 1); + #elif defined(DRAW_MODE_background) + gl_Position = vec4(a_position * 2.0, 0, 1); + v_texCoord = a_texCoord; #else gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1); v_texCoord = a_texCoord; From a7d636827ccd65399fc61bfd6418275a5f282697 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Fri, 2 Aug 2019 03:26:29 -0400 Subject: [PATCH 2/7] add touching color test for common clear colors --- test/integration/scratch-tests/clear-color.sb3 | Bin 0 -> 55957 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/integration/scratch-tests/clear-color.sb3 diff --git a/test/integration/scratch-tests/clear-color.sb3 b/test/integration/scratch-tests/clear-color.sb3 new file mode 100644 index 0000000000000000000000000000000000000000..42b6d851623851aa444af8f15f9f603ec06fdef1 GIT binary patch literal 55957 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%0AIEw`# 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 Wq4EgxU!$<@PqzE{HJJa`-G2cSlby~0 literal 0 HcmV?d00001 From f09131ea645515c4cb647eda6064b7f2f48d7182 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Wed, 10 Jun 2020 17:23:31 -0400 Subject: [PATCH 3/7] Snap _candidatesTouching bounds to integer coords When we construct bounds inside which we should loop over pixels, which is done in _candidatesBounds, we expect their dimensions+position to be integers when looping over them. If they aren't, weird things will occur (e.g. "phantom" touching-color results depending on the precise subpixel bounds position) that are not very fun to debug. --- src/RenderWebGL.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 37451d7fd..67aa8640e 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -1342,6 +1342,13 @@ class RenderWebGL extends EventEmitter { // Update the CPU position data drawable.updateCPURenderAttributes(); const candidateBounds = drawable.getFastBounds(); + + // Push bounds out to integers. If a drawable extends out into half a pixel, that half-pixel stil + // needs to be tested. Plus, in some areas we construct another rectangle from the union of these, + // and iterate over its pixels (width * height). Turns out that doesn't work so well when the + // width/height aren't integers. + candidateBounds.snapToInt(); + if (bounds.intersects(candidateBounds)) { result.push({ id, From 4fa042cead5270aeac911a1d12098263f79578de Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Wed, 17 Jun 2020 14:19:44 -0400 Subject: [PATCH 4/7] Remove unnecessary shader stuff --- src/shaders/sprite.frag | 2 ++ src/shaders/sprite.vert | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shaders/sprite.frag b/src/shaders/sprite.frag index 8ee6814f3..6b628592f 100644 --- a/src/shaders/sprite.frag +++ b/src/shaders/sprite.frag @@ -46,7 +46,9 @@ uniform vec4 u_backgroundColor; uniform sampler2D u_skin; +#ifndef DRAW_MODE_background varying vec2 v_texCoord; +#endif // Add this to divisors to prevent division by 0, which results in NaNs propagating through calculations. // Smaller values can cause problems on some mobile devices. diff --git a/src/shaders/sprite.vert b/src/shaders/sprite.vert index c70646c31..6f65cf83d 100644 --- a/src/shaders/sprite.vert +++ b/src/shaders/sprite.vert @@ -11,7 +11,7 @@ uniform vec4 u_penPoints; const float epsilon = 1e-3; #endif -#ifndef DRAW_MODE_line +#if !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background)) uniform mat4 u_projectionMatrix; uniform mat4 u_modelMatrix; attribute vec2 a_texCoord; @@ -62,7 +62,6 @@ void main() { gl_Position = vec4(position, 0, 1); #elif defined(DRAW_MODE_background) gl_Position = vec4(a_position * 2.0, 0, 1); - v_texCoord = a_texCoord; #else gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1); v_texCoord = a_texCoord; From 8db14c5094edb37851275b707c3da132131a1b02 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Wed, 17 Jun 2020 16:01:17 -0400 Subject: [PATCH 5/7] Clean up background color stuff --- src/RenderWebGL.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 67aa8640e..91f98c854 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -192,11 +192,11 @@ class RenderWebGL extends EventEmitter { this._snapshotCallbacks = []; /** @type {Array} - * @readonly */ - this._backgroundColor4f = [0, 0, 0, 0]; + * Don't set this directly-- use setBackgroundColor so it stays in sync with _backgroundColor3b */ + this._backgroundColor4f = [0, 0, 0, 1]; /** @type {Uint8ClampedArray} - * @readonly */ + * Don't set this directly-- use setBackgroundColor so it stays in sync with _backgroundColor4f */ this._backgroundColor3b = new Uint8ClampedArray(3); this._createGeometry(); @@ -258,7 +258,9 @@ class RenderWebGL extends EventEmitter { * @param {number} blue The blue component for the background. */ setBackgroundColor (red, green, blue) { - this._backgroundColor4f = [red, green, blue, 1]; + this._backgroundColor4f[0] = red; + this._backgroundColor4f[1] = green; + this._backgroundColor4f[2] = blue; this._backgroundColor3b[0] = red * 255; this._backgroundColor3b[1] = green * 255; From a2bc5a4974a81569d4a4af34e3fc86c08011fef5 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Wed, 17 Jun 2020 16:07:24 -0400 Subject: [PATCH 6/7] Fix "drawable's bounds" comments --- src/RenderWebGL.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 91f98c854..de8f60e5c 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -871,7 +871,7 @@ class RenderWebGL extends EventEmitter { } try { - // Using the stencil buffer, mask out the drawing to either the drawable's bounds + // Using the stencil buffer, mask out the drawing to either the drawable's alpha channel // or pixels of the drawable which match the mask color, depending on whether a mask color is given. // Masked-out pixels will not be checked. gl.enable(gl.STENCIL_TEST); @@ -931,7 +931,7 @@ class RenderWebGL extends EventEmitter { } for (let pixelBase = 0; pixelBase < pixels.length; pixelBase += 4) { - // Transparent pixels are masked (either by the drawable's bounds or color mask). + // Transparent pixels are masked (either by the drawable's alpha channel or color mask). if (pixels[pixelBase + 3] !== 0 && colorMatches(color3b, pixels, pixelBase)) { return true; } From 19398fa67adf98b78cb9749afe0357251488c685 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Wed, 17 Jun 2020 16:09:19 -0400 Subject: [PATCH 7/7] Fix typo: "that half-pixel stil" --- src/RenderWebGL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index de8f60e5c..5108e19e4 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -1345,7 +1345,7 @@ class RenderWebGL extends EventEmitter { drawable.updateCPURenderAttributes(); const candidateBounds = drawable.getFastBounds(); - // Push bounds out to integers. If a drawable extends out into half a pixel, that half-pixel stil + // Push bounds out to integers. If a drawable extends out into half a pixel, that half-pixel still // needs to be tested. Plus, in some areas we construct another rectangle from the union of these, // and iterate over its pixels (width * height). Turns out that doesn't work so well when the // width/height aren't integers.