1 puntos por GN⁺ 2024-11-21 | 1 comentarios | Compartir por WhatsApp
  • Los jaggies y el pixel crawling que aparecen en la rasterización se notan más en movimiento que en una imagen estática, y el artículo compara varios métodos de anti-aliasing con un demo circular en WebGL
  • SSAA, MSAA y FXAA tienen limitaciones distintas: costo de downsampling, dependencia del hardware y deformación de la forma por basarse en posprocesado, respectivamente
  • El Analytical Anti-Aliasing, cuando se conoce el borde matemático de una figura, usa un signed distance field para calcular la distancia al borde y aplica un desvanecimiento de alpha de 1 píxel alrededor del contorno
  • El tamaño del píxel puede calcularse directamente a partir del objeto y el tamaño de renderizado en 2D, y si hay perspectiva 3D se necesitan Screen Space derivatives como dFdx, dFdy y fwidth
  • Puede implementarse incluso en WebGL 1.0/OpenGLES 2.0 sin buffers adicionales ni hardware especial, pero requiere el SDF de toda la figura y tiene límites con formas de alta frecuencia menores a 1 píxel

Anti-aliasing visto con un demo de círculo en WebGL

  • El objetivo del artículo es revisar varias técnicas de Anti-Aliasing para reducir los jaggies que aparecen en la rasterización, y al final presentar una implementación de Analytical Anti-Aliasing
  • La comparación recorre SSAA, MSAA, FXAA, la familia MLAA/SMAA y AAA
  • El demo dibuja un círculo en movimiento en un canvas WebGL, y parte de la idea de que el anti-aliasing debe entenderse en movimiento más que en una imagen estática
  • El canvas de ejemplo renderiza a la resolución nativa del dispositivo, y el recuadro rojo ofrece una vista ampliada 4x
  • Para pantallas de alta resolución donde el aliasing se nota menos, ofrece cambiar entre resoluciones de render Native, 1/2, 1/4 y 1/8, usando integer scaling

Problemas que genera el renderizado básico del círculo

  • La forma más simple de renderizar el círculo es que el fragment shader emita color si length(uv) < 1.0 y, en caso contrario, haga discard
  • El círculo no depende de la resolución real de la geometría, sino que el shader decide qué está dentro y qué está fuera del círculo sobre un quad hecho con 4 vértices
  • varying vec2 uv se interpola en cada fragment y proporciona coordenadas centradas en 0 con un rango de -1 a +1
  • Este método corresponde a Alpha testing, y el valor de length(uv) se conecta después con el signed distance field usado en AAA
  • A baja resolución, el círculo se ve blocky y al moverse se hacen muy notorios el pixel crawling y el wobble, donde filas de píxeles aparecen y desaparecen
  • Las resoluciones 1/4 y 1/8 no solo representan una ampliación simple, sino también casos de elementos pequeños o lejanos en 3D

SSAA: downsampling simple pero costoso

  • SSAA significa Super Sampling Anti-Aliasing y consiste en dibujar a una resolución mayor para luego hacer downsample a un tamaño menor
  • La implementación de ejemplo dibuja el círculo en una textura de tamaño (canvas.width / resDiv) * 2, (canvas.height / resDiv) * 2, luego hace downsample a un framebuffer de resolución estándar y finalmente lo blitea a la pantalla
  • Renderizar al doble de resolución usa 4 píxeles de entrada por cada píxel de salida, así que la memoria y el cómputo aumentan 4 veces
  • En el ejemplo real sí ocurre anti-aliasing, pero se ve más débil de lo esperado
    • Debería haber 4 niveles de transparencia, pero al observarlo hay zonas donde solo se ven 2 niveles
    • A baja resolución, la transparencia de 4 niveles aparece sobre todo cerca de diagonales de 45 grados
    • En la parte inferior alineada a los ejes, solo se ven opaco total y 50% de transparencia, y faltan los niveles de 25% y 75%
  • La causa es que la forma del círculo no se muestrea a resolución 2x, sino que se vuelve a muestrear un resultado del círculo ya cuantizado
  • La implementación de ejemplo usa una textura de resolución 2x e interpolación lineal, así que en la práctica usa 5 veces más VRAM
  • Un SSAA bien hecho combina múltiples muestras de la escena sin buffer intermedio, por lo que requiere una integración profunda con el pipeline de renderizado

