簡體   English   中英

如何在WebGL中使用模板創建2d剪貼蒙版?

[英]How to use stenciling to create a 2d clipping mask in webgl?

我一直在研究一種創建類似於剪貼蒙版(在SVG中完成)的剪貼蒙版的方法。

根據我的發現,我選擇通過模板來實現。 但是,我的實現嚴重不正確。 我不確定gl.stencilOpgl.stencilFunc工作方式,因為似乎我需要渲染兩次掩蓋我的主要內容的片段。 一次,我渲染主要內容,一次,之后渲染參數。

這是工作測試: https : //dl.dropboxusercontent.com/u/1595444/experiments/two.js/issues/issue-56/stencil-buffer/test/clip.html

在此處輸入圖片說明

該測試的相關代碼段/部分可以在../src/renderers/webgl.jsL67開始找到:

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM