Nodes/Jovi_GLSL/COLOR PALETTE (JOV_GL)
ComfyUI Node

COLOR PALETTE (JOV_GL)

Generate Inigo Quilez's cosine palettes as actual images in ComfyUI

By Amorano·Created 2 years ago·Updated about a year ago· 20
COLOR PALETTE (JOV_GL)
  • bias
  • amp
  • freq
  • phase
  • iRes
  • RGBA
  • RGB
  • MASK
FRAGMENT// The MIT License // https://www.youtube.com/c/InigoQuilez // https://iquilezles.org/ // Copyright © 2015 Inigo Quilez // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // See https://iquilezles.org/articles/palettes for more information // // name: COLOR PALETTE // desc: Color palette creation using the formula: color(t) = a + b * cos[tau(c*t+d)]. See https://iquilezles.org/articles/palettes for more information. // category: CREATE // control: res, #ifndef LIB_CONST #define LIB_CONST //------------------------------------------------------------------------------ // CONSTANT //------------------------------------------------------------------------------ #define M_EPSILON 1.0e-10 // zero value for float comparisons #define M_DEG2RAD 0.017453292519943 // Degree to radian conversion factor #define M_RAD2DEG 57.29577951308232 // Radian to degree conversion factor #define M_TAU 6.283185307179586 // TAU (2 * π) #define M_TAU_INV 0.159154943091895 // TAU Inverse (1 / TAU) #define M_PI 3.141592653589793 // π #define M_PI_INV 0.318309886183790 // π Inverse (1 / π) #define M_PI_2 1.570796326794896 // π divided by 2 (π / 2) #define M_PI_4 0.785398163397448 // π divided by 4 (π / 4) #define M_3PI_4 2.356194490192345 // 3 * π divided by 4 (3π / 4) #define M_PHI 1.618033988749895 // Golden ratio (φ) #define M_PHI_INV 0.618033988749895 // Inverse of golden ratio (1 / φ) #define M_PHI_SQ 2.618033988749895 // Square of the golden ratio (φ^2) #define M_PHI_SQRT5 0.723606797749979 // φ / √5 (useful for fibonacci spherical distribution) #define M_GOLD_ANG 2.399963229728653 // Golden angle in radians #define M_E 2.718281828459045 // Euler's number (base of natural logarithm) #define M_LOG2E 1.442695040888963 // Log base 2 of e #define M_LOG10E 0.434294481903252 // Log base 10 of e #define M_LN2 0.693147180559945 // Natural log of 2 #define M_LN10 2.302585092994046 // Natural log of 10 #define M_SQRT2 1.414213562373095 // Square root of 2 #define M_SQRT3 1.732050807568877 // Square root of 3 #define M_SQRT2_INV 0.707106781186547 // 1 divided by square root of 2 (1 / sqrt(2)) #define M_SQRT3_INV 0.577350269189626 // 1 divided by square root of 3 (1 / sqrt(3)) #define M_SQRT5 2.236067977499790 // Square root of 5 //------------------------------------------------------------------------------ // GENERAL //------------------------------------------------------------------------------ // useful for triangle interpolation vec3 barycentricCoords(vec2 p, vec2 a, vec2 b, vec2 c) { vec2 v0 = b - a; vec2 v1 = c - a; vec2 v2 = p - a; float d00 = dot(v0, v0); float d01 = dot(v0, v1); float d11 = dot(v1, v1); float d20 = dot(v2, v0); float d21 = dot(v2, v1); float denom = d00 * d11 - d01 * d01; vec3 result; result.y = (d11 * d20 - d01 * d21) / denom; result.z = (d00 * d21 - d01 * d20) / denom; result.x = 1.0 - result.y - result.z; return result; } #endif uniform vec3 bias; // 0.5,0.5,0.5;0 | scale and bias (dc offset) uniform vec3 amp; // 0.5,0.5,0.5 | contrast and brightness (amplitude) uniform vec3 freq; // 1,1,1 | color cycle (R, G and B) (frequency) uniform vec3 phase; // 0,0,0 | starting offset for the cycle void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; vec3 col = bias + amp * cos(M_PI * (freq * uv.x + phase)); fragColor = vec4(col, 1.0); }

If you've ever messed with shaders, you know the Inigo Quilez cosine palette trick - the a + b * cos(tau(c*t + d)) formula that turns a handful of numbers into an entire gradient of pleasing, coherent colors. It's everywhere in Shadertoy, and it's the rare bit of graphics math that's genuinely fun to play with. This node renders it as an actual image you can drop into a ComfyUI workflow, which means you can use a palette you "tuned by eye" as real input data instead of just staring at it in a demo.

How it works

The node takes the IQ palette formula and sweeps it across the X axis of the canvas. Each RGB channel gets its own four controls - bias (the DC offset, where the color centers), amp (amplitude, how far the channel swings), freq (how many times that channel cycles across the image), and phase (where the cycle starts) - so you're really composing three stacked cosine waves into one gradient.

There's no image input here. This is a generator: you feed it parameters, and it produces a 512×512 gradient image (the iRes VEC2INT input controls width/height). Like everything in Jovi_GLSL it's a fragment shader, so changing a value re-renders instantly on the GPU. You'll find it under JOVI_GLSL 🌈 → CREATE.

The inputs that matter

  • bias, amp, freq, phase - each a VEC3, one component per RGB channel. The defaults (bias 0.5, amp 0.5, freq 1, phase 0) give you the classic gray-blue cosine ramp. Start there, then nudge freq per channel to get colorful bands.
  • iRes - output resolution, default 512×512.

