Nodes/kubakub nodes/kubakub shader
ComfyUI Node

kubakub shader

74 moving pictures on your GPU, no model to download

By kubakubkub·Created 19 days ago·Updated about 18 hours ago· 10
kubakub shader
  • image0
  • image1
  • image2
  • image3
  • mask
  • field
  • audio
  • regions
  • sound
  • images
  • masks
  • fps
  • audio
  • frame_count
  • report
  • depth
◄presetwarped noise►
◄code►
◄controls►
◄width0►
◄height0►
◄fps25.00►
◄seconds0.0►
◄speed1.00►
◄loops1►
◄looptrue►
◄time_offset0.0►
◄loop_fade1.0►
◄mask_fromauto►
◄cliptrue►
◄bpm0.0►
◄gain1.00►
◄release0.15►
◄unconnectedauto►
◄vector►
◄on_picturescreen►
◄picture_amount1.00►
◄only►

Here's the thing nobody tells you when you start a projection-mapping project: half of what ends up on the wall isn't AI at all. Patterns, light, masks, grids, a band running over the windows, tape artefacts, a wire mesh of the building. You can generate those with a diffusion model - people do, at a minute a frame, different every time, which for a looping install is a nuisance. Or you can draw them with a shader: instant, deterministic, loops perfectly, no model to load.

kubakub shader is the second option, built into the pack. Pick one of 74 presets sorted by type, adjust it with sliders, or paste a shader from shadertoy.com and use that. It gives you one picture per frame on images, the same as a mask on masks, and - when the preset is a 3D scene - a depth pass on depth.

How it runs, and why there's nothing to install

These are GLSL ES 3.00 fragment shaders executed on ComfyUI's own GL context - the same ANGLE-based one that ComfyUI's core GLSL node uses (comfy_extras/nodes_glsl.py). That's the whole reason a pack with a GPU shader engine adds exactly one package to your install (OpenCV), and why the node can say "no AI model" honestly. The context is the pack's own, because core's lives on the thread that ran it, and GL is imported on the first render only.

Each frame gets the usual uniforms plus the pack's own: iTime driven by speed, kLoop (a 0→1 phase, run loops times across the clip) which is what the presets actually animate on, the sound as kLevel, kLow, kMid, kHigh, kBeat and kBeats, the field and mask, your regions, and up to four pictures as iChannel0–iChannel3. If you paste code, anything declared as uniform float name; // default min max becomes a control - you set values in the controls field as scale = 5, warp = 2 and the report tells you what names and ranges exist. You don't have to read the shader to use it.

The presets are plain .glsl files in the repo, sorted by type: patterns, raymarched 3D scenes (melting forms, a colonnade, the facade as a relief), looks that work on your regions (each window its own colour, pace or pattern), picture looks, screen and tape (VHS, composite video, 8-bit), grade and lens, picture-with-depth effects, and overlays that run over time. There's a button under preset that shows them as moving pictures, which is the only sane way to shop in a list of 74.

Inputs you'll actually set

preset and code are alternatives: the preset is used while code is empty, so pasting code overrides it. controls is where you dial the preset in. width and height at 0 mean "the size of the first connected picture or mask, else 1280×720". fps, seconds and speed define the clip - note the split: presets run on loops, speed moves iTime, and setting speed to 0 gives you a still.

Then the interesting connections. image0 is your picture (a batch plays as a clip, one per frame): presets designed to work on a picture redraw it, everything else gets laid over it according to on_picture and picture_amount. mask is where the shader shows - kMask(uv) in the shader, and with clip on it also cuts the pictures black outside. field is a grey ramp from kubakub mask field, the path a band runs along. audio is what it hears, and connecting a sound makes a preset with a sound or beat control jump to 1 unless you type a value. regions with only is how the "on your regions" presets get their windows. mask_from decides whether masks is the shader's alpha or its brightness - worth remembering, since a pasted Shadertoy has no alpha (it writes none on shadertoy.com either), so brightness it is.

Outputs: images, masks, fps, audio (cut to the frames), frame_count, depth (from the 3D presets, near = white; one black frame from shaders that write none), and report.

Install and paste

Pack install is the usual:

