Connect generators, modifiers, combiners, and live audio inputs into signal chains no fixed preset can match. The Graph Editor is where VKO1 becomes your instrument. Available on iPhone, iPad, and Mac.
Overview
Every visualizer in VKO1 normally runs as a single fixed node. The Graph Editor lets you break that open — chain multiple nodes together, feed live audio bands into any parameter, and combine two generators into something that could never exist as a preset.
Run a generator through as many modifiers as you want before it reaches the output. Each node processes the image from the one before it.
Combiner nodes take two texture inputs and produce one output. Blend, key, displace, or beat-crossfade between any two generators in real time.
Input nodes output live values — bass energy, beat phase, LFO waveforms. Connect them to any float pin (amount, mix, reactivity) for parameter control that moves with the music.
The Canvas
The graph canvas is an infinite workspace. Nodes connect left to right, but you can arrange them however makes sense to you.
Two-finger drag to pan the canvas. Pinch to zoom between 0.3× and 3×. On iPhone, the canvas starts at 0.7× to fit more nodes on screen. On Mac, scroll to pan and use trackpad pinch to zoom.
Tap + in the toolbar to open the node palette. Long-press or right-click on empty canvas for a context menu. Max 16 nodes per graph.
Drag from an output pin (right side of a node) toward an input pin (left side). The wire snaps when you're within 30pt. Connecting to a pin that already has a wire replaces it.
Tap or click a node to select it. On Mac and iPad, parameters appear in the left panel. On iPhone, a sheet slides up automatically. Connections are listed at the bottom and can be removed individually.
Texture pins carry image data — generator and modifier outputs connect here. Float pins carry a single value — input nodes (LFO, Bass, etc.) connect here.
Tap the bookmark icon to save to your personal library. Tap the share icon to export a .vkograph file for backup or sharing with other VJO1 users.
Architecture
Every graph is a directed acyclic graph — no loops allowed. Execution follows topological order: inputs first, output last.
Produce a texture from scratch using time, audio, and parameters. Always the start of a signal chain.
Take one texture in, return a transformed texture out. Stack as many as you need.
Take two textures in, return one. Blend, mask, displace, key, or crossfade between two sources.
Output a live float value. Connect to any float pin on any other node to modulate parameters with music or time.
Every graph has exactly one. The texture connected to it is what gets displayed on the pad.
Generators · 25 nodes
Generators produce a texture from nothing. Every generator takes Reactivity and Complexity float pins, a Color Palette selector (33 palettes), and responds to beat phase, beat strength, and audio energy.
Layered sine-wave interference fields. The classic Lissajous plasma. Pulses on the beat and warps with energy. Pairs beautifully with Kaleidoscope.
Animated Voronoi diagram with glowing cell borders. Cell positions jitter with audio energy. Beat triggers a contraction that snaps cells into new formations.
Fractional Brownian Motion with domain warping. The warping amount scales with beat strength, creating a breathing, living texture.
Inverse-radius depth mapping with twist and spiral. Creates the classic VJ tunnel rush. Beat-reactive pulse accelerates the ride.
Multi-layer parallax stars with per-star twinkle. Beat triggers a flash across all layers simultaneously. 4–9 depth layers.
Concentric rotating rings of variable segment patterns. Complexity drives the number of subdivisions. Beat-reactive scale pulse.
Audio-driven circular rings. 8–32 spectral bins mapped to ring heights. Beat-reactive spike on the outer edge.
GPU compute particle system with gravity, bounce, and life decay. Beat triggers spawning bursts. One of the few generators using a compute pipeline.
Circular spectrum bars with glow. 8–32 frequency bins radiate outward from center. Beat-reactive tips flash on transients.
The spectrum as a waveform. Frequency bins drive amplitude across a horizontal field. Beat-reactive height multiplier.
Real-time waveform tracing. Shows the raw audio waveform as a glowing line. Best with high-contrast palettes.
Audio level display. A direct visual representation of signal amplitude. Useful as a layer behind other content.
Sharp animated grid with audio-driven ripple distortion at intersections. Beat snaps the grid pattern. Pairs with Displace for maximum chaos.
Concentric rotating polygons (3–8 sides) with sharp neon edges and layered glows. Beat-scale pulse. Excellent Luma Key source.
Ultra-thin laser beams radiating from center, accumulating additively. Rotates at staggered speeds. Beat strobe snaps all beams simultaneously.
Spectrum-driven radial triangular shards. Each triangle's height follows a specific frequency bin, creating a jagged energy crown.
HUD-style decoder with glitch blocks, scan lines, and corruption bursts. The aesthetic centrepiece of the industrial category. Pair with LFO Glitch.
Radar sweep with targeting brackets and coordinate markers. Snaps to new targeting positions on beat. Marathon-inspired.
Procedural glyph grid with glitch scrambling. Characters cycle through a procedural alphabet. Beat triggers a full-screen scramble.
Technical blueprint-style lines with directional pulse propagation. Looks like a circuit board coming to life.
ASCII-inspired terminal loading effect. Procedural text-like patterns fill and clear in rows. Beat triggers line corruption.
Tron-style orthogonal grid with glowing intersections. Energy drives the glow intensity. Beat pulses the intersection nodes.
Wireframe tunnel with a procedural mesh that deforms with audio. Depth perspective shifts on beat. Industrial companion to Tunnel.
Vector-based terrain topology rendered as isolines. Elevation shifts with energy. Beat triggers a tectonic resampling of the height field.
3D hologram-style cube with depth projection. Face brightness responds to audio. Beat drives rotation snaps.
Custom Shaders · GPU · No Dev Account Required
Write a Metal fragment function and run it as a generator node. VKO1 injects beat phase, BPM energy, time, jog wheel value, and resolution automatically — no boilerplate required. Start from a one-tap boilerplate, write code directly inside the app, or import a .metal file from your Files app.
Tap New Shader from Scratch in the node palette. VKO1 instantly generates a working boilerplate shader, compiles it, and adds the node — no file needed. Select the node and tap Edit Shader Code to customize it.
Select any Custom Shader node and tap Edit Shader Code in the inspector. The in-app editor opens with the current source. Edit and hit Compile — the node updates live. Compile errors appear in a red banner; tap the copy icon to copy them to clipboard.
Write your shader in any text editor (Notes, VS Code, Textastic), save as .metal, and tap Import .metal File from the node palette. VKO1 detects the function name, compiles, and adds the node automatically.
Your file must contain exactly one fragment function. The name can be anything — VKO1 detects it automatically.
fragment float4 your_shader_name( VertexOut in [[stage_in]], constant GeneratorUniforms &u [[buffer(0)]] ) { // u.time, u.beatPhase, u.energy, u.resolution, ... float2 uv = in.uv; return float4(uv, u.beatPhase, 1.0); // your logic here }
GeneratorUniformsAll fields are injected automatically. Access them via u.
Elapsed seconds since launch. Use for animation.
0 → 1 ramp that resets on every beat. Drives beat-sync pulses.
Normalized confidence of the last detected beat. 0–1.
Broadband audio energy. Peaks on loud hits. 0–1.
float2 — render target size in pixels.
Speed scalar — defaults to global BPM speed, but now connectable via the Speed pin. Wire Bass or LFO to a node's Speed pin to override per-node.
The Reactivity pin value (0–1). Scale energy by this.
The Complexity pin value (0–1). Use as a detail/scale control.
int — index 0–32 of the selected palette. Use for custom palette logic.
Jog wheel position (-1 → 1). Map to rotation, offset, or warp.
Reserved float for future use. Always 0.
// beat_rings.metal — paste into any text editor, save as .metal, import into VKO1 #include <metal_stdlib> using namespace metal; // VKO1 injects VertexOut + GeneratorUniforms automatically — no need to redefine them here // GeneratorUniforms includes: time, beatPhase, beatStrength, energy, resolution, // speed, reactivity, complexity, colorPalette (int), jogValue // --- Cosine palette helpers (same formula used by VKO1 built-in generators) --- float3 cosine_palette(float t, float3 a, float3 b, float3 c, float3 d) { return a + b * cos(6.283185 * (c * t + d)); } float3 get_palette_color(float t, int idx) { switch (idx) { // Cyberpunk, Neon, Fire, Ice, Nature, Synthwave, Mono, Rainbow case 0: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.0,1.0,1.0), float3(0.00,0.10,0.20)); case 1: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.0,1.0,0.5), float3(0.80,0.90,0.30)); case 2: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.0,0.7,0.4), float3(0.00,0.15,0.20)); case 3: return cosine_palette(t, float3(0.5,0.5,0.8), float3(0.4,0.4,0.2), float3(1.0), float3(0.00,0.33,0.67)); case 4: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.0,0.7,0.4), float3(0.30,0.20,0.20)); case 5: return cosine_palette(t, float3(0.5), float3(0.5), float3(2.0,1.0,0.0), float3(0.50,0.20,0.25)); case 6: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.0), float3(0.0)); case 7: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.0), float3(0.00,0.33,0.67)); // Toxic, Blood Moon, Electric, Lava, UV, Candy, Matrix, Inferno case 8: return cosine_palette(t, float3(0.2,0.6,0.0), float3(0.3,0.5,0.2), float3(1.0,1.5,0.5), float3(0.00,0.05,0.30)); case 9: return cosine_palette(t, float3(0.6,0.1,0.1), float3(0.5,0.3,0.3), float3(1.0,0.5,0.5), float3(0.00,0.10,0.30)); case 10: return cosine_palette(t, float3(0.2,0.2,0.8), float3(0.5,0.5,0.5), float3(1.0,1.0,2.0), float3(0.10,0.20,0.00)); case 11: return cosine_palette(t, float3(0.6,0.3,0.0), float3(0.5,0.4,0.3), float3(1.5,1.0,0.5), float3(0.00,0.05,0.10)); case 12: return cosine_palette(t, float3(0.4,0.0,0.6), float3(0.5,0.3,0.5), float3(1.5,0.5,2.0), float3(0.30,0.20,0.00)); case 13: return cosine_palette(t, float3(0.8,0.4,0.5), float3(0.5,0.5,0.5), float3(1.0,1.0,1.0), float3(0.00,0.15,0.50)); case 14: return cosine_palette(t, float3(0.0,0.4,0.0), float3(0.1,0.5,0.1), float3(0.5,1.5,0.5), float3(0.0)); case 15: return cosine_palette(t, float3(0.7,0.4,0.2), float3(0.6,0.5,0.4), float3(1.0,0.8,0.5), float3(0.00,0.05,0.15)); // Mono Red, Blue, Green, Purple, Amber, Cyan, Pink case 16: return cosine_palette(t, float3(0.4,0.0,0.0), float3(0.4,0.1,0.1), float3(1.0,0.3,0.3), float3(0.0)); case 17: return cosine_palette(t, float3(0.0,0.0,0.4), float3(0.1,0.1,0.5), float3(0.3,0.3,1.0), float3(0.0)); case 18: return cosine_palette(t, float3(0.0,0.3,0.0), float3(0.1,0.5,0.1), float3(0.3,1.0,0.3), float3(0.0)); case 19: return cosine_palette(t, float3(0.3,0.0,0.4), float3(0.3,0.1,0.5), float3(0.8,0.3,1.0), float3(0.0)); case 20: return cosine_palette(t, float3(0.4,0.2,0.0), float3(0.5,0.3,0.1), float3(1.0,0.6,0.2), float3(0.0)); case 21: return cosine_palette(t, float3(0.0,0.3,0.4), float3(0.1,0.4,0.5), float3(0.2,1.0,1.0), float3(0.0)); case 22: return cosine_palette(t, float3(0.4,0.0,0.2), float3(0.5,0.1,0.3), float3(1.0,0.2,0.6), float3(0.0)); // Sunset, Ocean, Vapor, Copper, Aurora, Coral, Midnight, Rust, Hologram, Marathon case 23: return cosine_palette(t, float3(0.5,0.5,0.5), float3(0.5,0.5,0.3), float3(1.0,0.7,0.7), float3(0.00,0.15,0.40)); case 24: return cosine_palette(t, float3(0.0,0.3,0.5), float3(0.3,0.4,0.4), float3(0.5,1.0,1.0), float3(0.20,0.10,0.00)); case 25: return cosine_palette(t, float3(0.8,0.7,0.8), float3(0.2,0.2,0.2), float3(1.0), float3(0.00,0.10,0.20)); case 26: return cosine_palette(t, float3(0.5,0.3,0.15), float3(0.4,0.3,0.2), float3(1.0,0.7,0.4), float3(0.00,0.05,0.10)); case 27: return cosine_palette(t, float3(0.3,0.5,0.4), float3(0.4,0.4,0.4), float3(1.0,1.0,1.5), float3(0.00,0.20,0.50)); case 28: return cosine_palette(t, float3(0.6,0.4,0.4), float3(0.4,0.3,0.3), float3(1.0,0.8,0.6), float3(0.00,0.10,0.25)); case 29: return cosine_palette(t, float3(0.1,0.1,0.3), float3(0.3,0.3,0.5), float3(0.5,0.5,1.5), float3(0.25,0.25,0.00)); case 30: return cosine_palette(t, float3(0.5,0.25,0.1), float3(0.4,0.3,0.2), float3(1.2,0.6,0.3), float3(0.00,0.10,0.20)); case 31: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.5), float3(0.30,0.20,0.10)); case 32: return cosine_palette(t, float3(0.45,0.55,0.30), float3(0.55,0.50,0.50), float3(1.0,0.8,1.2), float3(0.00,0.15,0.35)); default: return cosine_palette(t, float3(0.5), float3(0.5), float3(1.0), float3(0.00,0.10,0.20)); } } fragment float4 beat_rings( VertexOut in [[stage_in]], constant GeneratorUniforms &u [[buffer(0)]] ) { float2 uv = in.uv - 0.5; uv.x *= u.resolution.x / u.resolution.y; // correct aspect ratio float dist = length(uv); float freq = 6.0 + u.complexity * 12.0; float phase = dist * freq - u.time * u.speed; float ring = 0.5 + 0.5 * sin(phase + u.beatPhase * 6.2831); float pulse = 1.0 + u.energy * u.reactivity * 0.5; float3 col = get_palette_color(ring * pulse, u.colorPalette); // uses selected palette return float4(col, 1.0); }
Retro grid, wireframe cube, neon tunnel, digital rain, CRT monitor, laser grid, pixel warp, hex wave, diamond spin, aurora, kaleidoscope, plasma orb, spiral vortex, star warp, voronoi glass, holo HUD, and synth city. All use the full palette system, beat detection, jogwheel, complexity, and reactivity — great for learning how every uniform works.
.metal file — VKO1 compiles it and adds a Custom Shader nodeThese open-source GLSL/Metal collections are great starting points. Two quick changes make any Metal shader from these repos work in VKO1: rename ProjectedVertex → VertexOut, and prefix uniform fields with u. instead of whatever struct name the original uses. GLSL shaders need conversion to MSL (types, built-ins, and coordinate conventions differ).
Large Metal fragment shader collection for SwiftUI — noise fields, plasma, aurora, halftone, kaleidoscope, SDF shapes, distortions, and more. All MSL. Uses SwiftUI layer effect signatures, so strip the [[stitchable]] attribute and rewrite the function signature to the VKO1 format. The math is directly portable.
Warren Moore's Metal sample code from his Metal by Example book. API-first, clean conventions — the best reference for understanding how Metal rendering pipelines are structured before writing your own shaders from scratch. Less about effects, more about getting the fundamentals right.
github.com/metal-by-example/sample-code ↗Thousands of procedural fragment shaders. All are GLSL — convert vec2/vec3/vec4 → float2/float3/float4, rename iTime → u.time, iResolution.xy → u.resolution, replace fragCoord / iResolution with in.uv.
An iOS Metal shader live editor by Warren Moore — write a fragment function and see it render in real time. Includes a set of built-in starter shaders you can browse and copy. The shaders use a very similar single-struct uniform pattern to VKO1's GeneratorUniforms, so adaptation is minimal.
Open-source video filter framework with a large shader library — color grading, chroma key, morphological ops, bloom, vignette. Shaders follow clean Metal conventions. Good source for modifier-style effects if you want to hand-roll an in-graph filter.
github.com/MetalPetal/MetalPetal ↗~30 MSL shaders by Paul Hudson — procedural generators, transitions, blur variants, and distortion effects. Written for SwiftUI's [[stitchable]] convention. The logic is directly usable; the signature needs rewriting. Replace [[stitchable]] half4 name(float2 position, half4 color, ...) with the standard VKO1 signature, change half4 → float4, and map the explicit float parameters (time, size) to u.time and u.resolution.
The canonical learn-to-write-shaders resource. GLSL, but every example teaches a concept you then implement in MSL. Covers noise, patterns, shapes, and color — the foundation for writing original VKO1 shaders from scratch.
thebookofshaders.com ↗vec2/3/4 → float2/3/4 · mat2/3/4 → float2x2/3x3/4x4 · mix() stays mix() · fract() → fract() · texture2D() → tex.sample() · gl_FragCoord.xy / iResolution.xy → in.uv
Modifiers · 27 nodes
Modifiers take one texture in, return one transformed texture. The Amount pin (float, 0–1) is exposed on every modifier — connect an Input node to it for animated control. The Speed pin lets you override the global speed per-node. Stack multiple modifiers in a chain for compounding effects.
9-tap separable Gaussian blur. Amount controls radius (up to 3% of UV space). Stack two Blur nodes for a wider spread.
Horizontal mirroring. Supports hard mirror or blended mode. Fundamental for creating symmetrical VJ compositions.
Radial segmentation with alternating reflection. Param1 sets segment count (2–16). Amount controls blend strength. Works on any generator.
Lateral chromatic aberration — splits RGB channels horizontally. Amount drives the separation distance. Beat-reactive version of a classic lens effect.
Full-spectrum hue rotation via Rodrigues RGB-space rotation. Amount drives the rotation angle (0–360°). Connect an LFO to Amount for a continuously cycling palette.
Sobel operator edge detection. Amount controls edge magnitude threshold. Brilliant before Thermal for a glowing wireframe look.
Quantizes color to 2–16 levels. Amount controls the quantization step. Creates stark, graphic poster art from any generator.
Print-dot halftone effect with variable dot size. Param1 enables custom dot color, Param2–4 set the RGB values via the inspector's color picker.
Perlin-displacement UV distortion with beat-reactive boost. Amount controls displacement magnitude. Pushes every pixel in a noise-driven direction.
Sinusoidal horizontal and vertical waves applied to UV coordinates. Amount drives wave amplitude. Beat pulse doubles the wave height momentarily.
Blends the previous frame with the current frame, with a slight zoom on the feedback copy. Creates infinite tunnel-trail effects. Amount controls persistence (0.8–0.98 decay).
Maps luminance to a color ramp. Four colormaps: Thermal, Fire, Ice, Neon. Incredible after Edge Detect. Param1 selects the colormap in the inspector.
Keys out green, blue, or red with a configurable threshold. Useful when compositing external video sources. Param1 selects the key color.
Maps luminance to a two-color gradient. Amount controls the midpoint of the ramp. A lighter alternative to Thermal when you want a clean bi-color look.
Per-row random horizontal displacement with optional RGB split. Beat drives burst intensity. Two styles: Row Shift and RGB Split (Param1). Connect an LFO for rhythmic corruption.
Block pixelation at 2–64 pixel sizes. Amount controls block size. Snaps the image to a low-res grid. Effective at revealing the underlying structure of complex generators.
Desaturate or oversaturate the input. 0.5 = original. 0 = grayscale. 1 = fully vivid. Connect a Beat Strength input to slam color in on every hit.
CRT-style horizontal scan lines. Amount controls intensity. Param1 overrides spacing. Beat brightens the scan lines momentarily for a phosphor-pulse effect.
Single-pass Gaussian bloom with threshold extraction. Amount controls both the spread radius and the extraction threshold. Beat hits boost the glow intensity automatically. The go-to finish for any neon or laser generator.
These 7 nodes are powered by Apple's Core Image framework — hardware-accelerated and available on all devices. They expand into distortion, grading, and cinematic effects that go far beyond what a custom Metal shader can do in a single pass.
CITwirlDistortion — spirals the image outward from center. Amount controls twist angle (0→4π). Param1 sets the effect radius as a percentage of frame size. Wire Bass to Amount for a kick-driven spin.
CIVortexDistortion — rotational warp that pulls the whole frame into a spiral. Deeper and more continuous than Twirl. Wire a slow LFO to Amount for perpetual rotation that builds gradually.
CIPinchDistortion — squeeze the frame inward (Amount < 0.5) or bulge it outward (Amount > 0.5). Amount = 0.5 is neutral. Wire Beat Phase to create a lens pulse that breathes on every bar.
CIGaussianBlur with a soft edge clamp to avoid border artefacts. Amount controls radius (0–50 px). Unlike the Metal Blur node, this operates at full pixel resolution — better for soft-focus and depth-of-field looks.
CIColorControls — three independent sliders in the inspector: Saturation (0→2×), Brightness (−0.5→+0.5), Contrast (0.25→2). Amount is a wet/dry blend with the original. The most versatile color grading node in the graph.
CIAffineTransform — rotate, scale, and translate the frame. Amount = rotation angle (0→360°). Inspector exposes Scale (0.5–2×) and X/Y Offset. Wire an LFO to Amount for infinite slow rotation without any shader code.
8 cinematic photo filter presets: Noir, Chrome, Fade, Mono, Process, Tonal, Transfer, Instant. Param1 selects the preset in the inspector. Amount = wet/dry blend with the original. Stack after Color Controls for full color grading.
A special modifier that rotates the flat shader output in 3D space with perspective projection. The shader stays 2D, but the plane it lives on tilts, spins, and floats in perspective. Three rotation pins (X, Y, Z) are all connectable — wire audio inputs for reactive 3D movement.
Rotates the shader quad in 3D with perspective projection. Three float input pins — Rotate X, Rotate Y, Rotate Z — each connectable to Bass, LFO, Beat, etc. Inspector exposes Perspective (FOV strength) and Zoom sliders. Wire Bass → Rotate X and the shader tilts toward you on every kick. Wire LFO → Rotate Y for a slow floating display spin. Stack with Bloom for a dramatic floating-screen-in-the-void look.
Combiners · 6 nodes
Combiners take two texture inputs (A and B) and produce one output. The Mix pin controls the blend depth and is a float pin — connect any Input node to drive it dynamically. The Blend Mode selector is set in the inspector.
14 Photoshop-style blend modes: Normal, Multiply, Screen, Add, Subtract, Difference, Overlay, Hard Light, Soft Light, Darken, Lighten, Exclusion, Color Dodge, Color Burn. Mix controls how strongly B blends into A.
Uses B's luminance as an alpha mask for A. Bright areas of B show A; dark areas hide it. Connect any high-contrast generator as B for cut-out shapes.
Absolute per-pixel difference between A and B. Black where they match, bright where they diverge. Extraordinary when A and B are the same generator at different speeds.
Uses B's red and green channels as a UV displacement map for A. Mix controls displacement strength (up to 10% of UV). Beat multiplies the strength by up to 3×. Run a Plasma as B to bend any generator into fluid shapes.
Crossfades A↔B driven by beatPhase (0→1 per beat). Mix controls swing depth. Four modes: Smooth (sine A→B→A), Hard Cut (snaps at beat centre), Flash B (B pops on downbeat and decays to A), Flash A (inverse). The VJ's scene transition tool.
Replaces dark or bright areas of A with B based on luminance threshold. Mix controls the threshold. Mode 0: dark areas of A become B (stars punch through plasma). Mode 1: bright areas of A become B (inverse key). Smooth edge blending built in.
Mix = 0.3. Dark areas of Plasma (A) are replaced by the Starfield (B). The stars appear exactly where the plasma is darkest.
Inputs · 11 nodes
Input nodes produce a single float value (0–1). They have no texture input and no visual output — they only feed float pins on other nodes. Connect them to any float pin: Reactivity, Complexity, Amount, or Mix.
0→1 ramp that resets on every beat. Connect to a Combiner's Mix pin for a parameter that sweeps across every bar. The heartbeat of the system.
Onset detection strength (0–1). Spikes on transients. Connect to Bloom's Amount or a Modifier's Amount for impact-driven effects that only fire when the music hits hard.
Overall audio energy, smoothed. Slower-moving than Beat Strength. Good for driving background complexity parameters that breathe with the music rather than snap.
Average energy of spectrum bins 0–4 (roughly 20–300 Hz). The kick and sub frequencies. Connect to a generator's Reactivity or a Distort's Amount to make the low end shake the image.
Average energy of spectrum bins 5–15 (roughly 300 Hz–3 kHz). Snare, rhythm, and mid-frequency content. Great for driving Saturation or Wave Warp.
Average energy of spectrum bins 16–31 (roughly 3–20 kHz). Hi-hats, cymbals, and high-frequency shimmer. Connect to Bloom or Color Shift for high-end sparkle.
The full 32-bin spectrum array. This is a spectrum-type pin, not a float — it feeds spectrum-aware generator parameters directly. Used internally by audio-reactive generators.
Low-frequency oscillator. Rate: 0.1–10 Hz. Four shapes: Sine, Triangle, Square, Saw. The most versatile modulator — use Square to gate effects rhythmically, Sine for smooth sweeps.
A fixed value set by a slider (0–1). Use it to lock a parameter at a specific value, overriding audio reactivity entirely. Essential for controlled, stable looks.
The raw time value, growing continuously. Connect to a generator's Complexity to drive it at a fixed speed regardless of music. Wraps through the generator's own time calculation.
The current jog wheel rate (–1 to +1). If you have the jog wheel active in VKO1, this outputs its value live. Connect to Hue Rotate's Amount for manual color control during performance.
Workflow
Start from a preset and modify it, or build from scratch. Either way, the workflow is the same: source → shape → combine → control.
Tap the grid icon in the toolbar to open Graph Presets. Templates are pre-wired starting points — load one and explore what's connected before changing anything.
Every graph needs at least one generator. Tap + → Generators to add one. Set its Palette and Complexity in the inspector. Connect its output pin to the Output node to preview it.
Add a modifier between the generator and the output. Drag from the generator's output pin to the modifier's input pin. Then drag from the modifier's output to the Output node.
Add a Bass, LFO, or Beat Phase input node. Drag from its Value pin to any float pin on a modifier or combiner. Watch the effect animate in real time in the preview panel.
Presets
VKO1 ships with 22 ready-to-use graph templates. Each one demonstrates a different patching technique. Load them in the Graph Presets browser and modify them freely — they won't overwrite the originals.
Two organic generators blended at 60/40 mix using the Blend combiner in Normal mode. A gentle introduction to dual-generator graphs.
Screen blend mode makes the grids add together without blowing out. The result is a layered topographic HUD.
Demonstrates the Kaleidoscope modifier's Param1 override for segment count. Try connecting an LFO to Amount.
The Feedback modifier retains 70% of the previous frame, creating a trailing ghost tunnel. Increase Amount to 0.95 for extreme smear.
Add blend mode combines two audio-reactive generators. The result sums their energies without the darker regions cancelling each other.
Edge detection isolates the geometric borders of Neon Prism, then Thermal maps the edge luminance to a fire gradient.
Hard-cut beat crossfade switches between generators on each beat. Change the mode to Smooth for a gradual transition.
Dark areas of Plasma are replaced by the Starfield. Adjust Mix (threshold) to control how many stars are visible.
The Bass input node drives Bloom's Amount directly. Low-end hits bloom the cells outward. Shows the float pin patching workflow.
A square-wave LFO at 2 Hz gates the Glitch amount. Demonstrates how Input nodes can replace MIDI CC control in the graph.
The Particles flash in on the downbeat and decay back to Grid Pulse. Bloom sits after the crossfade so both sources benefit from it.
Bass energy drives the Twirl angle directly. The kick drum spins the plasma field. Try increasing Param1 (radius) for a wider affected area.
A very slow sine LFO rotates the Voronoi field continuously. The result is a living organism that never repeats exactly the same pattern.
Beat Phase sweeps 0→1 every bar, driving Pinch from neutral to full bulge. The tunnel lens pulses outward in sync with the music.
Soft Gaussian blur over atmospheric terrain, then Color Controls bumps saturation and contrast. A slow, textural look for ambient sets.
Color Controls cranked to full saturation, then Bloom halos every star. Pure neon — adjust the palette on the Starfield generator to shift the color story.
Noir desaturates and adds filmic grain, then Edge Detect traces the geometric borders. Cinematic black-and-white wireframe.
A very slow LFO rotates the entire frame via Affine Transform. The fractal pattern drifts slowly in a way that feels alive but never distracts.
The most complex template — 6 nodes. Two generators screen-blend, then Chrome film grading and Bloom finish it. Shows how the CI modifiers slot into a full signal chain.
Bass drives the Tunnel Warp's Speed pin — the tunnel accelerates on every kick. A square-wave LFO gates the Glitch for choppy digital breakup. Demonstrates the new connectable Speed pin.
Two LFOs at different rates drive the Speed of two generators independently. The slow sine makes stars drift in and out, the faster triangle pulses the plasma. Organic and alive without any audio input.
The plasma floats in 3D space — a slow LFO gently tilts the X axis while bass kicks rotate the Y axis. Bloom finishes it for a glowing floating-screen-in-the-void look. Showcases the new 2.5D Perspective modifier.
Advanced
Once you understand the basics, these patterns will push your graphs into territory no built-in preset can reach.
Run two generators into a Blend combiner, then put Feedback after the combiner. The feedback now captures the blended image — not just one source. The trails carry both generators inside them.
Add the same generator type twice — same palette, but one at complexity 0.2 and one at 0.8. Run them into a Difference combiner. You get an entirely new pattern from two identical sources running at different scales.
Run a generator into a Displace combiner as both Input A and Input B. The generator uses itself as its own displacement map. This creates recursive warping that changes completely over time.
Connect a Constant (value 0) to a generator's Reactivity pin to disable its audio response entirely. Now the generator is a stable texture you can layer other audio-reactive content over.
Wire Bass → a generator's Reactivity, Mid → a modifier's Amount, and Treble → a combiner's Mix. Each frequency band now controls a different visual parameter independently. The mix changes with the music's spectral balance.
Connect Beat Phase to a Blend combiner's Mix pin. The mix now sweeps from 0 to 1 within every beat and resets. Change the combiner to Overlay or Screen for a blend that pulses rather than fully switching.
Put Bloom before Kaleidoscope, not after. The Kaleidoscope will mirror the bloom glows into every segment, creating a symmetric corona effect. After gives you simple blurred segments — before gives you a crown of light.
Every generator, modifier, and combiner now has a connectable Speed pin. Wire Bass → Speed on a Tunnel Warp and the tunnel rushes forward with every kick. Wire different LFO rates to different generators' Speed pins to make them drift in and out of sync — like two turntables running at slightly different BPMs.
Put the Perspective 3D modifier at the end of any chain, right before Output. Wire a very slow LFO (0.1 Hz) to Rotate Y — the entire visual slowly rotates like a floating screen in the void. Add Bloom after it for a glowing halo around the tilted edges. The perspective strength slider in the inspector controls how dramatic the depth effect feels.
Use the bookmark icon to save graphs to your library. Give them names like "Neon Tunnel - Techno Set" or "Soft Ambient - Opener". Your library appears at the top of the presets browser and loads instantly.
The Graph Editor is built into VKO1. Open any pad, tap or click the graph icon, and start connecting nodes. No setup. No files. Just signal flow. Works on iPhone, iPad, and Mac.
Download on the App Store