5 points par GN⁺ 2025-09-09 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Présentation d’une méthode pour reproduire sur le web l’effet Liquid Glass dévoilé par Apple à la WWDC 2025, à l’aide de CSS, SVG et de calculs de réfraction basés sur la physique
  • Explication du principe de la réfraction et du processus de simulation de la réfraction ainsi que de la modélisation d’une surface en verre à l’aide de la loi de Snell
  • Utilisation d’une SVG displacement map pour générer un champ de vecteurs de déplacement adapté au rendu, avec démonstration de son application à de véritables composants d’UI
  • Possibilité, dans Chrome uniquement, d’utiliser un filtre SVG via backdrop-filter, avec des exemples d’application à divers éléments d’UI (loupe, interrupteur, lecteur, etc.)
  • Mention d’une implémentation possible en temps réel, mais avec des problèmes de compatibilité inter-navigateurs et des limites de performances, ainsi qu’un projet de future publication en open source

Introduction

Apple a présenté pour la première fois l’effet Liquid Glass lors de la WWDC de juin 2025. Cet effet donne aux éléments d’interface l’apparence d’un verre réfractant courbe, pour offrir une expérience visuelle proche d’une véritable surface en verre. Cet article propose un atelier pour créer un effet similaire sur le web à l’aide de CSS, d’une SVG displacement map et de calculs de réfraction basés sur la physique. L’objectif n’est pas une implémentation complète, mais une preuve de concept extensible qui reproduit les caractéristiques essentielles, comme la réfraction et les reflets spéculaires. La construction de l’effet commence par les principes de base expliquant comment la lumière se réfracte lorsqu’elle traverse des matériaux différents, puis progresse étape par étape. La démo interactive fournie à la fin ne fonctionne correctement que dans Chrome à l’heure actuelle.

Comprendre le phénomène de réfraction

La réfraction désigne le changement de direction de la lumière lorsqu’elle passe d’un matériau à un autre. Elle se produit parce que la vitesse de la lumière diffère selon les matériaux, et la relation entre l’angle d’incidence et l’angle de réfraction s’exprime par la loi de Snell :

  • n1 * sin(θ1) = n2 * sin(θ2)
    • n1 : indice de réfraction du premier milieu
    • θ1 : angle d’incidence
    • n2 : indice de réfraction du second milieu
    • θ2 : angle de réfraction

Ce que l’on peut observer dans le diagramme interactif :

  • si les deux milieux ont le même indice de réfraction, la lumière continue tout droit sans réfraction
  • si le second milieu a un indice de réfraction plus élevé, la lumière se réfracte vers la normale
  • si le second milieu a un indice de réfraction plus faible, la lumière s’en éloigne et, dans certains cas, une réflexion totale interne peut se produire
  • si la lumière incidente est perpendiculaire à la surface, elle continue tout droit quel que soit l’indice de réfraction

Limites de ce projet

Pour limiter la complexité et simplifier l’algorithme, les conditions suivantes sont posées :

  • l’indice de réfraction du milieu extérieur vaut 1 (air)
  • le matériau en verre interne utilise 1,5 (verre courant)
  • un seul événement de réfraction est pris en compte (la réfraction à la sortie est ignorée)
  • la lumière incidente est toujours perpendiculaire au plan de fond
  • tous les objets sont des formes 2D, et seule la forme circulaire est utilisée (une extension aux rectangles, etc. est possible mais demande des calculs supplémentaires)
  • il n’y a aucun espace entre l’objet et le plan de fond
  • avec ces conditions, il est possible de calculer simplement tous les rayons via la loi de Snell

Créer une surface en verre

Pour implémenter l’effet Liquid Glass, il faut définir mathématiquement la section du verre virtuel (lentille ou panneau courbe).

Fonction de surface

La surface du verre est définie par une surface function, qui représente l’épaisseur depuis le bord jusqu’à la partie intérieure plate.

  • valeur d’entrée 0 : contour extérieur, 1 : extrémité du biseau (début de la zone plane)
  • la dérivée de l’épaisseur en chaque point permet d’obtenir le vecteur normal de la surface
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 };

Principaux types de fonctions de surface

  • Convex Circle : y = sqrt((1 - (1 - x))^2)
    • forme simple en arc de cercle, qui s’aplatit rapidement vers l’intérieur et produit un bord de réfraction net
  • Convex Squircle : y = ((1 - (1 - x))^4)^(1/4)
    • forme souvent utilisée par Apple, avec une transition douce entre la courbe et la zone plane, ce qui conserve un effet naturel même lors d’un agrandissement
  • Concave : y = 1 - Convex(x)
    • forme concave (inverse du convexe), où la lumière se réfracte au-delà du bord de l’objet, ce qui nécessite un échantillonnage externe
  • Lip : y = mix(Convex(x), Concave(x), Smootherstep(x))
    • structure composite avec une lèvre saillante sur les bords et une légère courbure au centre

Ces quatre fonctions suffisent déjà à comparer efficacement les différences de réfraction selon la forme de la surface.

Simulation

Pour chaque fonction de surface, l’auteur simule le trajet de réfraction des rayons afin de visualiser les différences réelles d’effet.

  • une forme convexe (Convex) concentre le trajet de la lumière vers l’intérieur, tandis qu’une forme concave (Concave) le repousse vers l’extérieur
  • le Liquid Glass d’Apple privilégie le plus souvent des formes convexes (à quelques exceptions comme le Switch)
  • les flèches de fond affichent en couleur la magnitude de la réfraction (déplacement)
  • à distance égale des limites gauche et droite, le déplacement est identique, ce qui permet une réutilisation efficace

Génération du champ de vecteurs de déplacement

