fluent_scene technical report

The Science of an LSD Shader

A psychedelic trip is not a vague swirl of colour — it is a phenomenon you can derive from the wiring of the visual system. This report walks through fluent_scene’s new lsd filter and shows which neural mechanism each stage of the computation stands for.

starting engine… Open the live demo

What fluent_scene is

A homegrown engine for drawing pictures and effects on live video, in real time. A screen is a few lines of config, an effect is one line, and it runs on the GPU, so it's fast. The same code runs on robots and in browsers — this article's LSD effect is one of its filters. It's also built so an AI can author screens without breaking anything. Open source (MIT) on GitHub. The technical details come later in the article.

1. What people actually see

Decades of subjective reports have been sorted into a surprisingly precise taxonomy (the fullest catalogue is PsychonautWiki’s Visual effects). The main classes:

2. Why it looks that way — from molecule to cortex

2-0. Why LSD works at all — a key, a lock, and a lid

It starts with the shape of a molecule. At the core of LSD sits an indole ring — a benzene ring fused to a pyrrole ring — which is precisely the skeleton of serotonin, the brain’s own transmitter. LSD is, in effect, serotonin’s shape carried inside a larger, more rigid molecule, and it slots into the serotonin receptor’s binding pocket like a key.

In 2017, Wacker and colleagues solved the crystal structure of an LSD-bound serotonin receptor [13]. The decisive finding: the receptor’s extracellular loop 2 (EL2) folds over the entrance like a lid, trapping the molecule inside. That lid makes LSD extraordinarily slow to dissociate — it sits there for hours — which is why a trip lasts eight to twelve of them. Mutating the lid to make it more mobile speeds dissociation up and selectively removes the biased (β-arrestin) signalling.

Serotonin (5-HT) the lid stays open in and out in seconds = ordinary signalling LSD the EL2 lid closes hours to dissociate = an 8–12 hour trip diethylamide → same indole ring
Fig. 1 — In purple, the indole ring that serotonin and LSD share; it is the key that fits the pocket. The difference is on the way out: for LSD the extracellular loop EL2 closes over the entrance and traps the molecule, so dissociation is glacial and the effect runs for eight to twelve hours (Wacker et al. 2017).

In short: the indole ring fits the 5-HT2A receptor, the EL2 lid locks it in for hours, and cortical excitation stays off balance the whole time — the molecular origin of everything that follows.

2-1. The 5-HT2A receptor — cortical gain up, gating down

LSD’s main action is agonism at the serotonin 5-HT2A receptor. That raises the excitability of cortical pyramidal cells while damping the visual cortex’s alpha rhythm — the gate that normally thins incoming signal [4][6]. fMRI adds that thalamo-cortical connectivity increases, and that the loosening of thalamic sensory filtering correlates with how strong the visual hallucinations feel [5]. The upshot: the gain goes up and the filtering goes slack — colours deepen, edges sharpen, and faint patterns start to look meaningful.

Retina Thalamus (LGN) V1 Higher visual areas input features priors dominate gate loosens: unfiltered input passes [5] E/I balance breaks: patterns self-organize [2][3] pupils dilate: diffraction fringes 5-HT2A agonism → cortical gain ↑, alpha rhythm ↓ [4][6]
Fig. 2 — The visual pathway and where LSD acts. The purple arrow running back down from higher areas to V1 is the crux: the brain’s own predictions outweigh the evidence arriving from the world, and wherever input is thin, the brain paints something in.

2-2. Where the geometry comes from — V1, a logarithm, and a fractal

Klüver sorted geometric hallucinations into four classes in 1926 — the form constants: tunnels and funnels, spirals, lattices, cobwebs [1]. Why does everyone see the same handful of shapes? Ermentrout and Cowan gave a beautiful answer in 1979 [2].

Neurons in V1 excite their near neighbours and inhibit those a little further out. Push excitation up with a drug and that balance tips, so activity patterns arise spontaneously across the cortical sheet — the same bifurcation that gives Turing patterns in chemistry. What makes them visible is anatomy: the retina-to-V1 projection is approximately a complex logarithm, (x,y) → (log r, θ). Map plain cortical stripes back through it and you get:

A single plane wave — one tidy set of stripes — will not give you what people actually describe: masses of every size, nested fractally, streaming toward you. Two findings say why.

Drawing the theory’s lattice solutions straight out of a trigonometric function, though, comes out far too regular to be true. Two things recur in every report: there are no straight lines, right angles, or perfect circles, and you are flying through a 3D space where everything expands forever. So the shader’s geometry field uses no periodic function at all:

Klüver’s classes survive not as drawn figures but as statistics: multi-scale, flowing, biased toward the centre. Combined with the feedback zoom described below, the whole frame reads as something welling up out of the distance and rushing past you.

The demo below shows the principle. On the left, a pattern on the cortical sheet; on the right, the same pattern mapped back into retinal coordinates. “Nested lattice” is the multi-octave construction the shader uses:

cortical stripes  ──  inverse map r = e^u, θ = v  ──>  what is perceived

V1 cortical sheet (u = log r, v = θ)
perceived image (retinal coordinates)
Fig. 3 — Ermentrout–Cowan, live. On the cortex it is only a sum of simple waves; pushed through the logarithm, Klüver’s classes appear. “Nested lattice” stacks three frequency-doubled octaves, showing that self-similarity — the same structure at every scale — is the heart of a fractal hallucination. The shader’s geometry stage lays this multi-octave version over the darker parts of the image as masses.

2-3. Trails and after-images — a broken suppressor, and recursion

Normally the brain actively erases the smear a moving object leaves on the retina — motion streak suppression. LSD appears to push that circuit outside its working range, so frames that should have been erased persist [7]. The texture of the reports matters: the tail is not a smooth blur but a row of discrete frozen images, strobe-like.

Computationally that is feedback: the output re-entering the input. A single-pass shader has no memory of the previous frame, so the demo takes the rendered result each frame, scales and rotates it slightly, decays it, and composites it back into the next input. That recursion gives the trails — and also the endlessly proliferating fractal depth of the tunnel, the same dynamics as pointing a camera at its own monitor.

camera compose ⊕ fs_lsd filter output scale, rotate, decay (warp) fresh retinal image warp + colour + geometry previous frame two blend modes: smooth (weighted average) / glow trails (max blend = the discrete frozen frames [7])
Fig. 4 — The feedback loop in wasm/lsd.html. The purple path is the recursion; trails, palinopsia, and the recursive tunnel all come from it. The decay coefficient — the Persistence slider — stands for how well the suppressing circuit is still working.

2-4. Why the same image never comes twice — non-stationarity

The other signature of the experience is non-stationarity. It is never a static “effect”; it transforms continuously and never returns to a state it has been in. The transitions are not uniform either: some you only notice afterwards, some bleed slowly, some snap. Measurements agree:

The demo implements this as a trip conductor. Every parameter wanders around its slider value: a slow incommensurate jitter you never quite catch, plus metastable jumps arriving as a Poisson process (about one every twenty seconds). Each jump’s transition time is drawn log-uniformly from 0.25 to 20 seconds — a heavy tail — so some changes snap and others take the better part of a minute. And because the feedback loop is a nonlinear recursion, it is sensitive to its own history: no frame is ever produced twice.

3. Phenomenon → mechanism → implementation

PhenomenonNeural mechanismIn the shaderParameter
Drifting, breathingHigher gain and dominant priors destabilise where a contour is judged to be [4][6]Sampling coordinates warped by a slow radial swell plus two incommensurate travelling fieldsdrift
Colour enhancementUnfiltered input through a loosened thalamic gate [5]Saturation and contrast lifted, hue rotating slowlytrip
Sharpened acuityThe same amplification, acting on edge responsesFour-tap unsharp masktrip
Rainbow fringesDiffraction through dilated pupilsRadial RGB separation, widening toward the peripherychroma
Geometry (flying in 3D)V1 self-organisation [1][2][3] plus a raised fractal dimension [10]. It has a centre, it is finely detailed, and it expands foreverThree depth shells in an eternal zoom (Hann crossfade, content re-seeded by flight index). Masses are domain-warped value noise over four high-weighted octaves; nearer shells are brighter and combine by maximum; each shell owns a hue so depth separates in colourgeometry
Trails, after-imagesMotion streak suppression breaking down [7]Output fed back into input, decayed and slightly zoomed and turned; max blending reproduces the discrete frozen framesPersistence / Zoom / Swirl
Ceaseless transformationAn expanded dynamical repertoire [11][12] and scale-free fluctuation [10]The trip conductor: micro-jitter plus Poisson-arriving metastable jumps, transition times log-uniform over 0.25–20 sAuto-flux / Depth

4. Playing with the parameters

The demo lives at takatronix.github.io/fluent_scene/lsd.html. The picture fills the screen; the controls hide behind the ⚙ in the corner. ⛶ or a double-tap goes fullscreen, and on a phone the first tap does it for you. The pharmacology group drives the filter itself, recursion drives the feedback, and flux drives the trip conductor.