MSAA: ventajas y desventajas del muestreo basado en hardware

  • MSAA es una forma de supersampling, pero se aplica sobre todo a siluetas de modelos, geometría superpuesta y bordes de texturas con Alpha to Coverage activado
  • Su implementación depende del hardware de GPU y del proveedor gráfico, y el nivel de soporte varía según el hardware y el driver
  • Como WebGL 1 no soporta MSAA, el ejemplo usa un contexto WebGL 2
  • La UI del ejemplo compara No MSAA, 2x, 4x, 8x, 16x, 32x, 64x y resoluciones de render Native, 1/2, 1/4, 1/8
  • Con gl.MAX_SAMPLES se lee el número máximo de muestras soportadas y solo se habilitan las opciones seleccionables
  • En GPU móviles, la llamada renderbufferStorageMultisample() puede terminar forzándose en la práctica a 4x MSAA
    • En Android, aunque se permita elegir 2x, el driver lo fuerza a 4x
    • En iPhone y iPad, al elegir 2x se convierte en 4x, y la transparencia se redondea a valores cercanos a múltiplos de 50%, lo que genera bordes dobles en el ejemplo
  • Como MSAA se deja en manos del hardware, el dispositivo del usuario puede no soportar la función necesaria
  • El patrón de muestreo puede producir resultados distintos a lo esperado, y según el hardware los niveles de transparencia en el borde del círculo pueden verse en un “orden incorrecto”
  • En ciertas condiciones sigue siendo muy potente
    • forward rendering
    • geometría no demasiado densa
    • GPU con arquitectura de tile-based rendering
  • Rahul Prasad explica que en móvil MSAA no es tan costoso como en desktop, y que en algunas GPU móviles el MSAA 4x puede ser gratis
  • Como material adicional se menciona MSAA color resolve deep-dive de KhronosGroup Vulkan-Samples

El flujo de posprocesado que lleva a MLAA, SMAA y FXAA

  • Un artículo de 2009 de Alexander Reshetov propuso un enfoque para reducir bordes blocky en imágenes con aliasing detectando bordes y aplicando reglas de filtrado según la forma de los píxeles
  • Ese enfoque basado en morfología llevó a MLAA, y después se mejoró como SMAA, con más foco en eliminar artefactos sub-pixel
  • Algunos usuarios consideraban que la familia MLAA/SMAA era demasiado borrosa, y surgió la expresión “vaseline on the screen”
  • El anti-aliasing por posprocesado muestra una transición en la que el AA se mueve hacia shaders, alejándose de un soporte de hardware inestable

