Selección de formatos de imagen en desarrollo de videojuegos - Compresión de texturas y rendimiento de renderizado
Por qué el desarrollo de videojuegos necesita formatos de imagen diferentes
Las imágenes (texturas) en videojuegos tienen necesidades fundamentalmente diferentes a las imágenes web. La GPU necesita formatos comprimidos que permitan acceso aleatorio directo en la memoria de video, no formatos como JPEG/PNG que requieren descompresión completa.
Necesidades especiales de las texturas de juegos:
- Muestreo directo por GPU: las texturas deben almacenarse en la memoria de video en un formato que la GPU pueda leer directamente. JPEG/PNG necesitan descomprimirse completamente a píxeles sin comprimir antes de poder usarse
- Acceso aleatorio: durante el renderizado, la GPU necesita acceder aleatoriamente a cualquier región de la textura (filtrado de texturas), no puede leer secuencialmente como la decodificación en streaming
- Ratio de compresión fijo: la compresión de texturas GPU usa bloques de tamaño fijo (como 4x4 píxeles), asegurando tiempo de acceso constante en cualquier posición
- Limitaciones de memoria de video: los juegos pueden cargar miles de texturas simultáneamente; el ratio de compresión determina directamente cuánto contenido se puede cargar
Resultado: los juegos usan formatos especializados de compresión de texturas GPU (BC1-7, ASTC, ETC2), no los JPEG/PNG/WebP comunes en la web.
Mecanismo de compresión de texturas GPU - Serie BCn (DirectX)
BCn (Block Compression) es la familia de formatos estándar de compresión de texturas para la plataforma DirectX, que comprime texturas independientemente en bloques de 4x4 píxeles.
Resumen de formatos BCn:
- BC1 (DXT1): RGB, 4 bits/píxel (ratio de compresión 8:1). Cada bloque 4x4 almacena 2 colores extremo + 16 índices de 2 bits. Adecuado para texturas difusas sin Alpha
- BC3 (DXT5): RGBA, 8 bits/píxel (4:1). RGB de BC1 + bloque Alpha independiente. Adecuado para texturas que necesitan transparencia
- BC4: canal único, 4 bits/píxel. Adecuado para mapas de altura, mapas de rugosidad y otros datos de canal único
- BC5: dos canales, 8 bits/píxel. Adecuado para mapas de normales (solo almacena XY, Z se recupera por cálculo)
- BC7: RGBA, 8 bits/píxel. Formato de uso general con la mayor calidad, soporta múltiples modos de partición. Adecuado para texturas de alta calidad
Guía de selección: texturas difusas con BC1/BC7, mapas de normales con BC5, con Alpha usar BC3/BC7, datos de canal único con BC4. BC7 tiene la mejor calidad pero solo es compatible con hardware DX11+.
ASTC - Estándar para móviles y multiplataforma
ASTC (Adaptive Scalable Texture Compression) es un formato de compresión de texturas desarrollado por ARM, que soporta tamaños de bloque variables y se usa ampliamente en plataformas móviles.
Características de ASTC:
- Tamaño de bloque variable: desde 4x4 hasta 12x12, proporcionando un rango continuo de ratios de compresión desde 8 bits/píxel hasta 0.89 bits/píxel
- Formato unificado: un solo formato cubre LDR/HDR, 1-4 canales, texturas 2D/3D
- Alta calidad: a la misma tasa de compresión, la calidad generalmente supera a BCn y ETC2
Selección de tamaño de bloque:
- 4x4 (8 bpp): máxima calidad, adecuado para mapas de normales y texturas de UI
- 6x6 (3.56 bpp): buen equilibrio entre calidad y tamaño, adecuado para la mayoría de texturas difusas
- 8x8 (2 bpp): mayor compresión, adecuado para texturas de fondo y recursos menos importantes
Soporte de plataformas: iOS (A8+), Android (la mayoría de dispositivos modernos), macOS (Apple Silicon). En escritorio soportado a través de extensiones Vulkan/OpenGL.
Formatos contenedor - DDS, KTX2 y Basis Universal
Los datos de compresión de texturas GPU necesitan formatos contenedor para almacenar metadatos (dimensiones, formato, niveles de Mipmap, etc.).
Principales formatos contenedor:
- DDS (DirectDraw Surface): estándar del ecosistema DirectX. Soporta todos los formatos BCn, Mipmap, mapas de cubo, arrays de texturas. Primera opción para juegos Windows/Xbox
- KTX2 (Khronos Texture 2.0): estándar del ecosistema Vulkan/OpenGL. Soporta todos los formatos GPU, supercompresión Basis Universal, compresión adicional Zstandard. Primera opción multiplataforma
- Basis Universal: formato intermedio que puede transcodificarse en tiempo de ejecución al formato nativo de la plataforma objetivo (BC1-7, ASTC, ETC2). Un solo archivo se adapta a todas las plataformas
Ventajas de Basis Universal:
- Al empaquetar solo se necesita almacenar una copia de los datos de textura; en tiempo de ejecución se transcodifica según las capacidades de la GPU
- La velocidad de transcodificación es extremadamente rápida (< 1ms/textura), sin afectar el rendimiento de carga
- Reduce significativamente el tamaño del paquete de instalación del juego (no es necesario almacenar diferentes formatos para cada plataforma)
Selección del mejor formato específico por plataforma
Las GPUs de diferentes plataformas de juegos soportan diferentes formatos de textura, requiriendo una selección específica.
Formatos recomendados por plataforma:
- PC (Windows/DirectX): BC7 (alta calidad), BC1/BC3 (compatibilidad). Hardware DX11+ soporta completamente BC7
- PC (Vulkan): BC7 o ASTC (si el hardware objetivo lo soporta)
- iOS: ASTC (soporte completo desde chip A8 en adelante). Dispositivos antiguos usan PVRTC (obsoleto)
- Android: ASTC (la mayoría de dispositivos modernos), ETC2 (alternativa de amplia compatibilidad)
- Consolas (PS5/Xbox Series): BC7 (máxima calidad), BC1-5 (cuando se necesita ahorrar memoria de video)
- Web (WebGL/WebGPU): Basis Universal → transcodificación en tiempo de ejecución al formato soportado por el dispositivo
Estrategia multiplataforma: usar Basis Universal como formato fuente, transcodificar al formato de la plataforma objetivo en tiempo de compilación o ejecución. O generar paquetes de recursos en el formato correspondiente para cada plataforma en el pipeline de compilación.
Diseño de arquitectura de atlas de texturas y carga por streaming
Los juegos grandes necesitan gestionar miles de texturas; el empaquetado en atlas y la carga por streaming son claves para la optimización del rendimiento.
Atlas de texturas (Texture Atlas):
- Empaquetar múltiples texturas pequeñas en una textura grande, reduciendo Draw Calls y cambios de estado
- El tamaño del atlas es típicamente 2048x2048 o 4096x4096 (limitado por el tamaño máximo de textura de la GPU)
- Es necesario manejar el sangrado de bordes (bleeding): añadir 1-2 píxeles de relleno en los bordes de las subtexturas para evitar mezcla con texturas adyacentes durante el muestreo
Texturizado virtual (Virtual Texturing):
- Dividir texturas muy grandes (como terreno) en bloques pequeños (tiles), cargando solo los bloques del área actualmente visible
- Concepto similar a la memoria virtual: lógicamente es una textura enorme, físicamente solo una parte reside en la memoria de video
- Virtual Texture de Unreal Engine y MegaTexture de id Tech son implementaciones típicas
Carga por streaming de Mipmap:
- Cargar primero Mipmaps de baja resolución para visualización rápida, luego cargar niveles de alta resolución de forma asíncrona
- Ajustar dinámicamente el nivel de Mipmap residente según la distancia de la cámara, ahorrando memoria de video
- Sistemas de Texture Streaming de Unity y UE