User guide/Shader import + reactivity

Shader import + reactivity

Paste a shader, drive it from the music. Three layers, in the order to reach for them: the knobs that already exist, your own knobs from one comment block, then the audio uniforms read straight from your code. None of it needs an AI key.

Layer one: the knobs you already have

Open the Console. These act on whatever is on screen right now, imported shaders included, with no editing and no reload.

Bass
0 – 2 · starts at 1
Multiplies the low band before your shader sees it.
Mid
0 – 2 · starts at 1
Same, for the middle band.
Treble
0 – 2 · starts at 1
Same, for the top band.
Smooth
0.30 – 0.98 · starts at 0.40
Higher glides, lower twitches. One global analyser setting.
Intensity
1 – 11 · starts at 8
The big fader. Multiplies all three bands on top of the knobs above.
Speed
0.1 – 2 · starts at 1
Scales the scene clock for imported GLSL. Never touches the music.

They stack, and the stacking is the part most people miss:

What your shader actually receives u_bass = rawBass × Bass knob (0–2) × Intensity (0–2)

The Intensity fader reads 1 to 11 on screen but drives 0 to 2 underneath: display 6 is 1.0×, display 11 is 2.0×, and the default display 8 is 1.4×. A factory-fresh IKANDY is already feeding your shader 1.4 times what it was written for.

The Reactivity section

Two of its four knobs act on an imported shader:

Layer two: your own knobs, one comment block

Put a single line comment in your pasted source and IKANDY builds you real knobs in the Console's SCENE section: sliders, toggles, dropdowns, a proper colour picker. They persist with the scene and come back when it reloads.

// ikandy-controls: [ // {"id":"glow", "label":"Glow", "type":"float", "range":[0,2], "default":0.8, "mapsTo":"u_glow"}, // {"id":"tint", "label":"Tint", "type":"color", "default":"#66ccff", "mapsTo":"u_tint"}, // {"id":"spin", "label":"Spin", "type":"bool", "default":true, "mapsTo":"u_spin"} // ] void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 uv = fragCoord / iResolution.xy; vec3 col = u_tint * smoothstep(0.8, 0.0, length(uv - 0.5)); col *= 1.0 + u_glow * u_bassS; // your knob, times the music fragColor = vec4(col, 1.0); }

Put it anywhere in the pasted source. On a multipass shader it goes in the Common tab, or the top of Image if you have no Common tab, and every pass can read the uniform.

Four rules that will bite you

Fields

FieldNeededWhat it does
mapsToyesThe uniform name: u_ plus letters, digits, underscore. Cannot be a built-in like u_bass.
labelshouldThe name on the knob.
typeshouldfloat (knob, the default), int, color (picker, arrives as a vec3), bool (toggle), enum (dropdown, needs options).
rangefloat / int[min, max]
defaultshouldStarting value. Colours take "#rrggbb" or [r,g,b] in 0–1.
idshouldShort key used for saving. Defaults to mapsTo.
optionsenum[{"value":0,"label":"Soft"}, ...]
audioDefaultnoWires the knob to a band. See below.

Up to 12 controls. Duplicate or reserved mapsTo names are dropped, with the reason logged to the developer console.

In a WGSL import you read uc.glow inside fs_main, which is your mapsTo with the u_ prefix removed. Everything else is identical.

Point a knob at a band

This is the direct answer to “how do I put the bass on something else?” Add audioDefault to any float or int control and that knob is modulated by the band every frame, without touching your shader code.

// ikandy-controls: [ // {"id":"zoom", "label":"Zoom", "type":"float", "range":[0.5,3], "default":1.0, // "mapsTo":"u_zoom", "audioDefault": {"band":"bass", "gain":1.5}}, // // {"id":"hue", "label":"Hue", "type":"float", "range":[0,1], "default":0.2, // "mapsTo":"u_hue", "audioDefault": {"band":"treble", "gain":0.6}} // ]
How the value is computed each frame value = knob position × (1 + band × gain)

Bands are bass, mid, treble and volume. Gain is clamped to 0–8. The knob you set by hand stays the base, so you keep a manual trim on top of the music.

