Wie kann ich eine Szene strahlen, die nicht in den Speicher passt?

11

Wenn die zu strahlende Szene nicht im Speicher gespeichert werden kann, erscheint es unrealistisch, sie ohne Hinzufügen von mehr RAM zum Computer in einer praktischen Zeitspanne zu rendern, da verschiedene Teile der Szene möglicherweise mehrmals pro Pixel von der Festplatte geladen werden müssen .

Gibt es einen Weg daran vorbei? Ich versuche mir eine Möglichkeit auszudenken, eine große Anzahl von Berechnungen mit einer bestimmten Teilmenge der Szene gleichzeitig durchzuführen, um die Häufigkeit zu verringern, mit der sie in den Speicher geladen werden muss. Gibt es in einem solchen Fall eine andere Möglichkeit, die Geschwindigkeit zu verbessern?

Trichoplax
quelle

Antworten:

10

Wenn die Szene nicht vollständig in den Speicher passt, betreten Sie das Feld des Out-of-Core-Renderings. Hier gibt es im Wesentlichen zwei Ansätze: a) Generieren Sie Ihre Szene bei Bedarf. B) Laden Sie Ihre Szene bei Bedarf

Der erstere Ansatz passt gut zu den meisten Animationsworkflows, bei denen Modelle beispielsweise mit Catmull-Clark stark unterteilt sind und sehr speicherintensiv werden können, die Basisnetze selbst jedoch leicht in den Speicher passen. Pixar hat einige Artikel dazu (z. B. Ray Differentials und Multiresolution Geometry Caching für die Verteilung von Verteilungsstrahlen in komplexen Szenen ), aber das Wesentliche ist, dass Modelle nur dann unterteilt werden, wenn sie von einem Strahl getroffen werden, und nur so weit unterteilt werden, wie sie sind angemessen für einen solchen Strahl (z. B. diffuse Interreflexion erfordern weniger Genauigkeit als Spiegelreflexionen). Der Rest wird von einem Geometrie-Cache erledigt, der die unterteilten Modelle im Speicher hält und den Prozess hoffentlich durch eine gute Räumungsstrategie effizient macht.

Solange alle Ihre Basisnetze bequem in den Speicher passen, können Sie leicht aus dem Kern herausgehen und Netze auf Unterteilungsebenen rendern, die niemals in den Speicher passen würden. Der Geometrie-Cache lässt sich auch gut mit dem verfügbaren Speicher skalieren, sodass Sie RAM und Renderzeiten abwägen können. Dies wurde auch in Autos verwendet, glaube ich.

Der zweite Ansatz ist allgemeiner und beruht nicht auf einer starken Verwendung der Unterteilung. Stattdessen beruht es auf der Tatsache, dass Ihre Szene höchstwahrscheinlich von einem Künstler erstellt wurde und bereits in relativ kleine Objekte unterteilt ist, die individuell in das Gedächtnis passen. Die Idee ist dann, zwei Hierarchien beizubehalten (kD-Baum- oder Begrenzungsvolumenhierarchie): Eine Hierarchie der obersten Ebene, in der nur Begrenzungsrahmen der Objekte in Ihrer Szene gespeichert sind, und eine Hierarchie auf niedriger Ebene, in der die tatsächliche Geometrie gespeichert ist. Für jedes Objekt gibt es eine solche Hierarchie auf niedriger Ebene.

Bei diesem Ansatz speichern Sie idealerweise bereits einen Begrenzungsrahmen zusammen mit jedem Objekt auf der Festplatte. Während die Szene geladen wird, erstellen Sie zunächst nur die Hierarchie der obersten Ebene, dh Sie müssen nur die Begrenzungsrahmen und nicht die Geometrie betrachten. Anschließend verfolgen Sie die Strahlen und durchlaufen sie durch die Hierarchie. Immer wenn ein Strahl auf einen Blattknoten in der Hierarchie der obersten Ebene trifft (dh auf den Begrenzungsrahmen eines Objekts trifft), wird dieses Objekt in den Speicher geladen und seine Hierarchie auf niedriger Ebene erstellt. Der Strahl fährt dann fort, dieses Objekt zu verfolgen. In Kombination mit einem Objektcache, der so viel wie möglich von der Hierarchie auf niedriger Ebene im Speicher behält, kann dies eine recht gute Leistung erbringen.

