XNAのシーンマネージャーに適したデータ構造ソリューションは何ですか?


8

私は自分のゲームプロジェクトでXNAで遊んでいます。以前にOpenGLに触れ、Ogreで少し作業していたので、同じ概念をXNAで機能させようとしています。

具体的には、階層変換、錐台(場合によってはオクルージョン)カリング、および透明度オブジェクトのソートを処理するシーンマネージャーをXNAに追加しようとしています。

私の計画は、階層変換とライティングを処理するツリーシーンマネージャを構築し、錐台のカリングとオブジェクトの並べ替えにOctreeを使用することでした。問題は、透明度を正しくサポートするためにジオメトリの並べ替えを行う方法です。ポリゴンごとに並べ替えると非常にコストがかかるため、Ogreで管理することさえできないほど高価です。しかし、Ogreからの静止画像は正しく見えます。

それを行う方法、および使用するデータ構造とその機能に関するアイデアはありますか?私は周りの人々が使っていることを知っています:

  • オクトリーズ
  • Kdツリー(GameDevフォーラムの誰かが、これらはOctreesよりもはるかに優れていると言っています)
  • BSP(ポリゴンごとの順序を処理する必要がありますが、非常に高価です)
  • BVH(錐台およびオクルージョンカリングのみ)

ありがとうございました

トゥヌズ

回答:


6

オクトツリー(または単にクワッドツリー)とKdツリーはどちらも優れた汎用の空間分割スキームであり、ビルドパイプラインやエンジンがそれらを生成している場合、クエリを最適化するためのさまざまな方法で役立つことがわかります。 / iterations。これらは、固定ボリュームを階層的に細分することで機能します。これにより、オブジェクトスペースへのレイキャストのようなクエリを非常に安価にクエリできます(衝突チェックに最適)。

バウンディングボリューム階層は少し異なる方法で動作し(スペースを細分するのではなく、ツリー内のオブジェクトのボリュームを集約します)、不要なものを繰り返し処理しないようにトリミングする簡単な方法です。ただし、BVHは2つの兄弟ノードの関係に制限を設けていないため、レンダリングの順序を把握したり、任意の衝突クエリを実行したりするのに適した方法ではありません。

BSPシステムは、個々のポリゴンに基づいてワールドを細分割する場合に適していますが、大きなオブジェクトの場合は、ボリュームベースのアプローチの方が理にかなっています。

何よりも、これらのシステムはどれも、BSPのアプローチでさえ、透明度のレンダリング順序を決定するのに完璧ではないことは注目に値します。ポリゴンをその場で細分割できない限り、アルゴリズムを壊すジオメトリを構築することは常に可能です。あなたが探している可能性が最も高いのは、「ベストエフォート」ソリューションであり、ほとんどの場合、ジオメトリを正しく順序付けることができます。また、アートチームは、機能しないケースについてモデルを細分することができます(モデル/ポリゴンが異常に大きい、長い、または自己交差しているため)。小さいモデル/ノードは常に「正しく」ソートするのがはるかに簡単ですが、反復のオーバーヘッドの点で料金がかかります。

KdツリーとOct /クワッドツリーはどちらも優れた汎用ソリューションであり、プラットフォームにやさしい実装を作成できますが、最終的には、空間分割ツリーの深さ/複雑さとコストのバランスをとる必要があります。それを反復し、モデルごとのオーバーヘッド(つまり、描画呼び出しコスト)。XNAをターゲットにしている場合は、シンプルで高レベルに保つことをお勧めします。コンテンツの一部に並べ替えの問題がある場合は、コンテンツを変更してから、対応できるようになるまでエンジンを改善することを強く検討してください。最も基本的なレンダーソートが実装された後、リターンは急速に減少します。


フラグメントごとのソーティングを処理するデプスピーリングテクニックでさえ、しばしば良い結果が得られることを読んだことがあります。これは小さなゲームエンジンで実現可能だと思いますか?AAAゲームはこれらのテクニックを使用しますか?
tunnuz

KdツリーとOctreesの間で実装する方が良い/簡単だと思いますか?
tunnuz

すでに両方のC#実装が存在していなかったとしたら、私は非常に驚きます。それは、その本質(サブディビジョンとクエリ)がすべての実装で同じであるようなものですが、興味深いビットです(どのように反復/クエリ/ノードと項目を関連付けるか)はさまざまです。Oct / quadツリーは、私の考えでは概念的には単純ですが、指摘されているように、kdツリーはさまざまな点でより効率的です。私がおそらくkd-treeに行くのは、それが可能であれば、oct-treeを実行できるからです(ただし、その逆は必ずしも当てはまりません)。
MrCranky

1
フラグメントごとの並べ替えについては、エンジンについて何も知らないと言うのは難しいですが、少し時期尚早な最適化のように感じます。はい、AAAゲームはこれらの手法を使用する可能性がありますが、XNAエンジンが管理できるよりも多くのオブジェクトをシャッフルするため、最大限に活用するにはさらに極端な最適化手法が必要です。私のアドバイスは、常に基本(透過性の並べ替え)をしっかりと行うことです。パフォーマンスがまったくうまくいかないことがわかった場合は、独り占めして細かい並べ替えを行ってください。他の可能性は、最初にパフォーマンスを制限するものです。
MrCranky、2010

1
ブルートフォースを実行している間、BVツリーの使用をスキップするAAA開発者が実際にいますが、実際にクロックサイクルのほとんどを効率的に使用していることを確認して(LHS / L2 + L1キャッシュミスがないなど)、十分なパフォーマンスを提供します。うまく設計されたシステムでどれだけ多くのテストをプッシュできるかは驚くべきことです。
Simon

3

McCrankyは、あなたが言及したすべてのデータ構造を驚くほどカバーしましたが、R-Treeを検討したことがないようです。これらの構造に関する知識の本体は膨大であり、過去30年間の空間範囲クエリ(ほとんどの作業はデータベース理論家や実務家によって行われました)に非常に適しています。最近、RareのSebastian Sylvainが、GDCがなぜゲームでも機能するのかについて(特に、順序付けされたプロセッサを備えたコンソールで)GDCに関するコースを提供しました。あなたはそのPDFからさらに学ぶことができます:http//www.gdcvault.com/play/1012452/R-Trees-Adapting-out-of

素朴でシンプルな実装は非常に簡単で、基本的な構造により、改善の余地がたくさんあります(分割ヒューリスティックスの管理、機会のプリフェッチ、並列検索など)。


2

答えは、使用する予定のモデルの量に大きく依存します。私はXNAでこの種のことを実際に行ったことはありませんが、テストにAABBを使用し、モデルが多すぎない場合は、ブルートフォーステストで十分な場合があります。おそらくそれをスレッドに捨てることさえできるでしょう。C#に使用できるSSE / VMX最適化がどのように/あるかどうかはわかりませんが、AABBをメモリ内でリニアに取得できれば(CPUのキャッシュミスが発生しないように)、できるはずです。非常に短い時間で大量のテストを実行します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.