Was ist eine gute Datenstrukturlösung für einen Szenenmanager in XNA?

8

Ich spiele mit XNA für ein Spielprojekt von mir selbst, hatte zuvor Kontakt zu OpenGL und habe ein bisschen mit Ogre gearbeitet, also versuche ich, die gleichen Konzepte für XNA zum Laufen zu bringen.

Insbesondere versuche ich, XNA einen Szenenmanager hinzuzufügen, um hierarchische Transformationen, Kegelstumpf (möglicherweise sogar Okklusion) und Transparenzobjektsortierung zu handhaben.

Mein Plan war es, einen Baumszenenmanager für hierarchische Transformationen und Beleuchtung zu erstellen und dann einen Octree für das Ausstoßen von Stumpf und das Sortieren von Objekten zu verwenden. Das Problem ist, wie die Geometriesortierung durchgeführt wird, um Transparentfolien korrekt zu unterstützen. Ich weiß, dass das Sortieren sehr teuer ist, wenn es pro Polygon durchgeführt wird, so teuer, dass es nicht einmal von Ogre verwaltet wird. Aber Standbilder von Ogre sehen richtig aus.

Irgendwelche Ideen, wie es geht und welche Datenstrukturen verwendet werden sollen und welche Funktionen sie haben? Ich weiß, dass die Leute in der Umgebung Folgendes verwenden:

  • Octrees
  • Kd-Bäume (jemand im GameDev-Forum sagte, dass diese weitaus besser sind als Octrees)
  • BSP (das die Bestellung pro Polygon abwickeln sollte, aber sehr teuer ist)
  • BVH (aber nur für Kegelstumpf- und Okklusions-Keulung)

Vielen Dank

Tunnuz

tunnuz
quelle

Antworten:

6

Octtrees (oder auch nur Quadtrees) und Kd-Bäume sind gute allgemeine räumliche Partitionierungsschemata. Wenn Ihre Build-Pipeline und / oder Engine sie generiert, werden Sie feststellen, dass sie auf vielfältige Weise zur Optimierung von Abfragen nützlich sind / Iterationen. Sie arbeiten, indem sie ein festes Volume hierarchisch unterteilen, wodurch Abfragen wie Raycasting in Ihren Objektbereich sehr kostengünstig abzufragen sind (ideal für Kollisionsprüfungen).

Begrenzte Volumenhierarchien funktionieren auf etwas andere Weise (sie aggregieren die Volumina der Objekte im Baum, anstatt Räume zu unterteilen) und sind eine einfache Möglichkeit, unnötige Dinge von der Iteration abzuhalten. Da der BVH jedoch keine Einschränkungen hinsichtlich der Beziehung zwischen zwei Geschwisterknoten festlegt, ist dies kein so gutes Schema zum Ermitteln der Renderreihenfolge oder für beliebige Kollisionsabfragen.

BSP-Systeme sind gut, wenn Sie die Welt anhand einzelner Polygone unterteilen. Bei größeren Objekten ist ein volumenbasierter Ansatz jedoch sinnvoller.

Vor allem aber ist anzumerken, dass keines dieser Systeme perfekt für die Bestimmung der Renderreihenfolge für Transparenz geeignet ist, selbst der BSP-Ansatz. Es wird immer möglich sein, Geometrie zu konstruieren, die Ihren Algorithmus bricht, es sei denn, Sie können Polygone im laufenden Betrieb unterteilen. Was Sie höchstwahrscheinlich suchen, ist eine Best-Effort-Lösung, bei der die Geometrie in den meisten Fällen korrekt bestellt werden kann. und das Kunstteam kann Modelle für jeden Fall unterteilen, der nicht funktioniert (weil das Modell / die Polygone ungewöhnlich groß, lang oder sich selbst überschneidend sind). Kleinere Modelle / Knoten sind immer viel einfacher zu sortieren, aber Sie zahlen dafür in Bezug auf den Iterationsaufwand.

Kd-Bäume und Okt / Quad-Bäume sind beide gute Allzwecklösungen, für die eine plattformfreundliche Implementierung geschrieben werden kann, aber am Ende müssen Sie die Tiefe / Komplexität Ihres räumlichen Partitionierungsbaums gegen die Kosten von abwägen Iteration und der Overhead pro Modell (dh Anrufkosten ziehen). Wenn Sie auf XNA abzielen, würde ich empfehlen, es einfach und auf hohem Niveau zu halten. Wenn bei einigen Inhalten Sortierprobleme auftreten, sollten Sie den Inhalt unbedingt ändern, bevor Sie versuchen, Ihre Engine zu verbessern, bis er damit fertig wird. Die Renditen verringern sich sehr schnell, nachdem die grundlegendste Render-Sortierung implementiert wurde.