cd ComfyUI/custom_nodes
git clone https://github.com/kubakubkub/ComfyUI_KubaNodes
python -m pip install -r ComfyUI_KubaNodes/requirements.txt

Restart; ComfyUI 0.37.0+ required, since the pack is written against the newer V3 node API - the comfyui-ecosystem doc explains that, and it's why you'll find no NODE_CLASS_MAPPINGS in a modern pack like this one. If ComfyUI's own GLSL node doesn't run on your machine, this node won't either; that's the shared dependency. The workflow shader.json runs with nothing connected.

Pasting a Shadertoy: open it, click into the code, Ctrl+A, Ctrl+C, paste into code, queue. If there's a Common tab, paste that first and Image below it. Buffer-tab shaders (Buffer A–D) work too if you paste each tab under a line naming it, and the node assumes the usual iChannel0 = Buffer A wiring unless you say otherwise on that line. It won't download links, and it says so.

Where it bites

The node is honest about what can't work: cubemaps, 3D textures, sound shaders, keyboard, webcam, and iMouse (which reads as never pressed). It also refuses the surprises rather than throwing a graphics error. What it can't fix is RAM: 250 frames at 3840×2160 is about 33 GB, and the node will refuse a clip that doesn't fit and tell you what it needs - 3D presets take roughly twice that. On a 5070 Ti a simple preset is around 14 ms a frame at 1080p, warped noise about 32 ms, and a raymarched 3D preset around 100 ms at 1080p, so the shader is rarely the bottleneck; copying frames in and out is. And keep loops in mind: if your clip seems to move at a weird pace, that's the control doing the moving, not speed.

Categorykubakub/2d/shader

Inputs (31)

