OpenGL> = 3でVBOのみが許可されるのはなぜですか?


21

OpenGLバージョン3以降では、クライアント側レンダリングの使用が不要になりました。即時モードは廃止され、頂点配列は非推奨のようです。代わりに、私が正しく理解していれば、VBOは頂点をレンダリングする主な方法です。

すべてを均一にレンダリングする方法の背後にあるロジックを見ていますが、VBOには頂点配列に大きなマイナス面がないのですか?一般に、VBOは1 MBを超えるデータを含む大きなバッファーであると考えられていました。小さいジオメトリがたくさんあるシーンがある場合はどうなりますか?多数のノードを持つシーングラフがあり、各ノードには独自の変換などが必要です。各ノードは個別に削除したり、個別に追加したりすることもできます。以前は頂点配列を使用していました。したがって、最初の質問は、VBOに切り替えた場合、各オブジェクトにVBOを割り当てる必要があるため、シーングラフオブジェクトのオーバーヘッドが大きくなるかどうかです。

もう1つの懸念は、レンダリングするジオメトリが非常に動的になる可能性があることです。最悪の場合、すべてのジオメトリを一定期間フレームごとに再送する必要がある場合があります。この使用例では、VBOのパフォーマンスは頂点配列よりも劣りますか、それともVBOは頂点アレイと同じくらい機能しますが、それ以上は機能しませんか?

したがって、より簡潔な形式で、私の質問は次のとおりです。

1)VBOの割り当て/割り当て解除にかなりのオーバーヘッドがありますか(つまり、バッファーをセットアップするだけの行為です)。

2)フレームごとにCPUからデータを更新する場合、これは頂点配列を使用した場合よりも大幅に悪化する可能性がありますか?

そして最後に、私は知りたい:

3)上記の質問のいずれかに対する答えが「はい」の場合、なぜVBOよりも有利なレンダリングの他のモードを非推奨にするのですか?これらの潜在的な割り当てコストなどを軽減するために使用するはずのテクニックなど、ここに欠けているものはありますか?

4)これらの質問への回答は、使用しているOpenGLバージョンによって大幅に変わりますか?パフォーマンスの高い方法でVBOを使用してコードをOpenGL 3または4の上位互換にリファクタリングすると、同じ手法がOpenGL 2でうまく機能する可能性が高いか、特定の手法がOpenGL 3ではるかに高速になる可能性があります+およびOpenGL 2を使用する他のユーザー

スタックオーバーフローについてこの質問をしましたが、このサイトが私の質問に適している可能性があることに気付いたので、ここに再投稿しています。


1
投票する理由 それは二重ですか?もしそうなら、私はそれから利益を得ることができるようにリンクを見ることができますか?
重力

回答:


23

VBOの割り当て/割り当て解除にかなりのオーバーヘッドがあります(バッファーをセットアップするという単なる行為を意味します)。

「実質的」を定義します。通常、フレームの途中で作成しないのが賢明です。初期化中またはどこでもセットアップする必要があります。しかし、これは、テクスチャ、レンダーバッファー、シェーダーなど、ほとんどのOpenGLオブジェクトに当てはまります。

CPUからのデータをフレームごとに更新する場合、頂点配列を使用した場合よりも大幅に悪化する可能性がありますか?

それをできる?はい。OpenGLは、パフォーマンスではなく機能を定義します。あなたは確かに物事をずっと遅くすることができます。または、物事をより速くすることができます。それはすべてあなたがそれを使用する方法に依存します。

OpenGL Wikiには、データを適切にストリーミングする方法に関する優れた記事があります

上記の質問のいずれかに対する答えが「はい」の場合、なぜVBOよりも有利なレンダリングの他のモードを非推奨にするのですか?これらの潜在的な割り当てコストなどを軽減するために使用するはずのテクニックなど、ここに欠けているものはありますか?

まず、これらは非推奨ではありませんでした。廃止とは、将来のバージョンで何かを「削除する」とマークすることです。これらは3.0で廃止され、3.1コア以上で削除されました。

第二に、ARBは一般に、OpenGLからものを削除した理由を説明しています。これにより、スペックがより小さくシンプルになります。APIをより小さく、より合理化します。どのAPIを使用すべきかを簡単に知ることができます。2.1には、頂点データを提供する4つの方法がありました。3.1+には1があります。多くの不要なものを取り除きます。等。

これらの質問への回答は、使用しているOpenGLバージョンによって大幅に変わりますか?パフォーマンスの高い方法でVBOを使用してコードをOpenGL 3または4の上位互換にリファクタリングすると、同じ手法がOpenGL 2でうまく機能する可能性が高いか、特定の手法がOpenGL 3ではるかに高速になる可能性があります+およびOpenGL 2を使用する他のユーザー

多かれ少なかれ。MacOSXでのみ、3.1 + coreバージョンと3.0以前のバージョンの違いは本当に明らかです。互換性プロファイルは、LinuxおよびWindowsのすべてのドライバーによって実装されているため、これらのドライバーのコアプロファイルは、実際に互換性関数を呼び出さないようにチェックを追加しているだけであると想定できます。

Mac OSX 10.7では、GL 3.2コアを使用できますが、互換性プロファイルは使用できません。これは、必ずしも一方のパフォーマンステクニックと他方のパフォーマンステクニックの両方を意味するものではありません。しかし、違いがある場合、それはあなたがそれらを見るプラットフォームであることを意味します。