FXAA 3.11: estructura y límites de un AA de posprocesado rápido

  • FXAA es el algoritmo Fast approximate anti-aliasing de Timothy Lottes, inspirado en MLAA
  • La última versión publicada es FXAA 3.11, y el demo se basa en la versión lanzada el 12 de agosto de 2011
  • El demo compara la escena circular en resoluciones Native, 1/2, 1/4 y 1/8
  • La configuración base usa FXAA_PC 1, FXAA_QUALITY_PRESET 12, fxaaQualitySubpix 0.75, fxaaQualityEdgeThreshold 0.166, fxaaQualityEdgeThresholdMin 0.0833
  • FXAA primero muestrea la luminancia del píxel central y de arriba, abajo, izquierda y derecha, y si el contraste local es menor que el umbral devuelve el píxel original
  • Si no hace early exit, entonces muestrea también la luminancia diagonal, calcula la dirección horizontal o vertical del borde y busca en ambos sentidos hasta encontrar el final del borde
  • Al final desplaza la coordenada del píxel para hacer texture2D, y según el whitepaper oficial no se limita simplemente a difuminar el borde
  • En el demo circular, los bordes en reposo se ven suaves, pero cuando el círculo se mueve la forma se deforma
    • En las partes superior e inferior alineadas a los ejes aparecen y desaparecen pequeñas protuberancias
    • A baja resolución, el círculo pierde su forma redonda y tiembla como gráficos de PlayStation 1
  • Como solo considera el entorno 3x3 de cada píxel, no puede saber que esa región forma parte de un círculo grande
  • FXAA fue creado para aplicar anti-aliasing a escenas más complejas y ofrece múltiples configuraciones y presets
  • El demo completo con la escena de NeoTokyo° calcula el canal de luminancia a partir de una salida con aliasing y luego aplica FXAA, permitiendo ajustar todos los presets y settings

Entrada de FXAA y condiciones de parámetros

  • Si FXAA_GREEN_AS_LUMA se establece en 1, usa el canal verde en lugar de luma, y en ese caso la entrada RGB debe estar en un espacio de color no lineal
  • La entrada RGB de FXAA debe ser LDR; específicamente, FXAA debe aplicarse después del tonemapping
  • Si no se usa FXAA_GREEN_AS_LUMA, antes de ejecutar FXAA se debe guardar en el canal alpha la luma del espacio perceptual
  • La luma debe calcularse correctamente para que FXAA funcione bien
  • FXAA_QUALITY_PRESET es una configuración que intercambia rendimiento y calidad
    • 12 es el valor predeterminado
    • 15 y 29 son la calidad más alta
    • 39 es EXTREME QUALITY
  • fxaaQualitySubpix ajusta la cantidad de eliminación de aliasing sub-píxel
    • El valor predeterminado es 0.75
    • 1.00 es más suave, y 0.50 es más nítido pero elimina menos aliasing sub-píxel
    • 0.00 significa desactivado
  • fxaaQualityEdgeThreshold define el contraste local mínimo necesario para aplicar el algoritmo
  • fxaaQualityEdgeThresholdMin recorta las zonas oscuras del procesamiento
  • FXAA puede tener un costo de rendimiento bajo si ya existe un pipeline de postprocesado o si se usa deferred shading
  • En gráficos móviles, el acceso a memoria es costoso, así que si hay que crear una configuración nueva de render-to-texture para FXAA, su ventaja de costo se reduce

Lo esencial de Analytical Anti-Aliasing

  • Analytical Anti-Aliasing es un método que dibuja los píxeles ya suavizados sabiendo de antemano qué forma se necesita
  • Al dibujar formas 2D o 3D, hace un desvanecido exacto de 1 píxel en el borde de la forma
  • El ejemplo compara un círculo en resolución nativa, 1/2, 1/4 y 1/8, y muestra suavizado de bordes y conservación de la forma incluso en resoluciones bajas
  • circle-analytical.fs calcula el signed distance field del círculo con dist = length(uv)
  • Para desvanecer con un ancho de 1 píxel los píxeles cerca del borde del círculo, usa alpha = (1.0 - dist) / pixelSizeAdjusted
  • Este método es suave y sin artifacts, permite ajustar la cantidad de filtering y no requiere buffers adicionales ni hardware extra
  • Funciona incluso en WebGL 1.0 básico u OpenGLES 2.0 sin extensiones
  • El smoothing de 1 píxel es nítido, pero según la combinación de resolución de pantalla, tamaño y posición del círculo, los lados de 90 grados alineados al eje todavía pueden percibirse planos
  • Si se aplica filtering con base en el tamaño diagonal del píxel, √2 px = 1.4142..., puede reducirse esa sensación de planitud, aunque la forma se vuelve muy ligeramente más borrosa

