{
  "schemaVersion": 1,
  "id": "resin-pour",
  "version": "1.0.0",
  "status": "published",
  "kind": "object",
  "title": "Resin Pour",
  "summary": "A thread of clear resin pours into a wooden mould of three tinted layers with gems, pearls and rising bubbles, rings of ripples spreading from where it lands. Loops perfectly.",
  "description": "A pour of clear epoxy resin into a wooden mould, over a table of embedded treasures. A glossy thread of resin falls from above, rings of ripples spread across the surface where it lands, and below the surface three layers of tinted resin lie one over another with slowly undulating boundaries, gems, pearls and rings suspended between them and bubbles rising lazily through the layers. Choose the tints (ocean, sunset, forest or amethyst), how many gems are embedded, the strength of the ripples, the wood of the mould (oak, walnut or ebony), the seed, the backdrop colour and whether the camera sways.",
  "role": "Object (3D, three.js): a glossy, craft-and-satisfying resin-art showpiece for DIY, decor and product content.",
  "collections": [
    "satisfying",
    "chrome-glass",
    "product-reveals"
  ],
  "tags": [
    "resin",
    "epoxy",
    "resin pour",
    "resin art",
    "layers",
    "gems",
    "bubbles",
    "river table",
    "glossy",
    "studio",
    "loop",
    "3d"
  ],
  "synonyms": [
    "epoxy pour",
    "resin art",
    "resin river table",
    "clear resin",
    "layered resin",
    "casting resin"
  ],
  "useCases": [
    "A DIY, craft or home-decor brand scene",
    "A glossy satisfying loop",
    "A chemistry or materials explainer"
  ],
  "featured": null,
  "publishedAt": "2026-10-06",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/resin-pour.js",
    "exports": [
      {
        "name": "createResinPour",
        "signature": "createResinPour({ tints?, gems?, ripples?, wood?, seed? }) => { group, setProgress(progress), dispose() }",
        "description": "The mould, three resin layers, embedded gems, bubbles, stream and ripples, about 9 across, the floor of the mould on y = 0; needs an environment map."
      },
      {
        "name": "TINTS",
        "signature": "TINTS: { ocean, sunset, forest, amethyst }",
        "description": "Tints of the three layers, bottom to top."
      }
    ],
    "reusable": [
      "src/resin-pour.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Renderer, geometry and shader materials."
    },
    {
      "id": "chrome-material",
      "version": "1.1.0",
      "scope": "demo",
      "reason": "Studio environment light, backdrop and contact shadow."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "tints",
      "label": "Tints",
      "type": "select",
      "default": "ocean",
      "options": [
        {
          "value": "ocean",
          "label": "Ocean"
        },
        {
          "value": "sunset",
          "label": "Sunset"
        },
        {
          "value": "forest",
          "label": "Forest"
        },
        {
          "value": "amethyst",
          "label": "Amethyst"
        }
      ]
    },
    {
      "key": "gems",
      "label": "Gems",
      "type": "integer",
      "min": 0,
      "max": 60,
      "step": 2,
      "default": 24
    },
    {
      "key": "ripples",
      "label": "Ripples",
      "type": "number",
      "min": 0,
      "max": 2,
      "step": 0.1,
      "default": 1
    },
    {
      "key": "wood",
      "label": "Mould",
      "type": "select",
      "default": "walnut",
      "options": [
        {
          "value": "walnut",
          "label": "Walnut"
        },
        {
          "value": "oak",
          "label": "Oak"
        },
        {
          "value": "ebony",
          "label": "Ebony"
        }
      ]
    },
    {
      "key": "seed",
      "label": "Seed",
      "type": "integer",
      "min": 1,
      "max": 999,
      "step": 1,
      "default": 16
    },
    {
      "key": "background",
      "label": "Backdrop",
      "type": "color",
      "default": "#1a1e28"
    },
    {
      "key": "orbit",
      "label": "Camera sway",
      "type": "boolean",
      "default": true
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Ocean, walnut",
      "params": {}
    },
    {
      "id": "sunset",
      "label": "Sunset, oak",
      "params": {
        "tints": "sunset",
        "wood": "oak",
        "background": "#2a2018"
      }
    },
    {
      "id": "forest",
      "label": "Forest, many gems",
      "params": {
        "tints": "forest",
        "gems": 50,
        "seed": 6,
        "background": "#122018"
      }
    },
    {
      "id": "amethyst",
      "label": "Amethyst, calm",
      "params": {
        "tints": "amethyst",
        "ripples": 0.4,
        "wood": "ebony",
        "background": "#1c1228"
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 14,
    "posterSeconds": 3,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 14,
      "method": "The ripples travel four wavelengths' worth of phase per loop, the layer boundaries undulate in sines of whole cycles, the stream's stripes move whole periods and each bubble makes whole trips, so the last frame meets the first."
    },
    "seed": {
      "param": "seed",
      "behavior": "Seed places and orients the embedded gems and the bubbles: same seed, same treasure."
    }
  },
  "composition": {
    "inputs": "Time within the loop; the tints, gems, ripples, wood, seed, backdrop and camera sway.",
    "outputs": "A full frame rendered in 3D with a studio environment.",
    "coordinates": "The mould is 8 × 8 inside with its floor at y = 0; the layers' tops are at 0.55, 1.0 and 1.5; the stream falls from y = 8 at the centre; the camera looks down at about 36°.",
    "lighting": "A warm key light with a shadow map and the studio environment on the glossy resin.",
    "timing": "setProgress(progress) rewrites the layer surfaces and places rings and bubbles; frames render in any order.",
    "compatibleWith": [
      "chrome-material",
      "orbit-camera",
      "kinetic-title",
      "number-reveal"
    ],
    "notes": [
      "About 4 200 vertices rewritten per layer each frame; the layers are translucent without true refraction."
    ]
  },
  "reuse": [
    "Craft brand: Ocean, walnut.",
    "Warm decor: Sunset, oak.",
    "Dreamy: Amethyst, calm."
  ],
  "integration": {
    "newProject": "Create a WebGLRenderer with a studio environment and a shadow-casting light, add createResinPour().group and call pour.setProgress(progress) each frame.",
    "existingProject": "Copy src/resin-pour.js; add the group to your scene with an environment map."
  },
  "performance": {
    "notes": "Three 65×65 grids rewritten and re-normalised each frame, up to 60 gems and 36 bubbles with a shadow map: a few milliseconds a frame on an integrated Intel GPU.",
    "limits": "Software WebGL renders in several seconds a frame."
  },
  "limitations": [
    "The resin is translucent tinted slabs without true refraction, so the embedded objects are not bent.",
    "The stream is a fixed-shape thread with moving stripes, not a simulated fluid."
  ],
  "license": {
    "spdx": "MIT",
    "notice": "Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.",
    "thirdParty": []
  },
  "provenance": "Adapted from the owner's threejs-sketches/objects-scenes/resin-pour (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original studio object: three translucent tinted layers with whole-cycle undulation, a ring-rippled top, embedded gems, rising bubbles and a striped pouring stream on an exact loop.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-05",
      "notes": "Initial release."
    }
  ]
}
