Suavizado de contorno 101

Introducción

El suavizado de contorno es una especie de héroe anónimo en los gráficos web: es la razón por la que tenemos un texto claro y formas de vectores suaves en nuestras pantallas. En la actualidad, en los navegadores, se usan varios enfoques para el suavizado de contorno, que son los más obvios cuando se trata de la renderización de texto. Cuando el algoritmo que se usa para la antialización de interruptores puede generar resultados visuales inesperados. En este artículo, analizaremos los enfoques para el suavizado de contorno y cómo se dibujan los píxeles.

Como todos sabemos, todas nuestras pantallas están compuestas por píxeles. Es una cuadrícula gigante de bloques, cada uno de los cuales contiene componentes rojos, verdes y azules (RGB). A la distancia podemos ver imágenes, texto e íconos, pero de cerca podemos ver la cuadrícula de componentes RGB y cómo está compuesto todo.

Píxeles de una pantalla en primer plano. Cada píxel tiene componentes rojos, verdes y azules
Figura 1: Píxeles de una pantalla en primer plano. Cada píxel tiene componentes rojos, verdes y azules.

Suavizado

Entonces, ¿qué sucede cuando dibujamos una forma vectorial y esta pasa por una “parte” de un píxel? Supongamos que la forma que dibujamos es negra y que el fondo es blanco. ¿Deberíamos colorear ese píxel? Si lo coloreamos, ¿qué color debería ser? ¿Negro, gris, algo más?

El proceso de suavizado de contorno determina el color que debemos usar al rellenar los píxeles. La versión más simple se denomina suavizado de escala de grises y trata los tres componentes de los píxeles por igual. Entonces, si el píxel está medio cubierto, y vamos a suponer que el texto negro sobre blanco por un segundo, para que sea sencillo, pensarías que cada componente se establecerá con brillo medio (sabemos que lo hice), pero en realidad es más complejo que eso: debes tener en cuenta el gamma, lo que significa que probablemente nunca lo establecerás en ese valor exacto. Eso, por supuesto, hace las cosas un poco más complicadas, pero como esta es una introducción al tema, no voy a profundizar en eso aquí. Lo importante que debes saber es que el suavizado de contorno en escala de grises se maneja a nivel de los píxeles y, de hecho, podemos hacerlo mucho mejor.

Figura 2: Borde suavizado frente a bordes rígidos
Figura 2: Bordes antisuavizado y rígidos

En la Figura 2, se puede ver que se dibuja el mismo triángulo, pero, en la parte izquierda, se habilitó el suavizado de contorno y, en la derecha, se inhabilitó. Como puedes ver, cuando el suavizado de contorno está habilitado, los píxeles son tonos de gris cuando el triángulo solo pasa por una parte del píxel. Sin embargo, cuando se inhabilita, el píxel se rellena como negro sólido o blanco sólido, y la forma se ve dentada.

Renderización de texto

Cuando un navegador renderice texto, que es esencialmente una forma vectorial, se encontrará con el mismo problema: los caracteres del texto solo rellenarán parcialmente algunos píxeles, por lo que deseamos tener una estrategia sobre cómo rellenar esos píxeles. Idealmente, queremos que el texto tenga suavizado, ya que hará que sea más fácil y agradable de leer.

Sin embargo, resulta que el enfoque en escala de grises para el suavizado de contorno es solo una forma de manejarlo. Un enfoque que se suele adoptar es ser un poco más selectivo en cuanto a la forma en que habilitamos los componentes RGB de los píxeles. El proceso se denomina suavizado de contorno de subpíxeles y, a lo largo de los años, el equipo de ClearType de Microsoft ha invertido una gran cantidad de tiempo y esfuerzo para avanzar en él. Actualmente, se utiliza mucho más, y todos los principales navegadores lo utilizan en mayor o menor medida.

En primer lugar, dado que sabemos que cada píxel, de hecho, está formado por componentes rojos, verdes y azules separados, detectamos cuánta de cada uno de esos componentes se debe “encender” para el píxel en cuestión. Por lo tanto, si un píxel está "mediado" desde el lado izquierdo, podemos cambiar completamente el componente rojo, dejar el componente verde a mitad de camino y dejar el azul apagado. Este proceso se suele describir como "la triple de la resolución horizontal de la pantalla", y se basa en el hecho de que cada píxel es, en realidad, tres componentes separados, uno al lado del otro, y no una sola unidad.

Figura 3: Suavizado de contorno con escala de grises en comparación con subpíxeles
Figura 3: Suavizado de contorno con escala de grises en comparación con subpíxeles

En la figura 3 anterior, puedes ver que, a la izquierda, tratamos cada componente por igual y cada uno está activado o desactivado por igual (escala de grises). Sin embargo, en el lado derecho, usamos el enfoque de subpíxeles, que habilita cada componente (rojo, verde y azul) de manera diferente según cuánto se superponga con la forma que se dibuja.

