{"id":"balanced-stones","version":"1.0.0","title":"Balanced Stones","summary":"A cairn of smooth river stones balanced one on another, rocking ever so gently in low light. Loops perfectly.","kind":"object","target":"three","collections":["satisfying","backgrounds","hypnotic-loops"],"tags":["cairn","stones","balance","zen","pebbles","stacked stones","river stones","mindfulness","calm","nature","meditation","loop","3d"],"loopable":true,"motion":"procedural","durationSeconds":12,"status":"published","media":{"poster":"https://aipixelwizard.com/media/balanced-stones/1.0.0/poster.webp","preview":"https://aipixelwizard.com/media/balanced-stones/1.0.0/preview.mp4","sample":"https://aipixelwizard.com/media/balanced-stones/1.0.0/sample.mp4","sampleBytes":2108612,"sampleNote":"Pre-rendered with the default settings. Customised settings must be exported locally (npm run render)."},"urls":{"page":"https://aipixelwizard.com/visuals/balanced-stones","manifest":"https://aipixelwizard.com/api/v1/visuals/balanced-stones/versions/1.0.0","agentMd":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/agent.md","files":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/","demo":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/index.html"},"description":"A stack of river stones, each a little smaller than the one below and each a different pebble: rounded and flattened, worn smooth, painted with the grain of its rock (speckled granite, banded slate, a dark pebble with its white quartz band, layered sandstone, terracotta, white marble with grey veins, green jade). The cairn never quite stops moving: every stone rocks on its contact point with the one beneath, and the rocking adds up, so the top stone sways the most, slowly, as if a breath might topple the lot. It stands on a pale beach in low morning light that throws a long soft shadow, while the camera drifts slowly round it. Choose the mix of rock, the number of stones, how much they rock and lean, the ground, the light, the backdrop and whether the camera drifts.","role":"Object (3D, three.js): a calm, tactile hero object for wellbeing, mindfulness, nature and balance-themed content.","useCases":["A calm backdrop for meditation, yoga and wellbeing content","A balance, focus or \"keep it steady\" metaphor in a title scene","A nature, travel or retreat story opener"],"synonyms":["rock stack","stone stack","balanced rocks","zen stones","stacked pebbles","rock balancing","stone balancing","stone cairn"],"digest":"e0d8ddbc87bb48e39c990fd303af3e872a434e0c4a5bbdcfae56503f220aabf8","implementation":{"target":"three","runtime":"browser","language":"javascript","module":"esm","entry":"src/balanced-stones.js","exports":[{"name":"createBalancedStones","signature":"createBalancedStones({ stones?, rock?, rocking?, lean?, seed?, anisotropy? }) => { group, stones, setProgress(progress), dispose() }","description":"The cairn as a group of meshes standing on y = 0 (1 unit ≈ the base stone's radius): add it to a scene with a shadow-casting light and an environment map, and call setProgress each frame."},{"name":"ROCKS","signature":"ROCKS: { river, mono, warm, jade }","description":"The kinds of rock mixed in each palette."}],"reusable":["src/balanced-stones.js"],"demo":"demo.js","harness":"index.html"},"dependencies":[{"id":"three","version":"0.185.1","scope":"source","reason":"Renderer, geometry and physical 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."}],"uses":[],"usedBy":[],"params":[{"key":"rock","label":"Rock","type":"select","default":"river","options":[{"value":"river","label":"River stones"},{"value":"mono","label":"Black, grey and white"},{"value":"warm","label":"Sandstone and terracotta"},{"value":"jade","label":"Jade and marble"}]},{"key":"stones","label":"Stones","type":"integer","min":3,"max":9,"step":1,"default":7},{"key":"rocking","label":"Rocking","help":"How much each stone rocks on the one below.","type":"number","min":0,"max":2,"step":0.05,"default":1},{"key":"lean","label":"Lean","help":"How far each stone sits off the centre of the one below, and how tilted it is.","type":"number","min":0,"max":2,"step":0.05,"default":1},{"key":"ground","label":"Ground","type":"select","default":"sand","options":[{"value":"sand","label":"Pale sand"},{"value":"slate","label":"Slate"},{"value":"moss","label":"Moss"}]},{"key":"light","label":"Light","type":"select","default":"morning","options":[{"value":"morning","label":"Low morning sun"},{"value":"noon","label":"High noon"},{"value":"dusk","label":"Dusk"}]},{"key":"background","label":"Backdrop","type":"color","default":"#d9cdb8"},{"key":"orbit","label":"Camera drift","type":"boolean","default":true},{"key":"seed","label":"Seed","type":"integer","min":1,"max":999,"step":1,"default":4}],"presets":[{"id":"default","label":"River stones, morning sun","params":{}},{"id":"jade","label":"Jade and marble, noon","params":{"rock":"jade","light":"noon","background":"#cfd8cc","ground":"slate","seed":9}},{"id":"dusk","label":"Sandstone at dusk","params":{"rock":"warm","light":"dusk","background":"#c9a98a","stones":6,"seed":21}},{"id":"mono","label":"Black and white, slate floor","params":{"rock":"mono","ground":"slate","background":"#b8bcc2","stones":8,"rocking":1.3,"seed":5}}],"output":{"width":1080,"height":1080,"fps":30,"durationSeconds":12,"posterSeconds":3,"alpha":false,"motion":"procedural","loop":{"seamless":true,"cycleSeconds":12,"method":"Each stone rocks about two axes in sines of a whole number of cycles per loop (one to three), the rocking of every stone below adds to the stones above, and the camera drift is a sine of the loop, so the last frame meets the first."},"seed":{"param":"seed","behavior":"Seed shapes every pebble, picks its rock, size, offset and tilt and the rhythm of its rocking: same seed, same cairn."}},"composition":{"inputs":"Time within the loop; the rock, the number of stones, rocking, lean, ground, light, backdrop, camera drift and the seed.","outputs":"A full frame, rendered in 3D with soft shadows and a studio environment.","coordinates":"The cairn stands on the plane y = 0 at the origin; the base stone has a radius of about 1 and the stack of seven reaches y ≈ 4; the camera orbits a point at y = 1.9 from a low angle.","lighting":"A warm directional light with a soft shadow map (morning, noon or dusk), a hemisphere fill, the studio environment for the sheen and a soft contact shadow under the base.","timing":"setProgress(progress) sets every rocking angle as a whole number of cycles of the loop; frames render in any order.","compatibleWith":["chrome-material","orbit-camera","kinetic-title","number-reveal"],"notes":["Each pebble is a UV sphere pushed into a rounded, flattened solid (a super-ellipsoid), bumped with two octaves of smooth pseudo-noise and its normals averaged across the UV seam; the colour and bump maps are drawn once with Canvas 2D from the seed.","The stones are nested: each stone's pivot is a child of the pivot below, at the contact point, so the rocking accumulates up the stack."]},"reuse":["Meditation or wellbeing backdrop: River stones, morning sun.","Calm product-style loop: Jade and marble, noon.","Travel or retreat opener: Sandstone at dusk."],"integration":{"newProject":"Create a WebGLRenderer with shadows, a studio environment (see chrome-material) and a directional light that casts shadows; scene.add(createBalancedStones().group) and call cairn.setProgress(progress) each frame.","existingProject":"Copy src/balanced-stones.js; add cairn.group to your scene (with an environment map and a shadow-casting light) and call setProgress each frame."},"performance":{"notes":"Seven stones of about 12 000 triangles each, one shadow map, anti-aliasing. About 19 ms a frame at 1080p on an integrated Intel GPU.","limits":"Software WebGL (no GPU) renders in a second or two a frame."},"limitations":["The stones are not simulated: their balance is staged (the offsets are small), and a lean above about 1.5 can look physically impossible.","The stones' undersides are not flat, so they sink slightly into the stone below rather than touching at a point.","The ground is a flat textured disc, not a beach with ripples."],"license":{"spdx":"MIT","notice":"Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.","thirdParty":[]},"rights":{"approvedForPublicRelease":true},"provenance":"Adapted from the owner's threejs-sketches/objects-scenes/pebble-stack (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original object: bumped super-ellipsoid pebbles with seam-averaged normals, seeded procedural rock textures (granite, slate, quartz-banded basalt, sandstone, terracotta, marble, jade) and a nested chain of pivots so the rocking accumulates up an exact-loop stack.","changelog":[{"version":"1.0.0","date":"2026-10-05","notes":"Initial release."}],"verification":{"testedOn":"2026-10-06","inputs":{"balanced-stones@1.0.0":"e0d8ddbc87bb48e39c990fd303af3e872a434e0c4a5bbdcfae56503f220aabf8","three@0.185.1":"664ca387e5fab46ff2daaa6895e1d015426850891af5ea5082cbbcc3985b068c","chrome-material@1.1.0":"ecb41776bfc1ee88997604f916a5ffe833f971d7edcc97c855697a5792d6f1dd","apw-runtime@1.0.0":"5be859cdac74823ba0bcc32c6daf06688a871104d24db5d4ceaffffd84d7c40d"},"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":360,"renderSeconds":2639.8,"loopCheck":{"checked":true,"seamless":true,"maxDifference":0,"note":"Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255."},"determinism":{"checked":true,"identical":true},"errors":[],"media":{"poster":"/media/balanced-stones/1.0.0/poster.webp","preview":"/media/balanced-stones/1.0.0/preview.mp4","sample":"/media/balanced-stones/1.0.0/sample.mp4","sampleBytes":2108612}},"files":[{"path":"LICENSE","size":1072,"sha256":"8a5f3a96f07e11522ec4bdd0a583356f99bad1245920f9709cee09b995a45153","contentType":"text/plain; charset=utf-8","url":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/LICENSE"},{"path":"asset.json","size":10260,"sha256":"57789dd4d1c14e40328f300cbb9c9566dc8e5ed40af1b8aa6884827257e25276","contentType":"application/json; charset=utf-8","url":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/asset.json"},{"path":"demo.js","size":5254,"sha256":"1524ba8388089a4321414ced01f65aac9a9f1886806d18b3027d179c871d7902","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/demo.js"},{"path":"index.html","size":529,"sha256":"c7dd858a52f025a5de11a397ed0dee393d50b3dc83f86827b8c5f3b89d0454f4","contentType":"text/html; charset=utf-8","url":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/index.html"},{"path":"src/balanced-stones.js","size":14185,"sha256":"701a680e0e00327d805ee92687d19d69b6e6e8d3d5a79a5b22fa33576fa990c8","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/balanced-stones/1.0.0/src/balanced-stones.js"}],"warnings":[]}