Wie organisieren kommerzielle Spiele-Engines die Index- / Vertex-Puffer?


8

Vorwort: Diese Frage wird aus Direct3D-Sicht gestellt, weil ich damit vertraut bin.

Offensichtlich entsteht jedes Mal ein leichter Overhead, wenn wir den Vertex- oder Indexpuffer in Direct3D ändern (dh mit IASetIndexBuffer). Aber ich nehme an, wenn wir einen riesigen Index- / Scheitelpunktpuffer zuweisen, müssen wir den Speicher manuell verwalten und haben ein Fragmentierungsproblem (oder eine Pause, während wir alle Daten austauschen).

Wie laden / entladen kommerzielle Motoren Daten? Ich neige eher zu einem "Paket" -basierten Ansatz, daher hat ein "Paket" von Modellen einen eigenen Vertex / Index-Puffer, den wir laden / entladen können, da das Paket nicht mehr benötigt wird. und versuchen Sie dann, alle Instanzen aus demselben Paket zusammen zu zeichnen.

Aber würde mich interessieren, was die akzeptierte / übliche Art ist, damit umzugehen?


1
Dies ist eine gute Frage und gilt auch für OpenGL.
Glampert

Antworten:


13

Es gibt verschiedene Techniken zum Organisieren der Daten, und viele Spiele verwenden eine Mischung aus diesen.

Für statische Geometrie ist es am besten, weniger einzelne IBs und VBs zu haben.

Traditionell basieren Spiele auf Levels, was bedeutet, dass die Assets für einen Teil des Spiels geladen werden und dann das Spiel beginnt. Um die Ladezeiten zu minimieren, sind die Informationen ideal organisiert, um dies zu unterstützen (dh alles für die Ebene so schnell wie möglich zu laden, ohne auf dem Medium / der Festplatte herumzusuchen) und möglicherweise Informationen zwischen den Ebenen zu replizieren. Bei diesem Ansatz besteht ein Schema darin, einen großen VB und IB für ein Modell oder eine Reihe von Modellen zu haben und dann Teilmengen davon zum Zeichnen einzureichen.

Bei der Xbox 360 / PS 3-Generation war die RAM-Größe im Verhältnis zur Größe der Spiele recht gering, sodass die Engines "Streaming" -orientiert wurden, was bedeutet, dass sie Inhalte dynamisch laden, während sich der Spieler durch sie bewegt. Dies wird auch als "Open-World" -Ansatz bezeichnet. Bei diesem Ansatz besteht die Herausforderung darin, die Geometrie in Bits zu zerlegen, die Sie basierend auf räumlichen Hinweisen laden können. Eine weitere Herausforderung, insbesondere für 32-Bit-Plattformen, besteht darin, sicherzustellen, dass der Speicher über einen langen Zeitraum nicht fragmentiert wird (oder sogar der virtuelle Adressraum fragmentiert wird). Level-basierte Spiele setzen häufig den Speicher zwischen den Ebenen zurück, was Streaming-Engines nicht können so leicht. Daher ist es hilfreich, die IBs / VBs, die zugewiesen und als Pool wiederverwendet wurden, in eine feste Größe oder einen Satz fester Größen zu packen.

Für die Xbox One / PS 4-Generation gibt es im Vergleich zu früheren Konsolen viel RAM und viele zusätzliche Kerne, so dass viele Spiele ihre Assets aggressiv komprimieren und dann "zusätzliche" CPU-Kerne verwenden, um sie in der zu dekomprimieren Hintergrund. Beim virtuellen 64-Bit-Adressraum gibt es weniger Bedenken hinsichtlich der Fragmentierung des virtuellen Adressraums. Dieser Ansatz hält die Ladezeiten niedrig, packt Assets gut für den digitalen Download und unterstützt das Rendern in der offenen Welt. Hier wird der Pool-Ansatz zur Verwaltung von IBs / VBs verwendet.

Es gibt auch eine dynamische Geometrieübermittlung, die häufig für Gelände, verformbare / zerstörbare Modelle usw. verwendet wird. Sie ist in Bezug auf die GPU-Busbandbreite nicht effizient, sodass Spiele häufig eine Mischung aus statischer und dynamischer Geometrie aufweisen. In diesem Fall bedeutet das Direct3D Map DISCARD-Aktualisierungsmuster normalerweise, dass Sie nur einen einzelnen IB / VB verwenden (oder für Multithread-Rendering-Szenarien zwei IB / VB, bei denen Sie das Füllen / Rendern jedes Frames austauschen).


Danke für deine Antwort. Darf ich einige klärende Fragen stellen? Was ist das Direct3D Map DISCARD-Muster?
Xenoprimate

1
Das Muster wird hier für Direct3D 9 als Lock DISCARD beschrieben, aber dieses Muster wird mit Direct3D 10.x / 11.x sowie Map DISCARD für dynamische Ressourcen verwendet. Ein Beispiel dafür, wie dies für Direct3D 11 implementiert wird, finden Sie in der PrimitiveBatch-Klasse von DirectX Tool Kit .
Chuck Walbourn
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.