The GLSL Shader node lets you write custom fragment shaders in GLSL ES 3.00 (WebGL 2.0 compatible) to process images directly on the GPU. You can create image effects like blurs, color grading, film grain, glow, and much more - all running at GPU speed.Documentation Index
Fetch the complete documentation index at: https://docs.comfy.org/llms.txt
Use this file to discover all available pages before exploring further.
The GLSL Shader node is currently marked as experimental, so the node may be updated and extended in future releases.
Minimal Shader
The simplest possible shader - a passthrough that outputs the input image unchanged:Why GLSL ES 3.00? Shaders need to run in two environments: the browser (via WebGL 2.0, which only supports GLSL ES 3.00) for live preview in the ComfyUI frontend, and the Python backend (via desktop OpenGL) when the workflow executes. GLSL ES 3.00 is the common denominator that works in both places.
Available Uniforms
These uniforms are automatically set by ComfyUI. You don’t need to declare all of them - only declare the ones you use.Images
| Uniform | Type | Description |
|---|---|---|
u_image0 – u_image4 | sampler2D | Input images (up to 5). Sampled with texture(u_image0, v_texCoord). Images are RGBA float textures with linear filtering and clamp-to-edge wrapping. |
Floats
| Uniform | Type | Description |
|---|---|---|
u_float0 – u_float19 | float | Up to 20 user-controlled float values. Mapped from the floats input group on the node. |
Integers
| Uniform | Type | Description |
|---|---|---|
u_int0 – u_int19 | int | Up to 20 user-controlled integer values. Mapped from the ints input group on the node. |
Using int uniforms as dropdowns: Int uniforms pair well with the Custom Combo node’s index output - users pick an option from a dropdown and the shader receives the selected item’s index.
Booleans
| Uniform | Type | Description |
|---|---|---|
u_bool0 – u_bool9 | bool | Up to 10 user-controlled boolean values. Mapped from the bools input group on the node. |
Curves (1D LUTs)
| Uniform | Type | Description |
|---|---|---|
u_curve0 – u_curve3 | sampler2D | Up to 4 user-editable curve LUTs from the curves input group. Each curve is a 1D lookup table stored as a single-row texture. |
Using curve uniforms: Curves let users draw arbitrary tone-mapping graphs in the UI (e.g. for contrast, gamma, per-channel grading, or any custom Common uses: master RGB curves, per-channel R/G/B curves, luminance-driven remaps, custom gamma, and any effect where you want the user to shape a response curve visually.
input → output remap). Sample the curve using your input value as the X coordinate - remember to clamp it to [0, 1] first:Resolution
| Uniform | Type | Description |
|---|---|---|
u_resolution | vec2 | Output framebuffer dimensions in pixels (width, height). This is the size you’re writing to, which may differ from any input image’s size when size_mode is "custom". |
Computing texel size for sampling: Don’t use Use
1.0 / u_resolution to step one pixel in an input texture. u_resolution is the output size, which may not match the input’s size. Instead use textureSize() on the actual texture you’re sampling:u_resolution only when you need the output framebuffer dimensions themselves (e.g. computing gl_FragCoord.xy / u_resolution to get screen-space UVs).Multi-Pass
| Uniform | Type | Description |
|---|---|---|
u_pass | int | Current pass index (0-based). Only meaningful when using #pragma passes - see Multi-Pass Ping-Pong Rendering for details. |
Vertex Shader Output
| Varying | Type | Description |
|---|---|---|
v_texCoord | vec2 | Texture coordinates ranging from (0,0) at bottom-left to (1,1) at top-right. |
Multiple Outputs (MRT)
The node supports up to 4 simultaneous outputs using Multiple Render Targets. Declare additional outputs with explicit locations:fragColor maps to the corresponding IMAGE output on the node. ComfyUI auto-detects which outputs you use - unused outputs will be black.
Multi-Pass Ping-Pong Rendering
Some effects (like separable blur) need multiple passes over the image. Use the#pragma passes N directive to enable this:
How ping-pong works
- Pass 0: Reads from the original
u_image0input, writes to an internal ping-pong texture. - Pass 1–N: Reads from the previous pass output via
u_image0(the binding is swapped automatically), writes to the other ping-pong texture. - Final pass: Writes to the actual output framebuffer (
fragColor0).
When using multi-pass with MRT (multiple outputs), only the first output (
fragColor0) participates in ping-pong. The final pass writes all outputs.Examples
Grayscale Conversion
Image Blending
Blend two input images using a float parameter as the mix factor:Using an LLM to Generate Shaders
You can use any LLM (Claude, ChatGPT, etc.) to write GLSL shaders for you. Copy the following prompt and fill in your desired effect:Example prompt fill-in
Effect I want: A chromatic aberration effect that splits RGB channels outward from the center of the image. u_float0 controls the strength of the offset (0 = no effect, 10 = extremely strong). The offset should scale with distance from the center.