Outputs are the pack standard: RGBA, RGB, and MASK. The RGB/RGBA outputs are the ones you actually want - this thing's whole job is producing a color swatch image.

Install

Same as the rest of the pack, once. Via ComfyUI Manager, search Jovi_GLSL; or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/Amorano/Jovi_GLSL.git
cd Jovi_GLSL
pip install -r requirements.txt

Restart ComfyUI. The usual Jovi_GLSL dependencies apply - PyOpenGL, glfw, opencv-contrib-python, and cozy_comfyui from git - and it needs an OpenGL context to run. No models, no keys.

How to actually use it

The obvious move is generating a palette image and feeding it into an image-to-image or color-transfer workflow as a style reference. The sneakier one: because the palette is fully parameterized, you can treat bias/amp/freq/phase as your "mood dials" and batch-generate a set of candidate palettes, then pick the winner. It's also a nice sanity generator for shader debugging - if you know exactly what a given parameter set should look like, mismatches elsewhere in your pipeline become obvious fast. Don't expect the output to match the exact same formula in a tool with different normalization - but as a color playground in the graph, it's hard to beat.

CategoryJOV_GL 🌈/CREATE

Inputs (6)

NameTypeDefaultDescription
biasoptVEC30.5,0.5,0.5scale and bias (dc offset)
ampoptVEC30.5,0.5,0.5contrast and brightness (amplitude)
freqoptVEC31,1,1color cycle (R, G and B) (frequency)
phaseoptVEC30,0,0starting offset for the cycle
iResoptVEC2INT512,512Width and Height as a Vector2 Integer (x, y)
FRAGMENToptSTRING// The MIT License // https://www.youtube.com/c/InigoQuilez // https://iquilezles.org/ // Copyright © 2015 Inigo Quilez // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // See https://iquilezles.org/articles/palettes for more information // // name: COLOR PALETTE // desc: Color palette creation using the formula: color(t) = a + b * cos[tau(c*t+d)]. See https://iquilezles.org/articles/palettes for more information. // category: CREATE // control: res, #ifndef LIB_CONST #define LIB_CONST //------------------------------------------------------------------------------ // CONSTANT //------------------------------------------------------------------------------ #define M_EPSILON 1.0e-10 // zero value for float comparisons #define M_DEG2RAD 0.017453292519943 // Degree to radian conversion factor #define M_RAD2DEG 57.29577951308232 // Radian to degree conversion factor #define M_TAU 6.283185307179586 // TAU (2 * π) #define M_TAU_INV 0.159154943091895 // TAU Inverse (1 / TAU) #define M_PI 3.141592653589793 // π #define M_PI_INV 0.318309886183790 // π Inverse (1 / π) #define M_PI_2 1.570796326794896 // π divided by 2 (π / 2) #define M_PI_4 0.785398163397448 // π divided by 4 (π / 4) #define M_3PI_4 2.356194490192345 // 3 * π divided by 4 (3π / 4) #define M_PHI 1.618033988749895 // Golden ratio (φ) #define M_PHI_INV 0.618033988749895 // Inverse of golden ratio (1 / φ) #define M_PHI_SQ 2.618033988749895 // Square of the golden ratio (φ^2) #define M_PHI_SQRT5 0.723606797749979 // φ / √5 (useful for fibonacci spherical distribution) #define M_GOLD_ANG 2.399963229728653 // Golden angle in radians #define M_E 2.718281828459045 // Euler's number (base of natural logarithm) #define M_LOG2E 1.442695040888963 // Log base 2 of e #define M_LOG10E 0.434294481903252 // Log base 10 of e #define M_LN2 0.693147180559945 // Natural log of 2 #define M_LN10 2.302585092994046 // Natural log of 10 #define M_SQRT2 1.414213562373095 // Square root of 2 #define M_SQRT3 1.732050807568877 // Square root of 3 #define M_SQRT2_INV 0.707106781186547 // 1 divided by square root of 2 (1 / sqrt(2)) #define M_SQRT3_INV 0.577350269189626 // 1 divided by square root of 3 (1 / sqrt(3)) #define M_SQRT5 2.236067977499790 // Square root of 5 //------------------------------------------------------------------------------ // GENERAL //------------------------------------------------------------------------------ // useful for triangle interpolation vec3 barycentricCoords(vec2 p, vec2 a, vec2 b, vec2 c) { vec2 v0 = b - a; vec2 v1 = c - a; vec2 v2 = p - a; float d00 = dot(v0, v0); float d01 = dot(v0, v1); float d11 = dot(v1, v1); float d20 = dot(v2, v0); float d21 = dot(v2, v1); float denom = d00 * d11 - d01 * d01; vec3 result; result.y = (d11 * d20 - d01 * d21) / denom; result.z = (d00 * d21 - d01 * d20) / denom; result.x = 1.0 - result.y - result.z; return result; } #endif uniform vec3 bias; // 0.5,0.5,0.5;0 | scale and bias (dc offset) uniform vec3 amp; // 0.5,0.5,0.5 | contrast and brightness (amplitude) uniform vec3 freq; // 1,1,1 | color cycle (R, G and B) (frequency) uniform vec3 phase; // 0,0,0 | starting offset for the cycle void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; vec3 col = bias + amp * cos(M_PI * (freq * uv.x + phase)); fragColor = vec4(col, 1.0); }

Outputs (3)

NameTypeDescription
RGBAIMAGEFull channel [RGBA] image. If there is an alpha, the image will be masked out with it when using this output.
RGBIMAGEThree channel [RGB] image. There will be no alpha.
MASKMASKSingle channel mask output.