我一直在研究一种创建类似于 this one 的剪贴蒙版的方法。 (以 SVG 格式完成)。
根据我的发现,我选择通过模板来实现这一目标。然而我的实现是非常不正确的。我不完全确定 gl.stencilOp
和 gl.stencilFunc
是如何工作的,因为我似乎需要渲染两次屏蔽我的主要内容的片段。在渲染主要内容之前一次,在渲染主要内容之后一次使用不同的参数。
此测试的相关片段/部分可以在 ../src/renderers/webgl.js
中找到,从 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);
}
模拟 webgl 模板以像 svg 示例一样工作的指导将非常感激。
最佳答案
您需要做的是:
- 绘制模板区域(在您的例子中为蓝色矩形),
- 停止在模板中绘制
- 绘制您想要考虑使用模板的场景
- 停止模板
如下:
if (this._mask) {
// Clearing the stencil buffer
gl.clearStencil(0);
gl.clear(gl.STENCIL_BUFFER_BIT);
// Replacing the values at the stencil buffer to 1 on every pixel we draw
gl.stencilFunc(gl.ALWAYS, 1, 1);
gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
// disable color (u can also disable here the depth buffers)
gl.colorMask(false, false, false, false);
gl.enable(gl.STENCIL_TEST);
// Renders the mask through gl.drawArrays L111
webgl[this._mask._renderer.type].render.call(this._mask, gl, program, this);
// Telling the stencil now to draw/keep only pixels that equals 1 - which we set earlier
gl.stencilFunc(gl.EQUAL, 1, 1);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
// enabling back the color buffer
gl.colorMask(true, true, true, true);
}
// Renders main content through a series of gl.drawArrays calls
_.each(this.children, webgl.group.renderChild, {
gl: gl,
program: program
});
// Stop considering the stencil
if (this._mask) {
gl.disable(gl.STENCIL_TEST);
}
关于javascript - 如何使用模板在 webgl 中创建 2d 剪贴蒙版?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24687437/