Skip to content

Repository files navigation

ImWeb

ImWeb Preview

License: AGPL v3 Version Tests Open Collective Live Demo

ImWeb is Image/ine — reimagined — The legendary real-time video synthesis instrument created by Tom Demeyer and Steina Vasulka at STEIM Amsterdam, rebuilt for the modern browser and pointed toward what comes next. Free, open source, no installation required. → Try it live → imweb.image-ine.org

💖 Support ImWeb on Open Collective


Contents

What This Is · Quick Start · Features · Keyboard Reference · Architecture · Roadmap · Contributing · Credits · License · Support


What This Is

Image/ine was a rare instrument. Created at STEIM Amsterdam in the 1990s by Tom Demeyer in close collaboration with Steina Vasulka — one of the founders of video art — it treated video as a malleable, real-time medium for artistic performance. It ran on Mac OS 9 (1997) and later OS X (2008). No equivalent free tool has existed since.

ImWeb is a ground-up reimagining for the modern browser — an instrument rooted in the original's philosophy, extending a signal path that has always pointed toward what comes next.

Built with Three.js, Vite, and raw WebGL shaders — no framework dependencies, nothing between the artist and the signal.

Signal path:

INPUT SOURCES
  Camera · Movie A · Movie B · Stills Buffer · Color · Noise
  3D Scene · Draw · Slit Scan · Sequencer · GPU Particles · SDF Raymarcher
        ↓ any two into ↓
  Mix 1 | Mix 2 | Mix 3   (crossfade / Add / Multiply / Luma Mask / Displace)
        ↓ assigned to ↓
  Foreground | Background | DisplaceSrc
        ↓ effects chain ↓
  TransferMode → Displacement → WarpMap → Keyer → Blend
  → ColorShift → LUT → Interlace → Fade
        ↓
  Output canvas → fullscreen / second monitor / WebM record

Quick Start

Requires Node 18+

npm install
npm run dev
# → open http://localhost:5173

Chrome 113+ recommended for best WebGL performance. Firefox and Safari supported in WebGL mode with minor limitations.


Features (v0.25.0)

Input Sources

  • Camera (WebRTC, auto-start on load)
  • Movie Library — unlimited catalogue of clips with thumbnail, duration and filter box; auto-loaded from _imweb_ready/ on startup; drag a row onto a deck or use →A / →B
  • Movie decks A and B — two independent engines, 8 loaded clips each; speed (±3×), loop range, position scrub, BPM sync, mirror, mute; a full rack evicts its oldest clip, never the one playing
  • Mix buses ×3 — Mix 1/2/3, each crossfading or combining any two sources (Add, Multiply, Luma Mask, Displace); the mixed signal is itself a source, so it can be composited, captured and time-displaced
  • Analog TV — Phase 1 signal simulator (720×480); 4:3 cropping; hue/sat/bright/contrast grading
  • Stills buffer — capture up to 64 frames (8×8 grid), FrameSelect 1/2/3
  • Color source (HSV solid)
  • Noise source (pixel)
  • 3D scene — all geometry, transforms, material, camera; GLTF/GLB/OBJ/STL import; auto-spin; Cloner (MoGraph InstancedMesh) with Twist/Scatter/Wave/ScaleStep effectors; Blob/Morph vertex displacement; N-D Hypercube engine (4D–12D) with edge/face/instancer rendering; real-time pipeline texture on instancer geometry
  • Slit scan buffer
  • Draw layer (freehand canvas)
  • Text layer
  • GPU particle system
  • Sequencer buffers ×3 — record and loop any source; variable frame count (4–480 frames)
  • SDF raymarching generator — GPU-raymarched metaballs routable as pipeline source; Sphere/Box/Torus shapes; KIFS fractal folding; camera navigation; domain repetition; surface displacement; luma warp; triplanar video texturing; AO + glow; HSV colour; glass refraction + Fresnel; dedicated texSrc/refractSrc routing
  • Rutt-Etra Scan Processor — the 1972 scan processor, scanlines deflected by the luminance of any source and viewed through an orbiting perspective camera; drawn as beams or spherically shaded dots with independent widths; depth transfer function (gamma + pivot); asymmetric temporal slew in seconds, so live video becomes a viscous topography rather than jittery spikes; phosphor persistence with spatial bleed; phosphor tint or the source's own colour; full 360° orbit on both axes and free placement; and the raster wraps onto a Plane, Sphere, Cylinder, Torus, Catenoid, Helicoid or Gyroid
  • Drag-and-drop to load video/image files

