Hi there,
I am working on a GLSL shader where I map vertex values to a color palette based on a specified min/max range.
ghsl_colorlist.gh (14.1 KB)
As shown in the image below:
- Top version: I hardcoded the color values directly into the shader, and the output works exactly as expected.
// Fragment
#version 330
// --- Inputs from Vertex Shader ---
in float v_normalized;
// --- Output ---
out vec4 fragment_color;
void main() {
// 1. Hardcoded Color Palette (Your 10 CFD colors)
// We define these locally to ensure they always work regardless of external input.
vec3 colors[10];
colors[0] = vec3(75.0, 107.0, 169.0) / 255.0; // Blueish
colors[1] = vec3(115.0, 147.0, 202.0) / 255.0;
colors[2] = vec3(170.0, 200.0, 247.0) / 255.0;
colors[3] = vec3(193.0, 213.0, 208.0) / 255.0;
colors[4] = vec3(245.0, 239.0, 103.0) / 255.0;
colors[5] = vec3(252.0, 230.0, 74.0) / 255.0; // Yellowish
colors[6] = vec3(239.0, 156.0, 21.0) / 255.0;
colors[7] = vec3(234.0, 123.0, 0.0) / 255.0;
colors[8] = vec3(234.0, 74.0, 0.0) / 255.0;
colors[9] = vec3(234.0, 38.0, 0.0) / 255.0; // Reddish
// 2. Mapping Logic
// With 10 colors, there are exactly 9 segments to interpolate between.
float seg = v_normalized * 9.0;
// Find the two nearest color indices
int i1 = int(floor(seg));
int i2 = int(ceil(seg));
// Clamp indices to stay within array bounds [0, 9]
i1 = clamp(i1, 0, 9);
i2 = clamp(i2, 0, 9);
// 3. Linear Interpolation (Lerp)
// fract(seg) gives the fractional part (0.0 to 1.0) between the two indices
vec3 finalRGB = mix(colors[i1], colors[i2], fract(seg));
// 4. Final Output (Opaque color)
fragment_color = vec4(finalRGB, 1.0);
}
- Bottom version: I attempted to use an input
uniform vec3 color_list[]to pass the same colors, but the result is completely black.
// Fragment
#version 330
// --- Color Inputs from Grasshopper ---
// We define a fixed size array. Ensure your input list has 10 colors.
uniform vec3 color_list[10];
uniform int color_count;
// --- Data Inputs from Vertex Shader ---
in float v_normalized;
// --- Output ---
out vec4 fragment_color;
void main() {
vec3 final_rgb = vec3(0.0);
// 1. Safety Check: Ensure we have colors to work with
if (color_count > 1) {
// Calculate the position within the 9 segments (for 10 colors)
float seg = v_normalized * float(color_count - 1);
int i1 = int(floor(seg));
// 2. Robust Array Access
// Using a constant-length loop is the most compatible way to access
// uniform arrays in many GLSL environments.
for(int i = 0; i < 10; i++) {
if(i == i1) {
vec3 c1 = color_list[i];
vec3 c2 = color_list[min(i + 1, color_count - 1)];
// 3. Range Correction
// If Grasshopper sends 0-255, we convert to 0.0-1.0
if (max(c1.r, max(c1.g, c1.b)) > 1.0) c1 /= 255.0;
if (max(c2.r, max(c2.g, c2.b)) > 1.0) c2 /= 255.0;
// 4. Linear Interpolation between the two colors
final_rgb = mix(c1, c2, fract(seg));
break;
}
}
} else if (color_count == 1) {
final_rgb = color_list[0];
if (max(final_rgb.r, max(final_rgb.g, final_rgb.b)) > 1.0) final_rgb /= 255.0;
}
// 5. Final Fragment Output
fragment_color = vec4(final_rgb, 1.0);
}
Could anyone point out what I might be doing wrong or how to properly bind the color list? Any guidance would be greatly appreciated.
Thanks in advance!