El significado de “Analytical” y la implementación basada en SDF

  • En programación gráfica, “Analytical” se refiere a un efecto creado por cálculo a partir de la definición matemática de una shape cuya composición prevista ya se conoce
  • Este término se usa de forma flexible en computer graphics y, según el contexto, puede tener varios significados
  • La implementación se basa en un signed distance field y asume que en cada point muestreado se conoce la distancia hasta la shape deseada
  • Esta información puede hornearse en una texture, como en el renderizado de texto con SDF, o en shapes simples puede derivarse por píxel mediante fórmulas matemáticas
  • Según la signed distance, se hace fade out del borde de la shape, y si la distancia de fade se fija en 1 píxel se obtiene un borde suave
  • Las preguntas clave de implementación son cómo el shader sabe el tamaño del píxel y cómo hace el blend a partir de la distancia
  • Este enfoque ofrece pixel-perfection estable en movimiento, pero no encaja con la rasterización tradicional y requiere un signed distance field de la shape completa

Cálculo del tamaño de píxel: precálculo, dFdx/dFdy, fwidth

  • Si el ancho del fade del borde se fija en un valor constante, como el 95% del radio del círculo, puede verse bien en cierto tamaño y resolución, pero cuando cambia el tamaño puede volverse excesivamente suave o aparecer aliasing
  • El tamaño del píxel es uno de los problemas que resuelven las Screen Space derivatives
  • dFdx, dFdy y fwidth permiten obtener cuánto cambia un valor dado en unidades de píxel de pantalla
  • En el ejemplo, el cambio de distancia se obtiene con pixelSize = fwidth(dist) o pixelSize = length(vec2(dFdx(dist), dFdy(dist)))
  • Las Screen Space derivatives reflejan correctamente las transformaciones, incluida la perspectiva 3D, pero no forman parte del estándar de WebGL 1, por lo que se requiere la extensión GL_OES_standard_derivatives o WebGL 2
  • El método length() calcula la longitud del vector formado por dFdx y dFdy, mientras que fwidth() usa la aproximación abs(dFdx()) + abs(dFdy())
  • La aproximación de fwidth() puede escalarse demasiado en dirección diagonal, haciendo que el fade se aplique más en las diagonales
  • La extensión de Unity Shapes llama al AAA basado en fwidth() “Fast Local Anti-Aliasing” y al método basado en length() “Corrected Local Anti-Aliasing”
  • En 2D, como se conocen el tamaño del render context y el tamaño del quad, el tamaño del píxel puede calcularse directamente por objeto
  • El ejemplo pasa un tamaño de píxel basado en la altura con gl.uniform1f(pixelSizeCircle, (2.0 / (canvas.height / resDiv))), y este método funciona incluso en hardware antiguo sin WebGL 2 ni extensiones

Alpha blending y elección de la función step

  • Una vez calculado el ancho del fade, hay que ajustar la opacidad
  • En 2D, Alpha blending es una opción simple
  • Otra opción es usar MSAA junto con Alpha to Coverage, lo que puede servir en escenas 3D cuando se necesita escribir en el depth-buffer para lograr un blending correcto
  • El alpha debe desvanecerse según la distancia, y normalmente se usa una función step que interpola entre start y end
  • En implementaciones de anti-aliasing en GLSL se usa mucho smoothstep(), pero en este contexto, al ser una función dentro de 1 a 2 píxeles, casi no hay una curva perceptible
  • Si se elimina la interpolación Hermite de smoothstep(), se obtiene linearstep(), que es una interpolación lineal con clamp
  • Si en un quad solo hay una forma, también se puede eliminar el clamp
  • El alpha final puede calcularse con una división simple como float alpha = (1.0 - dist) / (pixelSize * smoothingAmount);
  • En rendimiento, la parte costosa sigue siendo la división por píxel, y las GPU modernas pueden optimizar las multiplicaciones y sumas de la interpolación Hermite con Fused Multiply-Add