Effects Chain

  • TransferMode — 22 blend modes (Add, Difference, Multiply, Screen, Overlay, etc.)
  • Displacement (amount, angle, offset, RotateGrey)
  • WarpMap — draw the displacement map directly on the output canvas, or drive the same brush from LFO/MIDI/OSC via WarpDrawX/Y; shared Radius and Strength; 16 slots and 8 procedural shapes recallable from a controller, with timed crossfade between maps
  • Luminance keyer (White, Black, Softness)
  • Blend / frame persistence / motion blur
  • ColorShift
  • 3D LUT colour grading (.cube files)
  • Interlace
  • Fade
  • Mirror / Quad mirror
  • Kaleidoscope
  • Bloom
  • Vignette
  • Chroma key (colour picker)
  • Film grain, scanlines
  • Video delay line
  • Pixel sort
  • Levels correction
  • Stroboscope

Controller Mapping

Right-click any parameter to assign:

  • Mouse X/Y
  • MIDI CC (with channel filter)
  • LFO (Sine/Triangle/Sawtooth/Ramp Down/Square/S&H; BPM sync; beat retrigger)
  • Audio FFT (bass / mid / high)
  • Audio beat detection + auto-BPM
  • Random
  • Fixed value
  • Key (keyboard trigger)
  • Expression (math formula)
  • OSC address (TouchOSC, Max, a Flic button) — or just OSC Learn: press the control and it binds
  • Gamepad stick or button — or Gamepad Learn: move the control and it binds, whatever the pad calls it
  • Latch — a button alternates a continuous parameter between the row's min and max
  • Relative sticks — a stick pushes the value and lets go of it, instead of springing back
  • Four mapping pages for every physical input (MIDI, OSC, gamepad), with soft takeover where a control has a position to take up
  • Parameter lock
  • Slew/smoothing (configurable lag time)

Automation & Sequencing

  • Automation recorder — record parameter movements, loop playback
  • Step sequencer — rhythmic preset recall; configurable pattern
  • Preset morph — smooth crossfade between two preset states

MIDI

  • MIDI CC input (per-channel filter)
  • MIDI Note input
  • MIDI Program Change → preset recall
  • MIDI Clock sync (BPM lock)
  • MIDI output feedback (motorized faders)
  • MIDI In and PAD IN monitors — the last controls touched, what they are called, and what they already drive

OSC & Gamepad

  • OSC over a bundled relay (node tools/osc-relay.mjs) — the browser cannot open a UDP socket
  • OSC feedback to exactly what the remote talks to, including a push to the new page's positions on a page switch
  • Any standard gamepad; a PAD chip shows when the browser can see it

Output

  • Fullscreen (double-click canvas or Cmd+F)
  • Second monitor — opens letterboxed popup on any connected display
  • Ghost mode — dims main canvas when second screen is active
  • Output resolution — Display / 720p / 1080p / 540p / Quarter
  • WebM recording
  • Non-realtime frame capture — 📷 pauses render loop; Step Frame / Auto-Run exports numbered PNG sequence

Project & State Management

  • Project → Bank → State hierarchy — standard live performance mental model
  • Project files (.imweb)Cmd+S or Export button downloads the full session
  • Banks — named groups of States; bank list in the Project tab; bank dropdown in the bottom-right corner
  • States — unlimited fully self-contained snapshots per Bank (parameter values + FX order + controller assignments + media refs); thumbnail grid in the bottom bar
  • Neutral State — resets all parameter values without touching controller assignments
  • Bank export/import (.imbank) — share a single bank
  • State export/import (.imstate) — share a single state

AI

