How my frustration with existing tools led me to build something new from the ground up. Submitted for the GILGA Intern position.
As a hobby, I do live visual performance (VJing). It's a lot of fun, and it lets me connect with artists across mediums I don't usually touch. I like to create music reactive visuals beside a DJ or musician, reacting to their sound and style and pace. I want it to feel like I'm playing an instrument too, and I'm able to flex my own creativity. But two of the most dominant VJ tools, Resolume and TouchDesigner, each fail in a different, critical way.
Resolume is an industry standard clip launching and music reactive visuals app. It's got some great features, but adding new types of generative visuals is extremely limited. You also can't really create actionable cues to change things easily. It didn't really let me get as creative as I wanted, and it was limited to a group of preset visuals.
Ceiling too lowTouchdesigner is the gold standard for creating incredible live reactive visuals, and it works through a powerful node-based system. In theory, it can do anything - but in practice, iterating live while a DJ performs is impossible. You can prebuild a set or a look that you can modify while on stage, but what if the DJ inspires you to do something completely different? Creating new and compelling looks on the fly is just not possible.
Floor too highIt's cool to go to a large scale live concert and watch a really rehearsed, really prepared show that follows a specific setlist. But when a group of musicians are just jamming, or when a group of artists are creating on the fly, pre-rendered visuals don't cut it.
I was forced to choose between creative control (TouchDesigner) and relative ease of use (Resolume). But in both cases, I couldn't iterate on the fly and let my creativity run free.
It's so much fun to become a part of the band in a way that feels as live as they do. When they create something awesome sonically, it should be reflected in the visuals. So as they follow their instincts, they should know that the visuals around them are following along too.
It's just more fun to see iterations live. When they can call out colors or cues or inspirations, and see how things change live on screen, it's a totally unique and creative experience. When the audience knows you're doing it live, just like the musicians, the appreciation for the visual art grows.
Lightbridge is a VJ performance system I designed and coded from scratch. I wanted the creative depth of TouchDesigner with the live performance tools of Resolume (and more). So that's what I made.
What started as a basic chain with a single ring source has grown into a full performance system - 40 sources, 32 effects, projection mapping, MIDI control, audio analysis, BPM detection, and more.
Early prototype — one source, basic parameters, no effects chain
Current build — 3D helix source, stacked effects, dual preview, color palette
Real-time FFT splits audio into sub-bass, kick, low-mid, mid, presence, and brilliance bands. Visuals are created with customizable parameters, that can be linked to any audio band.
Using Ableton Link, you can get BPM live from your DJ. Or you can tap it in yourself. And if that doesn't work, a custom C to WebAssembly beat tracker detects beat phase automatically from live audio input.
Any parameter can be modulated by audio, beat, LFOs, or envelopes. I can link a ring's radius to the kick drum, or tighten a spiral coil based on the mids. I can flicker between color palettes on the beat or manually tap in a pulse effect on a particle cloud.
Adjustable reaction speed and decay curves let you dial in exactly how the visuals react to the music. Some songs need it tight and punchy, others need it smoother and breathier.
Sources and effects live in a single ordered chain. Sources stack on top of each other, and effects apply to the stack (or directly onto a source, if that's what you want). I added blending modes for even more creative control.
From 3D tunnels and particle simulations to fluid dynamics and fractals, every source is generated in real-time via custom GLSL shaders. This is a hugely customizable tool and allows for importing other shaders available on the web.
Bloom, feedback, kaleidoscope, ASCII, pixel sort, color grading, barrel distortion, etc. There are tons to play with, and they can be audio reactive as well.
Effects can apply to individual sources before compositing, or to the entire accumulated output. This is what really lets you dial in the look you want, and create infinite combinations.
Built-in corner-pin warping, mesh subdivision (up to 8×8 grid), masking, and blending. This opens up tons of possibilities about creating a look in any given space, even if it's not a flat projector ready surface.
Output to any connected display, like a projector or a TV. You can run a preview on your laptop, and push or hold changes as you tweak them before they go live.
Save your mapping configuration per show location or venue. Really useful if you're moving between multiple common setups.
Output at any resolution and 60fps with almost no lag. Getting response time down to under 10ms was tough but critical!
You can organize your show into sets, each with its own chain, audio mods, and color palette. This lets you play and iterate on multiple base sets per show.
Full APC40 MkII protocol support. Map any parameter to any fader, knob, or button. The GUI mimics the physical controller. Hoping to add more controller support soon!
7-swatch HSB palettes per set. Visuals link to palette channels, so you can change one swatch and every corresponding visual will shift. Awesome for dedicated hue changes mid-performance!
Every action is autosaved, with a near infinite undo/redo capability. You can save individual shows and have preloaded sets ready to go whenever you want to perform.
I'm not trying to replace every use case - Touchdesigner is still awesome and the go to when I want to build something truly specific. But I've fully replaced Resolume in my workflow because Lightbridge is built specifically for how I want to VJ. It's focused on live performance and gives me the tools to iterate and modulate on the fly, like no other program on the market.
| Capability | Resolume | TouchDesigner | Lightbridge |
|---|---|---|---|
| Custom shader sources | ✗ | ✓ | ✓ 40 built-in |
| Real-time audio reactivity | Basic | ✓ (complex setup) | ✓ Zero config |
| Beat detection | ✗ (tap tempo) | Via plugin | ✓ Built-in WASM |
| Live-tweakable parameters | ✓ | Node graph navigation | ✓ Flat sliders |
| MIDI controller support | ✓ | ✓ | ✓ APC40 native |
| Show file / session prep | Composition files | ✗ (project files) | ✓ Full show state |
| Projection mapping | ✓ | ✓ | ✓ + venue presets |
| Performance set switching | Layer presets | ✗ | ✓ Instant |
| Time to performance-ready | Hours | Weeks | Hours |
OK, so I'm cheating a little bit. I've been working on this for the past 3 weeks and it's not exactly the hypothetical you asked for. But it's a recent project and a great case study for a problem in the wild that I spotted and chose to fix!
It works, in practice. It's still in development, and I'm exploring the boundaries of what I can do. But it's custom built for the problems I was facing, and it's a joy to use knowing it came from my own hands.
I'm not the only one with this problem. It's actually fun to have this toy to play with live, with your musician friends. It's a new category of live performance tool that lives right in the sweet zone of powerful and complex while being simple enough to use live.
I wrote this in Electron + Three.js + React + TypeScript, assisted by Claude Code. It's fast, responsive, extremely performant, and doesn't get held back by legacy software decisions.
My old workflow of creating a complicated node tree in Touchdesigner, wrangling the OSC controls to send it to Resolume, and ending up with a design that might not really fit the vibe just doesn't match how I wanted to create. And I know that other folks in the space I've spoken to have felt the same way.
I know this was supposed to be a hypothetical problem solving exercise, but I only started developing this app on March 6th. So I've been thinking in and living in this exact kind of problem solving space for the last few weeks, and it just felt right to share. I found a problem that frustrated me, did some research, and built an entire application to solve it. Here's a tiny taste of what that looks like — click below and make some noise.
Thanks for reading! Hopefully this shows you a little bit about how I think and what I do when something isn't working. Looking forward to hearing from you!