Adaptive Performance ofrece una mayor fidelidad y tasas de frames más fluidas

DAVID BERGER / UNITY TECHNOLOGIESContributor
Apr 1, 2019|9 minutos
Adaptive Performance ofrece una mayor fidelidad y tasas de frames más fluidas
Para tu comodidad, tradujimos esta página mediante traducción automática. No podemos garantizar la precisión ni la confiabilidad del contenido traducido. Si tienes alguna duda sobre la precisión del contenido traducido, consulta la versión oficial en inglés de la página web.

Recientemente terminamos la GDC 2019, donde hablamos sobre Adaptive Performance durante nuestra Keynote. Nos complace informarle de que ya están disponibles la versión preliminar y la muestra móvil Megacity para que pueda empezar a explorar esta función. Este blog explica más sobre Adaptive Performance y cómo aplicarlo a sus propios proyectos.

A diferencia de los juegos de PC o consola, aprovechar toda la potencia del hardware móvil requiere un delicado equilibrio para que los juegos luzcan bonitos y se reproduzcan con fluidez. Exigir al máximo las capacidades de un dispositivo puede comprometer rápidamente el rendimiento del juego al sobrecargar el hardware, lo que provoca ralentización, escasa duración de la batería y rendimiento irregular. Para los desarrolladores, esta cuestión resulta aún más problemática si se tiene en cuenta la amplia gama de dispositivos de gama baja a gama alta a los que van dirigidos.

Hoy en día, los desarrolladores adoptan diferentes tácticas para resolver este problema. Los dos enfoques principales que hemos visto son: intentar que los juegos rindan al máximo en todo el hardware de destino, lo que significa sacrificar la fidelidad gráfica y la tasa de fotogramas, o intentar anticiparse al comportamiento del hardware, lo que es realmente difícil porque no hay muchas opciones para medir con precisión las tendencias del hardware.

Cómo funciona Adaptive Performance

Adaptive Performance te ofrece una forma mejor de gestionar la temperatura y el rendimiento de tus juegos en un dispositivo en tiempo real, lo que te permite ajustar de forma proactiva sobre la marcha el rendimiento y la configuración de calidad de tu juego y utilizar el hardware sin sobrecargar el dispositivo. El resultado es una velocidad de fotogramas predecible y una disminución de la acumulación térmica, lo que permite tiempos de juego más largos y una experiencia de jugador mucho más agradable a la vez que se preserva la duración de la batería.

Para los desarrolladores, significa tener una visión nueva y más profunda del hardware con nuevas herramientas para hacer sus juegos más dinámicos y flexibles, proporcionando a sus jugadores las experiencias más fluidas y de mejor rendimiento cuando juegan en dispositivos móviles. Te da el control sobre decisiones que normalmente toma el sistema operativo, como cuándo funcionar a altas velocidades de reloj o qué ajustar para evitar la ralentización.

Dimos varias charlas sobre esta característica durante la GDC 2019. Puedes ver las diapositivas aquí y la Unity GDC Booth Talk - Megacity on mobile: Cómo lo optimizamos con Adaptive Performance a continuación.

Colaboración con Samsung en Adaptive Performance

Nos hemos asociado con Samsung, el mayor fabricante de dispositivos móviles Android del mundo, para ayudar a hacer realidad esta solución. Construido sobre GameSDK de Samsung, Adaptive Performance estará disponible primero para dispositivos Samsung Galaxy como el Samsung Galaxy S10 y Galaxy Fold, seguido de dispositivos Samsung Galaxy adicionales a finales de este año.

Primeros resultados

Estos gráficos (mostrados durante nuestra keynote de Unity en la GDC 2019) ilustran cómo Adaptive Performance ayuda a ofrecer una alta tasa de fotogramas constante con Megacity ejecutándose en el nuevo Samsung Galaxy S10.

Imagen de la velocidad de fotogramas

En rojo, puede ver la velocidad de fotogramas en Megacity antes de que añadiéramos Adaptive Performance; y en azul, puede ver los resultados después de que añadiéramos Adaptive Performance. Con Adaptive Performance, la demo funciona a 30 FPS durante mucho más tiempo y es mucho más estable.

¿Por qué Megaciudad?
Imagen de Megacity

Megacity es una ciudad futurista e interactiva con millones de entidades, que demuestra cómo Unity puede ejecutar incluso los proyectos más complejos en hardware móvil de última generación. En él se muestran los últimos avances de nuestra pila tecnológica orientada a los datos(DOTS), el nombre que reciben todos los proyectos bajo nuestro lema "Performance by Default" (Rendimiento por defecto), incluidos Entity Component System (ECS), Native Collections, C# Job System y el compilador Burst. Megacity se presentó por primera vez en Unite Los Ángeles 2018 y se lanzó para escritorio durante la GDC 2019.

