- Apresenta como recriar na web o efeito Liquid Glass revelado pela Apple na WWDC de 2025 usando CSS, SVG e cálculos de refração baseados em física
- Explica o princípio da refração e o processo de simulação da refração e de representação da superfície de vidro com a lei de Snell
- Mostra como gerar um campo vetorial de deslocamento adequado para renderização com SVG displacement map e demonstra que ele pode ser aplicado a componentes reais de UI
- No Chrome, é possível usar SVG filter como backdrop-filter, e o texto apresenta exemplos de aplicação em vários elementos de UI (lupa, switch, player etc.)
- Menciona que o efeito pode ser implementado em tempo real, mas há problemas de compatibilidade entre navegadores e limitações de desempenho, além de citar planos futuros de open source
Introdução
A Apple apresentou pela primeira vez o efeito Liquid Glass na WWDC de junho de 2025. Esse efeito faz com que elementos da interface pareçam vidro refrativo curvo, oferecendo uma experiência visual semelhante à de uma superfície de vidro real. Este texto aborda um exercício prático para criar um efeito parecido na web com CSS, SVG displacement map e cálculos de refração baseados em física. O objetivo não é uma implementação completa, mas uma prova de conceito escalável que reproduz características principais como refração e destaques especulares. A construção do efeito começa pelos princípios básicos de como a luz sofre refração ao atravessar materiais diferentes e avança passo a passo. A demo interativa fornecida no final atualmente funciona corretamente apenas no Chrome.
Entendendo o fenômeno da refração
Refração é o fenômeno em que a luz muda de direção ao passar de um material para outro. Isso acontece porque a velocidade da luz varia conforme o material, e a relação entre ângulo de incidência e ângulo de refração pode ser expressa pela lei de Snell:
- n1 * sin(θ1) = n2 * sin(θ2)
- n1: índice de refração do primeiro meio
- θ1: ângulo de incidência
- n2: índice de refração do segundo meio
- θ2: ângulo de refração
O que pode ser observado no diagrama interativo:
- Se os dois meios tiverem o mesmo índice de refração, a luz segue em linha reta sem refratar
- Quando o segundo meio tem índice de refração maior, a luz refrata em direção à normal
- Se o segundo meio tiver índice de refração menor, a luz se afasta da normal e, em alguns casos, pode ocorrer reflexão interna total
- Se a luz incidente for perpendicular à superfície, ela segue reta independentemente do índice de refração
Limites deste projeto
Para limitar a complexidade e simplificar o algoritmo, foram definidas as seguintes condições:
- O índice de refração do meio externo é 1 (ar)
- O material interno de vidro usa 1.5 (vidro comum)
- Apenas um evento de refração é considerado (ignorando a refração na saída)
- A luz incidente é sempre perpendicular ao plano de fundo
- Todos os objetos são formas 2D e apenas circulares (é possível expandir para retângulos etc., mas isso exige cálculos)
- Não há espaço entre o objeto e o plano de fundo
- Nessas condições, é possível calcular todos os raios de forma simples com a lei de Snell
Criando a superfície de vidro
Para implementar o efeito Liquid Glass, é preciso definir a seção transversal do vidro virtual (lente ou painel curvo) com uma função matemática.
Função de superfície
A superfície do vidro é definida por uma surface function, que representa a espessura desde a borda até a parte interna plana
- Valor de entrada 0: contorno externo, 1: fim do bezel (início da área plana)
- A partir da derivada da espessura em cada ponto, obtém-se o vetor normal da superfície
const height = f(distanceFromSide);
const delta = 0.001;
const y1 = f(distanceFromSide - delta);
const y2 = f(distanceFromSide + delta);
const derivative = (y2 - y1) / (2 * delta);
const normal = { x: -derivative, y: 1 };
Principais tipos de função de superfície
- Convex Circle: y = sqrt((1 - (1 - x))^2)
- Forma simples de arco circular; fica plana rapidamente em direção ao interior, deixando a refração da borda mais evidente
- Convex Squircle: y = ((1 - (1 - x))^4)^(1/4)
- Forma muito usada pela Apple; a transição entre curva e plano é suave, e o efeito continua natural mesmo ao ampliar
- Concave: y = 1 - Convex(x)
- Forma côncava (oposta da convexa), em que a luz refrata para fora do limite do objeto, exigindo amostragem externa
- Lip: y = mix(Convex(x), Concave(x), Smootherstep(x))
- Estrutura composta com uma borda saliente e uma curvatura rasa no centro
Só essas quatro funções já permitem comparar com eficiência as diferenças de refração conforme o formato da superfície.
Simulação
De acordo com cada função de superfície, é simulada a trajetória de refração dos raios, visualizando a diferença real do efeito.
- O formato convexo (Convex) concentra o caminho da luz para dentro, enquanto o côncavo (Concave) empurra para fora
- O Liquid Glass da Apple prefere majoritariamente formas convexas (com exceções como o Switch)
- As setas do fundo são coloridas pela magnitude para indicar a quantidade de refração (deslocamento)
- Distâncias iguais em relação às bordas esquerda e direita produzem o mesmo deslocamento, permitindo reutilização eficiente
Geração do campo vetorial de deslocamento
É construído um campo vetorial que representa, em cada posição da superfície de vidro, a direção e a intensidade do deslocamento da luz
- Em uma forma circular, o movimento ocorre sempre na direção da normal em relação à borda
Pré-cálculo da magnitude do deslocamento
- Como a magnitude do deslocamento é simétrica para cada distância em relação à borda, os valores são pré-calculados por unidade de raio e armazenados em um array
- Em 2D, o cálculo é feito apenas uma vez (simulando 127 raios) e depois rotacionado em torno do eixo z para gerar o campo completo
Normalização dos vetores
Para usar os vetores no displacement map, é feita a normalização (escala máxima 1.0)
- Os demais vetores têm sua magnitude dividida pelo valor máximo de deslocamento
const maximumDisplacement = Math.max(...displacementMagnitudes);
displacementVector_normalized = {
angle: normalAtBorder,
magnitude: magnitude / maximumDisplacement,
};
No SVG displacement map, ao converter novamente para pixels reais, o valor máximo original é restaurado multiplicando-se pela escala.
SVG Displacement Map
Para aplicar na prática os resultados matemáticos do cálculo de refração ao rendering no navegador, é usado um SVG displacement map
- Cada canal (RGBA, 8 bits) de
<feDisplacementMap />pode ser responsável pelos eixos X e Y do deslocamento - Cada canal tem valores de 0 a 255, e 128 significa neutro (sem deslocamento)
- O displacement map precisa obrigatoriamente ser convertido em imagem
<svg colorInterpolationFilters="sRGB">
<filter id={id}>
<feImage
href={displacementMapDataUrl}
x={0}
y={0}
width={width}
height={height}
result="displacement_map"
/>
<feDisplacementMap
in="SourceGraphic"
in2="displacement_map"
scale={scale}
xChannelSelector="R"
yChannelSelector="G"
/>
</filter>
</svg>
Scale
Os valores dos canais Red(X) e Green(Y) são mapeados para o intervalo [−1, 1]
- O atributo
scalemultiplica pelo deslocamento máximo em pixels para realizar o rendering real - Também é possível animar
scalepara ajustar a intensidade do efeito
Conversão de vetor → valores Red/Green
- O vetor de deslocamento (ângulo, magnitude) é convertido em coordenadas cartesianas x e y e então mapeado para 0~255 com base em 128 (neutro)
const x = Math.cos(angle) * magnitude;
const y = Math.sin(angle) * magnitude;
const result = {
r: 128 + x * 127,
g: 128 + y * 127,
b: 128,
a: 255,
};
A imagem finalizada pode então ser usada como displacement map em um filtro SVG.
Playground
No Playground interativo, é possível alterar em tempo real o formato da superfície, a espessura do bezel, a espessura do vidro e a escala do efeito, observando as mudanças no campo de refração, no displacement map e no rendering final.
Specular Highlight
Por fim, adiciona-se o specular highlight (destaque brilhante nas bordas da superfície de vidro)
- A implementação da Apple usa um tipo de rim light, no qual a intensidade do brilho varia conforme a normal da superfície e o ângulo da fonte de luz
Combinando refração e Specular Highlight
No filtro SVG final, o displacement map e a imagem de specular highlight são carregados separadamente com <feImage /> e combinados com <feBlend /> para criar o efeito final
- Ajustando os parâmetros do filtro, é possível produzir vários visuais diferentes
Usando SVG filter como backdrop-filter
- Para aplicar de fato o efeito Liquid Glass a componentes de UI, é necessário o suporte do Chrome a
backdrop-filter: url(#...) - Como o tamanho da imagem do
backdrop-filternão é ajustado automaticamente, é essencial preparar um displacement map compatível com o tamanho do elemento
.glass-panel {
backdrop-filter: url(#liquidGlassFilterId);
}
Aplicação em componentes reais de UI
Com base na refração calculada e no displacement map, são implementados exemplos aplicados a componentes de UI com aparência realista
- Apenas o Chrome consegue tratar SVG filter como
backdrop-filter - Os exemplos não são componentes reais de produção, mas demonstrações de como o efeito Liquid Glass pode ser aplicado a diferentes interfaces
Magnifying Glass
- Usa refração e zoom em ambos os lados, com dois displacement maps
- Sombras e ajuste de escala acrescentam um efeito interativo
- É possível deformar a lente por arraste e observar a trajetória da refração
- Inclui um specular highlight suave
Searchbox
- Aplica o efeito Liquid Glass a uma caixa de entrada padrão
Switch
- Usa um bezel do tipo lip, com exterior convexo e interior côncavo
- Apenas o slider central fica ampliado/reduzido, enquanto as bordas refratam a imagem interna
Slider
- Usa um bezel convexo, exibindo o valor atual normalmente através do vidro, enquanto os dois lados aplicam refração ao fundo
Music Player
-
Imita o estilo de painel Liquid Glass do Apple Music
-
Usa bezel convexo e specular highlight sutil para dar sensação de volume
-
Carrega capa do álbum e informações como nome da faixa usando a iTunes Search API
-
(fornece uma lista com nomes de faixas e informações do álbum)
Conclusão
Este protótipo representa de forma simplificada o conceito de Liquid Glass da Apple com efeitos de refração em tempo real e highlights simples. Na prática, ele só funciona de verdade em navegadores baseados em Chromium (ou Electron), e em outros navegadores pode ser substituído por uma camada de blur.
Trata-se de uma implementação experimental, e regenerar o displacement map a cada mudança de forma/tamanho é muito ineficiente (apenas alguns parâmetros, como o scale do filtro, podem ser animados).
Há a possibilidade de publicação futura em open source, e o autor afirma ter interesse em otimização e organização do código.
Ainda não há comentários.