Dithering en OpenGL

Hace poco enseñándole a mi amigo Jose lo último que había hecho para Antares con el Razer Hydra sobre cinemática inversa (haré un post sobre ello en breve), se fijó que en el cielo se veían bandas en la degradación de azules. Más tarde ese día me encontraba intentando aplicar dithering al renderizado de los planetas de nuevo, pues ya lo había intentado antes con resultados infructuosos.


Esta vez en vez de intentar generar una función de ruido, generé directamente una textura con ruido (valores aleatorios en R, G, B y A) desde Java y se la pasé al shader. Esta textura debe se de tipo float (4 floats de 4 bytes cada uno) en lugar de unsigned byte (4 bytes sólamente por píxel)


El dithering consiste en aplicar un ruido píxel a píxel, una pequeña variación aleatoria en los valores RGB de los píxels (en el shader se trabaja con los colores en formato float, de ahí que el ruido deba ser también float) que al pasar finalmente de float a unsigned byte (en algún momento se convierte a ese formato para generar la señal de vídeo), en vez de formarse bandas visibles, hace que se difuminen. Para hacerse una idea, el ruido tiene una centésima de la escala RGB de la imagen.


En mi caso he usado un ruido estático en espacio de pantalla, lo que significa que el ruido se aprecia “fijo” en la pantalla, como si estuviera sucia. Si usara ruido variable en el tiempo el renderizado tendría un aspecto granulado como de película antigua. Pero así como está ya me va bien.


Dos fotos para comparar el antes y el después del dithering (clic para ampliar)


Sin dithering:


ditherNoCon dithering:


ditherSiY un detalle ampliado, sin dithering:


ditherDetNoY el detalle con dithering:


ditherDetSi


Como ves el ruido elimina las bandas.


Hasta la próxima!