
Consejos de optimización móvil para artistas técnicos Parte II
Lo que encontrarás en esta página: Parte II de nuestra colección de consejos útiles para optimizar tus assets de arte para tu juego móvil. La parte I está aquí.
Puedes encontrar muchos otros consejos de optimización móvil en este libro electrónico y en este curso Unity Learn sobre la optimización del arte 3D para aplicaciones móviles.

Iluminación
La misma iluminación y los mismos materiales físicos de consolas y PC también se pueden adaptar a tu teléfono o tablet con el canal de renderizado universal (URP).
Agrupa tus llamadas de dibujo
Con cada frame, Unity determina los objetos que se deben renderizar y, luego, crea llamadas de dibujo (draw calls). Una llamada de dibujo (draw call) es una llamada a la API gráfica para dibujar objetos (p. ej., un triángulo), mientras que un lote es un grupo de llamadas de dibujo (draw calls) que se ejecutan en conjunto. El agrupamiento de objetos para dibujar minimiza los cambios de estado necesarios para dibujar cada objeto en un lote. Esto mejora el rendimiento al reducir el costo de CPU para renderizar los objetos.
- Lote dinámico: Para las mallas pequeñas, Unity puede agrupar y transformar los vértices en la CPU, y dibujarlos todos de una sola vez. Nota: Solo utilízalo si tienes suficientes mallas de poligonado bajo (menos de 900 atributos de vértices y no más de 300 vértices). El Dynamic Batcher no agrupa mallas más grandes que esta, por lo que perderá tiempo en CPU buscando mallas pequeñas para agrupar en cada frame.
- Loteado estático: Para la geometría no móvil, Unity puede reducir las llamadas de dibujo (draw calls) para las mallas que comparten el mismo material. Si bien es más eficiente que el procesamiento dinámico por lotes, consume más memoria.
- Instancias de GPU: Si tienes una gran cantidad de objetos idénticos, esta técnica los agrupa de manera más eficiente mediante el uso de hardware gráfico.
SRP Batching: Activa el SRP Batcher en tu asset de URP en Advanced. Esto puede acelerar significativamente los tiempos de renderizado de tu CPU, según la escena.
Evita demasiadas luces dinámicas
Es fundamental evitar agregar demasiadas luces dinámicas a tu aplicación móvil. Considera otras alternativas, como los efectos de shader personalizados y las sondas de luz para mallas dinámicas, así como la iluminación integrada para mallas estáticas.
Consulta esta tabla comparativa para ver los límites específicos de las luces en tiempo real del canal de renderizado integrado y el URP.
Desactivar sombras
La emisión de sombras se puede desactivar por MeshRenderer y Light. Desactiva las sombras siempre que sea posible para reducir las llamadas de dibujo.
También puedes crear sombras falsas utilizando una textura borrosa aplicada a una malla simple o cuadrilátero debajo de tus personajes. De lo contrario, puedes crear sombras tipo blob con shaders personalizados.

Integra tu iluminación en mapas de luz
Agrega iluminación espectacular a tu geometría estática con Global Illumination (GI). Marca los objetos con Contribute GI para almacenar iluminación de alta calidad en forma de mapas de luz.
Las sombras y la iluminación integradas se pueden renderizar sin afectar el rendimiento en el tiempo de ejecución. Progressive CPU y GPU Lightmapper pueden acelerar la integración de Global Illumination.
Sigue el manual y este artículo sobre optimización de la luz para comenzar a usar los mapas de luz en Unity.

Usar capas de luz
Para escenas complejas con varias luces, separa tus objetos mediante capas y, luego, limita la influencia de cada luz a una máscara de culling específica.

Usar sondas de luz (light probes) para mover objetos
Las sondas de luz (light probes) almacenan la información de iluminación integrada sobre el espacio vacío de tu escena y, al mismo tiempo, proporcionan iluminación de alta calidad (tanto directa como indirecta). Utilizan Spherical Harmonics, que calculan rápidamente en comparación con las luces dinámicas.

Minimiza las sondas de reflexión
Una sonda de reflexión puede crear reflejos realistas, pero puede ser muy costosa en términos de lotes. Utiliza mapas de cubos de baja resolución, máscaras de culling y compresión de texturas para mejorar el rendimiento del tiempo de ejecución.

Ten en cuenta los materiales transparentes
El renderizado de un objeto con transparencia siempre utiliza más recursos de la GPU que el renderizado de un objeto opaco, especialmente cuando los objetos transparentes se renderizan uno encima del otro varias veces, un proceso conocido como overdraw. Es una práctica recomendada utilizar un material opaco siempre que sea posible, especialmente para las plataformas móviles. Puedes revisar Overdraw con el depurador de gráficos RenderDoc.
Haz que los shaders sean simples
Utiliza el shader más simple posible (como un shader sin iluminación) y evita utilizar funciones innecesarias. Utiliza los shaders preconstruidos de Unity diseñados específicamente para sistemas como las partículas. El URP incluye varios shaders ligeros Lit y Unlit que ya están optimizados para plataformas móviles. Para minimizar el overdraw, reduce la cantidad o el tamaño de partículas en tu juego.
Para alcanzar los objetivos de rendimiento, piensa en utilizar materiales de Unlit Opaque con la mitad de precisión, cuando sea posible, y ten en cuenta las operaciones complejas en los nodos. Encuentra más consejos en esta sesión sobre Shader Graph.
Iluminación vs. Sombreadores sin iluminar
Al crear un shader, puedes decidir cómo reaccionará el material a la luz. La mayoría de los shaders se clasifican como iluminados o no iluminados. Un shader sin iluminación es el modelo de sombreado más rápido y computacionalmente más barato. Úsalo si apuntas a un dispositivo de menor gama.
Los puntos clave a considerar incluyen:
- La iluminación no afecta a un modelo de sombreado sin iluminación. Eso significa que no se necesitan muchos cálculos, como los cálculos de especularidad. El resultado es un renderizado más económico o más rápido.
- Usar una dirección de arte estilizada que se parezca a una caricatura funciona bien con el sombreado sin iluminación. Vale la pena considerar este estilo al desarrollar juegos para plataformas móviles.

