En el mundo del desarrollo gráfico moderno, la calidad visual y el rendimiento son aspectos fundamentales que un programador o artista digital debe entender y optimizar. Las texturas juegan un papel clave en esta ecuación, y dentro de ellas, la técnica de mipmapping y la selección adecuada de niveles mipmap son herramientas esenciales para evitar el famoso aliasing visual mientras se mantiene un rendimiento eficiente. A continuación, nos adentraremos en el detalle minucioso de cómo las GPUs seleccionan dichos niveles de mipmap y por qué esta selección es tan importante para lograr imágenes nítidas y performantes. Primero, es imprescindible comprender qué es mipmapping y por qué esta técnica es necesaria. La mipmap es una colección de versiones de una textura, cada una a diferentes resoluciones, generalmente reducidas a la mitad en tamaño sucesivamente.
Estos niveles se nombran desde el nivel 0, que es la textura en máxima resolución, hasta niveles mayores que se corresponden con texturas más pequeñas y borrosas. La razón principal para generar mipmaps es reducir el aliasing que ocurre cuando una textura de alta resolución es mapeada a superficies que varían en tamaño o ángulo en pantalla. Sin mipmaps, la pantalla puede mostrar patrones no deseados y un efecto pixelado, especialmente cuando la textura está muy alejada o vista en ángulos agudos. Cuando un fragmento (pixel) en pantalla necesita mostrar una porción de una textura, la GPU determina qué nivel de mipmap usar de forma automática. Esta selección está basada en la estimación de cuánto espacio de la textura ocupa un pixel en pantalla.
Para tomar esta decisión con precisión, la GPU calcula las derivadas parciales de las coordenadas de muestreo de la textura respecto a las coordenadas de la pantalla. En HLSL y otros lenguajes de shaders, estas derivadas se obtienen con funciones intrínsecas como ddx() y ddy(), que permiten calcular la tasa de cambio de las coordenadas de textura en dirección horizontal y vertical, respectivamente. Este cálculo es esencial porque la cantidad de distorsión y compresión de la textura en pantalla determina cuántos texeles están siendo mapeados a un solo pixel de la pantalla. Cuanto mayor sea esta tasa de cambio, mayor es la distorsión y, por lo tanto, se debería usar un nivel de mipmap inferior (una textura más pequeña y desenfocada) para mitigar el aliasing. El nivel de mipmap, o LOD (Level of Detail), se determina conceptualmente aplicando la fórmula logarítmica log2(ρ), donde ρ es un factor de escala asociado al máximo entre la norma de las derivadas parciales en cada dirección.
Esta metodología se basa en el cálculo del jacobiano de la transformación entre el espacio de pantalla y el espacio de textura. Sin embargo, en la práctica, el proceso es más complejo debido a la forma en que las GPUs manejan el cálculo de las derivadas y la selección del nivel mipmap. Este proceso no solo involucra magnitudes de derivadas simples, sino que también considera transformaciones elípticas que describen el mapa de huella o “footprint” de un píxel sobre el espacio de la textura. Dicha huella aparece como una elipse cuando se lleva a cabo una transformación lineal desde el espacio pantalla al espacio de textura. La correcta estimación del área y forma de esta huella es crucial para seleccionar un nivel de mipmap que refleje fielmente la cantidad de textura cubierta sin perder detalle o generar aliasing.
Para ello, la GPU aplica una transformación ortogonal apropiada al jacobiano, estudiada teóricamente en los trabajos de Heckbert de 1989, y que transforma las derivadas parciales en un sistema de coordenadas nuevo donde la elipse está alineada con los ejes principales. Este procedimiento elimina posibles deformaciones o sesgos causados por shearing, facilitando así el cálculo correcto de los ejes mayor y menor de la elipse, que definen la anisotropía de la huella de muestreo. La implementación práctica de esta transformación, incluyendo las numerosas condiciones especiales para componentes nulos o paralelos y la prevención de errores numéricos, es compleja y varía según el proveedor de hardware. Por ejemplo, las GPUs Nvidia tienden a usar aproximaciones más simples que sacrifican algo de precisión para ganar velocidad, mientras que otros fabricantes como AMD o Qualcomm pueden implementar métodos más refinados y matemáticamente rigurosos. Otro factor que modifica la selección del nivel mipmap es el tipo de filtrado de texturas utilizado.
El filtrado bilineal ajusta las muestras interpolando dentro del mismo nivel mipmap, lo que suaviza las transiciones entre texeles en esa textura. El filtrado trilineal es una extensión que suaviza aún más la transición interpolando entre dos niveles mipmap consecutivos basándose en el valor fraccional del LOD. Esto evita las duras transiciones de un nivel a otro, dando resultados visuales mucho más agradables. Más allá del trilineal, existe el filtrado anisotrópico, que aborda un desafío particular. Cuando la huella de muestreo de un píxel es altamente estirada en una dirección, la interpolación solo con mipmaps causa un desenfoque notable, pues encuentra difícil preservar detalles en una dirección específica.
El filtrado anisotrópico detecta estas situaciones, determina la razón de anisotropía entre los ejes mayor y menor de la huella y ajusta la cantidad y ubicación de las muestras tomadas a lo largo del eje con mayor distorsión. De esta forma, mejora la nitidez en ángulos oblicuos o superficies que se extienden hacia la cámara, manteniendo la calidad visual sin comprometer excesivamente el rendimiento. La selección adecuada del nivel de mipmap bajo filtrado anisotrópico implica que el nivel no se escoge simplemente basándose en la longitud del eje mayor, sino que usa la longitud del eje menor, que representa la resolución efectiva del área cubierta en texturas. Junto a esto, la GPU toma múltiples muestras a lo largo del eje de anisotropía y las promedia, lo que incrementa el detalle en los escenarios más complejos. Los desarrolladores que desean implementar o simular estas técnicas en shaders personalizados pueden valerse de las funciones SampleGrad y SampleLevel disponibles en APIs gráficas modernas.
SampleGrad permite especificar explícitamente las derivadas parciales cuando los cálculos automáticos no son confiables, mientras que SampleLevel permite seleccionar manualmente el nivel mipmap, útil para efectos especiales o técnicas avanzadas como la parallax mapping o el ray marching texturizado. Por otro lado, implementar un sistema de filtrado anisotrópico manualmente en shader es posible pero costoso en cómputo. Implica calcular la huella elíptica, determinar la dirección y razón de anisotropía, escoger la cantidad de muestras a tomar y realizar una serie de muestreos y mezclas múltiples. Este enfoque puede ser viable en plataformas donde el hardware carece de soporte nativo o para fines didácticos o experimentales, pero normalmente el hardware está optimizado para esta tarea, proporcionando resultados de alta calidad con un costo eficiente. En resumen, la selección de niveles de mipmap es un proceso elaborado que va mucho más allá de simplemente usar derivadas para escoger un nivel con base en la escala.