Bordes del quad, MSAA y corrección de 0.5 píxeles

  • Existe una interacción entre MSAA + Alpha to Coverage y el rasterizer que solo aparece en cierto hardware
  • Al usar MSAA + Alpha to Coverage, puede ocurrir que desaparezca exactamente 0.5 píxeles en un lado del quad, sin importar la cantidad de samples
  • Para lidiar con esto, el ejemplo añade al SDF un margen de 0.5 píxeles con una forma como dist += pixelSizeAdjusted * 0.5
  • En 2D, puede implementarse manualmente un tratamiento similar a NV_conservative_raster_dilate
    • En el vertex shader, se agranda el quad en 0.5 píxeles
    • En el fragment shader, se reduce el signed distance field en 0.5 píxeles
  • Los demos 2D de la página funcionan de esta manera, y vertex *= size + pixelSize cumple ese papel
  • Los problemas de gamma y premultiplied alpha también son importantes en todas las formas de AA, pero no se tratan para centrarse en AAA

Varias formas y extensión a 3D

  • Se pueden dibujar varias formas dentro de un mismo quad y aplicar anti-aliasing a cada una.
  • Si hay varias formas, ambas deben evaluarse por píxel, y los resultados deben hacerse clamp·weight·sum para que el anti-aliasing se mantenga incluso en los puntos de cruce.
  • Aplicar el color de una vez en la salida de la forma necesaria cuesta menos que dibujar una superposición de color en un pass separado.
  • El ejemplo 3D usa una cámara en movimiento y un cuadrado redondeado 2D colocado dentro de una perspectiva.
  • El fragment shader 3D calcula el SDF de una caja redondeada con roundedBoxSDF y obtiene el tamaño del píxel con length(vec2(dFdx(dist), dFdy(dist))).
  • Si hay multiplicación de matrices de cámara y perspectiva, usar derivados de screen space para obtener el tamaño del píxel es confiable.
  • En teoría, se podría multiplicar por píxel la matriz de perspectiva inversa a las coordenadas del fragmento sin usar derivados, pero el costo de rendimiento es alto.
  • Si se coloca el fade en el centro del borde, se puede reducir la deformación de la forma en tamaños pequeños o con perspectiva fuerte, pero los bordes pueden salirse del quad y generar hard edges o clipping.
  • NVIDIA introdujo la extensión NV_conservative_raster_dilate, que aporta píxeles adicionales en los bordes, pero no puede usarse en WebGL y está limitada a hardware de NVIDIA.

Casos de implementación reales

  • La extensión de Unity Shapes de Freya Holmér se considera la implementación funcionalmente más completa de este enfoque.
    • Aplica anti-aliasing a los SDF con MSAA o hace blending con el método AAA.
    • Incluye motion blur, gradientes de color que respetan la forma y una función que desvanece la opacidad de líneas de menos de 1 píxel.
    • La técnica para líneas de menos de 1 píxel se llama Line Thinness Fading.
  • Valve Software incorporó de forma amplia el renderizado con signed distance fields en el motor Source durante el desarrollo de Orange Box.
    • Se usó de forma destacada para crear elementos de UI suaves pero nítidos en el HUD de Team Fortress 2.
    • Desarrolló un sistema de shaders para line art que produce siluetas suaves incluso cuando imágenes de resolución fija se amplían a resoluciones altas.
    • También maneja outline y drop shadow, y puede aplicarse a elementos del mundo como letreros en espacio 3D.
  • Valve publicó la implementación en un paper de SIGGRAPH 2007, que también incluye casos dentro de mundos de juego 3D.
  • “Shape Decomposition for Multi-channel Distance Fields” de Viktor Chlumský es un caso que desarrolla la técnica mencionada en una nota al pie del paper de Valve.
    • Entre los trabajos relacionados están msdfgen y msdf-atlas-gen.
  • El enfoque de multi-channel distance field usa RGB y un término median para crear texto nítido, y coloca un SDF clásico en el canal alpha para manejar efectos como glow y drop shadow.
  • Los caracteres CJK requieren texturas más grandes por sus detalles finos, y reducir texturas grandes puede generar sus propios artifacts.
  • Un usuario de Hacker News, aappleby, mencionó que Google Maps usa AAA basado en formas capsule para segmentos de carretera.
    • aappleby dijo que él mismo lo escribió hace unos 10 años.
    • Explicó que, al verificarlo con el depurador WebGL Spector.js, el shader code del draw call de calles parece mostrar alpha mezclado dependiente de la forma.

