Devlog: Packed Level Actors para Unreal Engine

Devlog: Packed Level Actors para Unreal Engine

Thijs ReusThijs Reus
·14 de noviembre de 2025·7 min. de lectura
Tenga en cuenta que esta publicación ha sido traducida automáticamente.

En esta publicación, miramos usar Packed Level Actors para Unreal Engine para mejorar el rendimiento al renderizar múltiples instancias de una malla.

Es crucial ser eficiente con los recursos limitados disponibles al desarrollar para visores VR/MR, que tienen hardware bastante limitado. Por ejemplo, Meta menciona rangos de ejemplo de 200 - 1000 draw-calls y 1.3m - 1.8m triángulos para un Quest 3/3s, dependiendo del uso de CPU de la aplicación.

Stack Tecnológico

Para esta exploración, estamos usando el siguiente stack tecnológico:

Packed Level Actors

Un Packed Level Actor agrega mallas/actores seleccionados en un solo Nivel / Blueprint usando Instanced Static Mesh Components, ver documentación de Unreal Engine para detalles sobre cómo crear un Packed Level Actor.

El propósito principal es optimizar el rendimiento (usando Instanced Static Mesh Components, que usa un solo draw-call incluso al renderizar múltiples instancias de la misma malla por material), y potencialmente hacer más conveniente colocar ciertas composiciones de malla en un nivel múltiples veces.

Múltiples instancias de Packed Level Actor en un solo nivel

Después de algunas pruebas, parece que Unreal Engine no agrega automáticamente múltiples instancias de un Packed Level Actor cuando se colocan en un nivel, lo que mejoraría el rendimiento al reducir los draw-calls necesarios.

Usamos el siguiente escenario de prueba:

  • Tener un Packed Level Actor con un solo Instanced Static Mesh Component con 1 instancia para un segmento de edificio de aproximadamente 1.8k triángulos con 4 LODs
  • Colocar este Packed Level Actor 550 veces en un nivel
  • Observar el número de draw-calls y triángulos renderizados en el nivel usando la herramienta de depuración stat unit (valores Draws y Prims)

El resultado se puede ver en la siguiente imagen.

550 instancias PLA resultan en 559 draw-calls con 130k triángulos
550 instancias PLA resultan en 559 draw-calls con 130k triángulos

El resultado es bastante malo, dado que cada instancia de Packed Level Actor resulta en 1 draw-call. Al menos los LODs apropiados se usan para cada instancia, reduciendo el número de triángulos renderizados significativamente por debajo del máximo de 990k.

Fusionando múltiples instancias de Packed Level Actor en un solo nivel

En un intento de mejorar esta situación, creamos un Actor Blueprint que fusiona instancias idénticas de Packed Level Actor en tiempo de ejecución, comparando la malla y materiales usados.

El Blueprint básicamente hace lo siguiente:

  • Iterar sobre todos los Packed Level Actors en el nivel
    • Iterar sobre cada Instanced Static Mesh Component en el Packed Level Actor (source-component)
      • Si ya tenemos otro Instanced Static Mesh Component para la misma malla / materiales, agregar todas las instancias del source-component a este componente
      • Si aún no tenemos otro Instanced Static Mesh Component para la misma malla / materiales, usar el source-component para esto la próxima vez

El resultado se puede ver en la siguiente imagen.

Fusionar 550 instancias PLA resulta en 10 draw-calls con 995k triángulos - la instancia inferior izquierda incluso falló al renderizar de alguna manera
Fusionar 550 instancias PLA resulta en 10 draw-calls con 995k triángulos - la instancia inferior izquierda incluso falló al renderizar de alguna manera

El número de draw-calls se redujo significativamente (como se esperaba), pero el número de triángulos ha aumentado significativamente, lo cual es bastante malo. La razón es que el Instanced Static Mesh Component usado selecciona el LOD para la instancia más cercana, y usa eso para renderizar todas las instancias, sin importar qué tan lejos puedan estar.

El principal inconveniente de esta solución es que no funciona con iluminación horneada, ya que el resultado se verá terrible. Para niveles generados dinámicamente con iluminación dinámica funciona muy bien sin embargo.

Cuando se usa iluminación horneada, puedes en su lugar crear manualmente un Packed Level Actor que contiene todos los otros Packed Level Actors en el nivel. Unreal Engine soporta Packed Level Actors anidados, y agrega correctamente todo en (Hierarchical) Instanced Static Meshes.

Usando Hierarchical Instanced Static Mesh Components

En un intento de mejorar esta situación, hemos reemplazado el Instanced Static Mesh Component en el Blueprint del Packed Level Actor con un Hierarchical Instanced Static Mesh Component con los mismos atributos. Esto agrega un ligero overhead, pero elegirá el LOD apropiado para cada instancia, lo que puede reducir significativamente el número de triángulos renderizados, a costa de algunos draw-calls extra.

El resultado se puede ver en la siguiente imagen.

Fusionar 550 instancias jerárquicas PLA resulta en 14 draw-calls con 127k triángulos
Fusionar 550 instancias jerárquicas PLA resulta en 14 draw-calls con 127k triángulos

Este resultado es bastante bueno, considerando cuántas mallas se renderizan.

Conclusión

Durante el desarrollo es importante monitorear el rendimiento, especialmente para VR/MR dado el hardware limitado disponible. Al crear un Actor Blueprint para fusionar Packed Level Actors idénticos, y usar Hierarchical Instanced Static Mesh Components, podemos usar significativamente más y más mallas detalladas en un nivel, mientras mantenemos el rendimiento en niveles aceptables.

En este escenario de ejemplo, redujimos el número de draw-calls de 559 a 14, mientras aún consideramos LODs para mantener el número de triángulos alrededor de 130k, al crear un Actor Blueprint para fusionar instancias de Packed Level Actor en tiempo de ejecución, y usar Hierarchical Instanced Static Mesh Components.

EscenarioDraw callsTriángulos
550 Packed Level Actors individuales559130k
550 Packed Level Actors fusionados usando ISM10995k
550 Packed Level Actors fusionados usando HISM14127k

Nosotros en Immerstory estamos emocionados de apoyar a nuestros clientes con sus experiencias inmersivas, y esperamos compartir más progreso de exploración pronto.

¿Qué experiencia inmersiva te gustaría ver? ¡Déjanos saber!

Más del blog