Introdução à antialias

Introdução

O anti-aliasing é um herói desconhecido nos gráficos da Web. É por isso que temos texto claro e formas vetoriais suaves em nossas telas. Na verdade, há algumas abordagens atuais para o anti-aliasing usadas em navegadores que são mais óbvias quando se trata de renderização de texto. Quando o algoritmo usado para antialisar interruptores pode levar a resultados visuais inesperados. Neste artigo, vamos dar uma olhada nas abordagens da suavização e ver como os pixels são desenhados.

Todas as nossas telas são compostas, como todos sabemos, de pixels. É uma grade gigante de blocos, e cada um contém componentes vermelho, verde e azul (RGB). À distância, vemos imagens, textos e ícones, mas de perto podemos ver a grade de componentes RGB e como tudo é composto.

Pixels de uma tela de perto. Cada pixel tem componentes vermelhos, verdes e azuis
Figura 1: pixels de uma tela de perto. Cada pixel tem componentes vermelho, verde e azul.

Suavização

O que acontece quando estamos desenhando uma forma vetorial e ela passa por uma "parte" de um pixel? Vamos supor que a forma que estamos desenhando seja preta e que o fundo seja branco. Devemos colorir esse pixel? Se colorirmos, que cor deve ser? Preto, cinza, algo mais?

O processo de suavização determina qual cor devemos usar ao preencher pixels. A versão mais simples dele é chamada de suavização de escala de cinza e trata os três componentes dos pixels igualmente. Então, se o pixel estiver parcialmente coberto (por exemplo, usando texto preto em branco por um segundo), você pensaria que cada componente seria definido com metade do brilho (sei que sim), mas, na verdade, é mais complexo do que isso: você precisa considerar gamma, o que significa que você provavelmente nunca o definirá com esse valor exato. Claro que isso torna as coisas um pouco mais complicadas, mas como esta é uma introdução ao tópico, não vou me aprofundar nisso aqui. O importante a saber é que a suavização da escala de cinza é tratada no nível do pixel e podemos, na verdade, fazer muito melhor.

Figura 2 - Bordas com suavização e bordas rígidas
Figura 2: bordas suavizadas x bordas rígidas

Na Figura 2, é possível ver o mesmo triângulo sendo desenhado, mas, à esquerda, o anti-aliasing está ativado e, à direita, está desativado. Como você pode ver, quando a suavização está ativada, os pixels ficam em tons de cinza quando o triângulo só passa por parte do pixel. No entanto, quando desativado, o pixel é preenchido como preto sólido ou branco sólido e a forma parece irregular.

Renderização de texto

Sempre que um navegador estiver renderizando texto, que é essencialmente uma forma vetorial, encontraremos o mesmo problema: os caracteres de texto preencherão apenas parcialmente alguns pixels. Por isso, queremos ter uma estratégia de como preencher esses pixels. O ideal é que o texto seja suavizado, já que isso torna a leitura mais fácil e agradável.

No entanto, a abordagem de escala de cinza do antialiasing é apenas uma maneira de lidar com isso. Uma abordagem frequentemente adotada é ser um pouco mais seletivo na forma como ativamos os componentes RGB dos pixels. O processo é chamado de antialiasing de subpixels e, ao longo dos anos, a equipe da ClearType na Microsoft em particular investiu muito tempo e esforço para progredir nele. Ela é atualmente muito mais amplamente utilizada e todos os principais navegadores a utilizam em maior ou menor grau.

Em primeiro lugar, como sabemos que cada pixel é de fato composto por componentes vermelhos, verdes e azuis, detectamos quanto de cada um desses componentes deve ser "ativado" para o pixel em questão. Então, se um pixel estiver “metade coberto” do lado esquerdo, podemos alternar totalmente o componente vermelho, o verde para a metade e manter o azul desligado. Esse processo é frequentemente descrito como “triplicando a resolução horizontal da tela” e depende do fato de que cada pixel é na verdade os três componentes separados lado a lado em vez de uma única unidade.

Figura 3 - Suavização usando escala de cinza versus subpixel
Figura 3: suavização usando escala de cinza versus subpixel

Na figura 3 acima, podemos ver que, à esquerda, tratamos cada componente igualmente e todos estão ativados ou desativados igualmente (escala de cinza). No entanto, no lado direito, usamos a abordagem de subpixels, permitindo que cada componente (vermelho, verde e azul) seja diferente dependendo do quanto ele se sobrepõe à forma que está sendo desenhada.

Dito isso, no entanto, a visão humana não pesa de fato a luz vermelha, verde e azul igualmente. Somos muito mais sensíveis ao verde do que ao vermelho ou ao azul, e isso significa que, embora haja benefícios em comparação com o anti-aliasing de escala de cinza, como Darel Rex Finley observou, ativar cada componente separadamente não vai gerar uma melhoria de 3x na clareza. No entanto, o anti-aliasing de subpixel é definitivamente útil e significa que vemos o texto com mais clareza do que se o anti-aliasing em escala de cinza fosse usado.

