■ huff Home How It Works Install Interface MIDI OSC Output
--:--:--
The Interface
_

huff opens two windows. The controls window is your workspace. The canvas window is the fullscreen output that receives processed frames over the embedded WebSocket relay.

Controls are organised into collapsible groups. Click a group label to collapse or expand it. Collapsing a group does not disable its effects — use the ON toggle inside each group for that.


Top Bar

ControlDescription
FileLoad a video file. Drag-and-drop also works. MP4, MOV, WebM, and any format your system decoder handles.
▶ Play / ⏸ PauseToggle video playback. Resuming after pause restarts the frame pump automatically.
VOLOutput volume. Routed through a dedicated Web Audio AudioContext + GainNode so audio playback runs on its own thread and does not drop out under heavy canvas load. Drag to zero to mute.
RATEPlayback speed: 0.25×, 0.5×, 1×, 2×, 4×. Applies immediately without reloading.
LOOPLoop the file continuously. Unchecking plays once and stops.
↻ RefreshRe-seed glitch randomisation.
↺ ResetReset all parameters to defaults.
CLR BUFInstantly wipes the frame ring and all internal buffers (gBuf and the shared gScratch ping-pong buffer) and resets cluster physics. Use this to clear accumulated trails/feedback/glitch history without resetting any parameter values or noise phases — the animation continues from where it was.
CameraSelect a webcam from the dropdown. Click ↻ Refresh to scan for newly connected devices.
Seek BarScrub to any position in the loaded file. Uses fast keyframe seeking while dragging for low latency; playback resumes automatically on release.
Time DisplayShows current position and total duration as M:SS / M:SS.

Source Group

ControlDescription
BASE VIDEOShow the raw source frame underneath the glitch output.
BASE MIXOpacity of the base video layer at final composite. 0 = fully glitched output, 1 = raw source on top.
BASE BGBackground fill colour when no tile covers a pixel: Black, Green (chroma key), Blue, or White.
SEED ON LOADRandomise the seed each time a new file is loaded, giving every clip a visually distinct glitch pattern.
SEEDRandomisation seed. Same seed + parameters = same output.
QUALITYScales the frame ring depth (0 → 4 frames, 1 → 60 frames). The single most impactful performance lever.

Feedback Group

ControlRangeDescription
FEEDBACK0–3Contribution of the previous frame. Values > 1 over-expose.
PERSISTENCE0–10Decay rate between frames. Higher = trails linger longer.
FB X-1–1Horizontal translation per frame. Creates lateral drift.
FB Y-1–1Vertical translation per frame.
FB Z0.98–1.03Zoom per frame. < 1 = implode inward. > 1 = explode outward.
FB θ-2–2Rotation in degrees per frame. Creates spinning feedback tunnels.
↺ Reset MotionbuttonReturns FB X/Y/Z/θ to neutral (0, 0, 1.0, 0).
FEEDBACK above ~2.5 combined with non-neutral FB Z can saturate the buffer (full white or full black) within seconds. Recovery: lower FEEDBACK to 0, click ↺ Reset Motion, or use CLR BUF in the top bar to wipe the buffer instantly.

Glitch Group

The core datamosh engine. Reads tiles from past frames and blits them onto the current frame at noise-driven positions.

ControlRangeDescription
ONtoggleEnable/disable the glitch pass entirely.
DEPTH0–0.5How far back in the ring tiles are sampled.
SCATTER0–1Per-tile randomisation of the lookback index.
CORRUPT %0–7Fraction of grid tiles displaced per frame. 0 = nothing moves. 7 = every tile replaced.
DRIFT0–1Noise-driven oscillation of corruption density. The percentage breathes slowly when > 0.
PIXEL SIZE150–2000Tile size in pixels. Larger = blockier datamosh. Smaller = fine grain displacement.
GLITCH SIZE1–60Spatial scaling of each tile relative to PIXEL SIZE.
OPACITY0–1Alpha of each blit tile. Also scaled by the A/B Mix layer-priority weight.
JITTER0–1Magnitude of per-tile position noise.
SMEAR0–200Duplicate stamps trailed behind each tile.
SMEAR ANGLE0–360Direction of the smear trail. 0 = noise-driven per frame.
SPEED0–5Phase velocity of the noise field driving tile selection.
FINE0–10Secondary fine speed multiplier.
MULT0–10Overall speed multiplier.
GLITCH X / Y-1000–1000Base offset applied to all tile destination positions.

