Aquí tenéis la sexta entrega de la serie sobre aliasing. En esta entrega veremos qué es el Multisampling
Multisampling es la solución para aquellos que quieren usar supersampling, pero no se lo pueden permitir.
La idea es sencilla: en lugar de aumentar la resolución de todo el renderizado, ¿qué pasaría si dejamos la renderización de triángulos y profundidad a una resolución alta, pero dejamos que las texturas y el pixel shading a la baja resolución original?
La renderización normal va así:
- Por cada pixel final que es cubierto por un triángulo:
- Ejecutamos el pixel shader.
- Realizamos el test de profundidad.
- Escribimos el color del pixel.
Y el supersampling así:
- Por cada pixel obtenido con supersampling y que es cubierto por un triángulo
- Ejecutamos el pixel shader
- Realizamos el test de profundidad
- Escribimos el color del pixel
- Cuando pintamos toda la geometría, reescalamos la imagen al tamaño final.
El proceso del multisampling es:
- Por cada pixel que es cubierto por un triángulo
- Ejecutamos el pixel shader
- Por cada pixel obtenido con multisampling cubierto por la intersección del triángulo y el pixel actual:
- Realizamos el test de profundidad
- Escribimos el color del pixel
- Cuando pintamos toda la geometría, reescalamos la imagen al tamaño final.
Al contrario que el supersampling, que puede implementarse dibujando a un rendertarget normal y usando un pixel shader para aplicar el filtro del tamaño final, el multisampling requiere soporte hardware. En XNA, esto se habilita añadiendo esto al constructor de nuestra clase Game:
graphics.PreferMultiSampling = true;
Como la búsqueda del triángulo y el test de profundidad son realizados a una resolución alta, el multisampling es tan bueno como el supersampling contra el aliasing geométrico y de vértices de triángulos. Pero como el pixel shader sólo se ejecuta una vez por pixel, no sirve de mucho contra el aliasing de texturas o de sombras.
Este es un punto importante y que es fácil de olvidar: El multisampling sólo sabe de vértices y geometrías poligonales.
El multisampling puede suavizar los vértices de los triángulos, y también los vértices que se forman cuando un triángulo intersecta a otro, pero no sabe nada sobre lo que pasa en el interior de cada triángulo. Texturas, sombras e ilumnación producen los mismos resultados que si no se usase multisampling (pensando un poco: el pixel shader sólo se ejecuta una vez, después escribimos 2 o 4 copias del mismo color, y después filtramos estos colores, produciendo el mismo valor con el que empezamos). Si los triángulos tienen bordes interiores causados por las texturas o por las sombras del shader (por ejemplo la frontera de una textura con colores alpha), el multisampling es irrelevante. Esto suele sorprendernos cuando vemos el aliasing en sprites recortados y activamos el multisampling para intentar corregirlo y no pasa nada. Ésta es la naturaleza de la bestia, Si queremos eliminar el aliasing de los canales alpha necesitamos supersampling, o una de las técnicas basadas en texturas/sombras de las que hablamos antes.
Pero entonces ¿porqué es tan popular el multisampling? (y es muy popular, tanto que muchos confunden el término general de “antialiasing” con la técnica de “multisampling”).
La respuesta es fácil: es barato. En hardware (como en la XBOX 360) puede ser muy barato.
Recordemos que la GPU es un pipeline de procesos paralelos asíncrono. El multisampling aumenta el coste de algunas partes del proceso de este pipeline (rasterización, test de profundidad y escrituras en el framebuffer), pero no afecta a las partes que suelen ser los cuellos de botella en el rendimiento ( cálculo de vértices, sombreado de vértices, encaje de texturas y sombreado de píxeles). El trabajo añadido a cosas que no son el cuello de botella puede ser irrisorio, de manera que el multisampling se activa para mejorar la calidad visual con un coste muy bajo.
Aunque estemos bloqueados por el ancho de banda del framebuffer, los diseñadores de hardware son listos y pueden usar un montón de trucos de silicio para hacer que el multisampling sea eficiente, aprovechandose de que el mismo color se escribe muchas veces en una fila. Porqué malgastar memoria diciendo “escribe X, escribe X otra vez, otra vez y otra”, cuando podemos poner una copia de X en el bus, seguidos de un par de bits de flag indicando a donde debe ir el resultado.
Ántes de terminar, vamos a ver cuál es el resultado. Vamos a aplicarlo a nuestro modelo de tanque favorito, primero sin antialiasing, y después usando un multisampling de 4x:
Y las mismas imágenes con un poco de zoom:
Espero que os sirva
Juan Maria Laó Ramos.