Optimización de rendimiento
Optimiza tu escena para que cargue rápido y funcione sin problemas para todos los jugadores.
Hay varios aspectos que puedes optimizar en tus escenas para garantizar la mejor experiencia posible para los jugadores que las visitan. Este documento cubre algunas prácticas recomendadas que pueden marcar una gran diferencia en la rapidez con la que carga tu escena y en la fluidez con la que se ejecuta para los jugadores que están en ella o en escenas vecinas.
Ten en cuenta que muchos jugadores pueden estar visitando Decentraland usando hardware que no está diseñado para juegos, y a través del navegador, lo que limita cuánto del poder de procesamiento del hardware está disponible. La experiencia de visitar tu escena debe ser fluida para todos.
El Explorer de Decentraland aplica muchas optimizaciones a nivel del engine. Estas optimizaciones marcan una gran diferencia, pero el desafío de renderizar múltiples experiencias generadas por usuarios simultáneamente en un navegador es grande. Necesitamos tu ayuda para que todo funcione sin problemas.
Temporización
Reproducción de video
Reproducir videos es una de las cosas más costosas que el engine debe manejar. Si tu escena incluye videos, asegúrate de que solo UNO VideoTexture esté en uso a la vez. Puedes tener docenas de planos compartiendo la misma VideoTexture sin un impacto significativo en el rendimiento, pero en cuanto añades una segunda VideoTexture, sus efectos en la tasa de frames se vuelven muy notorios.
También debes evitar tener videos reproduciéndose en regiones donde no pueden verse. Por ejemplo, si tienes una pantalla en el interior, activa o desactiva el video usando un trigger area basado en cuándo el jugador entra y sale.
Carga perezosa
Si tu escena es grande, o tiene áreas interiores que no son siempre visibles, puedes optar por no cargar el conjunto completo de entidades desde el principio. En su lugar, carga el contenido por región a medida que el jugador visita diferentes partes de la escena. Esto puede reducir significativamente el tiempo de carga de la escena, y también la cantidad de texturas y contenido 3D que el engine necesita manejar en cada frame.
Por ejemplo, el edificio principal de un museo podría cargarse desde el inicio, pero las pinturas de cada piso solo se cargan para cada jugador cuando visitan ese piso.
Ver esta escena de ejemplo para ver cómo podría funcionar eso.
Para obtener el mejor resultado en términos de evitar tirones, oculta entidades cambiando la visible propiedad a false de la shape. Con este enfoque, las agregas al engine al crearlas, pero simplemente no haces visibles sus modelos.
Una alternativa es no añadir las entidades al engine hasta que sean necesarias. Esto puede resultar en algunos tirones cuando las entidades aparecen por primera vez, y también podrían tardar un par de segundos en volverse visibles. La ventaja de este enfoque es que es una forma válida de eludir la limitaciones de la escena. Ten en cuenta que el recuento de limitaciones de la escena es para el contenido que se está renderizando en la escena en un momento dado, no para el contenido total que podría renderizarse. Cargar y descargar partes de la escena debería permitirte sortear esas limitaciones.
📔 Nota: Las entidades que no son visibles pero están añadidas al engine sí cuentan para las limitaciones de la escena.
También puedes activar o desactivar animaciones para entidades que están lejos u ocultas. Por ejemplo, para un NPC que reproduce una animación idle muy sutil, podrías hacer que solo reproduzca esa animación cuando el jugador esté a menos de 20 metros. Usa un trigger area alrededor del NPC y activa o desactiva sus animaciones en consecuencia.
Bloques async
Bloques de async code se procesan en un hilo separado del resto de la escena, para evitar bloquear el progreso de todo lo demás.
Cualquier proceso que dependa de respuestas de servicios asíncronos, como getPlayerData() u getRealm() debería ejecutarse siempre en bloques async, ya que de lo contrario bloquean la carga del resto de la escena mientras esperan una respuesta. Lo mismo aplica a cualquier llamada a servidores de terceros.
Ten en cuenta que la escena se considerará completamente cargada cuando todo lo que no es async haya terminado. Los procesos async podrían seguir ejecutándose cuando el jugador entra en la escena. Evita situaciones donde un proceso async resulte en la carga de una entidad que potencialmente pueda dejar al jugador atrapado dentro de su geometría.
Apóyate en Events
Intenta hacer que la lógica de la escena dependa de escuchar events tanto como sea posible, en lugar de ejecutar comprobaciones en cada frame.
El update() función en un system se ejecuta en cada frame, 30 veces por segundo (idealmente). Evita hacer comprobaciones recurrentes si en su lugar puedes suscribirte a un event.
Por ejemplo, en lugar de comprobar constantemente los wearables del jugador, puedes suscribirte al onProfileChanged event, y comprobar los wearables del jugador solo cuando hayan cambiado.
Si debes usar un system, evita hacer comprobaciones o ajustes en cada frame. Puedes incluir un temporizador como parte de la función update y ejecutar la comprobación solo una vez por cada segundo completo, o el período que tenga sentido.
Optimizar modelos 3D
Hay varias formas en las que tus modelos 3D pueden optimizarse para ser más livianos.
Al trabajar con el Creator Hub, puedes ver estadísticas sobre los recursos usados por los modelos 3D en tu escena, y si superan alguna de las limitaciones de la escena.

Puedes expandir este menú para ver detalles.