Clusters Group

Locked directly beneath Glitch as part of the same conceptual unit. Biases glitch tile placement toward moving focal points (cluster centres) rather than scattering tiles randomly. Glitch must also be ON. Each centre has its own physics simulation with inertia, steering, and optional velocity bursts. Centres always use the physics simulation — even at SPEED 0, where the desired velocity is zero and centres glide to a stop and hold position (no per-frame re-randomisation).

ControlRangeDescription
ONtoggleEnable cluster-biased tile placement. Glitch must also be ON.
CENTERS1–20Number of cluster centres. Each is an independent physics body that tiles gravitate toward.
SPREAD1–300Radius in pixels around each centre within which tiles are distributed.
MIN RAD0–150Minimum distance from centre — creates a hollow ring of tiles.
SPATIAL GAP0–200Minimum pixel distance between any two tiles. Prevents overlap.
BIAS0–1Fraction of tiles forced into clusters. Remainder placed randomly across the canvas.
DRIFT0–5Adds noise-driven wandering to centre positions.
SPEED0–10Speed of cluster centre physics simulation, step 0.01 for fine low-end control. 0 = centres glide to a stop and hold still.
SPD VAR0–2Per-centre speed variation. Each centre gets its own speed multiplier so they move at different rates. 0 = all same speed.
PULSE0–10Periodic velocity kick — centres suddenly burst in a random direction then settle. Higher = more frequent bursts.
INERTIA0.01–0.99Momentum of cluster centres. High = smooth gliding. Low = snappy response to steering.

Layer Priority Group

A deliberately stable binary paint-order control between the Corrupt/Luma group and Scanlines. Pass 48 removes the old frame-alternating and pulse-order modes because they behaved like temporal flicker rather than meaningful layer hierarchy.

ControlOptionsDescription
PRIORITYSCAN TOP / CORRUPT TOPSCAN TOP draws Scanlines last. CORRUPT TOP draws the Corrupt/Luma group last. Both are stable until explicitly changed.

Luma Key Group

A luminance-derived key with explicit target, key source, Clip/Gain-style shaping, stored stencil memory and keyed-fill compositing. X-FADE and SOFT ADD retain the INDIGO-inspired pair; Pass 48 adds a small set of HUFF Classic blend fades over the same keyed patch.

ControlRange / OptionsDescription
ONtoggleEnable the Luma Key.
TARGETCOMPOSITE / CORRUPT / SCANChoose whether the key restores clean imagery over the composite or directly gates Corrupt / Scan objects.
DARK ↔ BRIGHT0–1Clip / luminance threshold.
GAIN0.25–4Controls key edge steepness.
MIX0–1Overall key opacity.
INVERTtoggleInvert the key signal.
KEY SRCLIVE / STENCILLIVE follows incoming luminance. STENCIL uses the captured internal luminance plane.
STENCILCAPTURECapture bounded luminance memory for later keying.
FADEX-FADE / SOFT ADD / LIGHTEN / DARKEN / MULTIPLY / OVERLAY / HARD LIGHT / DIFFERENCECOMPOSITE-target keyed-fill relationship. The first two preserve the existing behavior; the additional modes are HUFF Classic extensions using the same matte and keyed patch.
CLEANUP0–1Suppress low-level key leakage.
DENSITY0–1Push strong key regions toward full opacity.

Buffer Trails Group

ControlRangeDescription
ONtoggleEnable/disable.
TRAIL LAYERS0–4Number of ghost frames composited.
TRAIL DEPTH0–1How far back in the ring to pull trail frames from.
LUMA KEY0–1Drops dark pixels from trail frames. Only bright areas trail.