Der erste Vorteil eines solchen Ansatzes besteht darin, dass Objekte, die niemals getroffen werden, niemals geladen werden, was bedeutet, dass sie sich automatisch an die Sichtbarkeit in Ihrer Szene anpassen. Der zweite Vorteil ist, dass Sie, wenn Sie viele Strahlen verfolgen, ein Objekt nicht sofort laden müssen, da es von einem Strahl getroffen wird. Stattdessen können Sie diesen Strahl halten und warten, bis genügend Strahlen auf dieses Objekt getroffen haben, wodurch sich die Last über mehrere Strahlentreffer amortisiert.

Sie können diesen Ansatz auch mit einem Strahlensortierungsalgorithmus wie " Sortierte verzögerte Schattierung" für die Verfolgung von Produktionspfaden kombinieren , um ein Verprügeln aufgrund inkohärenter Strahlen zu vermeiden. Das erwähnte Papier beschreibt die Architektur von Disneys Hyperion-Renderer, der meiner Meinung nach für Big Hero 6 verwendet wird, sodass er höchstwahrscheinlich Szenen im Produktionsmaßstab verarbeiten kann.

Benedikt Bitterli
quelle
1
Das ist super interessant! So ist das Disney-Papier, das Sie verlinkt haben.
John Calsbeek
+1 So viele Antworten auf Dinge, über die ich mich immer gewundert habe!
Rotem
7

Wenn Sie Ihre Szene in einer räumlichen Struktur organisieren (die übliche Art ist eine Bounding Volume-Hierarchie ), können Sie eine Art virtuelle Szene verwenden (ich mache diesen Begriff in Bezug auf virtuelle Texturen ).

Ein Speichermanager würde nur eine begrenzte Anzahl von Begrenzungsrahmen gleichzeitig laden und die Operation abstrahieren, die darin besteht, einen abzurufen.

Auf diese Weise wird eine Box nur nach Bedarf geladen: Wenn ein Strahl auf eine Begrenzungsbox trifft, wird die Box geladen, um die Kollision zu beheben. Wenn später eine andere Box geladen werden muss, wird die nicht verwendete gelöscht, um Platz für die neue zu schaffen.

Wenn all diese Boxen geladen und gelöscht werden, ist die Strahlenkohärenz ein wichtiger Geschwindigkeitsfaktor. Ich nehme an, eine weitere Verbesserung könnte darin bestehen, das Laden zu verschieben, indem die Strahlen neu angeordnet werden, um zuerst die bereits geladenen Kisten zu behandeln.

Julien Guertault
quelle
Ja so etwas.
Joojaa
1

Was Sie tun, ist, dass Sie Dreiecke von der Festplatte in den Speicher laden, basierend auf dem, was zuvor getroffen wurde. Sie können zuerst mit Dreiecken in unmittelbarer Nähe beginnen. Der Grund dafür ist, dass in einem Bereich die Strahlen wahrscheinlich wiederholt auf dieselben Dreiecke treffen. Und irgendwann werden Sie etwas effizienter. (Aus diesem Grund ist es eine gute Idee, das Dreieck des letzten Treffers in der Okklusionsverfolgung zwischenzuspeichern, die sich nicht um die Reihenfolge kümmert.)

Zweitens speichern Sie die Dreiecke in einem räumlichen Baum, mit dem Sie schnell von der Festplatte aus suchen können, um zu erneuern, welche Teile sich im Speicher befinden. Laden Sie also nur Zweige, die dem Strahl im Weg stehen. Wenn es sich um eine Art Voxelbaum handelt, wie ein Octree, können Sie sogar Sekundärstrahlen sortieren und durch Kohärenz lösen. Ein BSP-Baum eignet sich auch gut zum Beschneiden von Bereichen.

Es gibt Fälle, in denen dies fehlschlägt, aber in den meisten Szenenbereichen einigermaßen effizient ist, wenn Sie kein Rauschen rendern ...

joojaa
quelle