Operaciones matemáticas en el shader de vértices
Los shaders de vértices funcionan en cada vértice, mientras que los shaders de píxeles (o fragmentos) se ejecutan en cada píxel. Por lo general, se renderizan más píxeles que vértices en pantalla. Esto significa que el shader de píxeles se ejecuta con más frecuencia que el shader de vértices. Debido a esto, te recomendamos pasar el cálculo del shader de píxeles al shader de vértices siempre que sea posible. Como siempre, después de trabajar en optimizaciones, debes hacer más perfiles para determinar la mejor solución para tu situación particular.
Las operaciones básicas, como la suma y la multiplicación, se procesan con mayor rapidez. Es mejor mantener la cantidad de operaciones matemáticas más lentas lo más pequeña posible. La cantidad de matemáticas complicadas que se utiliza debe mantenerse baja en los dispositivos antiguos, como los que utilizan GLES 2.0.
Batcher SRP
Al activar el SRP Batcher, mira la ventana Statistics (estadísticas) y Vertices Graph (gráficos de vértices) de la sección de renderizado en la vista Profiler (generador de perfiles). Aparte de un descenso en FPS, el número de triángulos y vértices que se procesan disminuye drásticamente. Debido a que nuestros objetos utilizan un shader compatible con el URP, el canal de renderizado agrupa automáticamente todos los datos de geometría relevantes para reducir la cantidad de datos procesados.
Animación de personajes
De forma predeterminada, Unity importa modelos animados con el rig genérico, aunque los desarrolladores suelen cambiar al rig humanoide al animar un personaje. Un rig humanoide consume entre un 30 y un 50 % más de tiempo de CPU que el rig genérico equivalente porque calcula la cinemática inversa y la reorientación de la animación para cada frame.
Renderizar mallas skinned es costoso. Asegúrate de que todos los objetos que utilicen un SkinnedMeshRenderer lo requieran. Si un GameObject solo necesita animación parte del tiempo, usa la función BakeMesh para congelar la malla con piel en una pose estática y, luego, cambia a un MeshRenderer más simple en el tiempo de ejecución.
Diseñado principalmente para personajes humanoides, el sistema Mecanim de Unity es bastante sofisticado, pero a menudo se utiliza para animar valores individuales (por ejemplo, el canal alfa de un elemento de interfaz de usuario). Evita usar en exceso los animadores. Especialmente en relación con los elementos de la interfaz de usuario (UI), considera crear funciones de tween o usar una biblioteca de terceros para animaciones simples (por ejemplo, DOTween o LeanTween).

Más consejos
Trabaja en un presupuesto de tiempo específico por frame
Cada frame tendrá un presupuesto de tiempo basado en tus frames por segundo (FPS) objetivo. Idealmente, una aplicación que se ejecute a 30 FPS permitirá aproximadamente 33,33 ms por frame (1000 ms / 30 FPS). Asimismo, un objetivo de 60 FPS deja 16.66 ms por frame.
Los dispositivos pueden exceder este presupuesto durante períodos cortos (por ejemplo, para cinemáticas o secuencias de carga), pero no durante un período prolongado.
Ajustes predefinidos
No dependas de la configuración predeterminada. Utiliza la pestaña Anulación específica de la plataforma para optimizar assets tales como texturas y geometría de malla. Los ajustes incorrectos pueden generar mayores tamaños de compilación, tiempos de compilación más largos y mal uso de la memoria. Considera usar la función de ajustes predefinidos para personalizar los ajustes de referencia que mejorarán un proyecto específico.
Limita el uso de cámaras
Cada cámara genera una carga adicional, independientemente de si está haciendo un trabajo significativo o no. Usa solo los componentes de la cámara necesarios para el renderizado. En las plataformas móviles de gama baja, cada cámara puede usar hasta 1 ms de tiempo de CPU.
Evita los efectos de pantalla completa
Los efectos de posprocesamiento de pantalla completa, como los brillos, pueden ralentizar enormemente el rendimiento. Úsalas con precaución en la dirección de arte de tu título.
Ten cuidado con Renderer.material
El acceso a Renderer.material en los scripts duplica el material y devuelve una referencia a la nueva copia. Esto rompe cualquier lote existente que ya incluya el material. Si deseas acceder al material del objeto en lote, usa Renderer.sharedMaterial en su lugar.