1
あなただけので、この質問をクロスポスト、私はちょうど私の答えをクロス投稿します。
ニコルボーラス

APIを簡潔に保つことのもう1つの利点は、OpenGL APIの実装が容易になることです。これは、元のOpenGL ES仕様では大きな考慮事項でした。
-notlesh

@stephelton:理にかなっています。「VBO以外のすべてを非推奨にする理由」の質問は、APIを無駄にしないことは完全に理にかなっていますが、多くのユースケースでVBOよりも優れている機能を非推奨にすることは理にかなっていないという考えに基づいています。私が聞いていることから、VBOを使用することには不利な点はないようですが、それ以外のすべてを非推奨にすることは完全に理にかなっています。
重力

@gravity VBOを使用する必要はありません。頂点の配列も使用できます。
notlesh

18

OpenGLの動作方法では、非VBOデータを使用するときはいつでも、ドライバーはそのコピーを作成する必要があります-実際には一時的なVBOを作成します-OpenGLの呼び出し間でユーザー空間の裸の配列を変更することはありません。

一時的な割り当てを高速化するためのドライバー側の策略があるかもしれませんが、コピーを回避するためにできることは何もありません。

ええ、あなたとドライバー開発者がすべてを正しく行う限り、VBOは常にスピードアップする必要があります。


6
私はこの答えが好きです。それは短く、要点まではもっと短いです。
TravisG

@JariKomppa:それは非常に合理的な説明のように聞こえます。私はまだ1つの懸念があります。VBOはかなり大きいオブジェクトであると想定されており、前回チェックしたときに1MBから4MBのバッファとして割り当てられることがよくありました。ジオメトリオブジェクトがそれほど大きくない場合でも、オブジェクトがたくさんあるので、パフォーマンスが気になりますか?私は、VBOが私が持っているものとは異なるユースケースのためのものであるのではないかと心配しています。複数のオブジェクトを1つのVBOにプールし、glDrawRangeElements個々のオブジェクトを描画するために使用する必要がありますか、それとも頂点配列のように非効率ですか?
重力

それが違いを生むとは思いませんが、もしそれが懸念だと感じたら、ベンチマークしてください。
ヤリコンパ

@JariKomppa:違いは何だと思いますか?glDrawRangeElements各オブジェクトに独自のVBOを与えるのではなく、いくつかのVBOで各VBO を複数回使用しますか?
重力

1
まさに。そこに大きな違いがあるとは思いませんが、いくつかのテストケースをプロファイリングすると、より多くの情報が得られるはずです。また、必要に応じて後でそのような変更を適用できるので、今は心配しません。
ジャリコンパ

9

頂点配列は非推奨のようです。代わりに、私が正しく理解していれば、

そうでもない。頂点配列は、頂点バッファーオブジェクトの基盤です。ストレージのみがクライアント側からサーバー側に移動しました。

小さいジオメトリがたくさんあるシーンがある場合はどうなりますか?

小さなジオメトリセットを大きなVBOにマージします。ジオメトリバッチごとに1つのVBOを持つ必要はありません。レンダリングのためにVBOのサブセットに完全に対処できます。gl…Pointer dataパラメータに非ゼロオフセットを使用します。

2)フレームごとにCPUからデータを更新する場合、これは頂点配列を使用した場合よりも大幅に悪化する可能性がありますか?

このために、GL_DYNAMIC_DRAWおよびGL_STREAM_DRAWバッファー使用フラグがあります。

上記の質問のいずれかに対する答えが「はい」の場合、なぜVBOよりも有利なレンダリングの他のモードを非推奨にするのですか?

利点がないからです。いずれにしても、ジオメトリデータをGPUに転送する必要があります。通常のクライアント側の頂点配列を使用すると、引き続きGPUへのDMA転送が発生し、イミディエイトモードでは最初に転送するバッチも構築されます。

VBOを使用しないことの利点はまったくありません。


したがって、VBOのパフォーマンスは頂点配列のパフォーマンスよりも一般的に悪いはずではありませんが、モードをGL_STREAM_DRAWに正しく設定した場合にのみですか?
重力

@Gravity:確かに。ただし、バッファモードは、予想される使用法に関する単なるヒントにすぎませんが、もちろん、そのヒントは、あなたがしようとしていることに忠実であるべきです。また、更新のためにバッファをプロセスのアドレス空間にマップできることを忘れないでください(glMapBuffer、glUnmapBuffer)。
datenwolf

しかし、その後、バッファをVRAMに入れることはできませんでした?または、それはまだVRAMにありますが、プロセス空間アドレスを介してアドレス指定できるだけですか?この手法を使用するとランダムアクセスは安価になりますか、それとも少数の連続した範囲のみを更新しようとする必要がありますか?
重力

@Gravity:バッファーは、読み取り専用、書き込み専用、または読み取り書き込みにマップできます。アップデートの場合は、書き込みのみを選択します。現在、最新のOSが仮想アドレス空間をどのように管理するか、つまりページメモリを通じて知ることが重要になります。書き込み専用マップの場合、DMA転送メモリの一部がマップされ、そのマップされた範囲への書き込みは多かれ少なかれ直接GPUメモリに送られます(コンテンツは最初にCPU RAMに書き込まれますが、DMAによってGPUに転送されます転送)。これは、データがクライアント側の頂点配列を通過する場合よりも直接的なパスであることが重要です。通常のプロセスメモリはDMAに適合しません
-datenwolf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.