Devlog: Packed Level Actors voor Unreal Engine

Devlog: Packed Level Actors voor Unreal Engine

Thijs ReusThijs Reus
·14 november 2025·7 min. leestijd
Let op: dit bericht is automatisch vertaald.

In dit bericht kijken we naar het gebruik van Packed Level Actors voor Unreal Engine om de prestaties te verbeteren bij het renderen van meerdere instanties van een mesh.

Het is cruciaal om efficiënt om te gaan met de beperkte beschikbare resources bij het ontwikkelen voor VR/MR-headsets, die vrij beperkte hardware hebben. Bijvoorbeeld, Meta vermeldt voorbeeldbereiken van 200 - 1000 draw-calls en 1,3 m - 1,8 m driehoeken voor een Quest 3/3s, afhankelijk van het CPU-gebruik van de applicatie.

Tech Stack

Voor deze verkenning gebruiken we de volgende tech stack:

Packed Level Actors

Een Packed Level Actor aggregeert geselecteerde meshes/actors in een enkel Level/Blueprint met behulp van Instanced Static Mesh Components, zie Unreal Engine documentatie voor details over het maken van een Packed Level Actor.

Het hoofddoel is om de prestaties te optimaliseren (door het gebruik van Instanced Static Mesh Components, die een enkele draw-call gebruiken, zelfs bij het renderen van meerdere instanties van hetzelfde mesh per materiaal), en mogelijk het handiger maken om bepaalde mesh-composities meerdere keren in een level te plaatsen.

Meerdere Packed Level Actor instanties in een enkel level

Na enige tests blijkt dat Unreal Engine meerdere instanties van een Packed Level Actor niet automatisch aggregeert wanneer ze in een level worden geplaatst, wat de prestaties zou verbeteren door de benodigde draw-calls te verminderen.

We hebben het volgende testscenario gebruikt:

  • Een Packed Level Actor met een enkele Instanced Static Mesh Component met 1 instantie voor een gebouwsegment van ongeveer 1,8k driehoeken met 4 LODs
  • Deze Packed Level Actor 550 keer in een level plaatsen
  • We observeren het aantal draw-calls en gerenderde driehoeken in het level met behulp van het stat unit debug-tool (Draws en Prims waarden)

Het resultaat is te zien in de volgende afbeelding.

550 PLA-instanties resulteren in 559 draw-calls met 130k driehoeken
550 PLA-instanties resulteren in 559 draw-calls met 130k driehoeken

Het resultaat is vrij slecht, gezien het feit dat elke Packed Level Actor-instantie resulteert in 1 draw-call. Ten minste worden de juiste LODs gebruikt voor elke instantie, waardoor het aantal gerenderde driehoeken aanzienlijk wordt verminderd, duidelijk onder het maximum van 990k.

Samenvoegen van meerdere Packed Level Actor instanties in een enkel level

In een poging om deze situatie te verbeteren, hebben we een Blueprint Actor gemaakt die identieke Packed Level Actor-instanties tijdens runtime samenvoegt, door de gebruikte mesh en materialen te vergelijken.

De Blueprint doet in principe het volgende:

  • Itereer over alle Packed Level Actors in het level
    • Itereer over elke Instanced Static Mesh Component in de Packed Level Actor (source-component)
      • Als we al een andere Instanced Static Mesh Component hebben voor hetzelfde mesh/materialen, voeg alle instanties uit de source-component toe aan deze component
      • Als we nog geen andere Instanced Static Mesh Component hebben voor hetzelfde mesh/materialen, gebruik de source-component voor de volgende keer

Het resultaat is te zien in de volgende afbeelding.

Samenvoegen van 550 PLA-instanties resulteert in 10 draw-calls met 995k driehoeken - de instantie linksonder kon om de een of andere reden niet worden gerenderd
Samenvoegen van 550 PLA-instanties resulteert in 10 draw-calls met 995k driehoeken - de instantie linksonder kon om de een of andere reden niet worden gerenderd

Het aantal draw-calls werd aanzienlijk verminderd (zoals verwacht), maar het aantal driehoeken is aanzienlijk toegenomen, wat vrij slecht is. De reden is dat de gebruikte Instanced Static Mesh Component het LOD selecteert voor de dichtstbijzijnde instantie en dit gebruikt om alle instanties te renderen, ongeacht hoe ver weg ze zijn.

Het belangrijkste nadeel van deze oplossing is dat het niet werkt met gebakken verlichting, omdat het resultaat er verschrikkelijk uit zal zien. Voor dynamisch gegenereerde levels met dynamische verlichting werkt het echter echt goed.

Bij gebruik van gebakken verlichting kunt u in plaats daarvan handmatig een Packed Level Actor maken die alle andere Packed Level Actors in het level bevat. Unreal Engine ondersteunt geneste Packed Level Actors en aggregeert alles correct in (Hierarchical) Instanced Static Meshes.

Gebruik van Hierarchical Instanced Static Mesh Components

In een poging om deze situatie te verbeteren, hebben we de Instanced Static Mesh Component in de Packed Level Actor Blueprint vervangen door een Hierarchical Instanced Static Mesh Component met dezelfde attributen. Dit voegt een lichte overhead toe, maar het zal het juiste LOD voor elke instantie kiezen, wat het aantal gerenderde driehoeken aanzienlijk kan verminderen, ten koste van enkele extra draw-calls.

Het resultaat is te zien in de volgende afbeelding.

Samenvoegen van 550 PLA-hiërarchische instanties resulteert in 14 draw-calls met 127k driehoeken
Samenvoegen van 550 PLA-hiërarchische instanties resulteert in 14 draw-calls met 127k driehoeken

Dit resultaat is vrij goed, gezien hoeveel meshes worden gerenderd.

Conclusie

Tijdens de ontwikkeling is het belangrijk om de prestaties te monitoren, vooral voor VR/MR gezien de beperkte beschikbare hardware. Door een Blueprint Actor te maken om identieke Packed Level Actors samen te voegen, en Hierarchical Instanced Static Mesh Components te gebruiken, kunnen we aanzienlijk meer en gedetailleerdere meshes in een level gebruiken, terwijl we de prestaties op acceptabele niveaus houden.

In dit voorbeeldscenario hebben we het aantal draw-calls verminderd van 559 naar 14, terwijl we nog steeds LODs overwegen om het aantal driehoeken rond 130k te houden, door een Blueprint Actor te maken die Packed Level Actor-instanties tijdens runtime samenvoegt, en Hierarchical Instanced Static Mesh Components te gebruiken.

ScenarioDraw-callsDriehoeken
550 individuele Packed Level Actors559130k
Samenvoegen van 550 Packed Level Actors met ISM10995k
Samenvoegen van 550 Packed Level Actors met HISM14127k

Wij bij Immerstory zijn enthousiast om onze klanten te ondersteunen met hun immersieve ervaringen, en kijken ernaar uit om binnenkort meer verkenning voortgang te delen.

Welke immersieve ervaring zou je graag willen zien? Laat het ons weten!

Meer van de blog