{"id":"bouncing-marbles-box","version":"1.1.0","title":"Bouncing Marbles in a Box","summary":"Shiny chrome balls pour into a glass box, bounce, roll and settle while the camera glides around.","kind":"example","target":"three","collections":["satisfying","chrome-glass","bouncing-falling"],"tags":["marbles","balls","chrome","glass","physics","bouncing","falling","box","3d","satisfying","camera","example"],"loopable":false,"motion":"simulation","durationSeconds":8,"status":"published","media":{"poster":"https://aipixelwizard.com/media/bouncing-marbles-box/1.1.0/poster.webp","preview":"https://aipixelwizard.com/media/bouncing-marbles-box/1.1.0/preview.mp4","sample":"https://aipixelwizard.com/media/bouncing-marbles-box/1.1.0/sample.mp4","sampleBytes":1187325,"sampleNote":"Pre-rendered with the default settings. Customised settings must be exported locally (npm run render)."},"urls":{"page":"https://aipixelwizard.com/visuals/bouncing-marbles-box","manifest":"https://aipixelwizard.com/api/v1/visuals/bouncing-marbles-box/versions/1.1.0","agentMd":"https://aipixelwizard.com/registry/bouncing-marbles-box/1.1.0/agent.md","files":"https://aipixelwizard.com/registry/bouncing-marbles-box/1.1.0/","demo":"https://aipixelwizard.com/registry/bouncing-marbles-box/1.1.0/index.html"},"description":"A complete scene built from four ingredients: real bouncing-ball physics, chrome material with studio lighting, a correctly set-up glass box and a smooth orbit camera. Balls drop in from above, collide, spin and come to rest. Switch to candy-coloured balls or a mix, change the number of balls, the bounciness and how far the camera travels. Use it as-is, or take just the parts you need.","role":"Complete example scene.","useCases":["Satisfying physics clip for social media","Starting point for 'X falls into Y' scenes","Showcase of chrome + glass rendering"],"synonyms":["shiny balls bouncing in a box","chrome balls","balls in glass box","glass container","marbles falling","shiny bouncing balls","bouncing balls glass"],"digest":"2795f54cc2445bbfe1c379558dd244ac1a7f9af2624c81faba3ada4133053694","implementation":{"target":"three","runtime":"browser","language":"javascript","module":"esm","entry":"demo.js","exports":[{"name":"createDemo","signature":"createDemo({ canvas, width, height, params, fps, duration }) => { renderFrame(info), dispose() }","description":"Builds the scene; the harness calls renderFrame for each frame."}],"reusable":[],"demo":"demo.js","harness":"index.html"},"dependencies":[{"id":"three","version":"0.185.1","scope":"source","reason":"WebGL rendering."},{"id":"bouncing-balls","version":"1.0.0","scope":"source","reason":"Physics."},{"id":"chrome-material","version":"1.0.0","scope":"source","reason":"Material and environment."},{"id":"glass-container","version":"1.1.0","scope":"source","reason":"Glass box, cove backdrop and backlight."},{"id":"orbit-camera","version":"1.0.0","scope":"source","reason":"Camera motion."},{"id":"apw-runtime","version":"1.0.0","scope":"source","reason":"Harness and export tools."}],"uses":[{"id":"bouncing-balls","version":"1.0.0","role":"Physics: ball positions and spins each frame."},{"id":"chrome-material","version":"1.0.0","role":"Ball surface and studio environment lighting."},{"id":"glass-container","version":"1.1.0","role":"The glass box, the cove backdrop and the backlight; inner size matches the physics box."},{"id":"orbit-camera","version":"1.0.0","role":"Camera path around the box."}],"usedBy":[],"params":[{"key":"count","label":"Number of balls","type":"integer","min":4,"max":40,"step":1,"default":18},{"key":"ballStyle","label":"Ball look","type":"select","default":"chrome","options":[{"value":"chrome","label":"All chrome"},{"value":"mixed","label":"Chrome + colour"},{"value":"candy","label":"Candy colours"}]},{"key":"bounciness","label":"Bounciness","type":"number","min":0.3,"max":0.9,"step":0.01,"default":0.68},{"key":"seed","label":"Variation","type":"integer","min":1,"max":9999,"step":1,"default":4},{"key":"turns","label":"Camera travel","help":"0 keeps the camera still; 1 is a full circle with an eased start and stop.","type":"number","min":0,"max":1,"step":0.05,"default":0.35},{"key":"cameraDistance","label":"Camera distance","type":"number","min":8,"max":18,"step":0.1,"default":11.5},{"key":"cameraHeight","label":"Camera height","type":"number","min":1,"max":9,"step":0.1,"default":5.2},{"key":"glassTint","label":"Glass tint","type":"color","default":"#e8fbff"},{"key":"lightWarmth","label":"Light warmth","type":"number","min":-1,"max":1,"step":0.05,"default":0.1},{"key":"background","label":"Background","type":"color","default":"#0b0b10"}],"presets":[{"id":"default","label":"Chrome pour","params":{}},{"id":"candy","label":"Candy pile","params":{"ballStyle":"candy","count":30,"bounciness":0.5}},{"id":"still","label":"Still camera, bouncy","params":{"turns":0,"bounciness":0.86,"count":10,"cameraHeight":3}}],"output":{"width":1080,"height":1080,"fps":30,"durationSeconds":8,"posterSeconds":2.4,"alpha":false,"motion":"simulation","loop":{"seamless":false,"method":"Balls fall and settle once."},"seed":{"param":"seed","behavior":"Same seed and settings give identical motion."}},"composition":{"inputs":"Parameters only.","outputs":"A rendered Three.js scene.","coordinates":"Y-up. Glass box inner volume 4 × 3 × 4 with floor at y = 0 — identical to the physics box.","lighting":"Studio environment from chrome-material; tone mapped.","timing":"Physics baked for the clip's fps/duration; camera driven by progress.","compatibleWith":[],"notes":["Ready to run: all four ingredients are tested together in this example."]},"reuse":["Swap the balls for other shapes (keep the physics positions) — dice, candies or logos.","Keep the glass box and physics, drop the orbit and use a fixed hero camera.","Recolour with ballStyle candy for a playful version."],"integration":{"newProject":"Download the pack, run npm install, then `npm run serve` and open bouncing-marbles-box/1.0.0/index.html. Export a video with `npm run render -- bouncing-marbles-box/1.0.0`.","existingProject":"Treat demo.js as a reference for wiring the ingredients together. Copy the ingredient source files into your project and reproduce the assembly in your own scene code; do not replace your project with this demo."},"performance":{"notes":"Glass transmission adds one render pass. Physics bake ~50 ms at load.","limits":"40 balls max in this example."},"limitations":["Balls do not reflect each other (environment-map reflections only).","No caustics through the glass."],"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"}]},"rights":{"approvedForPublicRelease":true},"provenance":"Original code written for AI Pixel Wizard in October 2026. Demo scene rebuilt in October 2026 to the catalog quality bar (docs/QUALITY.md).","changelog":[{"version":"1.1.0","date":"2026-10-03","notes":"New scene to the quality bar: cove backdrop, matte studio floor, clearer glass with lit edges, fitted camera. Same four ingredients."},{"version":"1.0.0","date":"2026-10-02","notes":"Initial release."}],"verification":{"testedOn":"2026-10-03","inputs":{"bouncing-marbles-box@1.1.0":"2795f54cc2445bbfe1c379558dd244ac1a7f9af2624c81faba3ada4133053694","three@0.185.1":"664ca387e5fab46ff2daaa6895e1d015426850891af5ea5082cbbcc3985b068c","bouncing-balls@1.0.0":"c0a270f1cb930672c8ac0851450d3ce2863d8d1effe87d35ad697a5729fb5429","apw-runtime@1.0.0":"5be859cdac74823ba0bcc32c6daf06688a871104d24db5d4ceaffffd84d7c40d","chrome-material@1.0.0":"cd8524db875223bd8ffc7b17ba8ac3e622590e4b2a6eac967a17cf60b927d9cb","glass-container@1.1.0":"973b74f1a14e01629f3ab77cec617fc211fb419f3e580b45284583aafaafecf4","orbit-camera@1.0.0":"e54405aabe47ddc8c4115651f25b8316d602d4f5fb0eef2c3630aba48bac3e09"},"environment":"Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0","renderer":"WebGL 2 via SwiftShader (software)","width":1080,"height":1080,"fps":30,"frames":240,"renderSeconds":380,"loopCheck":{"checked":false,"seamless":null,"maxDifference":null,"note":"Asset does not claim a seamless loop."},"determinism":{"checked":true,"identical":true},"errors":[],"media":{"poster":"/media/bouncing-marbles-box/1.1.0/poster.webp","preview":"/media/bouncing-marbles-box/1.1.0/preview.mp4","sample":"/media/bouncing-marbles-box/1.1.0/sample.mp4","sampleBytes":1187325}},"files":[{"path":"LICENSE","size":1072,"sha256":"8a5f3a96f07e11522ec4bdd0a583356f99bad1245920f9709cee09b995a45153","contentType":"text/plain; charset=utf-8","url":"https://aipixelwizard.com/registry/bouncing-marbles-box/1.1.0/LICENSE"},{"path":"asset.json","size":8238,"sha256":"4139470e45855e07bcd0625f14d3f74f1265398423e954df2940860a21539184","contentType":"application/json; charset=utf-8","url":"https://aipixelwizard.com/registry/bouncing-marbles-box/1.1.0/asset.json"},{"path":"demo.js","size":5145,"sha256":"d6f4f07acdc40ccba9b3327830352775e70d3eb88a2657cf47635e9fa0c491e1","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/bouncing-marbles-box/1.1.0/demo.js"},{"path":"index.html","size":539,"sha256":"72a3afbfe8ae5d775cf65e240b44bb56dd282f2ddef759c0f28bba941a98271e","contentType":"text/html; charset=utf-8","url":"https://aipixelwizard.com/registry/bouncing-marbles-box/1.1.0/index.html"}],"warnings":[]}