Nodes/kubakub nodes/kubakub shader mix
ComfyUI Node

kubakub shader mix

Two moving pictures and one number between them

By kubakubkub·Created 19 days ago·Updated about 18 hours ago· 10
kubakub shader mix
  • image
  • audio
  • a
  • b
  • sound
  • images
  • masks
  • fps
  • audio
  • frame_count
  • report
◄shader_aplasma►
◄shader_beight bit►
◄howa cuts b►
◄mix0.50►
◄curveconstant►
◄cycle2.00►
◄width1280►
◄height720►
◄fps25.00►
◄seconds4.00►
◄loops1►
◄controls_a►
◄controls_b►
◄code_a►
◄code_b►
◄mix_from0.00►
◄strength0.15►
◄soft0.10►

Two shader clips, one dial, and a way of joining them that isn't a crossfade. That's kubakub shader mix - and it earns its own node because a plain dissolve between two GPU-drawn patterns is the boring version. Here you get wipes shaped by the picture itself, and a melt where one clip pushes the other's pixels around.

It takes any two pictures or clips on a and b. In the pack's own workflow they're the images output of two kubakub shader nodes, which is the intended use: the mix node knows nothing about controls, size or length - everything about each shader is set on its own node, and this one only decides how they meet.

The three ways they meet

mix runs 0 to 1, where 0 is A and 1 is B. how decides what happens in between:

  • a cuts b: B appears first where A is bright and takes over from there - a wipe in the shape of A's pattern, not a straight line. soft sets how soft that edge is. This is the one that looks like it was designed rather than keyframed.
  • a bends b: A's picture pushes B's places around - red sideways, green up and down in the pattern's own channels - strongest half way through, so B melts out of A. strength sets how far it pushes, as a part of the picture's height.
  • blend: a plain fade. Useful, unexciting, occasionally exactly right.
  • b works on a: B treated as an effect on A's picture. Only when B is one of this node's own presets, which is the honest limitation of that mode.

Which brings up the shortcut worth knowing: if you want one shader to be the effect on another, you don't need this node at all. Connect shader A's images into image0 of shader B and B redraws A. Use the mix node when you want the transition between two clips, and the cable when you want a stack.

Timing: the curve is the point

curve runs mix over time: constant holds it at whatever mix is, ramp goes from A to B once, saw, triangle, sine and square repeat, and sound level / beats / bars / hits ride audio. cycle is the length of one run (and for beats and hits, the length of each one's ramp), mix_from is the value at the low end with mix as the high end.

Two practical notes from the docs. Connect shader A's fps output to this node's fps, or the curve runs at whatever pace the node assumed rather than the clip's. And A sets the size and the length: B is resized to A, and a shorter B plays again from its start, so if you cut on a beat you can't see, check the two clips aren't different lengths.

Running it with nothing connected

Unhook a and b and the node draws two of its own presets instead - shader_a defaulting to plasma, shader_b to eight bit, with controls_a, controls_b, code_a and code_b for each side, plus width, height, seconds and loops. Those side-specific fields appear when that input has nothing on it and hide once a cable arrives, which is a neat bit of UI. In that mode image supplies a picture for presets that need one (a preset that must have a picture falls back to the sample facade, and B takes A's picture), and how gains the b works on a option. audio feeds both the curve and any shader that listens, and a kubakub sound on sound takes precedence over the node's own audio and its own sound settings.

Outputs are the usual pack shape: images (one per frame), masks (one per frame, from brightness), fps, audio cut to the frames, frame_count, and report - which lists the size, the length, both shaders and their controls, and how the mix is running. When a mix looks wrong, the report is faster than guessing.

Install

Same pack, same one-liner:

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 or newer (the pack is written against the V3 node API - the comfyui-ecosystem write-up covers why a modern pack can ship with no NODE_CLASS_MAPPINGS at all and still be perfectly healthy). Or install from ComfyUI Manager, search kubakub nodes. No models, no extra packages: the shaders run on the GL context ComfyUI already ships. shader_mix.json runs standalone, since nothing connected means two built-in presets.

Three traps

A shader with Buffer tabs (simulations that read their own previous frame) does not run as a preset of this node - the docs say so outright. Render it with the shader node and connect its images to a instead. Second, strength and soft are doing very different jobs and people reach for the wrong one: strength is the bend's reach in a-bends-b, soft is the wipe's edge in a-cuts-b, and neither does anything in blend. Third, if the transition looks like it's happening too early or too late, it's almost always the fps cable, not the curve.

Categorykubakub/2d/shader

Inputs (23)

NameTypeDefaultDescription
shader_aCOMBOplasmaNothing connected to 'a': this preset is A.
shader_bCOMBOeight bitNothing connected to 'b': this preset is B.
howCOMBOa cuts bHow they meet between 0 and 1. a cuts b: B shows first where A is bright, a wipe in the shape of A's pattern. a bends b: A's picture pushes B's places around, B melts out of A. blend: a plain fade. b works on a: B is an effect on A; for two kubakub shaders do that with a cable instead (A's images into image0 of shader B), here it works when B is the preset of this node.
mixFLOAT0.500–10 = shader A, 1 = shader B. With a curve: the value the curve reaches.
curveCOMBOconstantHow the mix runs over time. constant = stays at 'mix'. ramp: from A to B once. saw / triangle / sine / square: again and again. sound level, beats, bars, hits: with the sound on 'audio'.
cycleFLOAT2.000.02–3600curve: seconds for one run (beats and hits: how long each one's ramp is).
widthINT12800–8192Nothing on 'a' / 'b': the width. 0 = the image's width. A connected clip sets the size.
heightINT7200–8192Nothing on 'a' / 'b': the height. 0 = the image's height.
fpsFLOAT25.001–120Frames per second: connect the fps of the kubakub shader on 'a', so the curve runs at the clip's pace.
secondsFLOAT4.000–3600Nothing on 'a' / 'b' (or two stills): how long. 0 = as long as the sound, else the clip on 'image', else 4 s. A connected clip sets the length.
loopsINT11–1000The presets of this node: how many times they run through.
imageoptIMAGEFor the presets of this node (nothing on 'a' / 'b'): a picture or a clip they work on (their image0). Without one, a preset that needs a picture takes the sample facade, and B takes A's picture.
audiooptAUDIOA sound for the curve (sound level, beats ...) and for shaders that listen. Passed on to 'audio'.
controls_aoptSTRINGPreset A's controls as 'name = number', commas or lines. The report lists them.
controls_boptSTRINGPreset B's controls.
code_aoptSTRINGShader A as pasted code (a Shadertoy or a GLSL fragment shader) instead of the preset.
code_boptSTRINGShader B as pasted code instead of the preset.
mix_fromoptFLOAT0.000–1curve: the mix at its low end ('mix' is its high end).
strengthoptFLOAT0.150–1a bends b: how far A pushes B half way through, as a part of the picture's height.
softoptFLOAT0.100–1a cuts b: how soft the edge of the wipe is.
aoptIMAGEA: what you see at mix = 0. The images of a kubakub shader (or any picture or clip). It sets the size and the length.
boptIMAGEB: what you see at mix = 1. The images of another kubakub shader. Another size is resized to A's, a shorter clip plays again from its start.
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 (6)

NameTypeDescription
imagesIMAGEOne picture per frame.
masksMASKOne mask per frame: how bright the picture is.
fpsFLOATFrames per second.
audioAUDIOThe sound, cut to the frames (silence without one).
frame_countINTHow many frames.
reportSTRINGSize, length, the two shaders and their controls, how the mix runs.