4

私のプログラムでは、多くの球を描きたいと思っています。まず、球の頂点とインデックスを作成し、voa/vbo/ibo にバインドします。その後、1000 個のランダム モデル マトリックスを作成します。これで、メッシュを描画する方法が 2 つあります。

  1. ModelMatrices 呼び出しのリストを 1000 回ループするだけglDrawElementsです。マトリックス MVP は CPU で計算され、ユニフォームのようにシェーダーに送信されます。
  2. すべてのマトリックスを追加の VBO にバインドし、「in」変数のようにシェーダーに送信します。次に、 で 1 回だけ呼び出しますglDrawElementsInstanced

テスト プログラムでは、1000 個の球体 (約 2000 万個の頂点) を描画します。最初の方法を使用すると約 27FPS になり、2 番目の方法ではパフォーマンスが 19 FPS に低下します。理論的には、2 番目の方法は 1 番目よりも優れたパフォーマンスを達成するはずです。

これがコードです。

ボトルネックは、頂点シェーダーでのこの乗算であると思います。これは(VP * ModelMatrix)、各 (メッシュの頂点) * 1000 ごとに実行する必要があるためです。

何をアップグレードでき、何が間違っていますか?

4

2 に答える 2

10

インスタンス化が常に成功するとは限りません。これは、実行する価値があるかどうかを確認するためにプロファイルする必要がある最適化の一種です。

一般に、多数のインスタンス (1000 はかなりの数ですが、十分ではありません。10,000 と考えてください) をレンダリングする場合は、インスタンス化が有効です (20,000 ではおそらく多すぎます。100 ~ 3000 を詳しく調べるか、それで)。また、インスタンスごとのデータは不必要に大きくなります。ベクトルと四元数を簡単に使用できる場合は、行列を使用します。

インスタンス化の目的は、CPU オーバーヘッドを削減することです。具体的には、描画呼び出しごとの CPU オーバーヘッドと状態変化です。合計 2,000 万の頂点があるため、1,000 回の描画呼び出しと状態変更の CPU オーバーヘッドが最大の問題ではない可能性が高くなります。

于 2012-10-09T14:45:22.900 に答える
5

回転不変の球体があるため、行列を単純な並進 vec3 (おそらく w = 均一スケール ?) に置き換えることができます。それが何かを変えるかどうかはわかりませんが、ALU に縛られることはめったにありません。しかし、20M の頂点はかなり多いです。

1000 ドローコール/フレームは、PC が処理できる範囲内 (通常は < 3000 ) であり、単純なバージョンがそれほど遅くないという事実を説明しています。

インスタンス化のパフォーマンスの低さについては、私にはよくわかりませんが、なんと 20k の頂点/メッシュに関係していると思われます。インスタンス化はかなり小さいメッシュ用に設計されているため、GPU はそれをうまく処理できない可能性があります。小さいメッシュ(200 頂点)で Vsync をオフにして比較してみてはいかがでしょうか? 私は興味がある。

于 2012-10-09T09:46:58.163 に答える