Figura 4 - Texto suavizado de subpixel. Componentes individuais dos pixels são ativados para criar o efeito geral
Figura 4 - Texto suavizado de subpixel. Componentes individuais dos pixels são ativados para criar o efeito geral.

Hora de ir direto ao ponto

O que tudo isso significa para nós, desenvolvedores? Do ponto de vista do Chrome, pelo menos há uma mistura de escala de cinza e anti-aliasing de subpixels usada para renderizar texto, e qual você obterá depende de alguns critérios. No entanto, para começar, precisamos entender um pouco sobre as camadas, já que esse é o principal critério em jogo. Se você ainda não conheceu as camadas e como elas são usadas internamente pelo Chrome, Tom Wiltzius escreveu uma introdução fantástica ao tópico que você deve ler primeiro.

Supondo que você esteja familiarizado com as camadas ou já tenha lido sobre elas, vamos continuar. Se a composição de hardware estiver ativada para a página e você tiver conteúdo de texto em uma camada que não é a camada raiz, ele será renderizado por padrão com o anti-aliasing em escala de cinza. Muitas vezes, os desenvolvedores percebem que, se aplicarem "hacks" a elementos para colocá-los nas próprias camadas (não raiz), como usar translateZ, veem o texto sendo renderizado de forma diferente. Muitas vezes, os desenvolvedores aplicam acionadores de "nova camada" em tempo real por meio de JavaScript ou CSS, fazendo com que a renderização do texto mude de subpixel para escala de cinza. Pode ser confuso se você não souber o que acionou a alteração na renderização. No entanto, se o texto estiver na camada raiz, ele deverá ser renderizado com anti-aliasing de subpixels e, consequentemente, será muito mais fácil de ler.

Mas, como tudo relacionado à Web, ela está mudando. O anti-aliasing de subpixel está sendo ativado no Chrome para texto em camadas não raiz, desde que a camada satisfaça três critérios. Vale a pena dizer que esses critérios se aplicam hoje, mas é provável que eles mudem, e você vai notar mais casos abordados ao longo do tempo. Hoje, esses critérios são:

  1. A camada tem uma cor de fundo totalmente opaca. O uso de border-radius ou um valor background-clip não padrão faz com que a camada seja tratada como não opaca, e a renderização de texto é revertida para o anti-aliasing em escala de cinza.
  2. A camada só pode ter transformação de identidade ou conversão integral aplicada a ela. Por "integral", queremos dizer valores arredondados. Por exemplo, translate(20.2px, 30px) resultaria em suavização de escala de cinza, já que o componente x, 20.2px, não é integral. A transformação de identidade significa simplesmente que não há rotação, translação ou dimensionamento adicional aplicado além do padrão.
  3. A camada tem uma opacidade 1.0. Qualquer alteração na opacidade altera a suavização de subpixel para escala de cinza.
Figura 5. Antes e depois: escala de cinza x subpixel. Observe o contorno de cor no texto à direita
Figura 5. Antes e depois: escala de cinza x subpixel. Observe o contorno de cor no texto à direita.

Uma última observação é que aplicar uma animação CSS pode causar a criação de uma nova camada, enquanto o uso de requestAnimationFrame não. Para alguns desenvolvedores, as diferenças de renderização de texto que implicam impediram o uso de animações CSS. Se você está usando JavaScript para animar elementos devido a diferenças de renderização de texto, verifique se essa atualização corrige alguns problemas.

Isso é o que temos no Chrome. No que diz respeito aos outros navegadores, o Opera, ao migrar para o Chromium, deve acompanhar de perto o comportamento do Chrome. O Internet Explorer parece usar a suavização de subpixels para praticamente todo o texto (se você tiver ativado o ClearType, é claro!), embora aparentemente não no modo Metro do Windows 8. Devido à proximidade do WebKit com o Blink, o Safari se comporta de maneira muito semelhante ao Chrome, embora sem essas novas melhorias que permitem mais anti-aliasing de subpixels. Em geral, o Firefox se comporta da mesma forma que o Internet Explorer, já que usa a suavização de subpixels para praticamente todo o texto. Essa não é uma lista completa, e é provável que existam casos em todos os navegadores em que o antialiasing em escala de cinza seja usado em vez do subpixel. No entanto, é bom saber que ele é amplamente utilizado no conjunto principal de navegadores.

Conclusão

Agora você sabe um pouco sobre como o antialiasing funciona e por que pode haver diferenças na renderização de texto nos seus sites e aplicativos, especialmente em dispositivos com DPI mais baixo. Se estiver interessado em acompanhar a implementação do Chrome com relação à renderização de texto, marque os seguintes bugs com uma estrela:

Recursos e referências