Repointing it live, without editing

You can move a control from one band to another while the shader runs:

The pill appears only on a shader the panel itself opened, which is why the save-then-open step matters. Loading a fresh paste gives you the knobs but not the pills. One more thing worth knowing: if you later edit the ikandy-controls block in the saved file, the file wins over the remembered pill settings on the next load.

Layer three: straight into the source

The fastest loop. The paste box is the editor: type in it and press Ctrl+Enter to recompile. IKANDY declares all of these for you, so just read them.

UniformWhat it carries
u_bass u_mid u_trebleThe three bands, after your Console knobs and Intensity. Fast and spiky.
u_bassS u_midS u_trebSThe same bands, envelope-smoothed. Use these for anything that should glide.
u_kickTightThe kick drum transient, 50–110 Hz. The structural pulse.
u_snareBackbeat body and crack. Good for colour and saturation flares.
u_hihat6–16 kHz tick. Fast, fine sparkle.
u_subBass20–60 Hz rumble. Slow glow and depth.
u_air16–22 kHz sheen. Slow shimmer.
u_bassHit u_midHit u_trebHitRaw onset envelopes per band.
u_buildup u_peak u_calm u_release u_sustain u_arcSong shape. These rise and fall over seconds, not beats. Stage the drop with them.
u_beat u_beatPhase u_barPhase u_bpmThe live beat clock.
u_driveThe Intensity fader itself, 0–2. Multiply your reactivity by it so your shader goes fully still at zero.
u_volume u_intensityOverall loudness. u_volume is the RMS of the bands, u_intensity is their mean.
spectrumAt(x) waveformAt(x)Helper functions. Sample the full spectrum or waveform; x and the result are both 0–1.

Shadertoy shaders work unchanged. Every iChannel resolves to IKANDY's live audio in the exact 512×2 texture format Shadertoy uses: FFT on one row, waveform on the other. A shader that already samples a music channel reacts the moment it loads, with nothing to press. iResolution, iMouse, iDate, iFrame and the rest are wired too. Shadertoy library textures do not travel with an export, so bind your own image or the shader renders without them.

The one real craft rule. Give each instrument its own job: kick drives one thing, snare another, hats another. That separation is the difference between a shader that pumps and a shader that just brightens all over. Driving everything from u_bass is the most common reason an import looks flat.

Colour, zoom, and the motion rule

Colour, brightness, glow, sparkle, saturation and contrast are open season. Drive any of it from any signal, as hard as you like.

Zoom, camera and whole-frame motion are different. Your hand-written shader can do it, because a fresh paste renders exactly as written and nothing rewrites your code. But IKANDY's own automatic tools will not wire audio into motion for you, and that is a decision rather than an oversight:

The reason is motion comfort. Repetitive whole-field movement in roughly the 0.08 to 0.5 Hz band is what makes people queasy, and music sitting at 100 to 140 BPM puts a bass-driven zoom uncomfortably close to it. If you want breathing zoom, write it yourself, keep the amplitude small, and watch it on a big screen for a few minutes before you put it in front of a room.

Two things people ask

Does an AI key change any of this?

No. Every layer above is free of provider cost and works offline. A key buys three things: IGNITE, which reads a non-reactive shader and proposes audio bindings for you to review before anything applies; Tune, which looks at the running frame and balances the gains; and AI Create, which writes whole scenes from a prompt. If you already write your own reactivity, a key mostly buys you the gain-balancing pass. See AI scene generation.

Can I build .milk presets in IKANDY?

Not today. IKANDY reads them very well: drop a folder of .milk files and they convert in the app, get security-screened, and land in rotation, tested with ten thousand presets at once. But nothing in the app writes a .milk file, so authoring still needs MilkDrop itself or a preset editor. See Visualizers + presets.

Shader import ships in the Pro tier, alongside the AI shader studio. See pricing; the Steam page is authoritative. Accurate as of IKANDY 1.6.5.
← PreviousMIDI, phone remote, gamepadNext →AI scene generation