Built into the instrument, not beside it — and with no backend: API keys stay in your browser.

  • Seven providers — Anthropic, Google Gemini, OpenAI, OpenRouter, DeepSeek, Kimi, and Ollama running fully local; switchable in one place
  • AI State Generator — "make a slow organic ocean" becomes a patch. The parameter vocabulary is derived live from the instrument, so 594 of 731 parameters are reachable; every value is validated and the panel reports what was set, clamped or ignored
  • AI shader generation — describe an effect and the GLSL streams into the editor as it is written. Start new or Refine the shader already there; compile-checked, one automatic repair round, last-good fallback; truncated or refused replies are caught rather than injected; one-click undo; dictate the prompt with the mic
  • Canvas vision — optionally let the model see the output: Refine judges the picture before the code, the Narrator describes the image instead of the patch, the Coach can tell you it has gone too dark or static. Off by default
  • AI Narrator & Coach — a description of the performance and suggestions for the next move; both speak only when the patch or the picture has actually changed, and the last Coach suggestions are kept
  • Token & cost meter — per provider and model, from each provider's own reported usage; local models show a real $0.00
  • OSC relaynode tools/osc-relay.mjs bridges UDP OSC (TouchOSC, Max, a Flic button) into the browser

UI

  • Signal path display — hidden by default; ┄ toolbar toggle; float/dock via Shift+P
  • Live GLSL editor — CodeMirror 6 with GLSL syntax highlighting; built-in and saveable user presets, recallable from MIDI/LFO over a configurable index range; auto-injected VJ uniform contract (audio FFT, previous frame, BPM/beat, level/bass/mid/high); insert routing to Master Output, Foreground, Background or Displace; compile errors fall back to the last good shader instead of dropping the render loop
  • First-visit onboarding overlay
  • Help menu (status-bar ?) — guided tour, keyboard shortcuts, the three manuals, About
  • Guided tour (Shift+G) — 27 steps in three tracks (Basics / Principles / Instruments); it points at controls, it never sets them
  • LFO visualiser in context menu
  • Vectorscope (Lissajous / waveform / FFT) as source
  • Parameter search overlay (/)
  • Keyboard help overlay (?)
  • Audio VU meter in status bar
  • Projection mapping — CSS homography corner-pin on second screen; calibration grid (G); corner nudge (arrow keys)

Keyboard Reference

Key Action
V Toggle camera
K Toggle keyer
B Toggle blend (motion persistence)
S Solo (bypass all effects)
C Capture frame to stills buffer
M Toggle movie playback
H Fade to black
Q Cycle Foreground source
A Cycle Background source
Z Cycle DisplaceSrc source
T Tap tempo
G Cycle canvas mode (Camera / Pad / Locked / Draw / Warp)
I Toggle parameter OSD
U Toggle state bar
? Keyboard help overlay
/ Parameter search overlay
0–9 Recall State 0–9
Shift+0 Neutral State
Shift+G Guided tour (resumes where you left off)
Shift+S Quick-save State to next empty slot
Shift+1–8 Select clip 1–8 on Movie Deck A
Option+1–8 Select clip 1–8 on Movie Deck B
Cmd/Ctrl+S Save project → downloads .imweb
Cmd/Ctrl+F Fullscreen output
NumPad +/- Next / previous Bank

Architecture

src/
  main.js                 Application bootstrap + render loop + feature wiring
  style.css               Dark performance UI
  controls/
    ParameterSystem.js    All controllable parameters + reactivity
    ControllerManager.js  Mouse, MIDI, LFO, Sound, Key, Random, Expression drivers
    LFO.js                Sine / Triangle / Sawtooth / Ramp Down / Square / S&H oscillators
  core/
    Pipeline.js           WebGL render-target compositing chain
  shaders/
    index.js              All GLSL effect shaders (keyer, displace, warp,
                          transfermode, colorshift, interlace, noise, blend,
                          LUT, kaleidoscope, bloom, film grain, pixel sort…)
  inputs/
    CameraInput.js        WebRTC getUserMedia → VideoTexture
    MovieInput.js         Video file → VideoTexture; speed/loop/scrub/BPM sync
    StillsBuffer.js       Frame capture store (up to 64 frames, 8×8 grid)
    SlitScanBuffer.js     Rolling slit scan effect
    TextLayer.js          Canvas 2D text → Texture
    SDFGenerator.js       GPU raymarched SDF metaballs → WebGLRenderTarget
  scene3d/
    SceneManager.js       Three.js 3D scene → RenderTarget; auto-spin, model import
    GeometryFactory.js    All procedural geometry generators
  audio/                  AudioWorklet engine — tape, spectral writer, corpus, granular
  ai/
    AIFeatures.js         Seven providers behind two routers (plain + streaming);
                          State Generator, shaders, vision, Narrator/Coach, metering
  state/
    Preset.js             Banks + States, persisted to IndexedDB
  ui/
    UI.js                 Parameter rows, tabs, StateBar, MemoryPanel,
                          signal path, context menus, seq cards

