En este tema, aprenderemos sobre la reducción de llamadas de dibujo (draw calls) en Unity, un aspecto crucial para optimizar el rendimiento de tu juego. Las llamadas de dibujo son instrucciones enviadas a la GPU para renderizar objetos en la pantalla. Un número elevado de estas llamadas puede afectar negativamente el rendimiento del juego, especialmente en dispositivos con recursos limitados.
Conceptos Clave
- Draw Calls: Instrucciones enviadas a la GPU para renderizar un objeto.
- Batching: Técnica para agrupar múltiples objetos en una sola llamada de dibujo.
- Instancing: Técnica para renderizar múltiples copias de un objeto con una sola llamada de dibujo.
- LOD (Level of Detail): Técnica para reducir la complejidad de los modelos a medida que se alejan de la cámara.
Técnicas para Reducir Draw Calls
- Batching
Unity ofrece dos tipos de batching: estático y dinámico.
Batching Estático
El batching estático agrupa objetos que no se mueven en una sola llamada de dibujo. Para usarlo:
- Selecciona los objetos en la escena.
- Marca la casilla "Static" en el Inspector.
Batching Dinámico
El batching dinámico agrupa objetos que se mueven y comparten el mismo material. Unity lo hace automáticamente si los objetos cumplen ciertos criterios (menos de 300 vértices, mismo material).
- Instancing
El instancing permite renderizar múltiples copias de un objeto con una sola llamada de dibujo. Es útil para objetos repetitivos como árboles o rocas.
// Ejemplo de código para usar instancing Material material = new Material(Shader.Find("Standard")); material.enableInstancing = true;
- Uso de Shaders Eficientes
Los shaders personalizados pueden optimizar el rendimiento. Por ejemplo, los shaders que soportan instancing pueden reducir significativamente las llamadas de dibujo.
// Ejemplo de un shader simple con instancing Shader "Custom/InstancedShader" { Properties { _Color ("Color", Color) = (1,1,1,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_instancing #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float4 color : COLOR; UNITY_VERTEX_OUTPUT_STEREO }; UNITY_INSTANCING_BUFFER_START(Props) UNITY_INSTANCING_BUFFER_END(Props) v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); o.pos = UnityObjectToClipPos(v.vertex); o.color = v.color; return o; } fixed4 frag (v2f i) : SV_Target { return i.color; } ENDCG } } }
- Level of Detail (LOD)
El LOD reduce la complejidad de los modelos a medida que se alejan de la cámara. Unity permite configurar LODs para cada modelo.
- Selecciona el objeto en la escena.
- Añade un componente "LOD Group".
- Configura los niveles de detalle.
// Ejemplo de código para configurar LODs LODGroup lodGroup = gameObject.AddComponent<LODGroup>(); LOD[] lods = new LOD[2]; lods[0] = new LOD(0.5f, new Renderer[] { renderer1 }); lods[1] = new LOD(0.2f, new Renderer[] { renderer2 }); lodGroup.SetLODs(lods); lodGroup.RecalculateBounds();
Ejercicio Práctico
Ejercicio 1: Implementar Batching Estático
- Crea una escena con varios objetos estáticos (por ejemplo, edificios).
- Marca todos los objetos como estáticos.
- Observa la reducción en las llamadas de dibujo usando el Profiler de Unity.
Ejercicio 2: Usar Instancing
- Crea una escena con múltiples copias de un objeto (por ejemplo, árboles).
- Aplica un material que soporte instancing.
- Observa la reducción en las llamadas de dibujo usando el Profiler de Unity.
Soluciones
Solución Ejercicio 1
- Selecciona todos los objetos estáticos en la escena.
- Marca la casilla "Static" en el Inspector.
- Abre el Profiler (Window > Analysis > Profiler) y observa la reducción en las llamadas de dibujo.
Solución Ejercicio 2
- Crea un material que soporte instancing.
- Aplica el material a todos los objetos repetitivos.
- Abre el Profiler y observa la reducción en las llamadas de dibujo.
Conclusión
Reducir las llamadas de dibujo es esencial para optimizar el rendimiento de tu juego en Unity. Técnicas como el batching, el instancing, el uso de shaders eficientes y el LOD pueden ayudarte a lograr un rendimiento óptimo. Practica estas técnicas en tus proyectos para familiarizarte con ellas y mejorar la eficiencia de tus juegos.
Curso de Unity
Módulo 1: Introducción a Unity
- Introducción a Unity e Instalación
- Descripción General de la Interfaz de Unity
- Creando Tu Primer Proyecto
- Objetos de Juego Básicos y Componentes
Módulo 2: Programación Básica en Unity
- Introducción a C# para Unity
- Creación y Adjunto de Scripts
- Entendiendo MonoBehaviour
- Manejo Básico de Entradas
Módulo 3: Trabajando con Activos
- Importación y Gestión de Activos
- Uso de la Tienda de Activos
- Creación y Uso de Prefabs
- Animación Básica
Módulo 4: Física y Colisiones
- Introducción a la Física en Unity
- Cuerpos Rígidos y Colisionadores
- Detección Básica de Colisiones
- Uso de Materiales Físicos
Módulo 5: Interfaz de Usuario (UI)
- Introducción a la UI de Unity
- Creación y Personalización de Elementos UI
- Manejo de Eventos UI
- Creación de Menús y HUDs
Módulo 6: Audio en Unity
- Introducción al Audio en Unity
- Importación y Uso de Clips de Audio
- Programación Básica de Audio
- Audio 3D y Sonido Espacial
Módulo 7: Programación Avanzada
- Conceptos Avanzados de C# para Unity
- Corutinas y Programación Asíncrona
- Objetos Scriptables
- Editores Personalizados y Gizmos
Módulo 8: Física Avanzada e IA
- Técnicas Avanzadas de Física
- Búsqueda de Caminos y Navegación
- Programación Básica de IA
- Máquinas de Estado y Árboles de Comportamiento
Módulo 9: Optimización y Rendimiento
- Técnicas de Perfilado y Optimización
- Gestión de Memoria
- Reducción de Llamadas de Dibujo
- Optimización de Física y Colisiones