¿Porque la digitalización de señales causa el aliasing?

Bienvenid@s a la segunda entrega sobre aliasing y antialiasing que estoy realizando gracias a Shawn Hargreaves.

La verdad es que me gustan las matemáticas, no soy muy bueno la verdad pero me gustan. Desde esa visión intentaré explicar el/los motivos por el que ocurre el aliasing de manera más detallada. Espero que os guste.

La mayoría de las operaciones involucradas en el renderizado gráfico pueden reducirse al muestreo digital de una señal. Pero ¿que es una señal?, una señal es un valor que cambia a medida que nos movemos por alguna coordenada en el espacio (que puede ser en 1D, 2D o 3 o más Ds ;)). Los tipos más comunes de señales que se usan en renderizado gráfico son:

  • Una textura, en la que el color cambia a medida que nos movemos por cada coordenada 2D de ella.
  • Una función de aplicación de luz (o shader), en la que el brillo cambia a medida que cambiamos el ángulo de la luz.
  • El borde de un triángulo, cuya posición cambia a medida que nos movemos por él.
  • La posición de un objeto que se mueve, que cambia con el tiempo.

Estas señales se pueden expresar con ecuaciones matemáticas, pero son representadas más comúnmente como una serie de señales digitales. por ejemplo: un array que guarda los valores de la señal para varias coordenadas

Nota: Se suele pensar que el mundo real usa señales analógicas, pero cuando nos metemos en el nivel cuántico está totalmente plagado de ejemplos digitales. Las partículas subatómicas son totalmente discretas. Los fotones o están o no están, así que el briyo de una luz nunca podría contener un número fraccional de fotones (por ejemplo 1,3 fotones). Las cosas sólo parecen que son continuas porque estas partículas son muy pequeñas. La realidad está pixelada, solo que a una resolución inmensa. 🙂

El muestreo ocurre cuando queremos transformar una señal en otra, por ejemplo:

  • Para renderizar un triángulo, transformamos su descripción matemática en un array de pixeles.
  • Para mapear una textura en ese triángulo, cogemos las señales de la textura y la ponemos en un array diferente de píxeles de colores.
  • Para iluminar el triángulo, transformamos una ecuación matemática de luz calculando su valor para cada píxel que forma l triángulo.

Aunque las implementaciones suelen estar muy optimizadas, todas ellas funcionan de la misma manera:

  • La señal de salida está definida como un array de valores digitales.
  • Cada elemento del array de salida tiene su correspondencia con la señal de entrada.
  • Si la señal de entrada es una ecuación matemática, se calcula.
  • O si la entrada son varios muestreos digitales, se busca el valor en la posición indicada.

¿Fácil? Pues es de aquí de donde vienen la mayoría de los aliasing.

Ejemplo con tiempo: Imaginemos una señal en una dimensión, guardada como un array de 512 valores digitales:

Señal digital de 512 valores

Ahora vamos a convertirla en un array de tan sólo 64 valores, cogiendo un valor de cada 8 de la señal original. Fijaos que no hay ningún motivo para tomar esos valores de forma uniforme. Sólo lo hace más fácil de visualizar, pero si fuésemos a mapear una textura en un lado de un objeto renderizado con una perspectiva 3D, la relación entre la entrada y la salida podría ser una función más compleja.

La nueva señal tiene una forma muy parecida a la original, pero con menos detalles:

Señal digital de 64 valores

Es feo, pero sólo es por haber reducido de 512 muestras a 64, si hiciésemos zoom out no se verían los bloques.

Si necesitase por algún motivo volver a una resolución de 512 valores, podríamos hacerlo interpolando los valores más que repetir los de la señal original. A esto se le conoce como filtro lineal (el ejemplo anterior usaba muestreo puntual) y produce una imagen que se parece más a la original aunque con menos detalles:

Imagen con filtro lineal

Ahora viene lo interesante, fijaos qué pasa si reducimos la señal de salida a una con tan sólo 16 muestreos:

Señal digital con 16 valores

Ahora 8:

Señal digital con 8 valores

7:

Señal digital con 7 valores

Y finalmente con 6:

Señal digital con 6 valores

¿Porqué la de 8 muestras tiene un pico, la de 7 es casi plana y la de 6 es casi la opuesta de la de 8?

El problema es que estamos haciendo un muestreo tan bajo que los valores obtenidos no son suficientes para hacer una representación adecuada de la señal original. Termina siendo una señal de salida casi aleatoria, ya que no se parece casi en nada a la original. Cuando reducimos el número de muestreos radicalmente el resultado final no suele tener sentido alguno.

Sin embargo, el alliasing puede ser un problema incluso cuando no reducimos el número de muestreos.

Vamos a ver un ejemplo:

  • Descarga esta imagen y ábrela con Paint.NET
  • En el menú ve a Image/Resize
  • En el desplegable de Resampling selecciona: Nearest Neighbor.
  • Escala al 80%
  • ¿Ves las rayas oscuras que aparecen?
  • Deshaz lo que has hecho (Ctrl+Z)
  • Ahora escala al 75%
  • Otras rayas totalmente diferentes
  • Imaginad lo feo que quedaría esto en una animación de una textura a media que se va alejando.

Espero que os sirva.

Juan María Laó Ramos.
Artículo original

Un pensamiento en “¿Porque la digitalización de señales causa el aliasing?

  1. Yelinna

    El muestreo usando menos muestras funciona en este ejemplo como un filtro pasabajas, donde las altas frecuencias de la señal (es decir, los cambios bruscos y/o rápidos) son omitidos pues al hallarse las alta frecuencias “entre muestras” terminan perdiéndose.

Los comentarios están cerrados.