5 puntos por GN⁺ 2025-09-09 | 2 comentarios | Compartir por WhatsApp
  • Apple presentó en la WWDC 2025 el efecto Liquid Glass, y aquí se muestra cómo recrearlo en la web usando CSS, SVG y cálculos de refracción basados en física
  • Se explican los principios de la refracción y el uso de la ley de Snell para describir una superficie de vidrio y simular la refracción
  • Se genera un campo de vectores de desplazamiento apto para renderizado con un SVG displacement map, y se demuestra que puede aplicarse a componentes reales de UI
  • En Chrome es posible usar un filtro SVG como backdrop-filter, y se presentan ejemplos aplicados a varios elementos de UI (lupa, interruptor, reproductor, etc.)
  • Se menciona que el efecto puede implementarse en tiempo real, aunque hay problemas de compatibilidad entre navegadores y limitaciones de rendimiento, además de planes futuros de código abierto

Introducción

Apple presentó por primera vez el efecto Liquid Glass en la WWDC de junio de 2025. Este efecto hace que los elementos de la interfaz parezcan vidrio refractivo curvo, ofreciendo una experiencia visual similar a la de una superficie de vidrio real. Este artículo aborda una práctica para crear un efecto similar en la web mediante CSS, SVG displacement map y cálculos de refracción basados en física. El objetivo no es una implementación perfecta, sino una prueba de concepto escalable que reproduzca características clave como la refracción y los reflejos especulares. Se parte de los principios básicos de cómo la luz se refracta al atravesar materiales distintos y se construye el efecto paso a paso. La demo interactiva incluida al final actualmente solo funciona correctamente en Chrome.

Entender el fenómeno de la refracción

La refracción es el fenómeno por el cual la dirección de la luz cambia al pasar de un material a otro. Ocurre porque la velocidad de la luz es distinta en cada medio, y la relación entre el ángulo de incidencia y el ángulo de refracción puede expresarse con la ley de Snell:

  • n1 * sin(θ1) = n2 * sin(θ2)
    • n1: índice de refracción del primer medio
    • θ1: ángulo de incidencia
    • n2: índice de refracción del segundo medio
    • θ2: ángulo de refracción

Lo que puede observarse en el diagrama interactivo:

  • Si los índices de refracción de ambos medios son iguales, la luz sigue recta sin refractarse
  • Si el segundo medio tiene un índice de refracción más alto, la luz se refracta hacia la normal
  • Si el segundo medio tiene un índice de refracción más bajo, la luz se aleja, y en algunos casos puede producirse reflexión interna total
  • Si la luz incide perpendicularmente sobre la superficie, sigue recta sin importar el índice de refracción

Limitaciones de este proyecto

Para limitar la complejidad y simplificar el algoritmo, se establecen las siguientes condiciones:

  • El índice de refracción del medio exterior es 1 (aire)
  • Para el material interno de vidrio se usa 1.5 (vidrio común)
  • Solo se considera un evento de refracción (se ignora la refracción a la salida)
  • La luz incidente siempre es perpendicular al plano del fondo
  • Todos los objetos son formas 2D y solo se usan círculos (puede ampliarse a rectángulos, etc., pero requiere cálculo)
  • No hay separación entre el objeto y el plano del fondo
  • Con estas condiciones, todas las trayectorias pueden calcularse de forma simple con la ley de Snell

Crear la superficie de vidrio

Para implementar el efecto Liquid Glass, es necesario definir con una función matemática la sección transversal del vidrio virtual (lente o panel curvo).

Función de superficie

La superficie de vidrio se define con una surface function, que representa el grosor desde el borde hasta la parte interior plana.

  • Valor de entrada 0: borde exterior, 1: fin del bisel (inicio del plano)
  • A partir de la derivada del grosor en cada punto se obtiene el vector normal de la superficie
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 };