Un champ de vecteurs est construit pour représenter, à chaque position sur toute la surface du verre, la direction et l’amplitude du déplacement de la lumière.

  • dans une forme circulaire, le déplacement se fait toujours dans la direction de la normale par rapport au bord

Pré-calculer l’amplitude du déplacement

  • l’amplitude du déplacement est symétrique selon la distance au bord, donc les valeurs sont pré-calculées par unité de rayon puis stockées dans un tableau
  • en 2D, le calcul n’est fait qu’une seule fois (simulation de 127 rayons), puis le champ complet est généré par rotation autour de l’axe z

Normalisation des vecteurs

Pour utiliser les vecteurs dans la displacement map, une normalisation (échelle maximale à 1,0) est effectuée.

  • toutes les amplitudes sont divisées par la valeur de déplacement maximale
const maximumDisplacement = Math.max(...displacementMagnitudes);
displacementVector_normalized = {
  angle: normalAtBorder,
  magnitude: magnitude / maximumDisplacement,
};

Dans la SVG displacement map, lors de la conversion réelle en pixels, la taille d’origine est restaurée en multipliant à nouveau par la valeur maximale de déplacement via scale.

SVG Displacement Map

Pour appliquer concrètement au rendu du navigateur le résultat des calculs mathématiques de réfraction, l’auteur utilise une SVG displacement map.

  • chaque canal (RGBA, 8 bits) de <feDisplacementMap /> peut être affecté respectivement aux axes X et Y du déplacement
  • chaque canal prend une valeur de 0 à 255, et 128 représente l’état neutre (aucun déplacement)
  • la displacement map doit impérativement être convertie en image
<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

Les valeurs des canaux Red(X) et Green(Y) sont mappées dans l’intervalle [−1, 1].

  • l’attribut scale multiplie ensuite ce résultat par le déplacement maximal en pixels pour obtenir le rendu réel
  • on peut animer scale pour ajuster l’intensité de l’effet

Conversion vecteur → valeurs Red/Green

  • après conversion du vecteur de déplacement (angle, amplitude) en coordonnées cartésiennes x et y, les valeurs sont mappées de 0 à 255 autour de 128 (neutre)
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,
};

L’image finale peut alors être utilisée comme displacement map d’un filtre SVG.

Playground

Dans le Playground interactif, il est possible de modifier en temps réel la forme de la surface, l’épaisseur du biseau, l’épaisseur du verre, l’échelle de l’effet, etc., afin d’observer les changements du champ de réfraction, de la displacement map et du rendu final.

Specular Highlight

Enfin, l’auteur ajoute un specular highlight (surbrillance lumineuse sur les bords de la surface en verre).

  • l’implémentation d’Apple repose sur une logique de rim light, où l’intensité lumineuse varie selon la normale de la surface et l’angle de la source lumineuse

Combiner réfraction et Specular Highlight

Dans le filtre SVG final, les images de displacement map et de specular highlight sont chargées séparément via <feImage />, puis fusionnées avec <feBlend /> pour produire l’effet final.

  • les paramètres du filtre permettent de créer différents rendus visuels

Utiliser un filtre SVG comme backdrop-filter

  • pour appliquer concrètement l’effet Liquid Glass à des composants d’UI, il faut le support de Chrome pour backdrop-filter: url(#...)
  • comme la taille de l’image utilisée par backdrop-filter ne s’ajuste pas automatiquement, il faut préparer une displacement map adaptée à la taille de l’élément
.glass-panel {
  backdrop-filter: url(#liquidGlassFilterId);
}

Application à de véritables composants d’UI

À partir de la réfraction calculée et de la displacement map, l’auteur montre des exemples d’application à des composants d’UI réalistes.

  • seul Chrome peut traiter un filtre SVG comme backdrop-filter
  • ces exemples ne sont pas de vrais composants de production, mais des démonstrations montrant comment l’effet Liquid Glass peut s’appliquer à différentes UI

Magnifying Glass

  • utilisation de la réfraction et du zoom des deux côtés, avec deux displacement maps
  • ajout d’ombres et d’ajustements d’échelle pour un effet interactif
  • possibilité de déformer la lentille par glisser-déposer et d’observer les trajets de réfraction
  • ajout d’un specular highlight doux

Searchbox

  • application de l’effet Liquid Glass à un champ de saisie standard

Switch

  • utilisation d’un biseau lip, convexe à l’extérieur et concave à l’intérieur
  • seul le slider central est agrandi/réduit, tandis que les bords appliquent la réfraction de l’image interne

Slider

  • utilisation d’un biseau convexe, avec affichage direct de la valeur courante à travers le verre, et application de la réfraction du fond sur les deux côtés

Music Player

  • imitation du style de panneau Liquid Glass d’Apple Music

  • biseau convexe et specular highlight subtil pour renforcer la sensation de relief

  • utilisation de l’iTunes Search API pour charger la pochette d’album, le titre du morceau et d’autres informations

  • (fourniture d’une liste de titres et d’informations d’album)

Conclusion

Ce prototype exprime de manière simplifiée le concept Liquid Glass d’Apple à l’aide d’un effet de réfraction en temps réel et de surbrillances simples. Il n’est réellement exploitable que dans les navigateurs basés sur Chromium (ou Electron), et peut être remplacé par une couche de blur dans les autres navigateurs.
Il s’agit d’une implémentation expérimentale, et la régénération de la displacement map à chaque changement de forme ou de taille est très inefficace (seuls certains paramètres comme le scale du filtre peuvent être animés).
Une publication future en open source est à l’étude, avec un intérêt affiché pour l’optimisation et le nettoyage du code.

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.