Aquí tienes algunos consejos para mejorar estas métricas:
Cuando sea posible, comparte texturas entre modelos 3D. Una buena práctica es usar una sola textura como atlas, compartida entre todos los modelos en la escena. Es mejor tener 1 textura grande compartida de 1024x1024 píxeles en lugar de varias pequeñas.
Nota: Evita usar el mismo archivo de imagen tanto para la textura albedo como para el mapa normal o el mapa emissive de un material. Usa archivos separados, incluso si son idénticos. Asignar el mismo archivo de imagen a diferentes tipos de propiedades de textura puede introducir artefactos visuales no deseados cuando se comprime en asset bundles.
.glb es un formato comprimido, siempre pesará menos que un .gltf. Por otro lado, con .gltf es fácil compartir imágenes de textura exportando las texturas como un archivo separado. Puedes tener lo mejor de ambos mundos usando la siguiente pipeline, que te permite tener .glb models con archivos de textura externos.
Evita usar transparencias blends. Las transparencias blend deben saltarse muchas de las optimizaciones de renderizado. Si es posible, favorece geometría opaca o con alpha testing.
Evita skinned meshes. Pueden degradar el rendimiento significativamente.
Conversión a Asset Bundle
Aproximadamente una vez al día, los servidores de contenido de Decentraland ejecutan un proceso para comprimir cada .gltf y .glb model en cada escena recientemente desplegada a formato asset bundle. Este formato es significativamente más ligero, lo que hace que las escenas carguen mucho más rápido y se ejecuten con mayor fluidez en el navegador.
📔 Nota: Si realizas un any cambio en un archivo de modelo 3D, incluso si solo es un cambio de nombre, se considerará un archivo nuevo y deberá convertirse a formato asset bundle nuevamente.
Conectividad
Si tu escena se conecta a servidores de terceros o usa el messagebus para enviar mensajes entre jugadores, también hay algunas cosas que deberías tener en cuenta.
Tu escena solo debería tener una conexión WebSockets activa a la vez.
Las llamadas HTTP son canalizadas por el engine de modo que solo una se maneja a la vez. Cualquier solicitud adicional se encola internamente y debe esperar a que otras solicitudes se completen. Este proceso de encolado se maneja automáticamente, no necesitas hacer nada.
Al usar el messagebus para enviar mensajes entre jugadores, ten en cuenta que todos los mensajes se envían a todos los demás jugadores en la server island. Evita situaciones donde un mensaje entrante resulte directamente en el envío de otro mensaje, ya que el número de mensajes puede crecer rápidamente de forma exponencial cuando hay una multitud en la escena.
UI de la escena
Las UI de escena pueden volverse costosas de renderizar cuando están compuestas por muchos elementos individuales. Ten en cuenta que cada elemento de UI requiere un drawcall separado en el engine.
Evita hacer ajustes en la UI en cada frame; esos son especialmente costosos y pueden terminar encolándose. Por ejemplo, si hay una barra de salud en tu UI que debe reducirse durante un período de tiempo, los jugadores probablemente no notarían una diferencia si se actualiza a 10 FPS en lugar de 30 FPS (en cada frame). El sistema que actualiza esta barra puede usar un temporizador breve que cuente 100 milisegundos y solo afectar la UI cuando este temporizador llegue a 0.
Evita tener muchos elementos de UI ocultos; estos también afectan al rendimiento incluso si no se están renderizando. Cuando sea posible, intenta crear componentes de UI bajo demanda.
Monitorea el rendimiento
La mejor métrica para saber qué tan bien se está desempeñando una escena es el FPS (Frames Per Second). En la vista previa, puedes ver el FPS actual de la escena en el panel de depuración. Debes aspirar a tener siempre 30 FPS o más.
En la escena desplegada, puedes activar el panel que muestra estas métricas escribiendo /showfps en la ventana de chat.
Uno de los principales cuellos de botella en el rendimiento de una escena suele ser el envío de mensajes entre el código de la escena y el engine.
Cuando ejecutas una escena en preview, observa que en la esquina superior derecha dice “Y = Toggle Panel”. Pulsa Y en el teclado para abrir un panel con información útil que se actualiza en tiempo real.
A medida que interactúas con cosas que implican mensajes entre el SDK y el engine, notarás que el número de ‘Processed Messages’ crece. Debes vigilar de cerca el número ‘Pending on Queue’, debería ser siempre 0 o cercano a 0. Esto te indica cuántos de estos mensajes no se llegaron a procesar y fueron empujados a una cola. Si el recuento de ‘Pending on Queue’ comienza a crecer, entonces has entrado en la zona de peligro y deberías pensar en optimizar más tu escena.
📔 Nota: No dejes el panel abierto mientras no lo estés usando, ya que tiene un impacto negativo en el rendimiento.
Ten en cuenta que el rendimiento que experimentas en preview puede diferir del de producción:
Las escenas vecinas circundantes podrían tener un impacto negativo
La compresión de los modelos 3D de las escenas en asset bundles puede tener un impacto positivo
Algunos jugadores que visitan tu escena pueden estar ejecutando en hardware menos potente
Siempre es buena práctica intentar desplegar tu escena primero en el test environment para realizar pruebas más exhaustivas.
Siempre pide retroalimentación a los jugadores. Nunca des por sentado que cómo tú experimentas la escena es lo mismo para todos los demás.
Última actualización