The powder is rice flour, and that is the entire point of it. A kolam goes down on the doorstep before sunrise, drawn freehand in flour rather than paint, so that ants and birds can eat it. By midday everyone coming in and out of the house has walked over it and it is gone. The next morning somebody crouches down and draws another one.

I have watched this happen my whole life and never once thought of it as a graphics problem. It is a drawing that is built to be destroyed.

So I made one that can be swept away and brought back exactly.

Most 3D on the web is scenery. Something rotates while you scroll past it, and nothing on the screen came from you. Threshold has only one thing on it, and it is the path your own hand took. Open the site, add ?seed=4821 to the address, and you get the pattern in the first screenshot: the same arcs in the same places, on a phone or on a desktop monitor. That number in the address bar is the whole drawing. Change it and you get a different one.

Live: https://three-d-demo-shivcreates.vercel.app

What you do

Drag once across the stone. Before your hand has finished moving, eight arcs have bloomed out of it, mirrored and rotated around the centre. That is the Eightfold. It is the dihedral group D4, which means the symmetry is not a taste decision, it is arithmetic, and the eight arms are congruent down to the last place a float can hold. The powder falls, bounces once, and settles into the wet stone.

There is nothing to read before you start. No instructions panel, no onboarding, no "click here". The response to the first millimetre of movement is the tutorial.

Press R, or the REPLAY button if you are on a phone, and the whole pattern lifts and falls again into exactly the same places. Press SWEEP and the doorstep is clean.

In the bottom corner the page shows the seed and a short print of the drawing, which is a fingerprint taken over where every grain came to rest. Replay it, resize the window, drag it onto a second monitor, switch the animation off. The fingerprint does not move.

What I would want a sceptic to know

The rice powder is not granular physics. Each grain follows a closed-form curve to its resting place and grains never collide with each other. The page says so itself, in the corner, tagged SIMULATED, because a piece whose whole argument is "you can check this" has no business being quiet about the part that is faked.

The fall curve is written down twice, once in JavaScript where the tests can reach it and once in GLSL where the GPU can. The core is not allowed to import a shader and the GPU cannot import JavaScript, so the duplication is unavoidable. I matched the two by hand and checked them against a frozen set of reference points, and they agree far below anything an eye or a screen could resolve. But nothing in the test suite compiles or runs the shader. Change the JavaScript and a test breaks. Change the shader, which is the half you actually look at, and nothing breaks. That fence closes in one direction only, and the open direction is the one that matters. It is the thing I most wanted to fix and did not.

There is a test that forbids the core from importing three.js or touching the browser at all. It works: I broke the rule on purpose to see it fail, and it caught me. It catches the honest version of the mistake. Somebody determined can walk straight past it in several ordinary ways and I know what they are, because I went looking for them.

And if your browser decides to render WebGL in software instead of on your graphics card, the page still loads and then it crawls. I built a fallback for WebGL being unavailable, and a governor for the frame rate dropping under load. This case is neither of those, so neither one catches it.

One decision, and what it bought

Nothing under src/core/ is allowed to import three.js, React, or anything that knows a browser exists. It is arithmetic over numbers, and that is all it is.

That single rule paid for three things. The whole core runs under node --test with no browser and no bundler, so the pattern is testable without a GPU. The drawing is reproducible, because nothing inside it is able to ask what time it is or which machine it is on. And when WebGL is missing, the fallback screen calls the same function and draws a kolam as flat SVG circles. That file's only import, the entire line one of it, is the core. If the core touched three.js, that file could not exist. The fallback is not a promise about the boundary, it is the proof of it.

Correction on that, since I would rather say it than have it found: the fallback draws its own doorstep pattern, not yours and not the one the seed in the address bar asks for. It is the same function. It is not the same picture.

Three things that went wrong

The one that stings. After a replay, the app announced in its accessibility live region that the print was unchanged. It never checked. The statement was true, and I have since proved it is true, but the whole claim of this piece is that you can verify the drawing came back, and the code was asserting that rather than testing it. A red-team pass found the sentence hardcoded four lines from the code that was supposed to earn it. It now captures the fingerprint before the replay, compares it after, and reports what actually happened, so if it ever stops being true the page will say so out loud. This is precisely the failure the project exists to be the opposite of, and I shipped it first.

