Phosphene Open Phosphene

Live-code GLSL shaders in your browser with Shader Lab

Shader Lab is Phosphene's twelfth engine: a code editor that runs your own GLSL fragment shader as a live, audio-reactive visual. Paste a Shadertoy sketch or write one from scratch. It recompiles as you type, reads the music, the beat and the current palette, and goes through the same color controls, effects and projection mapping as every other engine.

Open PhospheneFree, no sign-up. It runs in your browser.

Shader Lab in Phosphene: a GLSL code editor panel floating over the live shader it is rendering in the browser
The editor sits over the running shader, so you see each change as you make it.

Getting started

  1. Switch to Shader Lab. Press =, the key for engine 12.
  2. Open an example. Five come built in: Starter, Palette Plasma, Neon Tunnel, Spectrum Rings and Feedback Bloom. Starter is the smallest place to begin.
  3. Edit the code. With auto-run on, the shader recompiles as you type. Otherwise press Ctrl+Enter (Cmd+Enter on a Mac) to run it.
  4. Read any errors. Compile errors appear with their line numbers, and the last working shader keeps running, so a typo never blanks the screen mid-set.
  5. Keep it. Shaders save in the browser, and a share link carries your shader along with the rest of the scene.

Shadertoy compatibility

Shader Lab uses the same entry point as Shadertoy, so most single-pass sketches paste straight in:

void mainImage(out vec4 fragColor, in vec2 fragCoord)

Anything not in the reference below, such as Shadertoy's Buffer A–D passes or the keyboard texture, needs reworking. The single feedback channel covers many multipass tricks: trails, smearing and slow accumulation.

Uniform reference

Everything your shader can read. Values marked 0–1 are normalized.

Shadertoy-standard inputs

UniformTypeWhat it holds
iResolutionvec3Output size in pixels
iTimefloatTime in seconds
iTimeDeltafloatSeconds since the last frame
iFrameintFrame counter
iMousevec4Mouse or touch position, with Shadertoy semantics
iDatevec4Year, month, day and time of day in seconds
iChannel0sampler2DAudio, 512×2: row 0 FFT, row 1 waveform, value in .r
iChannel1sampler2DCamera or loaded image
iChannel2sampler2DThis shader's previous frame, for feedback

Phosphene extras

UniformTypeWhat it holds
iBass, iMid, iTreblefloatBand levels, 0–1
iLevelfloatOverall level, 0–1
iBeatfloatBeat pulse, 0–1: jumps on a beat, then decays
iBeatPhasefloatPosition inside the current beat, 0–1, from the beat clock
iBPMfloatCurrent tempo
iColor0–iColor3vec3The current palette as four RGB colors
iInput[4]vec3Up to four interaction points from the mouse, body tracking or OSC: x, y in 0–1 with 0,0 at bottom left (like fragCoord), z = strength
iSpeed, iWarp, iComplexity, iZoom, iSymmetryfloatThe matching Tune sliders

A short example

Rings that spread with the bass, brighten with the spectrum and flash on each beat, colored by whichever palette is active:

// Beat rings: paste over the Starter example
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    // Centered coordinates, screen height = 1
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    float r = length(uv);

    // Row 0 of iChannel0 is the FFT: low frequencies near the center
    float fft = texture(iChannel0, vec2(clamp(r, 0.0, 1.0), 0.25)).r;

    // Rings travel outward; more bass spreads them apart
    float rings = sin(r * (28.0 - 14.0 * iBass) - iTime * 3.0);
    rings = smoothstep(0.0, 0.1, rings) * (0.35 + fft);

    // Palette colors by distance, plus a flash on the beat
    vec3 col = mix(iColor0, iColor1, clamp(r * 1.4, 0.0, 1.0)) * rings;
    col += iColor2 * iBeat * 0.4 * (1.0 - clamp(r, 0.0, 1.0));

    fragColor = vec4(col, 1.0);
}

To add trails, mix in a slightly zoomed copy of the previous frame from iChannel2 before writing fragColor:

vec2 st = fragCoord / iResolution.xy;
vec3 prev = texture(iChannel2, (st - 0.5) * 0.985 + 0.5).rgb;
col = max(col, prev * 0.92);

Tips for live shaders

A custom GLSL shader running full screen in Phosphene's Shader Lab, with audio-reactive color from the active palette
Shader Lab output takes the same effects and mapping as the built-in engines.

Want people to steer your shader with their hands? iInput is fed by webcam body tracking and by OSC; the Kinect and OSC guide shows how to send it.

Open PhospheneIt's free, and there's nothing to install.