Symmetry Group

ControlOptionsDescription
ONtoggleEnable/disable.
MODEvertical / horizontal / bothVertical mirror, horizontal mirror, or both axes.
SYM POS0–1Position of the mirror axis. 0.5 = centred.

Scanlines Group

Displaces bands of the current video frame spatially — no temporal sampling from the ring. Bands shift the current content perpendicular to their axis; they do not pull from historical frames, so they stay smooth and follow live motion with no buffer-trail artifact. The whole band pattern can be rotated to any angle, including continuous spin.

ControlRangeDescription
ONtoggleEnable/disable.
ANGLE-180°–180°, step 0.5°Rotates the entire band pattern. 0° = horizontal bands displaced left/right. 90°/-90° = vertical bands displaced up/down. Any other value = diagonal bands. The band span and displacement axis are recalculated for the full rotated canvas so bands always cover the whole frame and stay centred, at any angle.
0° / -90° / 90° buttonsbuttonsSnap ANGLE directly to 0°, -90°, or 90°. Because the slider spans 360° in a small space, landing exactly on these values by dragging is impractical — these buttons jump to them instantly and update the label.
SPIN L / SPIN RtogglesContinuously rotate the band pattern left (counter-clockwise) or right (clockwise) instead of holding a static ANGLE. If both are somehow active, SPIN R takes priority. While neither is checked, the internal spin position stays in sync with the ANGLE slider so enabling spin starts from the slider's current angle with no jump.
SPIN SPD0.1–10Spin speed. At 1.0 the pattern completes a full rotation in roughly 12 seconds (60fps); higher values spin proportionally faster.
BANDS1–50Number of active displacement bands per frame.
SIZE1–120Base size of each band in pixels (along the band axis).
FOCUS0–1Biases where bands are distributed across the rotated span. 0.5 = even spread across the whole canvas. Toward 0 or 1 pulls bands toward one end of the span. Fixes the tendency of unbiased noise to cluster bands near the centre.
SHIFT0–0.5Maximum displacement perpendicular to the band axis, as a fraction of the canvas dimension along that axis.
SKEW-1–1Position-based offset along the displacement axis, making bands angle diagonally relative to their own axis.
DRIFT0–3Dual-frequency noise driving band position along the rotated span: a slow base wander layered with faster, smaller jitter. Higher values increase both.
ROLL-2–2Continuous scroll of all bands along the rotated span, independent of DRIFT. Positive and negative values scroll in opposite directions; 0 = no roll.
SPEED0–5Speed of the DRIFT/ROLL phase accumulation. Operates independently of glitch speed — works even with glitch off.
GAP0–200Snaps band positions to a regular grid spacing along the rotated span.
OPACITY0–1Alpha of displaced band content. Also scaled by the A/B Mix layer-priority weight.

Global Mix Group

Reintroduces the clean source into the active effects chain at a selected serial position. Position determines whether the clean relationship enters recursive Feedback or only affects a later/final image. Pass 48 keeps this deliberately light and adds only a fader-response curve; no new render pass or image source is introduced.

ControlRange / OptionsDescription
ONtoggleEnable/disable. Zero MIX remains a true bypass.
BLENDSCREEN / ADD / LIGHTEN / DODGE / MULTIPLY / DARKEN / BURN / OVERLAY / SOFT LIGHT / HARD LIGHT / DIFFERENCE / EXCLUSION / HUE / SATURATION / COLOR / LUMINOSITY / NORMALCanvas blend relationship between clean source and the current Process image.
MIX0–1Global Mix fader.
CURVELINEAR / SMOOTH / PUNCHLINEAR is exact legacy behavior. SMOOTH eases both ends. PUNCH brings the clean relationship in earlier. The curve changes only the effective alpha and adds no image-processing pass.
POSITIONBEFORE FB / AFTER FB / AFTER FLOW / FINALSelects the legal insertion point in the fixed Classic serial pipeline.

Solarize Group

THRESHOLD preserves the accepted HUFF Classic Solarize. LUMA QUANTIZE adds a Magic DaVE-inspired luminance quantiser using the same bounded Solarize scratch/readback path.

