# Psychedelica

*Twelve procedurally random Three.js scenes you can let run wild, or replay in order as a narrated twelve-chapter story.*

- Year: 2024
- Built with: Vue.js, Vite, Three.js, Tone.js, Pinia, Tailwind
- Updated: 2026-09-07T20:55:53.057Z
- live: https://psychedelica.abchaudary.me
- repo: https://github.com/abdullahchaudary/psychedelica

> Psychedelica renders 12 Three.js and Tone.js scenes: pure Math.random() chaos in Randomize mode, or the same 12 scenes as a narrated Story.

## What it is

Psychedelica is a generative visual and audio experience: twelve Three.js scenes, each with its own geometry, colour and motion, scored by Tone.js. There are two ways to watch it. Randomize lets `Math.random()` pick the next scene on its own, no two sessions alike. Story plays the same twelve scenes in a fixed order, each one titled and narrated. It installs as a PWA, straight from the browser.

## Where this started (origin story)

This one started with a question I've had since childhood: whether anything actually happens randomly, or whether "random" is just a word for a cause we haven't traced yet. Computers are famously bad at generating true randomness, still, even now, which is why Cloudflare photographs a wall of lava lamps to seed the entropy behind a meaningful share of the internet's encryption: physical chaos, because the digital kind isn't chaotic enough. That detail stuck with me. So did psychedelic drug research, which kept describing experiences people call "out of this world," as close to true randomness as human perception gets. My own philosophy runs the other way: nothing happens without a chain behind it, a cause and effect, weights in a network, a butterfly's wing. A wave breaks down into frequencies, a frequency into its components, and so on, until there's nothing left to trace. If that's true, "randomness" isn't a property of the world. It's a description of how much of the chain a mind has lost track of. I wanted to build something that let me sit with that question instead of just thinking about it, so I started working in Three.js.

## Twelve scenes, built from nothing but chance

`Psychedelica.js` defines twelve scenes, each its own field of Three.js geometry: boxes, spheres, cones, tori, dodecahedra, octahedra, picked at random, coloured at random, positioned and rotated at random, and nudged along a small random walk every frame. Every three seconds, a scene throws its entire object field away and rebuilds it from scratch. There is no noise function underneath any of it, no seeded generator, nothing engineered to look organic. It's `Math.random()`, called constantly, and nothing else. In Randomize mode, the app rolls that same function every twenty seconds to choose which of the twelve scenes plays next. Left running, it's the closest thing on this site to actual, undirected chance.

## The same twelve scenes, told as a story

Story mode is the other half of the argument. It's the identical twelve scenes, the same geometry, the same Tone.js instruments, but scheduled in a fixed order instead of a rolled one, each scene introduced by its own title card ("The Dance of Chaos," "Fixed Points in a Moving Universe," "The Circle of Creation" among them) and its own pre-recorded narration track, twelve `.wav` files, one per scene. Nothing about the underlying material changes between the two modes. What changes is whether a chain of decisions sits on top of it. Watch the same twelve scenes as Randomize and they read as noise. Watch them as Story and they read as a story. That gap is the entire thesis of this project, built directly into which button you press.

## The music is generated the same way

The sound isn't just reacting to the scene, it's built from the same chance the geometry is. A function called `getPsychedelicNote()` picks one of four custom scales at random, then a random note out of that scale, and the melody lines elsewhere pull their notes the same way, random chord tones with a randomly jittered timing offset on each hit, so no phrase repeats the way it did last time. All of it runs through a Tone.js synth stack (AM, mono, membrane, noise and metal synths covering lead, bass, kick, hi-hat and snare), with reverb, delay and chorus, and the effect settings and bassline shifting per scene the same way the geometry does. The music and narration busses are each routed through a `Tone.Panner3D` in HRTF mode, and their position keeps drifting to a new random point in space every one to five seconds, so the sound field is exactly as unsettled as the scene in front of it. One scene also draws on a fixed Catmull-Rom spline instead of random placement, a small deliberate island of order inside the twelve.

## Creativity, and the argument neither side has won

If nothing happens without a cause, creativity should be the easiest thing in the world to explain: not a spark from nowhere but a recombination, whatever a mind has taken in, run back through the same chain of decisions creativity claims to escape. The two ideas I built this around, chance and cause, are supposed to be opposites, but a scene rebuilt from `Math.random()` every three seconds and a melody built from `getPsychedelicNote()` are both still a program doing exactly what it was written to do. There's no dice inside a computer, only a function behaving like one. That's most of my answer to the free will question too. What the evidence keeps pointing toward is a chain, not a choice sitting outside it, and yet the debate hasn't closed, because thinking about your next thought doesn't feel like an output. It feels like a decision. Psychedelica doesn't resolve that. It just makes the same tension audible: press one button and the twelve scenes are noise, press the other and they're a story, and nothing about the twelve scenes themselves changed to make that true.

## Before any of it starts

The app opens on a photosensitivity warning, plainly worded, with a way to leave before anything plays: flashing lights, fast colour changes and intense audio are named up front, not buried in a settings menu. Twelve scenes of `Math.random()`-driven strobing geometry is exactly the kind of experience that warning exists for, and it's there on purpose, not as a formality.

## Stack

Vue 3, Vite, Pinia and vue-router hold the shell together; every scene owns its own Three.js render loop and its own slice of the Tone.js audio graph. It installs as a PWA (`vite-plugin-pwa`), full-screen display mode, so it runs the same whether it's opened in a browser tab or launched like an app.

## Outcome

What this became mattered more than how it went together. A friend of mine, studying design, used Psychedelica as the basis of his own university project and earned a distinction for it, work that went on to win him a scholarship at another university in Belgium. I built something to sit with a question about randomness and causality. What it generated, for someone else, was an actual path forward.

## Links

Live: [psychedelica.abchaudary.me](https://psychedelica.abchaudary.me). Source: [github.com/abdullahchaudary/psychedelica](https://github.com/abdullahchaudary/psychedelica). The synth stack and the PWA setup are close cousins of [MusicGen](/projects/musicgen), built around the same time and the same tools, aimed at a different question.