Sin embargo, con todo eso, la visión humana en realidad no pesa la luz roja, verde y azul por igual. Somos mucho más sensibles al verde que al rojo o al azul, y esto significa que, si bien hay un beneficio definido sobre el suavizado en escala de grises, como señala Darel Rex Finley, habilitar cada componente por separado no generará una mejora del triple en la claridad. Sin embargo, el suavizado de subpíxeles es muy útil, ya que significa que vemos el texto con mayor claridad que si se utiliza el suavizado en escala de grises.

Figura 4: Texto suavizado de subpíxel. Se habilitan componentes individuales de los píxeles para crear el efecto general.
Figura 4: Texto suavizado de subpíxeles. Los componentes individuales de los píxeles están habilitados para crear el efecto general.

Vamos al grano

¿Qué significa todo esto para nosotros como desarrolladores? Desde la perspectiva de Chrome, al menos, hay una combinación de suavizado de contorno en escala de grises y subpíxeles que se utiliza para renderizar texto, y cuál obtienes depende de algunos criterios. Sin embargo, para comenzar, debemos comprender un poco sobre las capas, ya que ese es el criterio principal en juego. Si no te has encontrado con capas y cómo Chrome las usa internamente, Tom Wiltzius escribió una fantástica introducción al tema que deberías leer primero.

Suponiendo que estás familiarizado con las capas o que acabas de leer sobre ellas, continuemos. Si la composición de hardware está habilitada para la página y tienes contenido de texto en una capa que no es la capa raíz, se renderizará de forma predeterminada con suavizado de escala de grises. Los desarrolladores a menudo notan que, si implementan modificaciones en los elementos para colocarlos en sus propias capas (no raíz) (como usar translateZ), notan que el texto se renderiza de manera diferente. A menudo, los desarrolladores aplican activadores de “nuevas capas” sobre la marcha a través de JavaScript o CSS, lo que hace que la renderización de texto cambie de subpíxel a escala de grises. Puede ser confuso si no sabes qué provocó el cambio de representación. Sin embargo, si tu texto reside en la capa raíz, se debe procesar con suavizado de contorno en subpíxeles y, por lo tanto, será mucho más claro de leer.

Pero como todo lo relacionado con la Web, está cambiando. Se habilitará el suavizado de contorno de subpíxeles en Chrome para el texto de las capas no raíz, siempre que la capa cumpla con tres criterios. Vale la pena decir que estos criterios se aplican hoy, pero es probable que cambien y se prevén más casos abordados con el tiempo. Actualmente, esos criterios son:

  1. La capa tiene un color de fondo completamente opaco. En particular, usar border-radius o un valor background-clip no predeterminado hace que la capa se trate como no opaca y la renderización de texto vuelve a suavizado de escala de grises.
  2. A la capa solo se le puede aplicar una transformación de identidad o una traslación integral. Cuando hablamos de integral, nos referimos a valores redondeados. Por ejemplo, translate(20.2px, 30px) daría como resultado un suavizado de contorno en escala de grises, ya que el componente de x, 20.2px, no es integral. La transformación de identidad simplemente significa que no se aplicó ninguna rotación, traslación o escalamiento adicional más allá de los valores predeterminados.
  3. La capa tiene una opacidad de 1.0. Cualquier cambio en la opacidad cambiará el suavizado de contorno de subpíxeles a escala de grises.
Figura 5: Antes y después: escala de grises frente a subpíxel. Ten en cuenta el borde del color del texto a la derecha.
Figura 5: Antes y después: escala de grises frente a subpíxel. Ten en cuenta el borde del color del texto a la derecha.

Por último, ten en cuenta que aplicar una animación CSS puede provocar la creación de una capa nueva, mientras que usar requestAnimationFrame no. Para algunos desarrolladores, las diferencias en la renderización de texto que implican impedir el uso de las animaciones CSS Si usaste JavaScript para animar elementos debido a diferencias en la renderización de texto, comprueba si esta actualización corrige el problema.

Eso es Chrome. En lo que respecta a otros navegadores, Opera, en su transición a Chromium, debería coincidir con los comportamientos de Chrome. Internet Explorer parece utilizar el suavizado de contorno de subpíxeles para casi todo el texto (si habilitaste ClearType, por supuesto), aunque aparentemente no en el modo Metro de Windows 8. Safari, dada la proximidad de WebKit a Blink, se comporta de manera muy similar a Chrome, aunque sin estas nuevas mejoras que permiten un mayor suavizado de subpíxeles. Firefox se comporta de la misma manera que Internet Explorer en la medida en que usa suavizado de subpíxeles para prácticamente todo el texto. Por supuesto, esta lista no es exhaustiva y es probable que en todos los navegadores se use el suavizado de contorno en escala de grises en lugar de subpíxeles. Sin embargo, es bueno saber que este suavizado de subpíxeles se usa mucho en el conjunto principal de navegadores.

Conclusión

Ahora sabes un poco sobre cómo funciona el suavizado de contorno y por qué podrías ver diferencias en la representación de texto en tus sitios y aplicaciones actualmente, especialmente en dispositivos con valores más bajos de PPP. Si te interesa continuar la implementación de Chrome con respecto a la renderización de texto, deberías destacar los siguientes errores:

Recursos y referencias