BD GLSL Batch (iterate uniforms)
Run a GLSL shader N times with different uniforms — one compile, one pass
- u_image0
- u_image1
- u_image2
- u_image3
- u_image4
- fc0_batch
- fc1_batch
- fc2_batch
- fc3_batch
- iteration_names
- iteration_count
Say you've built a GLSL skin-tint shader and you want to see it under five different lighting uniforms - or generate every variant of a texture atlas in one go. The dumb way is to re-run the workflow five times, recompiling the shader each time. The smart way is BD_GLSLBatch: it runs the same shader N times with different uniform values inside a single node call, compiles the shader once, and stacks the outputs along the batch dimension.
This is the batch-oriented cousin of the pack's single-shot GLSL shader node (the one behind the GLSL Skin Tinting template, with its ILM / SR+Parts / Unity / Unreal output quads). Where that node gives you one pass, this one gives you a batch - perfect for iterating skin tones, LUT variants, or any uniform sweep you'd otherwise hammer the queue with.
How it works
You supply the shader as a GLSL ES 3.0 fragment source (or point fragment_shader_file at an absolute path to a .glsl file, which is great for editing externally - the node picks up the latest version on each execution). It binds up to five images (u_image0..u_image4) as samplers, plus base uniform values via the floats and ints fields, one per line: u_float0=0.48, u_int0=255.
The per-iteration variation lives in vary_floats and vary_ints, using the same syntax but with comma-separated lists:
u_float0=0.5,0.4,0.3,0.2
u_int3=255,240,160,140
Iteration count is auto-detected from the longest vary list. Uniforms not listed in a vary spec keep their base value every iteration; single-value lines act as constants. iterations_override forces a count if you want control, and width/height set output resolution (0 = take u_image0's size).
Outputs
- fc0_batch / fc1_batch / fc2_batch / fc3_batch - the four fragment-color outputs, each stacked into an IMAGE batch of
N_iterations. Thefcnaming matches the pack's GLSL convention (multiple render targets). - iteration_names - one name per iteration (from the
iteration_namesfield) for downstream filename use, newline-joined. - iteration_count - how many iterations actually ran.
iteration_names is the detail that makes this usable: name your iterations light\nmedium\ndark\nzombie, then feed the names batch into a save node's suffix logic so every batch frame gets a sensible filename.
Install
Part of the BrainDead pack:
cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt
Or search "BrainDead" in ComfyUI Manager and restart. This is one of the heavier corners of the pack to get running - it needs a working GPU shader runtime, so if the pack's GLSL nodes fail on your setup, the single-shot GLSL node is the first thing to test.
Troubleshooting
- Wrong iteration count - count your vary lists. The node takes the longest; a stray longer list silently changes N.
- Batch frames all look identical - a uniform you meant to vary isn't in a vary spec (or is a single-value line, which is constant by design).
- Shader file edits don't appear -
fragment_shader_fileonly overrides when the path exists; double-check it's absolute and on disk.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| fragment_shader | STRING | #version 300 es precision highp float; in vec2 v_texCoord; uniform sampler2D u_image0; layout(location=0) out vec4 fragColor0; void main(){ fragColor0 = texture(u_image0, v_texCoord); } | The fragment shader source code (GLSL ES 3.0). OVERRIDDEN by fragment_shader_file if that path is set and exists. |
| fragment_shader_file | STRING | Optional ABSOLUTE path to a .glsl file. When set and the file exists, its contents are used instead of the fragment_shader text field. Lets you edit the shader externally and have BD_GLSLBatch pick up the latest version on each workflow execution. Example: /path/to/shaders/skin_shader.glsl | |
| floats | STRING | Base float uniform values, one per line: u_float0=0.48 u_float1=0.5 Indexes 0..19. Missing slots default to 0.0. | |
| ints | STRING | Base int uniform values, one per line: u_int0=255 u_int1=128 Indexes 0..12. Missing slots default to 0. | |
| vary_ints | STRING | Per-iteration int overrides. One uniform per line: u_int3=255,240,160,140 u_int4=255,190,110,190 Iteration count = longest list. Single-value lines are constants. | |
| vary_floats | STRING | Per-iteration float overrides. Same format as vary_ints. | |
| iteration_names | STRING | One name per iteration for downstream filename use: light medium dark zombie Defaults to '1', '2', '3', ... if empty. | |
| u_image0opt | IMAGE | Bound to sampler2D u_image0. | |
| u_image1opt | IMAGE | Bound to sampler2D u_image1. | |
| u_image2opt | IMAGE | Bound to sampler2D u_image2. | |
| u_image3opt | IMAGE | Bound to sampler2D u_image3. | |
| u_image4opt | IMAGE | Bound to sampler2D u_image4. | |
| iterations_overrideopt | INT | 00–128 | If > 0, force this iteration count. 0 = auto-detect from vary specs. |
| widthopt | INT | 00–8192 | Output width. 0 = use u_image0's width. |
| heightopt | INT | 00–8192 | Output height. 0 = use u_image0's height. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| fc0_batch | IMAGE | Stacked IMAGE batch (B=N_iterations) of fc0 outputs. |
| fc1_batch | IMAGE | — |
| fc2_batch | IMAGE | — |
| fc3_batch | IMAGE | — |
| iteration_names | STRING | Newline-joined iteration names, in order. |
| iteration_count | INT | — |