Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Occlusion Culling

In einer 3D-Rendering-Engine ist Occlusion Culling der Prozess, bei dem verdeckte Geometrie entfernt wird.

Auf dieser Seite erfahren Sie:

  • Was sind die Vorteile und Fallstricke des Occlusion Culling?

  • Wie man Occlusion Culling in Godot einrichtet.

  • Fehlerbehebung bei häufigen Problemen mit dem Occlusion Culling.

Siehe auch

Sie können sehen, wie Occlusion Culling in Aktion funktioniert, indem Sie das Occlusion Culling and Mesh LOD Demoprojekt verwenden.

Warum Occlusion Culling verwenden?

In dieser Beispielszene mit Hunderten von nebeneinander liegenden Räumen ist ein dynamisches Objekt (rote Kugel) hinter der Wand im beleuchteten Raum (links von der Tür) versteckt:

Beispielszene mit einem Occlusion Culling-freundlichen Layout

Beispielszene mit einem Occlusion Culling-freundlichen Layout

Wenn Occlusion Culling deaktiviert ist, müssen alle Räume hinter dem beleuchteten Raum gerendert werden. Das dynamische Objekt muss ebenfalls gerendert werden:

Beispielszene mit deaktiviertem Occlusion Culling (Drahtgitter)

Beispielszene mit deaktiviertem Occlusion Culling (Drahtgitter)

Bei aktiviertem Occlusion Culling müssen nur die Räume gerendert werden, die tatsächlich sichtbar sind. Das dynamische Objekt wird ebenfalls von der Wand verdeckt und muss daher nicht mehr gerendert werden:

Beispielszene mit aktiviertem Occlusion Culling (Drahtgitter)

Beispielszene mit aktiviertem Occlusion Culling (Drahtgitter)

Da die Engine weniger Arbeit hat (weniger zu rendernde Vertices und weniger Zeichenaufrufe), steigt die Performance, solange es genügend Occlusion Culling-Möglichkeiten in der Szene gibt. Das bedeutet, dass Occlusion Culling am effektivsten in Innenraumszenen ist, vorzugsweise mit vielen kleineren Räumen anstelle von wenigen größeren Räumen. Kombinieren Sie dies mit Mesh-Level of Detail (LOD) und Reichweitenbasierte Sichtbarkeit (HLOD), um die Performance weiter zu verbessern.

Bemerkung

Bei Verwendung des Clustered Forward Rendering-Backends führt die Engine bereits einen Tiefen-Vordurchlauf durch. Dieser besteht darin, eine reine Tiefenversion der Szene zu rendern, bevor die eigentlichen Materialien der Szene gerendert werden. Dadurch wird sichergestellt, dass jedes undurchsichtige Pixel nur einen Shading-Durchlauf erfährt, was die Overdraw-Kosten erheblich reduziert.

Die größten Performance-Vorteile lassen sich bei Verwendung des Forward Mobile-Rendering-Backends beobachten, da es aus Performance-Gründen keinen Tiefen-Vordurchlauf enthält. Infolgedessen wird Occlusion Culling bei diesem Rendering-Backend das Shading-Overdrawing aktiv verringern.

Nichtsdestotrotz bietet Occlusion Culling in komplexen 3D-Szenen auch bei Verwendung eines Tiefenvordurchlaufs einen deutlichen Vorteil. In Szenen mit wenigen Occlusion Culling-Möglichkeiten lohnt sich das Occlusion Culling jedoch möglicherweise nicht wegen des zusätzlichen Einrichtungsaufwands und der CPU-Auslastung.

Wie Occlusion Culling in Godot funktioniert

Bemerkung

"Occluder" bezieht sich auf den Umriss, der etwas verdeckt, während "Occludee" sich auf das Objekt bezieht, das verdeckt wird.

In Godot funktioniert Occlusion Culling, indem die Geometrie der Szene in einen niedrig aufgelösten Puffer auf der CPU gerastert wird. Dies geschieht mit der Software-Raytracing-Bibliothek Embree.

Die Engine verwendet dann diesen niedrig aufgelösten Puffer, um die AABB der Occludees gegen die Occluder-Umrisse zu testen. Die AABB des Occluders muss vollständig vom Umriss des Occludees verdeckt werden, der aussortiert werden soll.

Daher ist die Wahrscheinlichkeit, dass kleinere Objekte effektiv verdeckt werden, höher als bei größeren Objekten. Größere Verdeckungen (z. B. Wände) sind in der Regel auch viel effektiver als kleinere (z. B. Dekorationsgegenstände).

Occlusion Culling einrichten

Der erste Schritt zur Verwendung von Occlusion Culling besteht darin, die Projekteinstellung Rendern > **Occlusion Culling > Occlusion Culling verwenden zu aktivieren. (Vergewissern Sie sich, dass die Option Erweitert im Dialogfeld Projekteinstellungen aktiviert ist, damit sie angezeigt wird).