Pass 44 UI: inactive mode-specific controls are hidden. THRESHOLD shows THRESH + SOL R/G/B; LUMA QUANTIZE shows LEVEL + SOFT + INVERT. ON, MODE, AMOUNT and FLUIDITY remain visible in both modes.

ControlRangeDescription
ONtoggleEnable/disable.
MODETHRESHOLD / LUMA QUANTIZESelect the original or new Solarize algorithm.
THRESH0–1THRESHOLD only. Original luminance threshold.
LEVEL0–100%LUMA QUANTIZE only. Higher = coarser luminance contouring; 99% = two levels, 100% = luminance removed.
SOFT0–100%LUMA QUANTIZE only. Softens the step transitions.
INVERTtoggleLUMA QUANTIZE only. Reverses luminance while retaining chroma.
FLUIDITY0–100%Solarize-local temporal slew. 100% = instantaneous Pass 42 behavior; lower values make Solarize evolve more slowly without changing playback speed or adding a new frame-skip gate.
AMOUNT0–1Shared wet/dry strength.
SOL R / G / B0–2THRESHOLD only. Existing per-channel tint multipliers.

Flow Group

Noise-field UV displacement applied after Feedback. Each grid cell samples a Perlin noise field to determine where it pulls its source pixels from.

ControlRangeDescription
ONtoggleEnable/disable.
STRENGTH0–20Maximum pixel displacement.
SCALE40–200Spatial scale of the noise field — grid cell size in pixels.
SPEED0–4Multiplies the time accumulator driving the noise field. 0 = frozen — the warp pattern stops evolving but stays applied. 1 = normal speed.
PULSE0–200Frames back in the ring to sample during warp. Adds temporal smear. 0 = sample the current buffer.
PULL-1–1Radial bias added to the noise displacement. Positive values pull toward the canvas centre (implode). Negative values push away from centre (explode/centrifugal). 0 = pure noise field, no radial bias.
SWIRL-2–2Rotates each cell's displacement vector by an angle proportional to its distance from centre, adding a vortex/spiral motion on top of the noise field and any PULL. Positive and negative values spin in opposite directions.
TURB0–1Blends in a second noise octave at higher frequency and lower amplitude, layered on top of the base field for more turbulent, less uniform displacement. 0 = single-octave field only.

Presets

Presets are named snapshots of all current parameter values, stored in the browser's localStorage and listed in a dropdown for quick recall. JSON export/import provides portability across machines and sharing with collaborators.

ControlDescription
preset name fieldType a name, then click 💾 Save (or press Enter) to save the current parameter snapshot under that name.
💾 SaveSaves the current snapshot to localStorage under the name in the field. Overwrites an existing preset of the same name.
— saved presets — dropdownLists all saved preset names alphabetically. Double-click an entry to load it.
▶ LoadLoads the selected preset. Counts as one undo step.
✕ DeletePermanently removes the selected preset from localStorage.
↑ Export JSONDownloads all saved presets as a single timestamped .json file — a map of preset name → parameter snapshot.
↓ Import JSONLoads a previously exported file. A file containing a map of named presets merges all of them into your saved list (overwriting any name collisions). A file containing a single preset snapshot is imported under the name currently in the preset name field, or imported-<timestamp> if the field is empty.
Ctrl+Z / Cmd+Z10-step undo. Steps back through parameter changes one snapshot at a time. Loading a preset counts as one undo step.
Presets are stored in the browser's localStorage — treat this as a cache, not a primary store. Use ↑ Export JSON to back up presets to a file you keep with your project. Cluster centre positions and velocities are runtime state and are not saved in presets; loading a preset restores all slider values but cluster centres will be wherever their physics simulation currently has them.

Keyboard Shortcuts

KeyAction
PToggle the control panel. A pill indicator appears at the bottom of the screen reading "UI hidden · P to show" so you can always get back.
FToggle fullscreen.
Ctrl+Z / Cmd+ZUndo the last parameter change. Up to 10 steps.