2

これに似たクリッピング マスクを作成する方法を調査しています(SVG で作成)。

私の調査結果に基づいて、ステンシルによってこれを達成することにしました。しかし、私の実装はひどく間違っています。メインコンテンツを2回マスキングするフラグメントをレンダリングする必要があるように見えるため、どのようgl.stencilOpに機能するかは完全にはわかりません。gl.stencilFuncメイン コンテンツをレンダリングする前に 1 回、さまざまなパラメーターを使用してレンダリングした後に 1 回。

動作テストは次のとおりです: https://dl.dropboxusercontent.com/u/1595444/experiments/two.js/issues/issue-56/stencil-buffer/test/clip.html

ここに画像の説明を入力

このテストの関連するスニペット/部分は、次の場所にあり../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);

}

svg の例のように動作するように webgl ステンシルをエミュレートするためのガイダンスをいただければ幸いです。

4

1 に答える 1

3

あなたがする必要があるのは:

  • ステンシル領域 (この場合は青い長方形) を描画します。
  • ステンシルへの描画をやめる
  • ステンシルに検討したいシーンを描きます
  • ステンシルを停止

次のように:

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);
}
于 2014-07-23T08:50:18.550 に答える