Diese Projekteinstellung wird sofort übernommen, so dass Sie den Editor nicht neu starten müssen.

Nachdem Sie die Projekteinstellung aktiviert haben, müssen Sie noch einige Occluder erstellen. Aus Gründen der Performance verwendet die Engine nicht automatisch die gesamte sichtbare Geometrie als Grundlage für Occlusion Culling. Stattdessen benötigt die Engine eine vereinfachte Darstellung der Szene mit nur statischen Objekten, die gebacken werden sollen.

Es gibt zwei Möglichkeiten, Occluder in einer Szene einzurichten:

Manuelles Platzieren von Occludern

Dieser Ansatz eignet sich eher für spezielle Anwendungsfälle, wie z. B. die Erstellung von Okklusion für MultiMeshInstance3D-Setups oder CSG-Nodes (aufgrund der oben genannten Einschränkung).

Nachdem Sie die oben erwähnte Occlusion Culling Projekteinstellung aktiviert haben, fügen Sie einen OccluderInstance3D Node zu der Szene hinzu, die Ihre 3D-Ebene enthält. Wählen Sie den OccluderInstance3D-Node aus und wählen Sie dann in der Property Occluder einen Occluder-Typ, den Sie hinzufügen möchten:

  • QuadOccluder3D (eine einzelne Ebene)

  • BoxOccluder3D (ein Quader)

  • SphereOccluder3D (ein kugelförmiger Occluder)

  • PolygonOccluder3D (ein 2D-Polygon mit beliebig vielen Punkten)

Es gibt auch ArrayOccluder3D, dessen Punkte im Editor nicht verändert werden können, aber für die prozedurale Erzeugung aus einem Skript nützlich sein können.

Vorschau für Occlusion Culling

Sie können einen Debug-Zeichenmodus aktivieren, um zu sehen, was das Occlusion Culling tatsächlich "sieht". Klicken Sie in der oberen linken Ecke des 3D-Editor-Viewport auf den Button Perspektive (oder Orthogonal, je nach aktuellem Kameramodus) und wählen Sie dann Erweiterte Anzeige... > Occlusion Culling-Puffer. Dadurch wird der niedrig aufgelöste Puffer angezeigt, der von der Engine für Occlusion Culling verwendet wird.

Im gleichen Menü können Sie auch Informationen anzeigen und Frame-Zeit anzeigen aktivieren, um die Anzahl der Zeichenaufrufe und gerenderten Primitive (Vertices + Indizes) in der unteren rechten Ecke sowie die Anzahl der gerenderten Frames pro Sekunde in der oberen rechten Ecke anzuzeigen.

Wenn Sie Occlusion Culling in den Projekteinstellungen einschalten, während diese Informationen angezeigt werden, können Sie sehen, wie sehr Occlusion Culling die Performance Ihrer Szene verbessert. Beachten Sie, dass der Performance-Vorteil stark vom Blickwinkel der 3D-Editor-Kamera abhängt, da Occlusion Culling nur dann wirksam ist, wenn sich vor der Kamera verdeckte Objekte befinden.

Um Occlusion Culling zur Laufzeit einzuschalten, setzen Sie use_occlusion_culling im Root-Viewport wie folgt:

get_tree().root.use_occlusion_culling = true

Das Umschalten des Occlusion Culling während der Laufzeit ist nützlich, um die Performance eines laufenden Projekts zu vergleichen.

Überlegungen zur Performance

Gestalten Sie Ihre Level so, dass Sie Occlusion Culling nutzen können

Dies ist die wichtigste Richtlinie Bei einem guten Leveldesign geht es nicht nur darum, was das Gameplay erfordert, sondern es sollte auch die Occlusion berücksichtigt werden.

In Innenräumen sollten Sie undurchsichtige Wände hinzufügen, um die Sichtlinie in regelmäßigen Abständen zu "unterbrechen" und sicherzustellen, dass nicht zu viel von der Szene auf einmal zu sehen ist.

Verwenden Sie bei großen offenen Szenen nach Möglichkeit eine pyramidenartige Struktur für die Geländeerhebung. Dies bietet im Vergleich zu jeder anderen Geländeform die besten Möglichkeiten für das Culling.

Vermeiden Sie das Verschieben von OccluderInstance3D-Nodes während des Spielens

Dies schließt das Verschieben der Parent-Nodes von OccluderInstance3D-Nodes ein, da dies dazu führt, dass die Nodes selbst im globalen Raum verschoben werden und somit die BVH neu aufgebaut werden muss.

Das Umschalten der Sichtbarkeit einer OccluderInstance3D (oder der Sichtbarkeit eines ihrer Elternteile) ist weniger kostspielig, da die Aktualisierung nur einmal (und nicht ständig) erfolgen muss.

