I've been investigating a way to create a clipping mask similar to this one (done in SVG).
Based on my findings I chose to achieve this through stenciling. My implementation however is grossly incorrect. I'm not entirely sure how gl.stencilOp
and gl.stencilFunc
work because it seems like I need to render the fragment masking my main content twice. Once before I render the main content and once after with varying parameters.
Here's the working test: https://dl.dropboxusercontent.com/u/1595444/experiments/two.js/issues/issue-56/stencil-buffer/test/clip.html
The relevant snippet / portion of this test can be found in ../src/renderers/webgl.js
starting at L67
:
if (this._mask) {
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(gl.ALWAYS, 1, 1);
gl.colorMask(false, false, false, true);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
// Renders the mask through gl.drawArrays L111
webgl[this._mask._renderer.type].render.call(
this._mask, gl, program, this);
gl.colorMask(true, true, true, true);
gl.stencilFunc(gl.NOTEQUAL, 0, 1);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
}
// Renders main content through a series of gl.drawArrays calls
_.each(this.children, webgl.group.renderChild, {
gl: gl,
program: program
});
if (this._mask) {
gl.colorMask(false, false, false, false);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
// Re-render mask so main content doesn't flicker
webgl[this._mask._renderer.type].render.call(
this._mask, gl, program, this);
gl.colorMask(true, true, true, true);
gl.stencilFunc(gl.NOTEQUAL, 0, 1);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
gl.disable(gl.STENCIL_TEST);
}
Guidance to emulate the webgl stenciling to work like the svg example would be much appreciated.