Límites del enfoque SDF y discusión sobre TAA

  • Yakov Galka señala que el enfoque SDF puede generar aliasing porque muestrea el SDF en puntos específicos, por lo que si el SDF tiene componentes de alta frecuencia puede aparecer aliasing.
  • Al rasterizar un círculo de menos de 1 píxel, el enfoque de este artículo podría no eliminar por completo el aliasing.
  • Como método verdaderamente analítico para rasterizar con anti-aliasing formas poligonales y bezier, Yakov Galka menciona Wavelet Rasterization de J. Manson y S. Schaefer.
  • Tras la publicación del artículo, en los comentarios hubo retroalimentación de que la crítica a TAA había sido muy fuerte, y se reconoce que no se abordaron lo suficiente los problemas que TAA intenta resolver ni los que son difíciles de resolver con otras técnicas.
  • Timothy Lottes dijo que ve TAA como una evolución técnica clara, aunque con límites en la motion clarity.
  • FXAA 4 era un blender de 2 frames y es fundamentalmente distinto de TXAA; además, TXAA no usa MLAA y está basado en MSAA.
  • Como material para entender mejor TAA, se recomienda la charla de GDC Temporal Reprojection Anti-Aliasing in INSIDE de Lasse Jon Fuglsang Pedersen, desarrollador de Inside.
  • AAA se considera una técnica capaz de dibujar formas de varios tamaños con suavidad, nitidez y estabilidad en movimiento a resolución nativa.

