diff --git a/src/Drawable.js b/src/Drawable.js index 975ca95..cc1d9ab 100644 --- a/src/Drawable.js +++ b/src/Drawable.js @@ -36,8 +36,10 @@ const getLocalPosition = (drawable, vec) => { // localPosition matches that transformation. localPosition[0] = 0.5 - (((v0 * m[0]) + (v1 * m[4]) + m[12]) / d); localPosition[1] = (((v0 * m[1]) + (v1 * m[5]) + m[13]) / d) + 0.5; - // Apply texture effect transform. - EffectTransform.transformPoint(drawable, localPosition, localPosition); + // Apply texture effect transform if the localPosition is within the drawable's space. + if ((localPosition[0] >= 0 && localPosition[0] < 1) && (localPosition[1] >= 0 && localPosition[1] < 1)) { + EffectTransform.transformPoint(drawable, localPosition, localPosition); + } return localPosition; }; diff --git a/src/PenSkin.js b/src/PenSkin.js index fb0b0d9..1e500ba 100644 --- a/src/PenSkin.js +++ b/src/PenSkin.js @@ -154,6 +154,13 @@ class PenSkin extends Skin { return true; } + /** + * @returns {boolean} true if alpha is premultiplied, false otherwise + */ + get hasPremultipliedAlpha () { + return true; + } + /** * @return {Array} the "native" size, in texels, of this skin. [width, height] */ @@ -181,8 +188,9 @@ class PenSkin extends Skin { clear () { const gl = this._renderer.gl; twgl.bindFramebufferInfo(gl, this._framebuffer); - - gl.clearColor(1, 1, 1, 0); + + /* Reset framebuffer to transparent black */ + gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); const ctx = this._canvas.getContext('2d'); @@ -598,7 +606,7 @@ class PenSkin extends Skin { this._silhouetteBuffer = twgl.createFramebufferInfo(gl, [{format: gl.RGBA}], width, height); } - gl.clearColor(1, 1, 1, 0); + gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); this._silhouetteDirty = true; diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 05b35e2..f16b02d 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -1620,7 +1620,14 @@ class RenderWebGL extends EventEmitter { } twgl.setUniforms(currentShader, uniforms); - + + /* adjust blend function for this skin */ + if (drawable.skin.hasPremultipliedAlpha){ + gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + } else { + gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + } + twgl.drawBufferInfo(gl, this._bufferInfo, gl.TRIANGLES); } diff --git a/src/Skin.js b/src/Skin.js index d5fcbb3..e0e7413 100644 --- a/src/Skin.js +++ b/src/Skin.js @@ -76,6 +76,13 @@ class Skin extends EventEmitter { return false; } + /** + * @returns {boolean} true if alpha is premultiplied, false otherwise + */ + get hasPremultipliedAlpha () { + return false; + } + /** * @return {int} the unique ID for this Skin. */ diff --git a/src/shaders/sprite.frag b/src/shaders/sprite.frag index 055e9a2..a781baf 100644 --- a/src/shaders/sprite.frag +++ b/src/shaders/sprite.frag @@ -194,12 +194,6 @@ void main() discard; } #endif // DRAW_MODE_colorMask - - // WebGL defaults to premultiplied alpha - #ifndef DRAW_MODE_stamp - gl_FragColor.rgb *= gl_FragColor.a; - #endif // DRAW_MODE_stamp - #endif // DRAW_MODE_silhouette #else // DRAW_MODE_lineSample