NameTypeDefaultDescription
presetCOMBOwarped noiseA built-in shader. Used while 'code' is empty. The list is sorted by type: my presets, patterns, 3d scenes, on your regions, picture looks, screen and tape, grade and lens, picture with depth, over time. The button under it shows them as moving pictures. The report lists its controls.
codeSTRINGA shader from shadertoy.com instead of the preset. On its page click into the code, press Ctrl+A, then Ctrl+C, and paste here; a 'Common' tab goes first, the 'Image' tab below it. You do not need to read the code: the node says in plain words what a shader needs and what cannot work (buffer tabs, cubemaps, sound shaders). A complete GLSL ES 3.00 fragment shader works too.
controlsSTRINGValues for the shader's controls, e.g. 'scale = 5, warp = 2' (commas or lines). Empty = the defaults. The report lists every control with its range.
widthINT00–163840 = the size of the first connected picture or mask, else 1280.
heightINT00–163840 = the size of the first connected picture or mask, else 720.
fpsFLOAT25.001–120Frames per second.
secondsFLOAT0.00–3600Length. 0 = the length of the sound, else of the longest picture or mask batch, else 4 s.
speedFLOAT1.00-100–100How fast the shader's clock (iTime) runs. 0 = a still, negative = backwards. The presets run on the loop, not on the clock: their pace is 'loops'.
loopsINT11–1000How many times the presets run through within the clip (kLoop in a shader goes 0 to 1 that often). More = faster.
loopBOOLEANtrueThe last frame meets the first. The presets loop by themselves; a pasted shader is rendered a little longer and its end is faded into its start.
image0optIMAGEYour picture. A batch plays as a clip, one picture per frame. The presets that work on a picture redraw it; every other shader is laid over it (on_picture). iChannel0 in the shader; one that reads it with nothing connected gets the sample facade.
image1optIMAGEiChannel1 (e.g. a normal pass for the glass preset).
image2optIMAGEiChannel2.
image3optIMAGEiChannel3.
maskoptMASKWhere the shader shows: kMask(uv) in the shader, and with 'clip' the pictures and masks are cut to it. A batch plays one mask per frame (e.g. from kubakub mask animate).
fieldoptMASKA grey ramp from kubakub mask field: kField(uv) in the shader, the path a band runs along. Empty = a left to right ramp.
audiooptAUDIOWhat the shader hears: kLevel, kLow, kMid, kHigh (0-1), kBeat (1 on a beat, then falling), kBeats (a count). Passed on to 'audio'. Connecting a sound makes a preset follow it: its 'sound' or 'beat' control goes to 1 unless you type a value. A shader that listens without a sound runs on a built-in beat (120 bpm).
time_offsetoptFLOAT0.0-36000–36000The shader's clock at the first frame, in seconds.
loop_fadeoptFLOAT1.00–60loop: seconds over which the end fades into the start. 0 = no fade (for shaders that loop by themselves).
mask_fromoptCOMBOautoWhat 'masks' is made of: the shader's alpha, or how bright the picture is. auto = alpha when the shader writes one, else brightness. A Shadertoy (mainImage) has no alpha, as on shadertoy.com: only a plain fragment shader (void main) can write one.
clipoptBOOLEANtrueWith a mask connected: pictures and masks are black outside it.
bpmoptFLOAT0.00–400A tempo you know. 0 = found in the sound.
gainoptFLOAT1.000–10How loud the shader hears the sound.
releaseoptFLOAT0.150–5Seconds a sound level takes to fall after a peak.
unconnectedoptCOMBOautoWhat a shader reads on image0 - image3 when nothing is connected there. auto = the built-in noise for your own code (most Shadertoys expect a noise picture), the sample facade for a preset.
vectoroptSTRINGAn arrow for the shader to follow: draw it on the node (drag on the picture under 'draw the direction'), or type x, y of its start and x, y of its end, each 0 to 1 of the picture. Presets that run along the field (scan band, region contours ...) run from its start to its end when no field is connected; stripes, rain and pixel smear take its direction; rings, ripples and radar start at its start. Your own code reads kFrom, kTo, kDir and kVector. Empty = none.
on_pictureoptCOMBOscreenA picture on image0 and a shader that does not read it (the patterns, the 3d scenes, most pasted code): how the shader is laid over your picture. screen and add = its light on top; multiply = the shader as the light that falls on the picture (dark where the shader is dark); overlay = stronger contrast; difference = inverted where it is bright; displace = its light and dark bend the picture like glass; off = the shader alone (the picture only sets the size). With a mask the picture stays as it is outside it. 'masks' and 'depth' stay those of the shader. Presets that read the picture (picture looks, screen and tape, picture with depth) do not use this.
picture_amountoptFLOAT1.000–1on_picture: how much of the shader is laid over the picture. 0 = the picture alone.
regionsoptKUBA_REGIONSYour regions (from kubakub regions from masks, from illustrator, from id maps ...). The presets 'on your regions' treat every region on its own: its own colour, its own pace, a pattern that fits its box. Every other shader shows on the regions only (they are its mask when no mask is connected) and runs from each region's edge to its middle when it follows a field and none is connected. Your own code reads kRegion, kRegionUV, kRegionEdge, kRegionRand and kRegions. With image0 connected too, the picture stays as it is outside the regions: that picture is a material for kubakub region sampler ('material') and kubakub region video sampler.
onlyoptSTRINGWith regions connected: the shader draws in these regions only. Empty = all regions. For another shader on other regions, put a second kubakub shader behind this one (its images into image0 of the next). Written as in kubakub region plan: names with wildcards ('W_F1_*'), 'group:Windows', 'tag:front', 'region:3-7'; comma = or, space = and, '!' = not.
soundoptKUBA_SOUNDFrom kubakub sound: the sound and how it is heard (tempo, gain, release, band, threshold, gap), set once for every node that listens, so all of them step on the same beat. Connected, it comes before 'audio' and before this node's own sound settings.

Outputs (7)

NameTypeDescription
imagesIMAGEOne picture per frame.
masksMASKOne mask per frame: the shader's alpha or its brightness (mask_from).
fpsFLOATFrames per second.
audioAUDIOThe sound, cut to the frames (silence without one).
frame_countINTHow many frames.
reportSTRINGSize, length, what the shader uses, its controls and their values.
depthIMAGEHow near each pixel is, grey, near = white: from a shader that is a 3D scene (the presets melting forms, colonnade, facade relief, extrude, growth; your own code writes kDepth). For the depth presets on image1 of another kubakub shader, kubakub height animate or a depth ControlNet. One black picture from a shader that writes none.