Video Preparation

# Convert raw clips to ImWeb-optimised format (H.264 All-Intra, AAC audio)
node imweb-prep.js
# Drop source files in _raw_videos/, output goes to _imweb_ready/

As of v0.14.0 this writes faststart MP4s (-movflags +faststart), moving the moov atom to the front of the file. Without it a browser cannot report a clip's duration until it has read to EOF — seconds on a large All-Intra clip, or never under load.

Clips prepped before v0.14.0 need a one-off remux. It is lossless — no re-encode, no quality change:

ffmpeg -i old.mp4 -c copy -movflags +faststart new.mp4

Roadmap

Recently shipped:

  • Hands on — OSC and Gamepad Learn, Latch, relative sticks, mapping pages for every physical input, PAD IN (v0.25)
  • AI that can see — canvas vision, streaming shader generation, Refine mode, whole-instrument State Generator, token meter (v0.24)
  • Text layer, playable 3D orbit camera, MIDI mapping pages with soft takeover (v0.23)
  • Depth of field and bokeh (v0.22)
  • Audio engine — tape, spectral writer, corpus navigation, granular playback (v0.20)
  • Touch instrument — gesture arbitration, responsive layout, iPad-sized targets (v0.10–v0.11)
  • Dual-deck video and mix buses (v0.12–v0.13)
  • Live GLSL editor — CodeMirror, AI shader generation, last-good compile fallback (v0.13)
  • Performative warp drawing — draw the displacement map on the output (v0.13)
  • Movie Library — unlimited catalogue, two racks (v0.14)
  • Spacetime — shared frame history, a source on every temporal engine (v0.15)
  • Rutt-Etra Scan Processor — seven surfaces, phosphor decay, temporal slew (v0.15)
  • SDF field renderer — thirteen shapes, orbit camera, two-stop glow (v0.15)
  • Motion Extraction — a matte of what moves, into the keyer's own key source (v0.16)
  • RGB Channel Delay — per-channel time offset over the existing delay ring (v0.16)
  • Guided tour — three tracks, parsed live from docs/ImWeb-Guide.md (v0.18)
  • Seven slew curves in two declared families, and 0.001 Hz modulation (v0.19)
  • Controller menus reachable by Ctrl+click, on any trackpad (v0.19)

Next:

  • The model as a co-performer — a controller type, alongside LFO and MIDI, that writes goals the slew system turns into motion; adjustable temperament; instant hand-back to the performer
  • Semantic search across your own banks and states
  • Controller profiles — mappings portable between MIDI desks
  • Hypercube instancer texture switching (live source change without reset)
  • Performance profiling / GPU display
  • Multi-quad projection mapping (independent sources per quad)
  • Multi-cam workflow (per-layer camera selector)
  • iPad soak test of the dual-deck engine and the 8-tab bar on real hardware

See CHANGELOG.md for the full history and docs/imweb-obsidian.md for per-phase detail.


Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md for guidelines on bug reports, feature requests, and the development workflow.


Credits

Original Image/ine software: Tom Demeyer, STEIM Foundation, Amsterdam Co-conspirator: Steina Vasulka — without her, Image/ine would not exist ImOs9 manual: Sher Doruff ImWeb: Haraldur Karlsson

This project is a personal reimagining and artistic continuation. It is not affiliated with or endorsed by the STEIM Foundation (1959–2019).


License

GNU Affero General Public License v3.0 — see LICENSE for full text.

The AGPL v3 was chosen deliberately: any hosted derivative of ImWeb must remain open source. The license file includes a dedication to Tom Demeyer and Steina Vasulka.


Support

ImWeb is free for every artist on this planet, forever.

If it's useful to your practice, consider supporting its development:

💖 Open Collective — one-time or recurring donations, fully transparent

About

Real-time video synthesis instrument in the browser — a reimagining of Steina Vasulka & Tom Demeyer's Image/ine (STEIM). Compositing, 3D, audio engine, live GLSL, MIDI/OSC, and an AI layer that can see the output. Free, AGPL.

Topics

Resources

Contributing

Stars

10 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages