12

WebGL は、レンダリング コマンドの長いリストを完了するのを待たずに送信できるという点で、非同期で優れています。ただし、何らかの理由でレンダリングが完了するまで待機する必要がある場合は、 と同期して行う必要がありますgl.finish()gl.finishコールバックを受け取ってすぐに戻った方がいいのではないでしょうか?

質問:これを確実にエミュレートする方法はありますか?

使用例:多数の頂点を大きなオフスクリーン キャンバスにレンダリングしてdrawImageから、この大きなキャンバスのセクションをページ上の小さなキャンバスにコピーするために使用しています。私は実際に使用していませんが、同様の効果gl.finish()があるようです。drawImage()私のアプリケーションでは、再レンダリングはユーザーがアクション (ボタンのクリックなど) を実行したときにのみトリガーされ、数百ミリ秒かかる場合があります。レンダリング中にブラウザがまだ応答していて、スクロールなどを許可していればいいのですが、特にChromeソリューションを探していますが、FirefoxやSafariでも機能するものが良いでしょう.

考えられる (悪い) 答え:レンダリングにかかる​​時間を試して見積もり、 への呼び出しで始まるタイムアウトを設定することができますgl.finish()。ただし、すべてのサイズの頂点バッファーとすべてのユーザーに対してこの推定を確実に行うことは、かなりトリッキーで不正確になります。

可能な(非)回答: requestAnimationFrame私が探しているものはありますか...そうではありませんか?

2018 年に考えられる答え:おそらくImageBitmapAPI がこの問題を解決します - MDN docsを参照してください。

4

1 に答える 1

5

あなたはすでに部分的にあなたの答えを見つけdrawImage()ています:実際には、画像データを読み取る前にすべての未処理の描画コマンドを強制的に完了するという点で、終了のような動作があります。問題は、gl.finish()レンダリングが完了するのを待っていたとしても、現在と同じように動作することです。レンダリングが完了するまでメイン スレッドがブロックされ、ユーザーがページを操作できなくなります。

理想的には、このシナリオで必要なのは、一連の描画コマンドが実際に待機をブロックすることなく完了したことを示す、ある種のコールバックです。残念ながら、そのようなコールバックは存在しません (ブラウザの内部構造を考えると、コールバックを提供するのは驚くほど難しいでしょう!)

あなたの場合のまともな妥協点は、画像の準備ができていると感じる時期について、いくつかのインテリジェントな見積もりを行うことです。たとえば、ドローコールをディスパッチしたら、 をrequestAnimationFrame呼び出す前に3 ~ 4 秒間スピンしますdrawImage。常に時間がかかる場合 (10 フレーム?) は、より長くスピンしてください。これにより、ユーザーは通常どおりページと対話し続けることができ、コンテンツのレンダリングが終了しているため、画像の描画を実行するときに遅延が発生しないか、レンダリングの途中で同期ステップを実行するため遅延が大幅に減少します。サイトの使用目的によっては、非リアルタイム レンダリングが表示される前に 1 秒ほどスピンすることさえあるかもしれません。

これは確かに完璧な解決策ではありません。より良い答えがあればいいのにと思います。おそらく、WebGL は将来、このタイプのステータスを照会できるようになるでしょう。これは、あなたのようなケースでは価値があるためですが、今のところ、これができる最善の方法です。

于 2013-08-26T20:47:00.870 に答える