Megacity es el proyecto adecuado para demostrar un ejemplo de implementación de Adaptive Performance, ya que nos proporciona la flexibilidad necesaria para adaptar el juego de forma dinámica y proactiva para aprovechar al máximo el hardware. Adaptive Performance se construyó pensando en la escalabilidad, lo que funciona muy bien con los principios de DOTS utilizados para construir los cimientos de Megacity.

La versión móvil del proyecto cuenta con 4,5 millones de renderizadores de malla, 200.000 componentes de construcción, 100.000 fuentes de audio y más de 6 millones de entidades: un candidato ideal para demostrar las capacidades de Adaptive Performance.

Cómo funciona Adaptive Performance (en Megacity)

Después de instalar Adaptive Performance a través del gestor de paquetes de Unity, Unity añade automáticamente el subsistema Samsung GameSDK a su proyecto cuando lo compila en un dispositivo. Durante el tiempo de ejecución, Unity crea e inicia un Adaptive Performance Manager en los dispositivos compatibles, que le proporciona información sobre el estado térmico del dispositivo móvil. Puede suscribirse a eventos o consultar la información del Adaptive Performance Manager durante el tiempo de ejecución para reaccionar en tiempo real; de lo contrario, sólo informará de las estadísticas a la consola.

A modo de ejemplo, puede utilizar la API proporcionada para crear aplicaciones que reaccionen a las tendencias y eventos térmicos del dispositivo. Esto garantiza frecuencias de cuadro constantes durante un periodo de tiempo más largo, al tiempo que evita la ralentización térmica, incluso antes de que comience la ralentización. En la implementación de ejemplo de Adaptive Performance en Megacity, utilizamos tres formas distintas de suavizar la velocidad de fotogramas:

  • Empezando con niveles moderados de CPU y GPU, y aumentándolos gradualmente para eliminar los cuellos de botella, pudimos mantener bajo el consumo de energía.
  • Si veíamos que el dispositivo se acercaba al estrangulamiento, podíamos ajustar los parámetros de calidad para reducir la carga térmica, y decidimos bajar los niveles de LOD.
  • También redujimos la velocidad de fotogramas objetivo una vez que estuvimos cerca del estrangulamiento.
  • Cuando se alcanza la frecuencia de imagen objetivo y la temperatura disminuye, aumentamos los niveles de LOD, incrementamos la frecuencia de imagen objetivo y volvemos a reducir los niveles de CPU y GPU.

Estas capacidades permiten que tu juego consiga un rendimiento más fluido a lo largo del tiempo. Si sigues de cerca las tendencias térmicas de un dispositivo, puedes ajustar la configuración de rendimiento sobre la marcha para evitar por completo la ralentización.

Descargue aquí el proyecto de ejemplo Megacity mobile para ver cómo lo hemos hecho. Si tiene comentarios o preguntas sobre Megacity, visite este hilo del foro.

Gestor de Adaptive Performance

El corazón del paquete es el Adaptive Performance Manager, que Unity crea durante el arranque, permitiéndole acceder y suscribirse a notificaciones de eventos térmicos y de rendimiento fácilmente. El siguiente ejemplo muestra cómo acceder al Adaptive Performance Manager utilizando la interfaz IAdaptivePerformance en la función Start de su MonoBehaviour.

private IAdaptivePerformance ap = null;

void Inicio()
{
ap = Holder.instance;
}

Sucesos térmicos

Unity envía eventos térmicos cada vez que se producen cambios en el estado térmico del dispositivo. Los estados importantes son cuando el estrangulamiento es inminente y cuando se está produciendo. En el ejemplo siguiente, se suscribe a ThermalEvents para reducir o aumentar su lodBias, lo que ayuda a reducir la carga de la GPU.

usando UnityEngine;
using UnityEngine.Mobile.AdaptivePerformance;

public class AdaptiveLOD : MonoBehaviour
{
private IAdaptivePerformance ap = null;

void Inicio() {
si (Holder.instance == null)
volver;

ap = Holder.instance;

if (!ap.active)
volver;

QualitySettings.lodBias = 1;

ap.ThermalEvent += OnThermalEvent;
}

void OnThermalEvent(object obj, ThermalEventArgs ev) {
switch (ev.warningLevel) {
caso PerformanceWarningLevel.NoWarning:
QualitySettings.lodBias = 1;
romper;
case PerformanceWarningLevel.ThrottlingImminent:
QualitySettings.lodBias = 0.75f;
romper;
caso PerformanceWarningLevel.Throttling:
QualitySettings.lodBias = 0.5f;
romper;
}
}
}

