Stand der Technik Culling und Batching-Techniken beim Rendern

8

Ich arbeite gerade an der Aktualisierung und Umstrukturierung einer OpenGL-Render-Engine. Die Engine wird verwendet, um große Szenen von architektonischen Daten (Gebäude mit Innenräumen) zu visualisieren, und die Anzahl von Objekten kann ziemlich groß werden. Wie bei jedem Gebäude gibt es viele eingeschlossene Objekte in Wänden, und Sie sehen natürlich nur die Objekte, die sich im selben Raum befinden wie Sie, oder das Äußere, wenn Sie sich auf der Außenseite befinden. Dies hinterlässt eine große Anzahl von Objekten, die durch Okklusions-Culling und Frustum-Culling verschlossen werden sollten.

Gleichzeitig gibt es viele Wiederholungsgeometrien, die in Render-Batches zusammengefasst werden können, sowie viele Objekte, die mit instanziertem Rendering gerendert werden können.

Wie ich es sehe, kann es schwierig sein, Renderbatching und Culling auf optimale Weise zu kombinieren. Wenn Sie zu viele Objekte in derselben VBO ablegen, ist es schwierig, die Objekte auf der CPU zu entfernen, um das Rendern des Stapels zu überspringen. Zur gleichen Zeit, wenn Sie die Culling auf der CPU überspringen, werden viele Objekte von der GPU verarbeitet, während sie nicht sichtbar sind. Wenn Sie das Batching einfach überspringen, um einfacher auf der CPU zu cullen, wird es eine ungewollte Menge an Renderaufrufen geben.

Ich habe einige existierende Techniken und Theorien erforscht, wie diese Probleme in modernen Grafiken gelöst werden, aber ich konnte keine konkrete Lösung finden. Eine Idee, die ein Kollege und ich uns ausgedacht hatten, war die Beschränkung von Chargen auf Objekte, die relativ nahe beieinander lagen, z. B. alle Stühle in einem Raum oder in einem Radius von n Meetern. Dies könnte durch Verwendung von Oktbäumen vereinfacht und optimiert werden.

Hat jemand irgendwelche Hinweise auf Techniken, die für Szenenmanagement, Culling, Batching etc. in modernen Grafik-Engines verwendet werden?

    
Kristian Skarseth 21.06.2013, 10:38
quelle

1 Antwort

5

Es gibt viele Informationen über Kegelstümpfe und Okklusion im Internet. Das meiste kommt von Spieleentwicklern. Hier ist eine Liste mit einigen Artikeln, die Sie zum Einstieg bringen werden:

Mein (ziemlich schneller) Renderer funktioniert ähnlich wie dieser:

  1. Sammlung : Senden Sie alle Requisiten, die Sie rendern möchten, an den Renderer.
  2. Frustum culling : Der Renderer entfernt die unsichtbaren Requisiten aus der Liste mit mehreren parallelen Threads.
  3. Occlusion culling : Jetzt könntest du Okklusions-Culling auf der CPU durchführen (ich habe es noch nicht implementiert, weil ich es jetzt nicht brauche). Detaillierte Informationen dazu, wie man es effizient macht, finden Sie in den Folien Killzone und Crysis. Eine Lösung wäre, den Tiefenpuffer des vorherigen Rahmens von der GPU zurückzulesen und dann die Begrenzungsrechtecke der Objekte darüber zu rastern, um zu prüfen, ob das Objekt sichtbar ist.
  4. Teilen : Da Sie jetzt wissen, welche Objekte tatsächlich gerendert werden müssen, müssen Sie sie nach Gitter aufteilen, da jedes Gitter ein anderes Material oder eine andere Textur hat (sonst würden sie zu ein einzelnes Netz).
  5. Batching : Jetzt haben Sie eine Liste von zu rendernden Meshes. Sie können sie sortieren:
    • nach Tiefe (dies kann auf der Prop-Ebene anstelle der Mesh-Ebene erfolgen), um die Füllrate zu speichern (ich empfehle das nicht, wenn Ihre Fragment-Shader sehr einfach sind).
    • nach Mesh (weil es mehrere Instanzen desselben Meshes geben könnte und es das Hinzufügen von Instances erleichtern würde).
    • nach Textur, weil Texturschalter sehr teuer sind.
  6. Rendern : Durchläuft Ihre partitionierten Meshes und rendert sie.

Und als "Full Frontal Nacktheit" schon gesagt: Es gibt keine perfekte Lösung.

    
Tara 02.05.2014 12:23
quelle