Photosensitivity / epilepsy warning: This project renders rapidly changing neon visuals, recursive feedback, flashes, and high-contrast motion. Do not use it if you are sensitive to flashing lights or motion-triggered visual effects. Stop immediately if you feel discomfort, dizziness, eye strain, nausea, or any seizure-related symptoms.
Launch the Neon Recusion app (click this link): https://def.s.gy/neon-recursion
Expanded URL: https://gptenv.github.io/neon_recursion/
Preview URL: https://htmlpreview.github.io/?https://raw.githubusercontent.com/gptenv/neon_recursion/refs/heads/main/index.html
Version: webgl-wasm-v10.8-2026-06-stripefix-reactive
This is the browser-native WebGL/WASM Touchstone port. The Makefile builds touchstone.wasm, so use a wasm32-capable clang such as Homebrew LLVM on macOS.
Browsers require a secure context for camera/mic. localhost counts as secure:
./serve.shThen open:
http://127.0.0.1:8787/
This repository is ready to deploy through GitHub Actions. Every push to the
main branch runs .github/workflows/deploy-pages.yml, verifies the static
bundle with make, stages index.html, app.js, touchstone.wasm, and
assets/ when present, then publishes that artifact to GitHub Pages.
First-time push to a new GitHub repository:
git remote add origin git@github.com:YOUR_USER/YOUR_REPO.git
git push -u origin mainIf GitHub asks for a Pages source, choose GitHub Actions in
Settings -> Pages. After that, normal git push updates the live Pages site.
The app is expected to build from source. On this machine, source the shell profile first so Homebrew LLVM is on PATH:
source ~/.profile
make clean
makemake clean removes touchstone.wasm; make rebuilds it from src/touchstone.c and validates the bundle. Use this when you explicitly want to force just the WASM target:
make rebuild-wasmIf that fails with “cannot compile --target=wasm32”, install a WASM-capable LLVM/clang, Emscripten, or WASI SDK. On macOS with Homebrew LLVM:
brew install llvm
export PATH="/opt/homebrew/opt/llvm/bin:$PATH" # Apple Silicon
# or:
export PATH="/usr/local/opt/llvm/bin:$PATH" # Intel Homebrew
make rebuild-wasmmake distclean currently behaves the same as make clean.
1..9 / 0 activate preset within the current 10-preset bank
[ / ] shift number-key bank without changing active preset
Left / Right previous / next active preset
Horizontal swipe previous / next active preset
C / click / tap forge, save, append, bank-jump, and activate a new generated preset
Double-click /
double-tap /
Space force fullscreen, hide HUD, and toggle MP4/H.264 recording + download
with mic plus shared system/tab audio when available
Ctrl+N nuke current generated preset only
F toggle fullscreen and force HUD hidden
H toggle HUD, including while fullscreen is active
Y toggle Y-axis reflection / mirror mode, left-right flip; ON by default
X toggle X-axis reflection / vertical flip; ON by default
Z toggle Z-axis half-turn / 180-degree camera flip; OFF by default
R clear recursive feedback buffer
Up / Down reseed randomizers (change live seed offset for baked + forged presets)
Vertical swipe
and hold continuously change the randomizer seed offset
, / . feedback memory
- / = adjust drive (warping, colour, depth, reactions)
Generated presets remain saved in browser localStorage under the original v10 key for compatibility:
neon_recursion_touchstone_v107_presets
V10.8 uses a 24-value recipe schema. The random forger drives layered underlays, camera-feed displacement, previous-frame displacement, overlay masks, chromatic splitting, pseudo-alpha compositing, depth/parallax fields, palette behaviour, and audio/video reaction weighting. The shader keeps the readable V10 camera structure while restoring saturated recursive contrast, brighter colour cycling, stronger feedback displacement, and visible audio/video motion. Recipes select distinct audio reaction lanes, motion lanes, composition modes, color transforms, mask reactions, warp personalities, and feedback personalities. The 200 baked presets are regenerated through a mixed family/behavior recipe permutation so adjacent number-key slots produce more distinct looks.
V10.8 reworks the reactivity logic (richer body/air/beat/groove/detail drives, stronger onset/flux/groove response) and all 20 field families + lane behaviors for significantly more interesting, varied visuals. Diagonal stripe artifacts (the previous accidental interlacing-like x+y patterns) are gated behind an explicit stripe personality lane. The 200 baked + future forged presets use refreshed composition, color, mask, motion, feedback, and warp lanes so only explicit lens/warp personalities bend the camera layer heavily; other presets react through recolor, edge masks, block/poster changes, beat cutouts, feedback echo, contour bloom, and palette mutation.
The - and = keys adjust visual drive (warp amplitude, colour pressure, feedback behaviour, depth, overlay intensity, and audio/video reaction gain). Drive has a broad range (0..6).
The Up/Down keys and vertical swipe-hold change the live randomizer seed offset. The offset reseeds baked and generated recipes in place and also feeds future forged presets. New forged presets still use browser entropy and are chosen from multiple random candidates biased toward recipe-lane distance from existing presets. Holding or swiping vertically scrubs the seed offset continuously for live auditioning of variations.
F toggles browser fullscreen through the Fullscreen API. Pressing F also forces the HUD hidden; it does not toggle the HUD state. H remains independent and can bring the HUD back while fullscreen is active.
Double-click, double-tap, and Space always request fullscreen, force the HUD hidden, and then toggle canvas recording. Starting uses MediaRecorder MP4/H.264 support when the browser exposes it; stopping downloads the completed .mp4 and revokes the generated object URL after the download has been initiated, with any remaining URLs revoked on page unload.
Recordings wait for fresh fullscreen-sized app frames before MediaRecorder is created, then copy each rendered WebGL frame into a stable offscreen recording canvas and request capture frames from that canvas. This avoids recording directly from Chrome/macOS's fullscreen canvas compositor path, which can produce recordings that play for the full duration while showing only the first captured frame.
Audio reactivity and recording audio use one Web Audio mix of microphone input plus the browser-provided shared system/tab audio track. Browsers do not expose raw speaker output directly to pages; choose a screen, window, or tab and enable audio sharing in the browser picker when starting the app. Browser and OS support varies: when shared system/tab audio is unavailable or not granted, the app continues with mic audio or synthetic fallback.