3

2016年現在の編集:「乗算」値がglobalCompositeOperationに実装されています。リアルタイム グラフィックスには十分なパフォーマンスです。


基本的に、私は 2 つのキャンバス (1 つは描画に使用される非表示のキャンバス) を持っており、乗算ブレンド モードを使用して、非表示のキャンバスを表示されているキャンバスにブレンドしたいと考えています。

Context.globalCompositeOperation乗算は含まれません (私の意見ではそうすべきですが) imageData、キャンバスを手動でブレンドするのに使用するのは遅すぎます (これを 60fps で行う必要があります)。

キャンバスをブレンドするために使用できるより高速な方法はありますか? これはWebGLを使用して実行できると思いますが、使用した経験はありません。

4

1 に答える 1

5

WebGLのブレンドモードには、(ソースと宛先の)乗算も含まれていません。ただし、WebGLのテクスチャへのレンダリング機能を使用すると、乗算操作を効率的に実行できます。

  1. 表示されるキャンバスをWebGLキャンバスにします。
  2. 2つのテクスチャを作成します。それらを「ソース」および「宛先」と呼びます。
  3. 非表示のキャンバスコンテンツを「ソース」テクスチャにレンダリングします。これは、WebGL描画操作を直接使用して(余分なキャンバスを使用せずに)、または2D非表示キャンバスのコンテンツをテクスチャにアップロードすることによって(これは組み込みの操作です)実行できます。

    var sourceTexture = gl.createTexture()
    gl.bindTexture(gl.TEXTURE_2D, sourceTexture)
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, sourceCanvas)
    // ...also set texture filters — see any WebGL tutorial...
    
  4. 乗算する他のコンテンツを「宛先」テクスチャにレンダリングします。

  5. 最後に、実際に表示されているキャンバスをターゲットにして、フラグメントシェーダーを使用して、「ソース」テクスチャと「宛先」テクスチャを乗算します。ここでのテクニックは、後処理効果に使用されるテクニックです—そのようなチュートリアルまたは簡単な例を調べることをお勧めします。簡単に言うと、フラグメントシェーダーをキャンバス全体に適用するには、フルスクリーンのクワッド(ビューポート全体をカバーするジオメトリ)を描画します。頂点シェーダーは簡単で、フラグメントシェーダーは次のようになります。

    varying vec2 texCoord;
    uniform sampler2D sourceTexture;
    uniform sampler2D destTexture;
    void main(void) {
      gl_FragColor = texture2D(sourceTexture, texCoord) * texture2D(destTexture, texCoord);
    }
    

フレームごとに複数のオーバーラップする乗算ブレンドを実行する場合、たとえば8つ以下の場合は、上記の手順を拡張して複数のテクスチャを乗算できます。たくさんある場合は、3番目にレンダリングしてから役割を交換しながら、2つのテクスチャを乗算する複数の段階を実行する必要があります。

より具体的な回答が必要な場合は、乗算するグラフィックの数と種類の詳細を質問に広げてください。

于 2012-07-22T00:36:38.793 に答える