Ayúdame a comprender el filtrado anisotrópico (AF)

8

Últimamente he estado leyendo sobre el filtrado de texturas, es decir, el filtrado del vecino más cercano, el filtrado bilineal, el filtrado trilineal, el filtrado anisotrópico, los mapas MIP, los mapas RIP, etc.

Desde una perspectiva de alto nivel, creo que puedo entender estas técnicas, cómo funcionan y por qué existen, con la excepción del filtrado anisotrópico. El filtrado anisotrópico me está volviendo loco.

Puedo ver el problema de tener que texturizar una superficie que está en ángulo con respecto a la cámara, pero no entiendo cómo el muestreo de huellas trapezoidales podría resolver esto (aunque puedo ver el resultado). Esto probablemente se deba a que NO entiendo cómo se calcula la huella trapezoidal y cómo se pesan los télex cerrados para muestrear la textura.

Este artículo de Nvidia me confunde aún más al usar oraciones como " cuando un texel es trapezoidal " o " el filtrado anisotrópico escala la altura o el ancho de un mapa MIP en una relación relativa a la distorsión de la textura en perspectiva ". Texel trapezoidal? Escalando un MIPmap? ¿Qué significa esto?

¿Podría ayudarme a comprender cómo funcionan los niveles de FA y FA?

Tenga en cuenta que mi objetivo NO es tener una implementación de OpenGL o DirectX AF, sino comprender cómo funciona AF desde una perspectiva de alto nivel.

Nicola Masotti
fuente

Respuestas:

10

Para comprender la naturaleza del filtrado anisotrópico, debe tener una comprensión firme de lo que realmente significa el mapeo de texturas.

El término "mapeo de texturas" significa asignar posiciones en un objeto a ubicaciones en una textura. Esto permite que el rasterizador / sombreador, para cada posición en el objeto, obtenga los datos correspondientes de la textura. El método tradicional para hacer esto es asignar a cada vértice de un objeto una coordenada de textura, que asigna directamente esa posición a una ubicación en la textura. El rasterizador interpolará esta coordenada de textura a través de las caras de los diversos triángulos para producir la coordenada de textura utilizada para obtener el color de la textura.

Ahora, pensemos en el proceso de rasterización. ¿Cómo funciona? Toma un triángulo y lo divide en bloques del tamaño de píxeles que llamaremos "fragmentos". Ahora, estos bloques del tamaño de un píxel son del tamaño de un píxel en relación con la pantalla.

Pero estos fragmentos no tienen el tamaño de un píxel en relación con la textura. Imagine si nuestro rasterizador generara una coordenada de textura para cada esquina del fragmento. Ahora imagine dibujar esas 4 esquinas, no en el espacio de la pantalla, sino en el espacio de textura . ¿Qué forma tendría esto?

Bueno, eso depende de las coordenadas de textura. Es decir, depende de cómo se asigne la textura al polígono. Para cualquier fragmento en particular, podría ser un cuadrado alineado con un eje. Puede ser un cuadrado no alineado con el eje. Puede ser un rectángulo. Puede ser un trapecio. Podría ser prácticamente cualquier figura de cuatro lados (o al menos, convexas).

Si estaba accediendo a la textura correctamente, la forma de obtener el color de la textura para un fragmento sería averiguar qué es este rectángulo. Luego, busque cada texel de la textura dentro de ese rectángulo (usando la cobertura para escalar los colores que están en el borde). Luego promedie todos juntos. Eso sería un mapeo perfecto de texturas.

También sería extremadamente lento .

En aras del rendimiento, intentamos aproximarnos a la respuesta real. Basamos las cosas en una coordenada de textura, en lugar de las 4 que cubren el área del fragmento completo en el espacio de texel.

El filtrado basado en Mipmap utiliza imágenes de menor resolución. Estas imágenes son básicamente un acceso directo para el método perfecto, al precalcular cómo se verían los grandes bloques de colores cuando se combinaran. Entonces, cuando selecciona un mipmap más bajo, está utilizando valores precalculados donde cada texel representa un área de la textura.

El filtrado anisotrópico funciona aproximando el método perfecto (que puede y debe combinarse con mipmapping) mediante la toma de un número fijo de muestras adicionales. Pero, ¿cómo calcula el área en el espacio de texel para obtener, ya que todavía solo se le da una coordenada de textura?

Básicamente, hace trampa. Debido a que los sombreadores de fragmentos se ejecutan en bloques vecinos 2x2, es posible calcular la derivada de cualquier valor en el sombreador de fragmentos en el espacio de pantalla X e Y. Luego utiliza estas derivadas, junto con la coordenada de textura real, para calcular una aproximación de cuál sería la huella de textura del verdadero fragmento. Y luego realiza una serie de muestras dentro de esta área.

Aquí hay un diagrama para ayudar a explicarlo:

Huella de fragmentos y muestras anisotrópicas.  FYI: si lo has visto antes, es mío.

Los cuadrados en blanco y negro representan nuestra textura. Es solo un tablero de ajedrez de 2x2 tejidos blancos y negros.