Tipos principales de función de superficie

  • Convex Circle: y = sqrt((1 - (1 - x))^2)
    • Forma simple de arco circular; se aplana bruscamente hacia el interior y produce bordes de refracción bien marcados
  • Convex Squircle: y = ((1 - (1 - x))^4)^(1/4)
    • Una forma que Apple usa con frecuencia; la transición entre curva y plano es suave, y el efecto se mantiene natural incluso al escalar
  • Concave: y = 1 - Convex(x)
    • Forma cóncava (opuesta a convexa), donde la luz se refracta hacia fuera del borde del objeto y requiere muestreo externo
  • Lip: y = mix(Convex(x), Concave(x), Smootherstep(x))
    • Estructura compuesta con un borde sobresaliente y una curvatura poco profunda en el centro

Con solo estas cuatro funciones ya es posible comparar eficazmente las diferencias de refracción según la forma de la superficie.

Simulación

Se simula la trayectoria refractada de los rayos para cada función de superficie y así se visualizan las diferencias reales del efecto.

  • La forma convexa concentra la trayectoria de la luz hacia dentro, mientras que la cóncava la empuja hacia fuera
  • El Liquid Glass de Apple suele preferir formas convexas (con excepciones como el Switch)
  • Las flechas del fondo muestran la cantidad de refracción (desplazamiento) coloreada según su magnitud
  • A igual distancia respecto de los bordes izquierdo y derecho, se obtiene el mismo desplazamiento, lo que permite reutilización eficiente

Generar el campo de vectores de desplazamiento

Se construye un campo de vectores que representa, para cada posición de toda la superficie de vidrio, la dirección y magnitud del desplazamiento de la luz.

  • En una forma circular, el movimiento siempre ocurre en dirección normal respecto del borde

Precalcular la magnitud del desplazamiento

  • Como la magnitud del desplazamiento es simétrica según la distancia al borde, los valores se precalculan por radio y se guardan en un arreglo
  • En 2D se calcula una sola vez (simulando 127 rayos) y luego se rota alrededor del eje z para generar todo el campo

Normalización de vectores

Para usar los vectores en un displacement map, se realiza una normalización (escala máxima de 1.0).

  • Se toma el valor máximo de desplazamiento y se divide la magnitud del resto de vectores con base en él
const maximumDisplacement = Math.max(...displacementMagnitudes);
displacementVector_normalized = {
  angle: normalAtBorder,
  magnitude: magnitude / maximumDisplacement,
};

Al convertir nuevamente a unidades reales de píxel en el SVG displacement map, se multiplica otra vez por el valor máximo mediante scale para recuperar el tamaño original.

SVG Displacement Map

Para aplicar de forma práctica los resultados del cálculo matemático de refracción al renderizado del navegador, se usa un SVG displacement map.

  • Cada canal (RGBA, 8 bits) de <feDisplacementMap /> puede encargarse del desplazamiento en los ejes X y Y
  • Cada canal tiene valores de 0 a 255, y 128 representa el estado neutro (sin desplazamiento)
  • El displacement map debe convertirse obligatoriamente en una imagen
<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

Los valores de Red(X) y Green(Y) se mapean al rango [−1, 1].

  • Luego se multiplican por el desplazamiento máximo en píxeles mediante la propiedad scale para lograr el renderizado real
  • También se puede animar scale para ajustar la intensidad del efecto

Conversión de vector → valores Red/Green

  • El vector de desplazamiento (ángulo, magnitud) se convierte a coordenadas cartesianas x, y, y luego se mapea a 0~255 tomando 128 (neutro) como base
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,
};

La imagen final puede usarse como displacement map en un filtro SVG.

Playground

En el Playground interactivo se pueden cambiar en tiempo real la forma de la superficie, el grosor del bisel, el grosor del vidrio, la escala del efecto, etc., para experimentar cómo cambian el campo de refracción, el displacement map y el renderizado final.

Specular Highlight

Por último, se añade el specular highlight (el brillo marcado en los bordes de la superficie de vidrio).

  • La implementación de Apple usa un tipo de rim light, donde la intensidad del brillo varía según la normal de la superficie y el ángulo de la fuente de luz