The ground. A pass meant to make the stone read as wet turned the entire frame orange-brown and parked a bright lamp blob in the lower right that fought the kolam for your eye. I rejected it and reverted. The cause was in my own design spec, not in the implementation: the lamp was being added to the ground independently of the ground's own colour, and a light term that is not multiplied by an albedo is not light, it is fog. Multiply it through and the stone drops back to near-black with the powder as the only warm thing in the picture.

The judging pass measured its own tooling. A simulated judge walk reported the frame rate collapsing and was about to file it as a blocker. Then it checked its instrument instead of its finding: the headless browser it was driving had quietly fallen back to software rendering. On real hardware the frame rate is solid, even with the buffer completely full and the CPU throttled. It threw out the measurement and kept the risk underneath it, because a locked-down school laptop can do exactly the same thing to a real judge. That is the software-rendering gap listed above.

Reduced motion, and no GPU at all

Switch motion off and the grains arrive already settled. No falling, no bounce, and the idle camera stops drifting. The fingerprint is identical, and it is identical for a structural reason rather than a careful one: the accessibility setting is a number handed to the shader, and there is no path from it back to the arithmetic that decides where a grain lands. You can turn the animation off. You cannot change the drawing by turning it off.

Kill WebGL entirely and you get a composed frame rather than an error message. Title, the Tamil line, a kolam as SVG circles, and a colophon that leaves the grain count out rather than quoting a figure it is not actually showing.

How this was made, and by what

The rules allow AI tools, I used a great deal of one, and here is the full account.

Threshold was built by Pit Crew, a system of fourteen specialist agents I wrote, running on Claude Code with Anthropic's Claude Opus 5. I directed it and made every decision that mattered. The agents did the work. Named by contribution:

  • Scout verified the rules, dates, prizes and judging criteria against Devpost's API and the live rules page before a line was written.
  • Strategist read the rubric and made the two calls that decided the whole project: stay out of the saturated categories, and generate every piece of geometry in code rather than downloading a model.
  • Architect turned the idea into a task board with an explicit cut order.
  • Designer wrote the visual spec: palette, camera pitch, lighting, type, the fallback frame. It also found the fog bug in its own spec.
  • Frontend and Backend built the thing.
  • Deployer put it on Vercel and confirmed it was genuinely public while signed out, and caught that a similarly named Vercel alias belongs to a complete stranger.
  • Test User walked the deployed URL the way a judge would, alone, on a desktop and on a phone, and tried to misuse it.
  • Red Team attacked the project's own claims with an independent hash rather than trusting the app's own, ran control arms to prove its instruments were not lying to it, and produced both the defects fixed above and the gaps disclosed above.
  • Debugger fixed them, each one with a named regression test.
  • Scribe drafted this description. I rewrote it.

What I personally did: chose the kolam, set the time budget, rejected the ground pass, ruled on what could ship and what had to be disclosed instead of hidden, and refused to let the crew create a public repository under my name without me. Every commit is authored by me because I approved every one.

No 3D asset was downloaded, generated by an image model, or imported. Every grain position, the stone, the lighting and the composition are code in this repository. The two typefaces are open-source webfonts, Instrument Serif and IBM Plex Sans, installed from npm.

What is next

The gap I could not close is the first one I would open the editor for: a test that actually executes the shader's arithmetic and holds it against the JavaScript, so the fence closes both ways. I know exactly how to write it. I ran out of hours, not ideas.

After that, the thing I actually want is for your kolam to be in the address bar, not just the seed. Draw one, send someone the link, and have the same drawing land on their doorstep.

The requirements, checked

  • Publicly accessible website link: https://three-d-demo-shivcreates.vercel.app, live, works signed out, no login, no account, nothing stored.
  • Description explaining idea and inspiration: this.
  • At least three screenshots: desktop hero, a hand-drawn stroke on desktop, and the whole thing on a phone.
  • Demo video: optional, and noted as such.
  • Technologies and tools used: listed in the Built With field, including the AI tooling.
  • Source code: the repository linked on this page. Nothing is minified away from you; a fresh build from that source reproduces the file the live site is serving.

Closing

By midday the kolam is gone. That was never a flaw in it. Someone sweeps the step, and before light the next morning they crouch down and draw another one. On this doorstep the sweeping is a button, and so is the coming back.

Built With

Share this project:

Updates