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?
quelle
Antworten:
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).
quelle