{
  "schemaVersion": 1,
  "id": "iridescent-blob",
  "version": "1.0.0",
  "status": "published",
  "kind": "object",
  "title": "Iridescent Morphing Blob",
  "summary": "A glossy blob that slowly morphs with a soap-bubble rainbow sheen. Loops perfectly.",
  "description": "A shiny, soft shape that gently swells and ripples like a drop of liquid, with a rainbow oil-slick sheen that shifts as it turns. Pick two colours for the hollows and the peaks, then dial how much it wobbles and how bumpy it is. The movement is built so the last frame flows straight back into the first.",
  "role": "Hero object: a morphing, iridescent 3D shape.",
  "collections": [
    "hypnotic-loops",
    "chrome-glass",
    "backgrounds"
  ],
  "tags": [
    "blob",
    "iridescent",
    "holographic",
    "morph",
    "liquid",
    "organic",
    "oil slick",
    "soap bubble",
    "3d",
    "loop",
    "abstract",
    "shiny"
  ],
  "synonyms": [
    "shiny moving blob",
    "liquid blob",
    "morphing shape",
    "holographic ball",
    "rainbow sheen",
    "wobbly sphere",
    "jelly",
    "lava lamp",
    "pearlescent"
  ],
  "useCases": [
    "Abstract hero loop for a launch",
    "Calming ambient visual",
    "A liquid-chrome or holographic object"
  ],
  "featured": 3,
  "publishedAt": "2026-10-02",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/iridescent-blob.js",
    "exports": [
      {
        "name": "createBlob",
        "signature": "createBlob({ radius?, amplitude?, frequency?, cycles?, waves?, seed?, segments?, colorA?, colorB?, material? }) => { mesh, update(phase), dispose() }",
        "description": "Morphing sphere mesh; call update(phase 0…1) each frame."
      },
      {
        "name": "createIridescentMaterial",
        "signature": "createIridescentMaterial({ colorA?, iridescence?, roughness? }) => THREE.MeshPhysicalMaterial",
        "description": "Thin-film iridescent physical material using vertex colours."
      }
    ],
    "reusable": [
      "src/iridescent-blob.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Geometry, physical material with iridescence."
    },
    {
      "id": "chrome-material",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo uses createStudioEnvironment; iridescence needs an environment map to show."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "colorA",
      "label": "Hollow colour",
      "type": "color",
      "default": "#8a5cff"
    },
    {
      "key": "colorB",
      "label": "Peak colour",
      "type": "color",
      "default": "#2ee6d6"
    },
    {
      "key": "wobble",
      "label": "Wobble",
      "help": "How far the surface moves in and out.",
      "type": "number",
      "min": 0,
      "max": 0.35,
      "step": 0.01,
      "default": 0.16
    },
    {
      "key": "bumpiness",
      "label": "Bumpiness",
      "type": "number",
      "min": 0.8,
      "max": 4,
      "step": 0.1,
      "default": 2.2
    },
    {
      "key": "speed",
      "label": "Speed",
      "help": "Morph cycles per loop.",
      "type": "integer",
      "min": 1,
      "max": 3,
      "step": 1,
      "default": 1
    },
    {
      "key": "iridescence",
      "label": "Rainbow sheen",
      "type": "number",
      "min": 0,
      "max": 1,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "seed",
      "label": "Variation",
      "type": "integer",
      "min": 1,
      "max": 9999,
      "step": 1,
      "default": 3
    },
    {
      "key": "background",
      "label": "Background",
      "type": "color",
      "default": "#08080c"
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Violet & teal",
      "params": {}
    },
    {
      "id": "peach",
      "label": "Peach pearl",
      "params": {
        "colorA": "#ff7a90",
        "colorB": "#ffd59e",
        "wobble": 0.1,
        "background": "#140b0e"
      }
    },
    {
      "id": "wild",
      "label": "Wild & bumpy",
      "params": {
        "wobble": 0.3,
        "bumpiness": 3.4,
        "speed": 2,
        "colorA": "#1b3cff",
        "colorB": "#ff3df2"
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 8,
    "posterSeconds": 2,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 8,
      "method": "Every wave advances a whole number of cycles and the spin completes whole turns, so frame N equals frame 0."
    },
    "seed": {
      "param": "seed",
      "behavior": "Seed picks the wave directions and phases. Same seed, same shape."
    }
  },
  "composition": {
    "inputs": "Loop phase 0…1 (frame / durationFrames). Needs scene.environment for the sheen.",
    "outputs": "A THREE.Mesh whose geometry is rewritten by update(phase).",
    "coordinates": "Centred on the origin, radius ≈ 1 ± wobble.",
    "lighting": "Image-based (scene.environment). Without it the iridescence is barely visible.",
    "timing": "update(phase) is a pure function of phase; frames can be rendered in any order.",
    "compatibleWith": [
      "chrome-material",
      "orbit-camera",
      "gradient-background"
    ],
    "notes": [
      "Vertex count is segments × 0.75·segments; 128 is smooth at 1080p."
    ]
  },
  "reuse": [
    "Swap the material for createChromeMaterial to get a liquid-chrome blob.",
    "Use several small blobs with different seeds as floating background shapes.",
    "Put it behind a Kinetic Title as a product-launch backdrop."
  ],
  "integration": {
    "newProject": "Create a Three.js scene with an environment map, add createBlob().mesh and call update(frame / totalFrames) every frame.",
    "existingProject": "Copy src/iridescent-blob.js. Add blob.mesh to your existing scene and call blob.update(phase) from your frame loop. Keep your camera and lights; add an environment map if your scene has none."
  },
  "performance": {
    "notes": "Deforms ~12,000 vertices on the CPU each frame and recomputes normals. Smooth on laptops at 30–60 fps.",
    "limits": "Lower segments (e.g. 64) on phones. A GPU vertex-shader port would be faster but is not included."
  },
  "limitations": [
    "Not a fluid simulation: the motion is a sum of waves, which reads as liquid but does not split or merge."
  ],
  "license": {
    "spdx": "MIT",
    "notice": "Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License (see LICENSE in this folder).",
    "thirdParty": [
      {
        "name": "three.js",
        "version": "0.185.1",
        "license": "MIT",
        "url": "https://github.com/mrdoob/three.js"
      }
    ]
  },
  "provenance": "Original code written for AI Pixel Wizard in October 2026.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-02",
      "notes": "Initial release."
    }
  ]
}