Recipes worth trying

5. Implementation notes

The filter is one function — fs_lsd() in include/fluent_scene/shared/filters_shared.h, written once in the GLSL∩C++ subset and run identically by the CPU reference, Vulkan, and WebGPU (whose WGSL is machine-translated through naga). Time arrives through the time parameter slot, driven per frame by the host in the same pattern fx::Ripple uses, so at time=0 the filter is static and golden-testable. The feedback loop is closed outside the filter pipeline, in the demo, leaving the core renderers untouched.

// the heart of the geometry stage (from fs_lsd): depth shells expanding forever
float zp = t * 0.3;                        // flight speed, octaves per second
float zf = zp - floor(zp);
for (int i = 0; i < 3; ++i) {
    float e  = float(i) - zf;              // depth exponent; smaller is nearer
    float sc = exp2(e);                    // shrinks in domain → expands on screen
    float m  = float(i) + floor(zp);       // this shell’s flight index
    vec2  off = hash(m);                   // fresh content per shell
    float w  = 0.5 - 0.5*cos(2.094*(e+1)); // Hann window: born, grown, gone
    vec2 pl = pc * 3.0 * sc + warp * 2.2 * sc + off;
    float nv = vnoise(pl) * 0.38 + vnoise(pl * 2.1) * 0.27   // weighted toward
             + vnoise(pl * 4.4) * 0.2 + vnoise(pl * 8.9) * 0.15;  // the fine octaves
    float near_f = smoothstep(2.0, -1.0, e);
    float clv = smoothstep(0.52, 0.72, nv) * w * (0.5 + 0.5*near_f);
    mass_ph = clv > mass ? m*2.39996 + ... : mass_ph;  // the shell’s own hue
    mass = max(mass, clv);                 // near occludes far = depth
}
This is a computational approximation of a visual phenomenon — neither a faithful reproduction of a drug experience nor an encouragement to seek one. Flashing and spiralling patterns can be intense for photosensitive viewers; start with gentle settings.

References

  1. Klüver, H. (1966). Mescal and Mechanisms of Hallucinations. University of Chicago Press. (the origin of the form constants; first published 1926)
  2. Ermentrout, G. B. & Cowan, J. D. (1979). A mathematical theory of visual hallucination patterns. Biological Cybernetics, 34, 137–150.
  3. Bressloff, P. C., Cowan, J. D., Golubitsky, M., et al. (2001). What geometric visual hallucinations tell us about the visual cortex. Neural Computation, 14(3), 473–491.
  4. Carhart-Harris, R. L., et al. (2016). Neural correlates of the LSD experience revealed by multimodal neuroimaging. PNAS, 113(17), 4853–4858.
  5. Müller, F., et al. (2017). Increased thalamic resting-state connectivity as a core driver of LSD-induced hallucinations. Acta Psychiatrica Scandinavica, 136(6), 648–657.
  6. Kometer, M. & Vollenweider, F. X. (2016). Serotonergic hallucinogen-induced visual perceptual alterations. Current Topics in Behavioral Neurosciences, 36, 257–282.
  7. Dubois, J. & VanRullen, R. (2011). Visual trails: do the doors of perception open periodically? PLOS Biology, 9(5), e1001056.
  8. Kwan, A. C., et al. (2024). Neural mechanisms of psychedelic visual imagery. Molecular Psychiatry, 30, 809–818.
  9. General audience: A Math Theory for Why People Hallucinate (Quanta Magazine, 2018) / phenomenology catalogue: PsychonautWiki
  10. Varley, T. F., Carhart-Harris, R., Roseman, L., Menon, D. K. & Stamatakis, E. A. (2020). Serotonergic psychedelics LSD & psilocybin increase the fractal dimension of cortical brain activity in spatial and temporal domains. NeuroImage, 220, 117049.
  11. Tagliazucchi, E., Carhart-Harris, R., Leech, R., Nutt, D. & Chialvo, D. R. (2014). Enhanced repertoire of brain dynamical states during the psychedelic experience. Human Brain Mapping, 35(11), 5442–5456.
  12. Atasoy, S., et al. (2017). Connectome-harmonic decomposition of human brain activity reveals dynamical repertoire re-organization under LSD. Scientific Reports, 7, 17661.
  13. Wacker, D., Wang, S., McCorvy, J. D., et al. (2017). Crystal structure of an LSD-bound human serotonin receptor. Cell, 168(3), 377–389. (the EL2 lid and ultra-slow dissociation — the structural basis of the long duration)