CreativeCode Channels
Feed your shader real images — iChannel0–3, Shadertoy style
- iChannel0
- iChannel1
- iChannel2
- iChannel3
- channels
Pure procedural math gets old fast. Sooner or later you want a shader that reads something - your generated image, a texture, a previous render - and distorts, recolors, or composites it in real time. CreativeCode Channels is the door for that: it takes up to four images and hands them to your shader as textures, exactly the way Shadertoy's iChannel0–3 inputs work. In the launch thread the author's answer to "does it take an input image into consideration?" was a link straight to this node. That's its whole reason to exist.
What it does
The node is a thin "pack" node, not a renderer. It bundles up to four IMAGE inputs (iChannel0 through iChannel3) plus two texture-sampling settings into a single CC_CHANNELS object, which you wire into the channels input of a CreativeCodeRender (Code2Vid) node. The render node then uploads those images as GPU textures before each render pass, and your shader samples them with the standard Shadertoy vocabulary:
vec4 tex = texture(iChannel0, uv);
fragColor = tex;
In p5.js they arrive as p5.Image objects: image(iChannel0, 0, 0);. Because the plumbing mirrors Shadertoy's own channel convention, a lot of Shadertoy code that uses input textures genuinely does work copy-paste - which is exactly what this pack is aiming for.
The inputs that matter
iChannel0–iChannel3- four image slots, wired from anything that outputsIMAGE. Load a texture with a LoadImage node, or pipe in the output of a latent decode or another render. You can chain these: render one shader, feed its frames into the next via a Channels node, and build a multi-pass effect without ever leaving the graph.texture_wrap-repeat(default),clamp, ormirror. This decides what happens at the edges of the texture.repeatis right for tiling patterns;clampis what you want for photos you don't want seaming across the UV range.texture_filter-linear(default, smooth) ornearest(crisp). Choosenearestwhen you're sampling pixel art or anything where you want hard edges, not blurry interpolation.
Only connect what you actually sample in the shader. A shader reading an unconnected channel is sampling an unbound texture, and the result is undefined - wire the slots your code uses and leave the rest empty.
The honest gotchas
This node does nothing by itself. It has no preview, no output image - just the channels socket, and if you don't wire that into a Code2Vid node, the node sits there doing absolutely nothing. That's not a bug; it's a data-carrying node.
And remember the four-channel ceiling is a Shadertoy convention, not a suggestion. If your effect needs more than four source textures, you'll need to bake them into a single image first (texture atlas), because the pack's GLSL interface stops at iChannel3.
Install
Same as the rest of the pack:
cd ComfyUI/custom_nodes
git clone https://github.com/SKBv0/ComfyUI_CreativeCode.git
pip install -r ComfyUI_CreativeCode/requirements.txt
Restart ComfyUI, then find CreativeCode Channels under the CreativeCode category. No models to download; the only real dependency is moderngl for the GLSL backend.
For how small and simple it is, this node quietly unlocks most of the pack's interesting workflows - image-in-shader effects, texture-driven animation, chained multi-pass renders. If you're hitting the limits of pure math, wire a texture in.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| iChannel0opt | IMAGE | — | |
| iChannel1opt | IMAGE | — | |
| iChannel2opt | IMAGE | — | |
| iChannel3opt | IMAGE | — | |
| texture_wrapopt | COMBO | repeat | 3 options: repeat, clamp, mirror |
| texture_filteropt | COMBO | linear | 2 options: linear, nearest |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| channels | CC_CHANNELS | — |