
Compresión de texturas KTX2
Las texturas son omnipresentes en las aplicaciones gráficas modernas. Proporcionan información de color y material a nuestros modelos.
Cuanto mayor sea la resolución de nuestra textura, más detalle podremos obtener. Hoy en día, las cámaras de alta resolución se están volviendo más accesibles y asequibles. Sin embargo, esto tiene un costo: el uso de memoria.
Disponemos de formatos de imagen comprimidos como JPEG y PNG que reducen el uso de memoria de las imágenes almacenadas en disco. Estos formatos también son útiles para aplicaciones web, ya que permiten reducir la cantidad de datos que se deben transferir a través de la red, disminuyendo así los tiempos de carga de las páginas web. Sin embargo, formatos como JPEG no pueden ser interpretados por la tarjeta gráfica (GPU); están diseñados únicamente para comprimir imágenes, no para renderizarlas. Una imagen JPEG debe ser descomprimida antes de enviarla a la GPU para su renderizado.
La siguiente es una imagen de 256×256 píxeles.

Created with GIMP
Comprimida como JPEG, con alta calidad, pesa 53,5 KB.
Una vez que descomprimimos la imagen a formato RGBA8 para que la consuma la GPU, ocupará 256 KB. ¡Eso es aproximadamente 5 veces más!
Esta es una imagen muy pequeña pero, por ejemplo, una imagen en 4K (que hoy en día es muy común) ocuparía 64 MB. Las aplicaciones grandes suelen tener muchos recursos, incluidas texturas, por lo que esto puede crecer rápidamente y consumir toda la memoria de la GPU (VRAM), especialmente en dispositivos de bajo consumo como teléfonos inteligentes, tabletas y dispositivos de realidad virtual.
Los formatos de compresión de texturas fueron inventados para permitir la compresión de imágenes en la GPU. Estos formatos de compresión están diseñados para adaptarse a la arquitectura de las GPUs y lograr un rendimiento óptimo. Esto se traduce no solo en una menor utilización de la VRAM, sino también en:
- Tiempos de carga más rápidos, ya que la cantidad de datos que se deben transferir a la GPU es menor.
- Mejores tasas de fotogramas (frame rates), ya que se reducen los requisitos de ancho de banda para las transferencias internas.
Varios fabricantes de tarjetas gráficas, en colaboración con los principales actores involucrados, desarrollaron distintos formatos de compresión de texturas. Algunos ejemplos de estos formatos son:
- La familia de formatos BC (también conocida como S3TC), como BC1, BC3, BC6H, BC7 (entre otros). Estos formatos son exclusivos de las plataformas de escritorio.
- La familia ETC (Ericsson Texture Compression), compuesta por ETC1, ETC2, ETC2_EAC y EAC. Estos formatos fueron adoptados principalmente por OpenGL y se utilizan en plataformas Android y WebGL.
- PVRTC es una familia de formatos exclusiva de los chips PowerVR. Fue importante porque era el único formato compatible en iOS. Actualmente está quedando obsoleto, ya que Apple está adoptando ASTC para todos sus dispositivos.
- ASTC es el formato de compresión de texturas más avanzado en la actualidad. Es un estándar desarrollado por el grupo Khronos, y ahora es el formato de facto para dispositivos móviles.
Como puedes imaginar, tener tantos formatos de compresión de texturas puede ser un gran dolor de cabeza para los desarrolladores de aplicaciones que se preocupan por lograr un buen rendimiento en múltiples plataformas.
El grupo Khronos ha intentado resolver este problema de fragmentación con el formato contenedor KTX2 y los supercompression schemes. Los exploraremos más a fondo en las siguientes secciones.
KTX1
Antes de KTX2, como habrás imaginado, existía KTX1.
KTX1 era un formato contenedor de imágenes simple — es decir, simplemente es un formato que contiene imágenes, las cuales pueden estar en distintos formatos. Podía contener cualquiera de los formatos de compresión de texturas mencionados anteriormente, y también podía contener imágenes RGBA sin comprimir. Es simple, y funciona sin más.
El problema era que, si querías dar soporte a múltiples plataformas, el contenedor KTX1 debía incluir las imágenes en los formatos específicos para cada una de ellas. Eso puede ser difícil de mantener y supone almacenar la misma información en cada formato (los archivos se vuelven más grandes).
KTX2
KTX2 busca resolver aún más la fragmentación mediante formatos transcodificables y supercompression schemes.
Además de los formatos de imagen compatibles con KTX1, KTX2 añade dos formatos transcodificables: Universal ASTC (UASTC) y ETC1S. Estos formatos están diseñados para ser convertidos a los formatos de compresión de texturas específicos de cada plataforma. La conversión desde estos llamados formatos transcodificables a los formatos de compresión de texturas es extremadamente rápida, por lo que es un proceso que puede realizarse sin problemas en tiempo de ejecución (este proceso se llama transcoding).
Además de eso, KTX2 añade soporte para los supercompression schemes. Es una técnica que comprime aún más los formatos transcodificables en disco. Con estas técnicas, podemos lograr archivos KTX2, que son de tamaño similar a JPEG, o incluso más pequeños, a veces.
[imagen de https://www.khronos.org/ktx/]
Como convertir imágenes a KTX
Para convertir tus imágenes a KTX, puedes utilizar las herramientas oficiales de línea de comandos de KTX-Software.
Puedes compilar las herramientas de línea de comandos a partir de los archivos fuente, pero lo más fácil es descargar el instalador en la sección de Releases.
Durante la instalación, verifica que la opción “Command line tools” está marcada.
Dentro de la carpeta de instalación encontrarás la herramienta que necesitas: toktx.exe.
Comando básico:
toktx.exe –encode uastc –zcmp 15 –genmipmap output.ktx input.jpg |
–zcmp: configura el nivel de compresión en disco.
–genmipmap: la cadena de mipmaps completa se generará y se guardará dentro del fichero KTX. Esta es la opción recomendada, ya que generar una cadena de mipmaps de texturas comprimidas es un proceso costoso como para hacerlo en tiempo de ejecución.
Otra opción interesante es –uastc_quality, la cual permite ajustar la calidad vs velocidad de compresión.
toktx.exe –encode uastc –zcmp 15 –genmipmap –uastc_quality 3 output.ktx input.jpg |
toktx tiene un montón de opciones que deberías leer para sacarle todo el partido:
toktx.exe –help |
Benchmarks
Como ejemplo, vamos a usar una esfera simple con un material PBR.
Hemos creado dos materiales idénticos, excepto por el hecho de que uno usa texturas JPG, y el otro, usa texturas KTX.
Como puedes ver, usar KTX reduce drásticamente el uso de VRAM. Las 4 imágenes completas suman 128MB de VRAM cuando se usa JPG, versus 32MB cuando se usa KTX. La calidad de la imagen final es similar, y no notarás la diferencia.
Además, parece que para la mayoría de las imágenes KTX ocupa menos espacio en disco que JPG, aunque puede que no siempre sea el caso.
Para esta prueba, hemos convertido las imágenes JPG a KTX usando la herramienta oficial de línea de comandos «toktx». Encontrar el mejor conjunto de parámetros para pasar a esta herramienta de línea de comandos es un arte, ya que implica jugar con diferentes compromisos calidad/rendimiento. Deberías tratar de encontrar los parámetros más adecuados para las imágenes de tu aplicación, teniendo en cuenta los requisitos de calidad/rendimiento. Por ejemplo, los mapas normales normalmente requieren más precisión que los mapas de color.
Estos son los parámetros que hemos usado para el ejemplo anterior:
color: & ‘C:\Program Files\KTX-Software\bin\toktx.exe’ –encode uastc –genmipmap –assign_oetf srgb –target_type RGB –uastc_quality 3 –uastc_rdo_l 4 –zcmp 20 .\Ktx\Bricks_color.ktx .\Jpg\Bricks_color.jpg
normals: & ‘C:\Program Files\KTX-Software\bin\toktx.exe’ –encode uastc –genmipmap –assign_oetf linear –target_type RGB –normalize –uastc_quality 3 –uastc_rdo_l 0.5 –zcmp 20 .\Ktx\Bricks_normals.ktx .\Jpg\Bricks_normals.jpg
pbr: & ‘C:\Program Files\KTX-Software\bin\toktx.exe’ –encode uastc –genmipmap –assign_oetf linear –target_type RG –uastc_quality 3 –uastc_rdo_l 1 –zcmp 20 .\Ktx\Bricks_pbr.ktx .\Jpg\Bricks_pbr.jpg
AO: & ‘C:\Program Files\KTX-Software\bin\toktx.exe’ –encode uastc –genmipmap –assign_oetf linear –target_type R –uastc_quality 3 –uastc_rdo_l 4 –zcmp 20 .\Ktx\Bricks_AO.ktx .\Jpg\Bricks_AO.jpg |
KTX en Evergine
Hemos añadido soporte tanto para KTX1 como KTX2 y todos los formatos de textura comprimidos específicos de cada plataforma.
Esta es una gran noticia para todas las aplicaciones, pero especialmente para aplicaciones web, ya que su adopción puede mejorar enormemente los tiempos de carga.
Ahora puedes optimizar tus aplicaciones gráficas poca inversión por parte del usuario; toda la funcionalidad de KTX está integrada dentro del motor de forma transparente.
El usuario puede importar archivos KTX en el editor como cualquier otro formato de imagen y usarlos en materiales. La extensión del archivo tiene que ser «.ktx» o «.ktx2».
El Evergine.ImageRuntime ha sido extendido para permitir la carga de archivos KTX.
Si tus archivos GLTF incluyen imágenes KTX (embebidas o referenciadas), todo funcionará automáticamente sin tener que hacer nada.