In diesem Beitrag schauen wir uns die Verwendung von Packed Level Actors für Unreal Engine an, um die Performance beim Rendern mehrerer Instanzen eines Meshes zu verbessern.
Es ist entscheidend, mit den begrenzten verfügbaren Ressourcen effizient umzugehen, wenn man für VR/MR-Headsets entwickelt, die über ziemlich begrenzte Hardware verfügen. Beispielsweise erwähnt Meta Beispielbereiche von 200 - 1000 Draw-Calls und 1,3 Mio. - 1,8 Mio. Dreiecke für eine Quest 3/3s, abhängig von der CPU-Nutzung der Anwendung.
Tech Stack
Für diese Erkundung verwenden wir den folgenden Tech Stack:
Packed Level Actors
Ein Packed Level Actor aggregiert ausgewählte Meshes/Actors in einem einzigen Level/Blueprint unter Verwendung von Instanced Static Mesh Components, siehe Unreal Engine Dokumentation für Details zur Erstellung eines Packed Level Actors.
Der Hauptzweck ist die Optimierung der Performance (durch die Verwendung von Instanced Static Mesh Components, die einen einzigen Draw-Call verwenden, auch wenn mehrere Instanzen desselben Meshes pro Material gerendert werden), und möglicherweise die bequemere Platzierung bestimmter Mesh-Kompositionen mehrfach in einem Level.
Mehrere Packed Level Actor Instanzen in einem einzigen Level
Nach einigen Tests scheint es, dass Unreal Engine mehrere Instanzen eines Packed Level Actors nicht automatisch aggregiert, wenn sie in einem Level platziert werden, was die Performance verbessern würde, indem die benötigten Draw-Calls reduziert werden.
Wir haben das folgende Testszenario verwendet:
- Einen Packed Level Actor mit einer einzelnen Instanced Static Mesh Component mit 1 Instanz für ein Gebäudesegment von etwa 1,8k Dreiecken mit 4 LODs
- Diesen Packed Level Actor 550 Mal in einem Level platzieren
- Die Anzahl der Draw-Calls und gerenderten Dreiecke im Level beobachten, indem das
stat unitDebug-Tool verwendet wird (DrawsundPrimsWerte)
Das Ergebnis ist im folgenden Bild zu sehen.

Das Ergebnis ist ziemlich schlecht, da jede Packed Level Actor Instanz zu 1 Draw-Call führt. Zumindest werden die richtigen LODs für jede Instanz verwendet, was die Anzahl der gerenderten Dreiecke deutlich unter das Maximum von 990k reduziert.
Zusammenführen mehrerer Packed Level Actor Instanzen in einem einzigen Level
In einem Versuch, diese Situation zu verbessern, haben wir einen Blueprint Actor erstellt, der identische Packed Level Actor Instanzen zur Laufzeit zusammenführt, indem die verwendeten Meshes und Materialien verglichen werden.
Der Blueprint macht im Wesentlichen Folgendes:
- Iteriere über alle Packed Level Actors im Level
- Iteriere über jede Instanced Static Mesh Component im Packed Level Actor (
source-component)- Wenn wir bereits eine andere Instanced Static Mesh Component für dasselbe Mesh/Materialien haben, füge alle Instanzen aus der
source-componentzu dieser Component hinzu - Wenn wir noch keine andere Instanced Static Mesh Component für dasselbe Mesh/Materialien haben, verwende die
source-componentfür das nächste Mal
- Wenn wir bereits eine andere Instanced Static Mesh Component für dasselbe Mesh/Materialien haben, füge alle Instanzen aus der
- Iteriere über jede Instanced Static Mesh Component im Packed Level Actor (
Das Ergebnis ist im folgenden Bild zu sehen.

Die Anzahl der Draw-Calls wurde deutlich reduziert (wie erwartet), aber die Anzahl der Dreiecke hat deutlich zugenommen, was ziemlich schlecht ist. Der Grund ist, dass die verwendete Instanced Static Mesh Component das LOD für die nächste Instanz auswählt und dieses verwendet, um alle Instanzen zu rendern, egal wie weit entfernt sie sein mögen.
Der Hauptnachteil dieser Lösung ist, dass sie nicht mit Baked Lighting funktioniert, da das Ergebnis schrecklich aussehen wird. Für dynamisch generierte Level mit dynamischem Licht funktioniert es jedoch wirklich gut.
Bei Verwendung von Baked Lighting kann man stattdessen manuell einen Packed Level Actor erstellen, der alle anderen Packed Level Actors im Level enthält. Unreal Engine unterstützt verschachtelte Packed Level Actors und aggregiert alles korrekt in (Hierarchical) Instanced Static Meshes.
Verwendung von Hierarchical Instanced Static Mesh Components
In einem Versuch, diese Situation zu verbessern, haben wir die Instanced Static Mesh Component im Packed Level Actor Blueprint durch eine Hierarchical Instanced Static Mesh Component mit denselben Attributen ersetzt. Dies fügt einen leichten Overhead hinzu, aber es wird das richtige LOD für jede Instanz auswählen, was die Anzahl der gerenderten Dreiecke deutlich reduzieren kann, auf Kosten einiger zusätzlicher Draw-Calls.
Das Ergebnis ist im folgenden Bild zu sehen.

Dieses Ergebnis ist ziemlich gut, wenn man bedenkt, wie viele Meshes gerendert werden.
Fazit
Während der Entwicklung ist es wichtig, die Performance zu überwachen, besonders für VR/MR angesichts der begrenzten verfügbaren Hardware. Durch die Erstellung eines Blueprint Actors zum Zusammenführen identischer Packed Level Actors und die Verwendung von Hierarchical Instanced Static Mesh Components können wir deutlich mehr und detailliertere Meshes in einem Level verwenden, während die Performance auf akzeptablem Niveau bleibt.
In diesem Beispielszenario haben wir die Anzahl der Draw-Calls von 559 auf 14 reduziert, während wir weiterhin LODs berücksichtigen, um die Anzahl der Dreiecke bei etwa 130k zu halten, indem wir einen Blueprint Actor erstellen, der Packed Level Actor Instanzen zur Laufzeit zusammenführt, und Hierarchical Instanced Static Mesh Components verwenden.
| Szenario | Draw-Calls | Dreiecke |
|---|---|---|
| 550 einzelne Packed Level Actors | 559 | 130k |
| Zusammenführen von 550 Packed Level Actors mit ISM | 10 | 995k |
| Zusammenführen von 550 Packed Level Actors mit HISM | 14 | 127k |
Wir bei Immerstory sind begeistert, unsere Kunden bei ihren immersiven Erfahrungen zu unterstützen, und freuen uns darauf, bald weitere Erkundungsfortschritte zu teilen.
Welche immersieve Erfahrung würdest du gerne sehen? Lass es uns wissen!

