2014-01-05 12 views
5

私は2Dレイヤーベースのアプリケーションに取り組んでいます。私はWebGLを使って合成したいと思います。これらの層は、互いに対してシフトされてもよく、各フレームの各(小さな)部分だけが変化してもよい。しかし、その長方形部分の幅と高さは予期せず変化する可能性があります。 レイヤーごとに1つのキャンバス(2D)と1つのテクスチャを使用したいと思います。各フレームは、変更されたレイヤーの部分だけを各キャンバスに再描画し、その小さな領域をGPUにアップロードして、テクスチャ、GPUが私のために合成する前に。しかし、画像の一部だけをテクスチャの一部にアップロードする効率的な方法は見つけられていません。 texSubImage2D()はテクスチャの一部を更新しますが、完全な画像/キャンバスのみを使用し、使用する画像の矩形領域を指定することはできないようです。WebGL:イメージ/キャンバスの一部だけをテクスチャとしてアップロードする効率的な方法はありますか?

私はこれを行うためのいくつかの方法を考えているが、それぞれが明確なオーバーヘッドを持っているようだ

  • 使用getImageData() + texSubImage2D()のみにGPUにキャンバスのピクセルを変換するには(オーバーヘッドを変える部分をアップロードtexImage2D()
  • とImageDataをのデータ)
  • 層全体のキャンバスを再アップロード各フレーム又は各レイヤの変更のために完全に適合するように、正しい寸法に小さなcanvas2Dサイズを変更/作成し、その後、関連を更新するためにそれを送信するtexSubImage2D()を使用テクスチャ(メモリrエスケープオーバーヘッド)

ですから、テクスチャの画像/キャンバスの一部を指定する方法はありますか? texImagePart2D()texSubImagePart2Dのようなものは、使用する画像/キャンバスの矩形領域を指定するために、さらに4つのパラメータ、sourceXsourceYsourceWidthsourceHeightを受け入れますか?

+0

少なくとも、組み込みGPUのほとんどでは、TexSubImage2D APIが遅くなります。 TexImage2D自体を使うほうが良いでしょう。 – prabindh

+0

その一部だけが変更されたとしても、テクスチャ全体を再アップロードするよりも速い方法はありませんか?しかし、私は理解していない、なぜそれが全体の質感ではなく、小さなrectをアップロードするだけで、それは遅くなるだろうか?既存のテクスチャを変更するのが遅いのですか? – Jor

答えて

4

残念ながら、キャンバス/画像の一部をアップロードする方法はありません。

WebGLのベースとなるOpenGL ES 2.0では、これを行う方法が提供されていません。 OpenGL ES 3.0では、ソースの小さな四角形をテクスチャやテクスチャの一部にアップロードする方法が提供されているため、WebGLの次のバージョンでその機能が提供される可能性があります。

今のところアップロードに役立つ別のキャンバスを使用できます。まずサイズ試合にキャンバスを使用すると、

canvasForCopying.width = widthToCopy; 
canvasForCopying.height= heightToCopy; 

をアップロードしたい部分は、その後にアップロードすることを使用し、あなたが

canvasForCopying2DContext.drawImage(
    srcCanvas, srcX, srcY, widthToCopy, heightToCopy, 
    0, 0, widthToCopy, heightToCopy); 

をコピーするためのキャンバスにコピーしたかったキャンバスの部分をコピーあなたがそれを望むところのテクスチャ。

gl.texSubImage2D(gl.TEXTURE_2D, 0, destX, destY, gl.RGBA, gl.UNSIGNED_BYTE, 
       canvasForCopying); 

getImageDataブラウザは画像データを取得し、それがグラフィックパイプラインをストールreadPixelsを呼び出す必要があるため、そう遅くなります。ブラウザはdrawImageのためにそれをする必要はありません。 texImage2Dは、時にはそれがドライバ/ GPUに依存するが、明らかに、時にはtexImage2DtexSubImage2Dができないのに対し、DMAを使用して実装することができtexSubImage2Dよりも速くすることができる理由については

texImage2Dは、新しいテクスチャを作成し、古いものをゆっくりと破棄することによってパイプライン化することもできます。texSubImage2Dはそうすることができません。

個人的に私はそれを心配しませんが、確認したい場合は、texImage2DtexSubImage2Dの両方を使用して何万ものテクスチャをアップロードしてください(グラフィックはパイプライン化されているので時間はかかりません)。テクスチャが大きく、更新したい部分がテクスチャの25%より小さい場合、texSubImage2Dが速くなることがわかります。少なくともそれは私が最後にチェックしたものです。現在のドライバは、texSubImage2Dに電話して、内容全体を置き換えると内部でtexImage2Dというコードを呼び出すと、少なくとも最適化されています。

+0

詳細な回答ありがとうございました。私はそのdrawImage/texSubImage2Dの回避策を使用すると思います。よろしく。 – Jor

関連する問題