{
  "schemaVersion": 1,
  "id": "liquid-glass",
  "version": "1.0.0",
  "status": "published",
  "kind": "material",
  "title": "Liquid Glass",
  "summary": "A thick slab of clear glass glides over your backdrop, bending what is behind it with a faint rainbow fringe, and morphs from pill to circle to rounded square. The look from every 2026 interface.",
  "description": "The liquid glass look that spread from Apple’s interfaces into motion design and the web: a rounded, bevelled slab of clear glass that refracts whatever sits behind it, splits light into a subtle colour fringe at its edges (dispersion), catches a bright specular rim from the studio lights and morphs between shapes as it moves. Put it over colour bands, a word, a logo or a photo plane; set the glass thickness, how much it bends light, the frosting and the colour fringe; choose whether it morphs and how far it glides.",
  "role": "Foreground glass element (Three.js) that refracts an opaque backdrop.",
  "collections": [
    "chrome-glass",
    "product-reveals",
    "backgrounds"
  ],
  "tags": [
    "liquid glass",
    "glass",
    "refraction",
    "dispersion",
    "glassmorphism",
    "frosted",
    "pill",
    "morph",
    "apple",
    "ui",
    "3d",
    "three.js",
    "transmission",
    "chromatic"
  ],
  "synonyms": [
    "liquid glass effect",
    "glass pill",
    "glass button",
    "glassmorphism animation",
    "refracting glass",
    "apple liquid glass",
    "glass morph",
    "lens",
    "magnifier",
    "glass overlay"
  ],
  "useCases": [
    "Product or app launch visual",
    "Logo or word under moving glass",
    "Background element for a UI showcase",
    "Transition element over a photo"
  ],
  "featured": 1,
  "publishedAt": "2026-10-03",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/liquid-glass.js",
    "exports": [
      {
        "name": "createLiquidGlassMaterial",
        "signature": "createLiquidGlassMaterial({ tint?, ior?, thickness?, roughness?, dispersion?, clearcoat?, envMapIntensity? }) => THREE.MeshPhysicalMaterial",
        "description": "Thick clear glass with transmission, dispersion and a clear coat."
      },
      {
        "name": "createSlabGeometry",
        "signature": "createSlabGeometry({ width?, height?, depth?, radius?, bevel?, segments? }) => THREE.BufferGeometry",
        "description": "A rounded-rectangle slab with a bevelled edge."
      },
      {
        "name": "createLiquidGlass",
        "signature": "createLiquidGlass({ shapes?, depth?, bevel?, material?, hover?, drift?, tiltAmount?, cycles? }) => { mesh, update(progress), setShape(w, h, r), shapeAt(progress), dispose() }",
        "description": "A slab that morphs through shape keyframes, hovers and tilts as a pure function of progress (exact loop)."
      }
    ],
    "reusable": [
      "src/liquid-glass.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "WebGL rendering (MeshPhysicalMaterial transmission and dispersion)."
    },
    {
      "id": "chrome-material",
      "version": "1.1.0",
      "scope": "demo",
      "reason": "Demo uses the studio environment, cove and floor. Any environment map works with the glass."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "backdrop",
      "label": "Behind the glass",
      "type": "select",
      "default": "bands",
      "options": [
        {
          "value": "bands",
          "label": "Colour bands"
        },
        {
          "value": "dots",
          "label": "Dot grid"
        },
        {
          "value": "gradient",
          "label": "Gradient"
        }
      ]
    },
    {
      "key": "text",
      "label": "Word on the backdrop",
      "type": "text",
      "default": "LIQUID",
      "maxLength": 16,
      "sensitive": true
    },
    {
      "key": "morph",
      "label": "Morph between shapes",
      "type": "boolean",
      "default": true
    },
    {
      "key": "cycles",
      "label": "Morph cycles per clip",
      "type": "integer",
      "min": 1,
      "max": 2,
      "step": 1,
      "default": 1
    },
    {
      "key": "thickness",
      "label": "Glass thickness",
      "help": "Thicker glass bends the backdrop more.",
      "type": "number",
      "min": 0.2,
      "max": 0.9,
      "step": 0.01,
      "default": 0.5
    },
    {
      "key": "ior",
      "label": "Bend of light (IOR)",
      "help": "1.5 is window glass, 1.33 water, 2.4 diamond.",
      "type": "number",
      "min": 1.1,
      "max": 2.4,
      "step": 0.01,
      "default": 1.5
    },
    {
      "key": "dispersion",
      "label": "Colour fringe",
      "help": "The rainbow split at the edges. 0 is none.",
      "type": "number",
      "min": 0,
      "max": 0.4,
      "step": 0.01,
      "default": 0.14
    },
    {
      "key": "frost",
      "label": "Frosting",
      "type": "number",
      "min": 0,
      "max": 0.3,
      "step": 0.01,
      "default": 0.02
    },
    {
      "key": "glide",
      "label": "Glide distance",
      "type": "number",
      "min": 0,
      "max": 1.2,
      "step": 0.05,
      "default": 0.55
    },
    {
      "key": "tilt",
      "label": "Tilt",
      "type": "number",
      "min": 0,
      "max": 0.4,
      "step": 0.01,
      "default": 0.16
    },
    {
      "key": "tint",
      "label": "Glass tint",
      "type": "color",
      "default": "#ffffff"
    },
    {
      "key": "colorA",
      "label": "Backdrop colour 1",
      "type": "color",
      "default": "#ff4f3d"
    },
    {
      "key": "colorB",
      "label": "Backdrop colour 2",
      "type": "color",
      "default": "#1e3cff"
    },
    {
      "key": "colorC",
      "label": "Backdrop colour 3",
      "type": "color",
      "default": "#ffd23f"
    },
    {
      "key": "textColor",
      "label": "Word colour",
      "type": "color",
      "default": "#ffffff"
    },
    {
      "key": "background",
      "label": "Background",
      "type": "color",
      "default": "#0f1117"
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Bands",
      "params": {}
    },
    {
      "id": "frosted",
      "label": "Frosted pill",
      "params": {
        "frost": 0.09,
        "dispersion": 0.04,
        "morph": false,
        "backdrop": "gradient",
        "colorA": "#2b1c6b",
        "colorB": "#8a3cff",
        "colorC": "#ff6fb5"
      }
    },
    {
      "id": "lens",
      "label": "Thick lens",
      "params": {
        "thickness": 0.9,
        "ior": 1.9,
        "dispersion": 0.3,
        "backdrop": "dots",
        "colorA": "#f1e9d6",
        "colorB": "#1b1e27",
        "colorC": "#d84a2c",
        "background": "#f1f2f4",
        "textColor": "#1b1e27"
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 8,
    "posterSeconds": 1.2,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 8,
      "method": "Shape keyframes, glide, hover and tilt are periodic in clip progress; the clip returns exactly to its start."
    },
    "seed": null
  },
  "composition": {
    "inputs": "Clip progress (frame / durationFrames). A material and shape keyframes.",
    "outputs": "A THREE.Mesh placed at the origin; update(progress) moves and morphs it.",
    "coordinates": "Y-up, centred on the origin, facing +Z. Default slab about 2.6 × 1.15 × 0.5 units; put the backdrop at z ≈ −1.5.",
    "lighting": "Needs scene.environment for highlights. The studio from Chrome Material works well.",
    "timing": "Pure function of progress. Whole cycles loop exactly.",
    "compatibleWith": [
      "chrome-material",
      "orbit-camera",
      "kinetic-title",
      "gradient-background",
      "glass-container"
    ],
    "notes": [
      "Transmission sees only opaque objects: put a photo, text or colour on an opaque plane behind the glass, not a transparent one.",
      "Morphing rebuilds the geometry when the shape changes; it is cheap at this size, but keep segments modest for long clips."
    ]
  },
  "reuse": [
    "Put a logo or product name on the backdrop plane and let the glass glide across it for a launch bumper.",
    "Use it as a lens: a thick, high-IOR slab over a photo plane, driven by Orbit Camera for a slow pass.",
    "Layer Kinetic Title underneath on an opaque canvas texture so the letters refract as they rise."
  ],
  "integration": {
    "newProject": "Create the studio (chrome-material), an opaque backdrop plane at z = −1.6, then createLiquidGlass() and call update(progress) each frame.",
    "existingProject": "Copy src/liquid-glass.js. Add the mesh to your scene with an environment map; call update(progress) or setShape() yourself."
  },
  "performance": {
    "notes": "One transmission pass per frame; dispersion adds three samples. Fine at 1080p on a GPU.",
    "limits": "Software WebGL renders slowly (about 1–3 s per 1080p frame)."
  },
  "limitations": [
    "Glass behind glass is not visible through the front face (a Three.js transmission limit).",
    "The slab is a flat extrusion; it does not deform like a true liquid, it morphs between rounded shapes."
  ],
  "license": {
    "spdx": "MIT",
    "notice": "Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.",
    "thirdParty": []
  },
  "provenance": "Original code written for AI Pixel Wizard on 3 October 2026 by an automated agent, inspired by the liquid glass trend (Apple’s interface material, Webflow’s Three.js refraction showcase, open-source Liquid Glass web implementations on X). No code, images or shaders were copied; the technique is Three.js MeshPhysicalMaterial transmission with dispersion.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-03",
      "notes": "Initial release."
    }
  ]
}
