Vertex Buffer Objects(VBO)について何年も聞いた後、私はついにそれらを試してみることにしました(私のものは通常、パフォーマンスが重要ではないことは明らかです...)
以下に私の実験について説明しますが、簡単に言うと、「単純な」ダイレクトモード(glBegin()/ glEnd())、頂点配列(CPU側)、VBO(GPU側)の間で区別できないパフォーマンスが見られます。レンダリングモード。私はこれがなぜであるか、そしてどのような条件下でVBOが彼らの原始的な(しゃれを意図した)祖先を大幅に凌駕するのを見ることができるかを理解しようとしています。
実験のために、私は多数の点の(静的な)3Dガウス雲を生成しました。各ポイントには、頂点と色の情報が関連付けられています。次に、「軌道を回る」動作のように、連続するフレームでカメラを雲の周りで回転させました。繰り返しますが、ポイントは静的であり、目だけが移動します(gluLookAt()を介して)。データは、レンダリングの前に1回生成され、レンダリングループで使用するために2つの配列に格納されます。
直接レンダリングの場合、データセット全体が単一のglBegin()/ glEnd()ブロックにレンダリングされ、ループにはそれぞれglColor3fv()およびglVertex3fv()への単一の呼び出しが含まれます。
頂点配列とVBOレンダリングの場合、データセット全体が1回のglDrawArrays()呼び出しでレンダリングされます。
次に、タイトなループで1分ほど実行し、高性能タイマーを使用して平均FPSを測定します。
上記のように、パフォーマンスはデスクトップマシン(XP x64、8GB RAM、512 MB Quadro 1700)とラップトップ(XP32、4GB RAM、256 MB Quadro NVS 110)の両方で区別できませんでした。ただし、ポイント数に応じて期待どおりにスケーリングされました。もちろん、vsyncも無効にしました。
ラップトップの実行からの特定の結果(GL_POINTSを使用したレンダリング):
glBegin()/ glEnd():
頂点配列(CPU側):
頂点バッファオブジェクト(GPU側):
同じデータをGL_TRIANGLE_STRIPでレンダリングしたところ、同様に区別できなくなりました(ただし、余分なラスタライズが原因で予想どおりに遅くなりました)。誰かが欲しいなら、私もそれらの番号を投稿することができます。 。
3Dレンダリングを最適化するための多くの要因があります。通常、4つのボトルネックがあります。
頂点またはピクセルのスループットを最大化しながらCPU(およびバス)が大量にあるため、テストの結果は歪んでいます。 VBOは、CPUを下げるために使用されます(API呼び出しが少なく、CPU DMA転送と並行して)。CPUにバインドされていないため、ゲインは得られません。これが最適化101です。たとえばCPUは、大量のAPI呼び出しを発行するだけでなく、AIや物理学などの他の目的で必要になるため、貴重になります。頂点データ(たとえば、3つのフロート)をメモリポインターに直接書き込む方がはるかに高速であることが簡単にわかります。 3つのfloatをメモリに書き込む関数を呼び出すよりも、少なくとも呼び出しのサイクルを節約できます。
足りないものがいくつかあるかもしれません:
これは大げさな推測ですが、ラップトップのカードにはこの種の操作がまったくない可能性があります(つまり、エミュレートします)。
データをGPUのメモリにコピーしていますか(glBufferData
(GL_ARRAY_BUFFER
とGL_STATIC_DRAW
またはGL_DYNAMIC_DRAW
paramのいずれかを使用)、またはメイン(非GPU)配列へのポインターを使用していますか?メモリ?(フレームごとにコピーする必要があるため、パフォーマンスが低下します)
インデックスをglBufferData
およびGL_ELEMENT_ARRAY_BUFFER
パラメータを介して送信される別のバッファとして渡していますか?
これらの3つのことを行うと、パフォーマンスが大幅に向上します。 Python(v/pyOpenGl)の場合、数100要素よりも大きい配列では約1000倍、C++では最大5倍高速ですが、配列では50k〜10mの頂点です。
これがc ++(Core2Duo/8600GTS)のテスト結果です。
pts vbo glb/e ratio
100 3900 3900 1.00
1k 3800 3200 1.18
10k 3600 2700 1.33
100k 1500 400 3.75
1m 213 49 4.34
10m 24 5 4.80
したがって、10mの頂点でも通常のフレームレートでしたが、glB/eでは遅くなりました。
補足として:
「ダイレクトモード」(glBegin/glEnd)は、次ではサポートされていません。
したがって、アプリケーションをモバイルプラットフォーム(iPhoneなど)に移植する予定がある場合は、それに慣れないでください。
私は大学でOpenGLを教えていますが、glBegin/glEndを説明するスライドの周りには、太字の「使用しない」ヘッダーが付いた大きな赤いボックスがあります。
頂点配列を使用すると、あと2行で、最初からサイクルを節約できます。
レッドブックを読んで、VBOの方がおそらく速いと述べた箇所を覚えていますハードウェアによって異なります。一部のハードウェアはそれらを最適化しますが、他のハードウェアは最適化しません。ハードウェアがそうではない可能性があります。
14Mpoints/sはそれほど多くはありません。疑わしいです。描画を行う完全なコードと初期化を確認できますか? (その14M/sをSlavaVishnyakovが取得する240M/s(!)と比較してください)。 1Kのドローで640K/sに低下することはさらに疑わしいです(とにかく、〜3800 SwapBuffersで制限されているように見える彼の3.8M/sと比較して)。
私は、テストがあなたがそれが測定すると思うものを測定しないに違いない。