El punto naranja es la coordenada de textura para el fragmento en cuestión. El contorno rojo es la huella del fragmento, que se centra en la coordenada de textura.

Los cuadros verdes representan los elementos de texto a los que puede acceder una implementación de filtrado anisotrópico (los detalles de los algoritmos de filtrado anisotrópico son específicos de la plataforma, por lo que solo puedo explicar la idea general).

Este diagrama particular sugiere que una implementación podría acceder a 4 texels. Ah, sí, los cuadros verdes cubren 7 de ellos, pero el cuadro verde en el centro podría extraerse de un mapa MIP más pequeño, obteniendo así el equivalente de 4 texels en una búsqueda. La implementación, por supuesto, ponderaría el promedio de esa búsqueda en 4 en relación con los texel individuales.

Si el límite de filtrado anisotrópico fuera 2 en lugar de 4 (o superior), la implementación seleccionaría 2 de esas muestras para representar la huella del fragmento.

Nicol Bolas
fuente
Gracias por explicar esto y perdón por la respuesta tardía, pero tuve que encontrar el tiempo para leer esto con mucho cuidado. Siento que el único párrafo que no entiendo completamente es aquel en el que hablas sobre sombreadores de fragmentos y derivados. ¿Qué se deriva exactamente en el espacio de pantalla X e Y? ¿Es el valor de coordenadas de textura?
Nicola Masotti
@NicolaMasotti: "Derivado" es un término de cálculo. En este caso, es la tasa de cambio de la coordenada de textura, a través de la superficie del triángulo, en el espacio de pantalla X o Y. Si no conoce el cálculo, entonces no voy a poder explicarlo para ti en una sola publicación.
Nicol Bolas
Afortunadamente sé lo que es un derivado. ¿Hay algún lugar donde pueda ver las matemáticas exactas?
Nicola Masotti
Además, propondría un par de cambios en su respuesta, es decir, " depende de cómo se asigna el polígono a la textura " en lugar de " depende de cómo se asigna la textura al polígono ". Además, cuando dice: " usar la cobertura para escalar los colores que están en el borde ", ¿en realidad quiere decir " colores de peso que están en el borde "?
Nicola Masotti
3

Algunos puntos que probablemente ya conozcas, pero que solo quiero exponer para que otros lo lean. En este caso, el filtrado se refiere al filtrado de paso bajo como el que podría obtener de un desenfoque gaussiano o un desenfoque de cuadro. Necesitamos hacer esto porque estamos tomando algunos medios que tienen altas frecuencias y los estamos convirtiendo en un espacio más pequeño. Si no lo filtramos, obtendríamos artefactos de alias, que se verían mal. Por lo tanto, filtramos las frecuencias que son demasiado altas para reproducirlas con precisión en la versión escalada. (Y pasamos las frecuencias bajas, por lo que usamos un filtro de "paso bajo" como un desenfoque).

Así que pensemos en esto primero desde el punto de vista de un desenfoque. Un desenfoque es un tipo de convolución. Tomamos el núcleo de convolución y lo multiplicamos por todos los píxeles en un área y luego los sumamos y dividimos por el peso. Eso nos da la salida de un píxel. Luego lo movemos y lo hacemos nuevamente para el siguiente píxel, y nuevamente, etc.

Es realmente costoso hacerlo de esa manera, por lo que hay una manera de hacer trampa. Algunos núcleos de convolución (particularmente un núcleo de desenfoque gaussiano y un núcleo de desenfoque de caja) se pueden separar en un paso horizontal y vertical. Puede filtrar todo con solo un núcleo horizontal primero, luego tomar el resultado de eso y filtrarlo solo con un núcleo vertical, y el resultado será idéntico a hacer el cálculo más costoso en cada punto. Aquí hay un ejemplo:

Original:

Hawai

Desenfoque horizontal:

Hawaii borrosa horizontalmente

Horizontal seguido de Vertical Blur:

Hawaii borrosa horizontalmente y luego verticalmente

Entonces podemos separar el filtrado en un paso vertical y horizontal. ¿Y qué? Bueno, resulta que podemos hacer lo mismo para las transformaciones espaciales. Si piensa en una rotación en perspectiva, así:

Hawai girado alrededor del eje Y

Se puede dividir en una escala X:

ingrese la descripción de la imagen aquí

seguido de una escala de cada columna por una cantidad ligeramente diferente:

Hawaii escala en X y luego proporcionalmente en Y

Entonces ahora tiene 2 operaciones de escalado diferentes. Para obtener el filtrado correcto para esto, querrá filtrar más en X que en Y, y querrá filtrar por una cantidad diferente para cada columna. La primera columna no se filtra porque tiene el mismo tamaño que el original. La segunda columna se vuelve un poco más pequeña porque es un poco más pequeña que la primera, etc. La última columna obtiene el mayor filtrado de cualquier columna.

La palabra "anisotropía" viene del griego "an" que significa "no", "isos" que significa igual y "tropos" que significa "dirección". Entonces significa "no es igual en todas las direcciones". Y eso es exactamente lo que vemos: la escala y el filtrado se realizan en diferentes cantidades en cada dirección.

usuario1118321
fuente