Wenn Sie beispielsweise eine Schiebe- oder Drehtür haben, können Sie dafür sorgen, dass der OccluderInstance3D-Node kein Child-Node der Tür selbst ist (so dass sich der Occluder nie bewegt), aber Sie können die Sichtbarkeit des OccluderInstance3D-Nodes ausblenden, sobald sich die Tür zu öffnen beginnt. Sie können den OccluderInstance3D-Node wieder einblenden, sobald die Tür vollständig geschlossen ist.

Wenn Sie einen OccluderInstance3D-Node während des Spiels unbedingt verschieben müssen, verwenden Sie dafür eine primitive Occluder3D-Shape anstelle einer komplexen gebackenen Shape.

Verwenden Sie möglichst einfache Occluder-Shapes

Wenn Sie in komplexen 3D-Szenen eine geringe Performance oder Stuttering feststellen, kann dies bedeuten, dass die CPU durch das Rendern detaillierter Occluder überlastet ist. Wählen Sie den OccluderInstance3D-Node, erhöhen Sie die Property Backen > Vereinfachung und backen Sie die Occluder erneut.

Achten Sie darauf, dass der Wert für die Vereinfachung angemessen ist. Werte, die für die Geometrie der Ebene zu hoch sind, können dazu führen, dass falsches Occlusion Culling auftritt, wie in Mein Occludee wird gecullt, obwohl er es nicht sollte.

Wenn dies immer noch nicht zu einer ausreichend niedrigen CPU-Auslastung führt, können Sie versuchen, die Projekteinstellung Rendern > Occlusion Culling > BVH Build-Qualität anzupassen und/oder Rendern > Occlusion Culling > Occlusion-Strahlen pro Thread zu verringern. Um diese Einstellungen zu sehen, müssen Sie die Option Erweitert im Dialogfeld Projekteinstellungen aktivieren.

Fehlersuche

Mein Occludee wird nicht gecullt, wenn er es sollte

Auf der Seite des Occluders:

Vergewissern Sie sich zunächst, dass die Property Backen > Cull-Maske in der OccluderInstance3D so eingestellt ist, dass die gewünschten Meshes gebacken werden können. Die Sichtbarkeitsebene der MeshInstance3D-Nodes muss innerhalb der Cull-Maske liegen, damit das Mesh beim Backen berücksichtigt wird.

Beachten Sie außerdem, dass beim Backen von Occludern nur Meshes mit undurchsichtigen Materialien berücksichtigt werden. Flächen mit transparenten Materialien werden nicht in das Backen einbezogen, selbst wenn die auf sie angewendete Textur vollständig undurchsichtig ist.

Schließlich ist zu beachten, dass MultiMeshInstance3D, GPUParticles3D, CPUParticles3D und CSG-Nodes beim Backen von Occludern nicht berücksichtigt werden. Als Workaround können Sie OccluderInstance3D-Nodes für diese manuell hinzufügen.

Auf der Seite des Occludees:

Vergewissern Sie sich, dass Extra Cull Margin so niedrig wie möglich eingestellt ist (normalerweise sollte es 0.0 sein), und dass Ignore Occlusion Culling im Abschnitt GeometryInstance3D des Objekts deaktiviert ist.

Überprüfen Sie auch die Größe der AABB (die durch einen orangefarbenen Kasten dargestellt wird, wenn Sie den Node auswählen). Diese achsenparallele Bounding Box muss vollständig vom Umriss des Occluders verdeckt werden, damit der Occludee ausgeblendet werden kann.

Mein Occludee wird gecullt, obwohl er es nicht sollte

Die wahrscheinlichste Ursache dafür ist, dass Objekte, die in den Occluder-Backvorgang eingeschlossen waren, nach dem Backen der Occluder verschoben wurden. Dies kann zum Beispiel passieren, wenn Sie die Geometrie Ihrer Ebene verschieben oder das Layout neu anordnen. Um dies zu beheben, wählen Sie den OccluderInstance3D-Node aus und backen Sie die Occluder erneut.

Das kann auch passieren, weil dynamische Objekte in den Backvorgang einbezogen wurden, obwohl sie es nicht sollten. Verwenden Sie den Occlusion Culling-Debug-Zeichenmodus, um nach Occluder-Shapes zu suchen, die nicht vorhanden sein sollten, und passen Sie dann die Back-Cull-Maske entsprechend an.

Die letzte mögliche Ursache für dieses Problem ist eine zu aggressive Vereinfachung des Meshes während des Backvorgangs der Occluder. Wählen Sie den OccluderInstance3D-Node aus, verringern Sie die Property Backen > Vereinfachung und backen Sie die Occluder erneut.

Als letzten Ausweg können Sie die Property Occlusion Culling ignorieren für den Occludee aktivieren. Dies hebt die Performance-Verbesserungen des Occlusion Culling für dieses Objekt auf, aber es ist sinnvoll, dies für Objekte zu tun, die nie gecullt werden (wie z. B. ein First-Person-View-Modell).