lunes, 12 de octubre de 2015

"Compilando" circuitos en MotoGT

Los que hayan jugado MotoGT sabrán que la primera vez corren en un circuito deben esperar buen rato hasta que cargue. Luego, las siguientes veces carga mucho mucho más rápido. Esto se debe a que cuando descargan MotoGT no descargan todas las imágenes que necesita para montar el circuito en pantalla. En su lugar, descargan otro conjunto de imágenes, a partir de las cuales se puede obtener el primero. Digamos que serían como los "fuentes" de los gráficos del circuito. Esto es así por varios motivos interesantes que vengo a comentar. Y como en estos días estuve reimplementando todo ese sistema para MotoGT2, también traigo novedades y algunas capturas para que vean cómo está mejorando el juego.

El molesto cartel que aparece en las primeras carreras luego de instalar MotoGT 1

Empecemos por detallar mejor qué requiere un circuito, y cómo lo genero. En mi juego, la parte "visual" del circuito es básicamente una imagen gigante. Creo que es más común en este tipo de juegos armar el mapa en base a tiles, o algo similar un poco menos estructurado. La ventaja de estos métodos es que utilizan texturas pequeñas que se van repitiendo y combinando para conformar el mapa. Como son pequeños patrones que se repiten, suelen tener una buena resolución. En mi método, en cambio, un circuito grande ocupa realmente mucho espacio en memoria. No necesito una malla, ni tengo que armar las partes, ni mantener un tilemap, ni nada de eso. Pero tengo que limitar el tamaño de los circuitos, o la resolución de sus imágenes para evitar problemas.

Por tomar un ejemplo, el primer circuito utiliza una imagen de 3025x2909 pixeles. Esto serían unos 30 megas. Las dibujo escaladas entre 3 y 5 veces (en comparación con las demás texturas). Entonces, cuando la cámara hace su máximo zoom, se ven algo pixeladas o blureadas, dependiendo del filtro que use para el escalado. Pero en general, cuando la moto se mueve (que es lo más común), entre que la cámara se aleja un poco, y que el movimiento hace más difíciles de apreciar a los detalles, ese factor de escala queda bien y no molesta.

En un primer momento usé esta estrategia porque me resultaba más simple. Dibujaba la base de los circuitos con Inkscape, y luego con Gimp les aplicaba algunos efectos para que no parezcan tan básicos. Cargarlos en el juego era relativamente trivial. Solo tuve la precaución de partir las imágenes en piezas de no más de 512x512px para evitar problemas en placas de video que no soportaban texturas "grandes". Y con esto todo parecía bastante decente.

Parte de las imágenes "fuente" (como salen de Inkscape) para el circuito "Water Lane".
Derecha: capa "base" (superficies), Izquierda: capa "over" (objetos sobre la superficie).

Pero había dos problemas. Por un lado, el espacio que ocupaban en disco estas imágenes. Tenía que subir un juego de 300 megas, y ustedes tenían que bajar 300 megas... ¿y tanto para eso? Seamos realistas, lo gráficos de MotoGT, a pesar de mis esfuerzos, son bastante bizarros. No justifican tanta descarga (detesto bajar un juego de 1GB y que sea una porquería... habiendo tantos juegazos de menos de 100MB), y a mi me era tedioso andar subiendo actualizaciones tan grandes. Entonces quería un paquete chico, así que busqué cómo comprimir estos recursos gráficos. Todas las imágenes se guardan como png, que de por sí ya es un formato con muy buena compresión y sin pérdida.

Pero si hay algo que arruina a un algoritmo de compresión, es el ruido aleatorio. Y es mayormente ruido lo que yo agregaba en Gimp para que las "texturas" parezcan texturas y no sean solo colores lisos. Para poner números, una de esas imágenes gigantes con la compresión del png, sin ruido ocupa alrededor de 1MB, y con ruido casi 30MB. Así que mi estrategia fue incluir las imágenes sin ruido en la descarga, y que MotoGT les aplique ese ruido al cargarlas por primera vez. Por esto la primera vez tardaba tanto. Pero una vez aplicado el ruido, MotoGT guardaba las versiones ruidosas, y entonces ya nunca más volvía a necesitar tanto tiempo.

Jugando a mejorar el aspecto de "Water Lane" con GIMP.

Y con esto yo obtengo otra gran ventaja adicional (y para mi en lo personal más importante): si quiero modificar el circuito, no tengo que volver a hacer todos los pasos a mano en Gimp. Solo exporto el png base desde Inkscape, y dejo que MotoGT haga el resto. Esa automatización, desde el punto de vista de quien arma los circuitos, es algo muy muy bueno. En MotoGT tengo para cada circuito al menos dos de estas imágenes, una con la base (superficies), y otra con los objetos que van sobre la pista (como por ejemplo tribunas). MotoGT1 le aplicaba ruido a la primera, y le pegaba la segunda encima. Estos pasos estaban en un pequeño script al que se le podían hacer algunas mínimas variaciones. Los algoritmos para los efectos no triviales fueron copiados y adaptados desde el código fuente del mismísimo Gimp (código muy prolijo por cierto a pesar de ser código C).

Recientemente reimplementé todo esto para MotoGT2, y en el camino agregué unos cuantos filtros nuevos, y flexibilicé bastante ese minilenguaje para el script con los pasos. Ahora tengo más filtros, más modos de mezclas entre capas, mecanismos de selección para aplicar los filtros en zonas, etc. Y todo controlable dese ese pequeño script. Digamos entonces que el workflow para hacer un circuito es: 1) dibujar en Inkscape la base y la capa de objetos; 2) exportar las dos cosas a png; 3) encontrar en gimp la combinación de capas y filtros que mejor funcione; 4) escribir esas combinaciones en el script; 5) ajustarme el casco y cargar MotoGT. 

Imágenes generadas automáticamente por MotoGT 1 (izquierda) y MotoGT 2 (derecha) a partir base y over.
Parece que base mejoró mucho, ahora tocará trabajar sobre over.

Entonces, el trabajo creativo lo hago experimentando con Inkscape y Gimp, y cuando llego a algo que me gusta, lo traduzco a mi script. Si necesito un filtro o un modo de mezcla de Gimp nuevo en mi motor, siempre están sus fuentes y su muy buena documentación para implementarlo. Con todo esto, ahora tengo dentro de MotoGT una mini-biblioteca de procesamiento de imágenes propia, fácil de extender, y cada vez más completa. Los resultados empiezan a estar a la vista.

No hay comentarios:

Publicar un comentario