Combinar refracción y Specular Highlight

En el filtro SVG final, la displacement map y la imagen de specular highlight se cargan por separado con <feImage /> y se combinan con <feBlend /> para generar el efecto final.

  • Ajustando los parámetros del filtro pueden lograrse distintos resultados visuales

Usar un filtro SVG como backdrop-filter

  • Para aplicar de manera práctica el efecto Liquid Glass a componentes de UI, se necesita el soporte de Chrome para backdrop-filter: url(#...)
  • Como el tamaño de la imagen de backdrop-filter no se ajusta automáticamente, es indispensable preparar un displacement map acorde al tamaño del elemento
.glass-panel {
  backdrop-filter: url(#liquidGlassFilterId);
}

Aplicación a componentes reales de UI

Se implementan ejemplos aplicados a componentes de UI realistas a partir de la refracción calculada y el displacement map.

  • Solo Chrome puede procesar filtros SVG como backdrop-filter
  • Los ejemplos no son componentes reales de producción; su objetivo es mostrar cómo puede aplicarse el efecto Liquid Glass a distintas UI

Magnifying Glass

  • Usa refracción y zoom en ambos lados, con dos displacement maps
  • Se añade un efecto interactivo con sombras y ajuste de escala
  • Permite deformar la lente arrastrándola y observar la trayectoria de la refracción
  • Incluye un specular highlight suave

Searchbox

  • Aplica el efecto Liquid Glass a un campo de entrada estándar

Switch

  • Usa un bisel tipo lip, con exterior convexo e interior cóncavo
  • Solo el deslizador central aparece ampliado o reducido, mientras que los bordes refractan la imagen interior

Slider

  • Usa un bisel convexo; muestra el valor actual tal cual a través del vidrio y aplica refracción del fondo a ambos lados

Music Player

  • Imita el estilo de panel Liquid Glass de Apple Music

  • Usa un bisel convexo y un specular highlight sutil para dar sensación de volumen

  • Carga carátulas de álbum y datos como el nombre de la canción mediante la iTunes Search API

  • (Se proporciona una lista con nombres de canciones e información de álbumes)

Conclusión

Este prototipo expresa de forma simplificada el concepto de Liquid Glass de Apple mediante un efecto de refracción en tiempo real y reflejos sencillos. Solo puede funcionar de forma práctica en navegadores basados en Chromium (o en Electron), y en otros navegadores puede sustituirse por una capa de blur.
Se trata de una implementación experimental, y regenerar el displacement map cada vez que cambia la forma o el tamaño es muy ineficiente (solo algunos parámetros, como la scale del filtro, pueden animarse).
Se está considerando una futura publicación como código abierto, y se menciona interés en optimización y limpieza del código.

2 comentarios

 
bobross0 2025-09-16

Es de los efectos de liquid glass que he visto en la web, el más parecido hasta ahora.

 
GN⁺ 2025-09-09
Comentarios de Hacker News
  • Tiene experiencia creando algo similar con shaders de WebGL, con la ventaja de que funciona en varios navegadores; comparte https://real-glass.vercel.app. La parte difícil fue reproducir correctamente el efecto de refracción detrás de elementos HTML reales.
    • Le da curiosidad cuál es la causa del efecto fantasma/del retraso que aparece al poner el efecto de vidrio sobre texto y moverlo.
    • Le parece increíble; incluso da la impresión de que se implementó el efecto de dispersión con separación de color en los bordes.
    • Se ve muy bien, pero para usarlo de verdad la respuesta es demasiado lenta; el del autor original funciona mucho más fluido.
    • Impresionante.
  • Le impresiona que incluso en una Macbook Pro M4-Max haya tirones al hacer scroll; si una técnica así se aplicara a toda la UI, le preocuparía mucho el rendimiento. Probablemente Apple puede hacerlo porque lo ha optimizado al extremo.
    • Como autor del artículo, intentó corregir de antemano los problemas de rendimiento, pero alguien lo publicó en HN antes de lo esperado. Lo que señalan es cierto: ahora mismo va algo lento y necesita más optimización. No solo la refracción/el mapa de desplazamiento, también otras partes como la visualización siguen sin optimizarse.
    • Como hizo mejoras de rendimiento rápidas en Chrome, puede que ahora esté un poco mejor. En Safari el renderizado de SVG sigue siendo lento. Como se publicó antes de lo esperado, todavía quedan cosas por mejorar.
    • En este sitio el scroll no se siente fluido. En la mayoría de los casos CSS no aprovecha bien la GPU. Parece que Apple añadió tratamiento especial en el silicio para manejar la UI.
    • En su computadora pasa lo mismo; tampoco se veía bien el efecto del borde.
  • El contenido es bueno, pero también fueron excelentes la estructura general y la calidad del artículo. El concepto de liquid glass en sí no aporta ventajas adicionales importantes al UX en la práctica (de hecho, si se usa en exceso puede perjudicarlo), pero sí resulta una experiencia fresca y disfrutable.
  • Destaca que es un demo exclusivo para Chrome y que la demo interactiva final solo funciona en Chrome (por las limitaciones de backdrop-filter causadas por el filtro SVG); en otros navegadores sí se puede leer el artículo o probar una simulación simple. Ante eso hubo una respuesta humorística: "¡Deshonra para toda tu familia!"
    • Que se permita algo así es inevitable; el objetivo es mostrar una función que solo está soportada en cierto navegador.
    • Curiosamente, en su caso la página iba más lenta y el scroll se trababa más en Chrome, mientras que en Firefox, aunque el efecto no es compatible, se sentía más fluido. Aun así, el artículo le impresionó muchísimo.
    • A él también le pasó algo parecido, pero de forma curiosa en FireFox se veía bastante bien.
    • Si alguien quiere referencias, puede consultar https://youtu.be/GamP4chXJ2I?t=17.
  • Era de esperarse que el lenguaje de diseño liquid glass llegara a la web, pero si un sitio va a drenarle la batería por distorsionar texto, no piensa quedarse mucho tiempo. Como ya muchos señalaron los tirones, no va a insistir más en ello.
  • Es un trabajo genial y se nota el cuidado, pero liquid glass como tal se refiere a todo un lenguaje de diseño: elementos cercanos que se fusionan como metaballs, distintos modos de tintado/transparencia, controles en una capa separada del contenido, etc. Esta implementación sería más bien algo cercano a un simple "glass shader".
    • La fusión de elementos se puede resolver con el filtro mucho más simple "Goo"; es una técnica usada desde hace tiempo. Implementación de referencia: https://codepen.io/lenymo/pen/pJzWVy
  • Hizo un fork de una librería JS para liquid-glass y añadió un parche de corrección de posición; puede ser divertido usarla en presentaciones. Código fuente: https://github.com/nkzw-tech/liquid-glass
    • Está genial; de hecho, le gusta más esta versión.
  • En Firefox solo funcionan algunos efectos (¡pero con mejor rendimiento!), aun así es la mejor implementación que ha visto hasta ahora. Como en los últimos días investigó bastante el tema, le impresionó todavía más. Lo que más le gustó fue el diseño del sitio y las visualizaciones interactivas tan cuidadas. Le pareció al nivel del trabajo de Bartosz Ciechanowski y Josh Comeau, y espera que publiquen el código fuente.
  • Le parece un gran intento pese a las limitaciones de compatibilidad entre navegadores; los ejemplos interactivos en línea aportaron valor adicional. Por momentos sintió que estaba leyendo un artículo de Ciechanowski (referencia: https://ciechanow.ski/).
  • Se pregunta si la nueva barra de desplazamiento y los botones con ray tracing realmente son más funcionales y mejoran la productividad frente a los viejos botones del modo texto de Turbo Vision o de Windows 3.