Ten en cuenta que si reduces el lodBias por debajo de un valor de 1, tendrá un impacto visual en muchos casos y podría producirse un LOD object-popping, pero es una forma fácil de reducir la carga gráfica si no es necesario para la experiencia de juego. En caso de que quieras tomar decisiones aún más detalladas para afinar cómo se manejan los gráficos y el comportamiento de tu juego, los eventos de cuello de botella son muy útiles.

Niveles de rendimiento de la CPU y la GPU

La CPU y la GPU de un dispositivo móvil representan una parte muy importante de su consumo energético, sobre todo cuando se ejecuta un juego. Normalmente, el sistema operativo decide qué velocidades de reloj se utilizan para la CPU y la GPU.

Los núcleos de la CPU y las GPU son menos eficientes cuando funcionan a su máxima velocidad de reloj. Al funcionar a altas velocidades de reloj, el dispositivo móvil se sobrecalienta con facilidad y el sistema operativo regula la frecuencia de la CPU y la GPU para enfriar el dispositivo.

Puede evitar esta situación limitando las velocidades de reloj máximas permitidas con estas propiedades:

  • IAdaptivePerformance.cpuLevel
  • IAdaptivePerformance.gpuLevel

La aplicación puede configurar esas propiedades basándose en sus conocimientos especiales sobre los requisitos de rendimiento actuales y decidir, en función del escenario, si los niveles deben bajarse o subirse.

  • ¿Alcanzó la aplicación la frecuencia de imagen objetivo en los fotogramas anteriores?
  • ¿La aplicación está en una escena del juego o en un menú?
  • ¿Se avecina una escena pesada?
  • ¿Se trata de un evento en el que interviene la CPU o la GPU?
  • ¿Mostrará anuncios que no requieran altos niveles de CPU/GPU?

public void EnterMenu(){
if (!ap.active)
volver;

// Establece un nivel bajo de CPU y GPU en el menú
ap.cpuLevel = 0;
ap.gpuLevel = 0;
// Establecer objetivo bajo FPS
Application.targetFrameRate = 15;
}

public void ExitMenu(){
// Establecer mayor nivel de CPU y GPU al volver al juego
ap.cpuLevel = ap.maxCpuPerformanceLevel;
ap.gpuLevel = ap.maxGpuPerformanceLevel;
}

Un sistema de alerta temprana de cuellos de botella en el rendimiento

En el Adaptive Performance Manager, puedes suscribirte para recibir eventos de cuellos de botella de rendimiento que te informen de si estás limitado por GPU, CPU o "frame-rate". Frame-rate bound significa que el juego está limitado por Application.targetFrameRate, en cuyo caso la aplicación debería considerar reducir sus requisitos de rendimiento.

El controlador de tiempo de fotogramas de la GPU, que se ejecuta en segundo plano y se puede consultar a través del Gestor, controla el tiempo de hardware que la GPU ha empleado en el último fotograma; por el momento, el tiempo de la CPU se calcula sumando los subsistemas internos de Unity. Dependiendo del juego y del escenario, puedes hacer que reaccione de forma diferente cuando el juego está ligado a la CPU o a la GPU según los cambios de estado térmico.

void OnBottleneckChange(object obj, PerformanceBottleneckChangeEventArgs ev) {
switch (ev.bottleneck) {
case CuelloDeCuello.ObjetivoTasaDeCuadros:
if (ap.cpuLevel > 0) {
ap.cpuLevel--;
}
if (ap.gpuLevel > 0) {
ap.gpuLevel--;
}
romper;
caso PerformanceBottleneck.GPU:
if (ap.gpuLevel < ap.maxGpuPerformanceLevel) {
ap.gpuLevel++;
}
romper;
caso PerformanceBottleneck.CPU:
if (ap.cpuLevel < ap.maxCpuPerformanceLevel) {
ap.cpuLevel++;
}
romper;
}
}

Hay muchas formas diferentes de optimizar los juegos, y los ejemplos anteriores y en Megacity sólo ofrecen algunas sugerencias sobre cómo hacerlo; en última instancia, depende mucho de lo que funcione mejor para tu juego. Para más información, consulte también la documentación del paquete.

El futuro de Adaptive Performance

Esto es sólo el principio. Vamos a seguir invirtiendo en Adaptive Performance, añadiendo más funciones y dando soporte a más dispositivos con el tiempo. El paquete actual incluye una API de bajo nivel, pero ya estamos trabajando en una API de alto nivel basada en componentes y compatible con DOTS, que debería facilitar aún más la adaptación del rendimiento en tus proyectos Unity. Esté atento para más información.

Empiece hoy mismo

Ya está disponible una versión Preview de Adaptive Performance para Unity 2019.1 (beta) a través del Unity Package Manager. Puede acceder a él aquí. Para obtener información actualizada sobre Adaptive Performance, ver cómo lo utilizan otros desarrolladores y enviar preguntas o comentarios, visite el foro.