MrCranky
quelle
Ich habe gelesen, dass selbst Tiefenschältechniken zur Sortierung pro Fragment oft gute Ergebnisse erzielen. Denken Sie, dass dies mit einer kleinen Spiel-Engine möglich ist? Verwenden AAA-Spiele diese Techniken?
Tunnuz
Was ist Ihrer Meinung nach besser / einfacher zwischen Kd-Bäumen und Octrees zu implementieren?
Tunnuz
Es würde mich sehr wundern, wenn es für beide noch keine C # -Implementierung gäbe: Es ist die Art von Sache, bei der das Fleisch davon (die Unterteilung und die Abfrage) für alle Implementierungen gleich ist, aber die interessanten Teile (Wie iterieren / abfragen / verknüpfen Sie Elemente mit den Knoten) kann variieren. Okt / Quad-Bäume sind meiner Meinung nach konzeptionell einfacher, aber wie bereits erwähnt, sind KD-Bäume in vielerlei Hinsicht effizienter. Ich würde wahrscheinlich kd-tree gehen, nur weil, wenn du das kannst, du Oct-Tree machen kannst (aber das Gegenteil ist nicht unbedingt der Fall).
MrCranky
1
Was die Sortierung nach Fragmenten betrifft: Ohne etwas über Ihre Engine zu wissen, ist es schwer zu sagen, aber es fühlt sich wie eine vorzeitige Optimierung an. Ja, AAA-Spiele verwenden möglicherweise diese Techniken, aber sie mischen auch mehr Objekte, als eine XNA-Engine verwalten kann, und erfordern daher extremere Optimierungstechniken, um das Beste daraus zu machen. Mein Rat wäre immer, die Grundlagen (Transparenz-Sortierung) solide zu machen, und wenn Sie feststellen, dass die Leistung einfach nicht auf dem neuesten Stand ist, dann gehen Sie das ganze Schwein und machen Sie eine feinkörnigere Sortierung. Die Chancen stehen gut, dass etwas anderes zuerst die Leistung einschränkt.
MrCranky
1
Es gibt tatsächlich AAA-Entwickler, die die Verwendung von BV-Bäumen überspringen, da sie dies mit Brute-Force tun, während sie sicherstellen, dass Sie die meisten Taktzyklen tatsächlich effizient nutzen (keine LHS / L2 + L1-Cache-Fehler usw.), die eine ausreichend gute Leistung bieten. Es ist erstaunlich, wie viele Tests Sie mit einem gut gestalteten System durchführen können.
Simon
3

McCranky deckte erstaunlicherweise alle von Ihnen erwähnten Datenstrukturen ab, aber ich sehe, dass Sie nicht an R-Trees gedacht haben. Das Wissen über diese Strukturen ist riesig und sie eignen sich sehr gut für räumliche Bereichsabfragen (die meisten Arbeiten wurden von Datenbanktheoretikern und -praktikern in den letzten 30 Jahren durchgeführt). Kürzlich hat Sebastian Sylvain von Rare einen Kurs über die GDC gegeben, warum sie auch für Spiele arbeiten (insbesondere auf Konsolen mit in-order-Prozessoren). Sie können mehr aus dem PDF erfahren: http://www.gdcvault.com/play/1012452/R-Trees-Adapting-out-of

Eine naive und einfache Implementierung ist ziemlich einfach, und die Grundstruktur bietet viel Raum für Verbesserungen (bessere Verwaltung der Aufteilungsheuristik, Vorabrufmöglichkeiten, parallele Suche usw.).

Roter Ritter
quelle
2

Die Antwort hängt stark von der Anzahl der Modelle ab, die Sie verwenden möchten. Ich habe für XNA nicht wirklich mit solchen Dingen gearbeitet, aber wenn Sie AABBs für die Tests verwenden und nicht zu viele Modelle haben, sind Sie mit einem Brute-Force-Test möglicherweise gut genug. Vielleicht sogar auf einen Faden werfen. Ich bin nicht sicher, wie / ob es SSE / VMX-Optimierungen gibt, die für C # verwendet werden können, aber wenn Sie es schaffen, die AABBs linear im Speicher abzurufen (damit Sie keine Cache-Fehler für die CPU erhalten), sollten Sie in der Lage sein eine große Anzahl von Tests in kürzester Zeit durchzusetzen.

Simon
quelle