1 comentarios

 
GN⁺ 2024-11-21
Comentarios en Hacker News
  • Soy el autor, así que responderé si tienen preguntas

    • Google Maps usa AAA con forma de cápsula para todos los tramos de carretera. Lo escribí hace como 10 años :D
    • Gran artículo. Estaba tratando de entender el antialiasing de fuentes MSDF y vi algunas afirmaciones
      Se dice que el antialiasing debe hacerse en espacio sRGB linealizado, no en espacio sRGB [1] [2], pero como durante décadas no se hizo así, las fuentes se han ido ajustando y a veces sRGB da mejores resultados [3] [4]. Me pregunto si tienes algún consejo sobre antialiasing en espacio lineal vs sRGB
      [1] https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-ga...
      [2] http://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing...
      [3] https://news.ycombinator.com/item?id=12023985
      [4] http://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing...
    • Como corrección menor, WebGL sí soporta MSAA desde WebGL1. Pero en WebGL1 solo está disponible en el canvas, no puedes controlar la cantidad de muestras y básicamente solo puedes activar o desactivar el antialiasing
      Incluso en WebGL2 todavía no hay objetos de textura MSAA y solo se soportan render buffers MSAA, así que no puedes leer muestras individuales directamente desde el shader. Es una función útil para pases de render de resolve personalizados, pero eso solo es posible en WebGPU
    • Estoy de acuerdo en que la tendencia reciente de depender de upscalers se ha pasado de la raya y hace que muchos juegos AAA produzcan resultados borrosos y llenos de artefactos. Pero después de ver este análisis profundo de Digital Foundry [1], me pareció bastante convincente el argumento de que tecnologías como DLSS pueden lograr una estabilidad en movimiento y una nitidez que solo ellas consiguen, e incluso superar a SSAA
      Así que ahora ya no pienso “TAA == borroso”, sino más bien “si se usa bien TAA + machine learning, es el mejor antialiasing posible hoy en juegos 3D”. Me da curiosidad saber qué opinas
      [1] https://youtu.be/WG8w9Yg5B3g
    • Me da curiosidad cuánto tiempo te tomó escribir este artículo
      Yo también he escrito algunas entradas de blog basadas en visualización en tiempo real y toman muchísimo tiempo. Aun así, creo que ese es el camino correcto. En una época saturada de contenido, aunque tome más tiempo, me parece mejor para todos hacer menos contenido pero de alta calidad
  • Más que el antialiasing en sí, el problema mayor es todo lo que lo rodea. En la configuración de los juegos casi no explican qué diferencia hay entre las muchas siglas que puedes elegir, y la mitad ni siquiera sé qué significan
    Claro, uno puede buscarlo, pero estaría bien que pensaran un poco más en la facilidad de uso. Creo que este artículo me servirá como referencia en adelante

    • Juegos/gráficos es sin duda un campo lleno de jerga técnica. Si no quieres convertirte en mago, puedes simplemente ir cambiando cosas y ver el resultado. Me gusta el enfoque de poner tooltips detallados en la configuración, como hace Dolphin, pero siempre va a quedar cierto grado de conocimiento tácito
      A nivel meta, siento que últimamente veo muy seguido una reacción contra las siglas. Yo diría que nunca había sido tan fácil como ahora buscar estas cosas. Claro que hay siglas que sí dificultan el aprendizaje o funcionan como una forma de gatekeeping, pero también necesitamos nombrar conceptos con un nivel útil de precisión para poder trabajar, así que me parecen bastante razonables las siglas de configuración gráfica en los juegos
  • Hacer análisis de programación gráfica con ejemplos en WebGL es una genialidad. Es hipertexto que realmente aprovecha las fortalezas del medio. Me recuerda al tipo de artículos que uno podría ver en https://pudding.cool/, pero con mucha más profundidad
    Llevo un tiempo usando MSAAx4 en un motor de render y últimamente había estado pensando si cambiar a una implementación de FXAA/TAA, pero ahora ya no estoy tan seguro de hacerlo. Aprendí mucho aquí y creo que voy a probar un enfoque analítico para elementos de UI. No suelen aparecer tan seguido en HN artículos sobre programación gráfica, pero para quienes quieran más, recomiendo este recurso con recopilaciones de análisis de frames:
    https://www.adriancourreges.com/blog/

    • Steve Wittens también escribe muchos artículos de este estilo en https://acko.net/, como ilustraciones matemáticas mezcladas con WebGL
      Mi favorito en particular es https://acko.net/blog/how-to-fold-a-julia-fractal/. Nunca había visto un recurso que me ayudara tanto a entender la relación entre las funciones trigonométricas y los números complejos
    • De verdad odio TAA. Sobre todo con frame rates bajos, el ghosting es demasiado fuerte. Muchas veces cambio adrede a algoritmos más lentos para evitarlo
  • Los frames con círculos y secciones ampliadas transmiten el mensaje de forma excelente. Todo el artículo se lee muy bien

  • SDF o mSDF no son el futuro, sino clásicos suficientemente buenos
    Diría que la parte de “hay que resolver todos los segmentos de curvas Bézier por píxel, así que el rendimiento cae mucho” es más bien el futuro o el presente. Slug y DirectWrite ya se usan con buen rendimiento
    https://sluglibrary.com/
    https://learn.microsoft.com/en-us/windows/win32/directwrite/...

    • Tampoco hay que olvidar el renderizado de curvas implícitas [0]. La patente está por expirar pronto [1]
      [0]: https://www.microsoft.com/en-us/research/wp-content/uploads/...
      [1]: https://patents.google.com/patent/US20070097123A1/en
    • Hace como 20 años escribí una implementación del paper de Loop/Blinn para Microsoft Game Studios, y me pregunto si todavía la siguen usando
      Hubo que trabajar muchísimo para dejarla a nivel de producción. La teselación basada en Voronoi de ese paper se comportaba patológicamente mal con muchos caracteres asiáticos
    • Puede que lo recuerde completamente mal, pero ¿el algoritmo que usa Slug no está cubierto por una patente?
  • Mientras hacía scroll en el artículo, lo primero que me saltó a la vista fue la captura de NeoTokyo. Corrí por ese pasillo miles de veces. Administré el servidor de ese mod durante años y la pasé increíble con una comunidad pequeña, talentosa y muy buena

    • Lo más sorprendente es que todavía se juega activamente. Todos los viernes en la noche se llena un servidor, y a veces también pasa los sábados y domingos. Tiene una base de fans bastante dedicada, y nunca había visto ese nivel de compromiso en un juego multijugador tan viejo
  • Como alguien que ha escrito tanto motores de renderizado 2D como 3D, agregaría una pequeña pista: realmente son muy distintos. No es solo una dimensión más; los objetivos, casos de uso y expectativas son completamente diferentes
    Así que, más que decir que “todo lo que se habla aquí también se extiende al 3D”, diría que este artículo en su mayor parte trata sobre renderizado 3D, no sobre renderizado 2D. Un buen artículo que aborda este tema desde la perspectiva del renderizado 2D es https://ciechanow.ski/alpha-compositing/
    En 3D a nadie le importa, pero en 2D un criterio de antialiasing muy importante es la precisión y el sesgo. Por ejemplo, AAA tiene mucho sesgo, así que es impreciso. Si dibujas la misma forma varias veces en la misma posición, se vuelve más opaca o más oscura. Con MSAA eso no pasa; el error está acotado y no hay sesgo

    • Ayer vi tu proyecto [0] mientras estaba pensando en un renderizador vectorial 3D basado en WebGPU en JS/TS
      El dibujo de líneas gruesas me pareció especialmente interesante, porque es difícil [1]. Hace poco también vi esto [2], y me puse a pensar si se podría usar esa técnica convirtiendo todas las formas en segmentos de curvas Bézier cuadráticas. Me interesa saber si te parece un camino que valga la pena seguir
      [0] https://github.com/Lichtso/contrast_renderer
      [1] https://mattdesl.svbtle.com/drawing-lines-is-hard
      [2] https://scribe.rip/@evanwallace/easy-scalable-text-rendering...
    • Es difícil considerar que este artículo se generalice tal cual al 3D
      La solución propuesta depende de campos de distancia con signo, pero pasa muy por encima de la parte importante: “¿distancia a qué?”. En 2D es claro, porque basta con medir la distancia hasta el borde entre el objeto y el fondo, es decir, hasta la silueta
      En 3D se complica porque el objeto puede rotar y generar autooclusión. ¿Con respecto a qué se mediría el SDF? La silueta 2D proyectada de un objeto 3D cambia constantemente, así que no se puede simplemente precalcular
  • Me alegró ver el enlace a Captain Disillusion. No conocía a ese tipo, y su trabajo es impresionante. Link directo para quien tenga interés en efectos de video: https://www.youtube.com/@CaptainDisillusion

  • El artículo está bien estructurado, pero creo que la parte donde ataca a TAA puede llevar a confusión. El antialiasing con SDF no es, de ninguna manera, una alternativa a TAA
    TAA trata todo tipo de aliasing, pero aquí solo se trata el aliasing de bordes. Muchos juegos modernos usan enfoques basados en Monte Carlo para la iluminación indirecta y otros efectos, y eso en la práctica requiere TAA

  • La parte de “los chips móviles soportan exactamente MSAAx4 y la situación es extraña. En Android puedes elegir 2x, pero el driver igual lo fuerza a 4x” me parece un poco rara
    En mi teléfono Android sí se nota claramente la diferencia entre 2x y 4x, aunque no se ve tan “redondeado” como del lado de iPhone