{"id":"hourglass","version":"1.0.0","title":"Hourglass","summary":"A glass-and-brass hourglass: the sand runs, the glass flips, the sand runs again. Loops perfectly.","kind":"object","target":"three","collections":["satisfying","hypnotic-loops","product-reveals"],"tags":["hourglass","sand timer","time","countdown","deadline","sand","glass","brass","clock","loop","3d"],"loopable":true,"motion":"procedural","durationSeconds":16,"status":"published","media":{"poster":"https://aipixelwizard.com/media/hourglass/1.0.0/poster.webp","preview":"https://aipixelwizard.com/media/hourglass/1.0.0/preview.mp4","sample":"https://aipixelwizard.com/media/hourglass/1.0.0/sample.mp4","sampleBytes":1589753,"sampleNote":"Pre-rendered with the default settings. Customised settings must be exported locally (npm run render)."},"urls":{"page":"https://aipixelwizard.com/visuals/hourglass","manifest":"https://aipixelwizard.com/api/v1/visuals/hourglass/versions/1.0.0","agentMd":"https://aipixelwizard.com/registry/hourglass/1.0.0/agent.md","files":"https://aipixelwizard.com/registry/hourglass/1.0.0/","demo":"https://aipixelwizard.com/registry/hourglass/1.0.0/index.html"},"description":"A classic sand glass floating in a dark studio: a glass double-bulb between two turned metal plates on three slender posts. A thin stream of sand runs through the neck, the upper pile sinking into a funnel while the lower one builds a cone at the angle of repose; when it has all run through the glass turns over, the sand slumping from the cone into a funnel on its new top, and it runs again. Choose the sand (any colour), the metal of the frame (brass, copper, chrome or black), a tint in the glass, and how much of the loop is spent turning the glass over.","role":"Hero object (Three.js 3D): the classic symbol of time running out, for countdowns, deadlines and reflective content.","useCases":["A deadline, countdown or limited-offer visual: time is running out","A reflective, philosophical or documentary shot about time","A calm, satisfying loop behind a quote or a title"],"synonyms":["sand glass","sand clock","egg timer","time running out","countdown timer","falling sand","time passing","deadline animation"],"digest":"06c46e25249807efe6eff43986bfa0eb450c45ac2130dfc9c1bb40edd64b308a","implementation":{"target":"three","runtime":"browser","language":"javascript","module":"esm","entry":"src/hourglass.js","exports":[{"name":"createHourglass","signature":"createHourglass({ sand?, finish?, tint?, origin?, seed? }) => { group, half, uniforms, update(time, loopSeconds, { flip? }), dispose() }","description":"The hourglass as a THREE.Group (1 unit = 10 cm), hung at origin. update(time, loopSeconds) runs the sand and then turns the glass over; the whole thing repeats exactly. Set uniforms.uKey to your key light's direction."},{"name":"FINISHES","signature":"FINISHES: { brass, copper, chrome, black }","description":"Finishes for the plates and posts."}],"reusable":["src/hourglass.js"],"demo":"demo.js","harness":"index.html"},"dependencies":[{"id":"three","version":"0.185.1","scope":"source","reason":"Renderer, physical glass and metal, and the sand's ray-marching shader."},{"id":"chrome-material","version":"1.1.0","scope":"demo","reason":"Studio environment light, backdrop, floor and contact shadow."},{"id":"apw-runtime","version":"1.0.0","scope":"demo","reason":"Demo harness."}],"uses":[],"usedBy":[],"params":[{"key":"sand","label":"Sand","type":"color","default":"#e3b86a"},{"key":"finish","label":"Frame","type":"select","default":"brass","options":[{"value":"brass","label":"Brass"},{"value":"copper","label":"Copper"},{"value":"chrome","label":"Chrome"},{"value":"black","label":"Black lacquer"}]},{"key":"tint","label":"Glass tint","type":"color","default":"#ffffff"},{"key":"flip","label":"Time spent turning over","help":"The share of the loop that the glass spends turning, 0.1 to 0.35.","type":"number","min":0.1,"max":0.35,"step":0.01,"default":0.2},{"key":"background","label":"Backdrop","type":"color","default":"#10131b"},{"key":"seed","label":"Seed","help":"Changes the grain of the sand.","type":"integer","min":1,"max":999,"step":1,"default":3}],"presets":[{"id":"default","label":"Golden sand, brass frame","params":{}},{"id":"chrome","label":"White sand, chrome frame","params":{"sand":"#f1efe8","finish":"chrome","background":"#0b121d","seed":8}},{"id":"red","label":"Red sand, black lacquer","params":{"sand":"#d13a2e","finish":"black","tint":"#e6f4ff","background":"#1a1012","seed":12}},{"id":"copper","label":"Slate sand, copper frame","params":{"sand":"#6b7388","finish":"copper","background":"#241b17","flip":0.14,"seed":5}}],"output":{"width":1080,"height":1080,"fps":30,"durationSeconds":16,"posterSeconds":6,"alpha":false,"motion":"procedural","loop":{"seamless":true,"cycleSeconds":16,"method":"The sand runs, then the glass turns over by exactly half a turn. The glass, plates, posts and sand are all symmetric under that half turn (the grain is defined in each bulb's own frame), so the last frame meets the first."},"seed":{"param":"seed","behavior":"Seed changes the grain of the sand and the glints in it."}},"composition":{"inputs":"Time within the loop; the sand colour, frame finish, glass tint and the share of the loop spent turning over.","outputs":"A THREE.Group: plates, posts, glass and the sand volume, centred on the origin (or origin option).","coordinates":"1 unit = 10 cm. The glass is 2.6 tall inside two plates, 3.0 overall, and 1.1 across at its widest.","lighting":"Physical glass and metal: needs scene.environment. The sand is lit in its own shader by a key light (set uniforms.uKey to the real light's direction) and a sky fill.","timing":"update(time, loopSeconds) is a pure function of time; frames render in any order.","compatibleWith":["chrome-material","orbit-camera","kinetic-title"],"notes":["The sand volume is opaque on purpose: three.js transmission refracts only opaque objects, so the glass can show it.","To make a countdown, set the loop to your countdown's length and spend the flip share at its end."]},"reuse":["Deadline: Golden sand, brass frame, with a bold 'Time is running out' over the top.","Timer sting: White sand in chrome, a 10-second loop, then your logo.","Documentary: Slate sand in copper, slow, behind a voice-over about time."],"integration":{"newProject":"Set scene.environment (createStudioEnvironment from Chrome Material works), add createHourglass({ origin }).group and a light, set uniforms.uKey, and call update(time, loopSeconds) each frame.","existingProject":"Copy src/hourglass.js. Add the group to your scene (scale it to suit), set uniforms.uKey to your key light, and call update(seconds, loopSeconds) every frame."},"performance":{"notes":"One ray-marched pass over the glass's silhouette (up to 110 steps) and one transmissive glass shell. Smooth at 1080p on laptop GPUs.","limits":"Software WebGL (no GPU) renders slowly. Transmission renders the opaque scene a second time."},"limitations":["The sand is a smooth volume with a grain texture, not simulated grains: the stream is a thin steady column.","The glass turns about its centre in mid-air; it never rests on a surface."],"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":"Adapted from the owner's threejs-sketches/objects-scenes/hourglass-sand (and webgpu-hourglass-flow) (MIT), rebuilt for AI Pixel Wizard in October 2026: a ray-marched sand volume with a cone and a funnel at the angle of repose, a stream, a modelled glass and turned frame that are symmetric under a half turn so the flip loops exactly, and the frame/time contract.","changelog":[{"version":"1.0.0","date":"2026-10-05","notes":"Initial release."}],"verification":{"testedOn":"2026-10-06","inputs":{"hourglass@1.0.0":"06c46e25249807efe6eff43986bfa0eb450c45ac2130dfc9c1bb40edd64b308a","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":480,"renderSeconds":2647.4,"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/hourglass/1.0.0/poster.webp","preview":"/media/hourglass/1.0.0/preview.mp4","sample":"/media/hourglass/1.0.0/sample.mp4","sampleBytes":1589753}},"files":[{"path":"LICENSE","size":1072,"sha256":"8a5f3a96f07e11522ec4bdd0a583356f99bad1245920f9709cee09b995a45153","contentType":"text/plain; charset=utf-8","url":"https://aipixelwizard.com/registry/hourglass/1.0.0/LICENSE"},{"path":"asset.json","size":8765,"sha256":"318991d3d703a506e4104caf4de4258469eb17450affd38c8902e5e418d5c5c8","contentType":"application/json; charset=utf-8","url":"https://aipixelwizard.com/registry/hourglass/1.0.0/asset.json"},{"path":"demo.js","size":2995,"sha256":"0224b0aa43e7b5c3526e0cf9940c2d0f850bf26081dda89c035c0d1752f050eb","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/hourglass/1.0.0/demo.js"},{"path":"index.html","size":523,"sha256":"2af40da96e7b07949ed8f5ee9bb90b1b659602577ecc0221fe82b9cd5aca3368","contentType":"text/html; charset=utf-8","url":"https://aipixelwizard.com/registry/hourglass/1.0.0/index.html"},{"path":"src/hourglass.js","size":14724,"sha256":"b5691e2f896756c24ec7d472dcc981ace18883e6bb1d41e8d203eca44bf07fee","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/hourglass/1.0.0/src/hourglass.js"}],"warnings":[]}