MIPMap Mayhem
Ya lo dicen muchos: leer es malo porque da ideas. Y las ideas, pues ya se sabe, a veces, nos llevan a follones ^_^. Hace bastantes meses leí un paper,, que describía cómo en muchas ocasiones dejamos pasar buenas oportunidades de afinar nuestro render empleando recursos gratuitos[1] del pipeline. Y ya algo menos crípticamente, describía que se pueden editar los niveles de MIP para mancharlos de colores, parece evidente, pero es más potente y flexible de lo que parece.
El ejemplo del artículo era realmente bueno: supongamos que queremos rendear una chimenea cubierta por una finísima capa de hollín. Cuando la miramos directamente, es decir: perpendicularmente, podemos ver el cemento del que está hecha, quizá ennegrecido, pero vemos claramente el gris. Sin embargo, conforme alejamos la vista y observamos zonas más alejadas del tubo, este es progresivamente más y más negro. En un shader, podríamos emplear el ángulo que forma el punto de vista y la superficie para, empleando por ejemplo una textura degradada de un sólo píxel de ancho, obtener un factor de ennegrecimiento, eso es como mínimo un producto dot más una consulta de textura y probablemente una suma ponderada con respecto al color computado para el material base [2]. Lo que quizá sea demasiado para una maldita chimenea, que en realidad está ahí sólo como decorado, etc. etc.
El articulista proponía un camino lateral para obtener el mismo efecto. ¡Usar la cadena de MIPMap! Es decir: pintar de negro los MIPs más profundos, de modo que el filtrado nos dé ese oscurecimiento, sin necesidad de emplear más ranuras de shader: ¡todo pasa por la textura! Okydoky, echando memoria, recuerdo cómo era todo aquello y me digo: mañana de domingo, … no hay resaca a la vista, c’mon, lets do it!
Empecemos por la chimenea, algo suave y redondeado, … un cilindrito!

Vale, aprovechando que también estoy intentando pulir un poquito mi XSI, hago yo mismo el modelado[3], el mapeado UV y me monto una textura inicial. Y aquí es donde viene el problema: no tengo photoshop! Y tampoco tengo ganas de machacar ninguna versión, he decidido mantener algo más a ralla el volumen de software de origen oscurete que consumo: el GIMP tendrá que valer.
A esto, hay que añadir otra situación: me es físicamente imposible (por tiempo) aprender en profundidad muchas más cosas ahora, así que debo mantenerme en DirectX. Esto me lleva a usar DDS preferentemente ya que luego podré usar todas las demás herramientas que Hasefrocht incluye en su mastodóntico SDK.
OK, recapitulando: DDS + MIPMap y todo sobre XSI PERO no hay photoshop, esto va a ser divertido[4]!
Lo primero que se necesita es bajar el SDK de Microsoft, eso es más que evidente. Luego hay que hacerse con las tools de texturas de nVidia, que podéis bajar del site de: nVidia Texture tools. Todo es recomendable y el mundo de las texturas es gigantesco, pero lo único necesario es el paquete DDS Utilities. Con todo instalado se tira para alante y:
1. Se crea la textura difusa base y se deja bien guardada.
2. La textura base carece de MIPs así que hay que crearlos, para eso Microsoft nos ofrece una herramientita: Texconv.exe con la que podemos batchear una conversión a DDS más la creación de los MIP chains:
texconv -m 6 -f R8G8B8 -ft DDS tex_cilinder.png
Codigo que genera 6 niveles de MIP en RGB de 24 bits desde tex_cilinder.png.
3. Ok, tenemos los MIPs pero no podemos editarlos, al menos no fácilmente ya que no disponemos de photoshop. Aquí entra la utilidad de nVidia[5], en particular:
detach tex_cilinder separa el DDS inicial en toda la cadena de MIPs, es incómodo, pero vamos, se puede automatizar empleando un .bat, ó si dispones de una consola de verdad en tu sistema, pues miel sobre ojeras.
4. En este punto tenemos un puñao de ficheros que no podemos editar, de nuevo empleando las nVidia DDS tools:
readDXT tex_cilinder_00.dds tras lo cual tendremos TGAs, que sí puede editar GIMP.
Yo hice algo tan tontorrón como esto:

Como veis el mip inicial es más o menos plano y luego meto dos cambios muy muy cantosos para poder verlos fácilmente en el render.
5. En este punto hay que hacer el camino inverso TGA –> DDS y luego, recomponer el MIP chain:
texconv -m 1 -f R8G8B8 -ft DDS tex_cilinder_01.tga Notar que se le pide un mipchain de longitud 1
6. y para terminar, recomponer el MIP chain sobre un DDS:
stitch tex_cilinder
Y se termina obteniendo una textura en DDS con los MIP maps modificados. Ya con ese material volví hacia XSI y compuse un árbol de render sobre DX muy sencillo, sin shaders programables y con una simple textura, activé el filtro MIP y listo: como veis, las UVs se fueron de baras directamente, lo que me molestó muchísimo. Además no he encontrado un modo sencillo de crear un render de aspecto plano, es decir, con luz ultra-blanca desde cualquier punto, acabaré componiéndolo en un zeider…

La coña de esta técnica es que funciona. Es curioso verla en marcha, … llama la atención, impresiona, sobre todo porque el MIP-mapping suele ser un punto del render que solemos ignorar, simplemente está ahí y fuera.
El tortuoso camino de la conversión de texturas
Bien, el numero de pasos que hay que dar para editar un MIP-Chain es ridículo, pero de momento no se me ha ocurrido nada mejor (legalmente), si se me llega a ocurrir algo os lo haré saber, como siempre.
–
1. Sí, ya sé que lo único gratuito es no ejecutar absolutamente nada.
2. Lo que en sí mismo no significa nada: en una 8800 GTX te-la-suda! ![]()
3. Soy 1337, ¡he logrado modelar un cilindro! ¡Chúpate esa Baena!
4. Entre otras cosas porque la versión 5.0.x de XSI se da cada castaña con DirectX de alucinar. Se mete unos crashes por desconectar nodos de texturas que son de terror. Esperemos que la versión 6.5.x arregle y reenfoque todo el asunto.
5. Que viene con dos PDFs de ayuda, así que no incluyo ningún link para documentar.