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 asegurar la mejor experiencia posible para los jugadores que las visitan. Este documento cubre algunas buenas prácticas que pueden marcar una gran diferencia en la velocidad de carga de 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 gaming, 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 debería ser fluida para todos.

El Explorer de Decentraland aplica muchas optimizaciones a nivel de engine. Estas optimizaciones marcan una gran diferencia, pero el reto de renderizar múltiples experiencias generadas por usuarios simultáneamente en un navegador es grande. Necesitamos tu ayuda para que todo funcione de forma fluida.

Temporización

Reproducción de video

Reproducir videos es una de las tareas más costosas para el engine. 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 tan pronto como añades una segunda VideoTexture, sus efectos en la tasa de frames se vuelven muy notables.

También deberías evitar que los videos se reproduzcan 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.

circle-info

💡 Tip: Un truco que varias escenas han usado es hacer stream de un único video con múltiples regiones que se mapean de forma diferente a distintos planos. Cada pantalla de video usa UV mappingarrow-up-right para mostrar únicamente una parte distinta de la VideoTexture. Gracias a esto, puede parecer que hay videos separados reproduciéndose sin el coste de múltiples VideoTextures.

circle-info

💡 Tip: Cuando los jugadores están fuera de tu escena, las VideoTextures no se actualizan en cada frame. Esto ayuda a reducir el impacto en las escenas circundantes. No obstante, lo ideal es activar la reproducción de cualquier video solo cuando los jugadores entran en tu escenaarrow-up-right .

Carga diferida

Si tu escena es grande, o tiene áreas interiores que no siempre son visibles, puedes optar por no cargar el conjunto completo de entities desde el inicio. 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 cargan para cada jugador a medida que visita cada piso.

Ver esta escena de ejemploarrow-up-right para cómo podría funcionar eso.

Para obtener el mejor resultado en términos de evitar tirones, oculta entidades cambiando la propiedad visible de su shape a false. Con este enfoque, las añades al engine al crearlas, pero simplemente no haces visibles sus modelos.

Una alternativa es no añadir las entities al engine hasta que sean necesarias. Esto puede resultar en algunos tirones cuando las entities aparezcan por primera vez, y también podrían tardar un par de segundos en hacerse visibles. La ventaja de este enfoque es que es una forma válida de sortear el limitaciones de la escenaarrow-up-right. 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.

circle-exclamation

También puedes activar o desactivar animaciones para entities que estén lejanas 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.

circle-info

💡 Tip: Cuando una entity está lejos y lo suficientemente pequeña, el engine la elimina por culling. Este culling ayuda a nivel de drawcall, pero eliminar entities del engine siempre es mejor. Este culling tampoco tiene en cuenta la oclusión por otras entities, por lo que entidades que no son tan pequeñas pero están ocultas por una pared siguen siendo renderizadas.

Bloques async

Bloques de async codearrow-up-right 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 asincrónicos, como getPlayerData() o getRealm() siempre debería ejecutarse 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 entity 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 eventsarrow-up-right tanto como sea posible, en lugar de ejecutar comprobaciones en cada frame.

El update() función en un systemarrow-up-right 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 de 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 ligeros.

Al trabajar con el Creator Hubarrow-up-rightPuedes ver estadísticas sobre los recursos usados por los modelos 3D en tu escena, y si superan alguno de los limitaciones de la escenaarrow-up-right.



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 única textura como atlas, compartida entre todos los modelos de 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 emisivo de un material. Usa archivos separados, aunque sean idénticos. Asignar el mismo archivo de imagen a diferentes tipos de propiedades de textura puede introducir artefactos visuales indeseados cuando se comprimen 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 texturas como un archivo separado. Puedes tener lo mejor de ambos mundos usando la siguiente pipelinearrow-up-right, que te permite tener .glb models con archivos de textura externos.

  • Evita usar transparencias blended. Las transparencias blended deben sortear bastantes optimizaciones de renderizado. Si es posible, favorece geometría opaca o con alpha test.

  • Evita los skinned meshes. Pueden reducir el rendimiento de forma significativa.

circle-info

💡 Tip: Lee más sobre buenas prácticas de modelos 3D en la [3D Modeling Section](/creator/3d-modeling/3d-models

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 recién desplegada a formato asset bundle. Este formato es significativamente más ligero, haciendo que las escenas carguen mucho más rápido y se ejecuten con más suavidad en el navegador.

circle-info

💡 Tip: Al planear un evento en Decentraland, asegúrate de desplegar tu escena un día antes, para que los modelos ya estén convertidos a asset bundles para entonces. Si no quieres arruinar la sorpresa antes del evento, puedes desplegar una versión de tu escena que incluya todos los modelos 3D finales en la carpeta del proyecto, pero donde estos no sean visibles o su tamaño esté establecido en 0.

circle-exclamation

Conectividad

Si tu escena se conecta a servidores de terceros o usa el messagebusarrow-up-right para enviar mensajes entre jugadores, también hay algunas cosas que podrías tener en cuenta.

  • Tu escena debería tener solo una conexión WebSockets activa a la vez.

  • Las llamadas HTTP son canalizadas por el engine de modo que solo una se procesa 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 messagebusarrow-up-right para enviar mensajes entre jugadores, ten en cuenta que todos los mensajes se envían a todos los demás jugadores en la isla del servidor. Evita situaciones en las que 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 multitud en la escena.

UI de la escena

Las UIs 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.

circle-info

💡 Tip: Intenta fusionar múltiples elementos en una sola imagen. Por ejemplo, si tienes un menú con múltiples elementos de texto, lo ideal es tener el texto de las fichas y cualquier imagen adicional horneados en la imagen de fondo. Eso evita que el engine tenga que hacer un drawcall adicional por frame para cada elemento de texto.

Evita hacer ajustes en la UI en cada frame; éstos son especialmente costosos y pueden terminar encolados. Por ejemplo, si hay una barra de salud en tu UI que debería encogerse durante un periodo de tiempo, los jugadores probablemente no noten la 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 afectar la UI solo 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.

Monitoriza el rendimiento

La mejor métrica para saber qué tan bien se está comportando una escena es el FPS (Frames Per Second). En preview, puedes ver el FPS actual de la escena en el panel de debug. 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, fíjate 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 procesaron y fueron empujados a una cola. Si el conteo de ‘Pending on Queue’ empieza a crecer, entonces has entrado en la zona de peligro y deberías pensar en optimizar más tu escena.

circle-exclamation

Ten en cuenta que el rendimiento que experimentes 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 usando hardware menos potente

Siempre es buena práctica intentar desplegar tu escena primero en el test environmentarrow-up-right para realizar pruebas más exhaustivas.

Pregunta siempre a los jugadores por feedback. Nunca des por sentado que la forma en que tú experimentas la escena es la misma para todos los demás.

Última actualización