I drawing a set of quads. For each quad I have a defined color in a vertex of it.
E.g. now my set of quads looks like:
My guess is there will be issues with the hue colours you're using and vertex interpolation (e.g. skipping some bands). Instead, maybe pass in a single channel value and calculate the hue and discrete levels (as @vesan does) within the fragment shader. I use these functions myself...
vec3 hueToRGB(float h)
{
h = fract(h) * 6.0;
vec3 rgb;
rgb.r = clamp(abs(3.0 - h)-1.0, 0.0, 1.0);
rgb.g = clamp(2.0 - abs(2.0 - h), 0.0, 1.0);
rgb.b = clamp(2.0 - abs(4.0 - h), 0.0, 1.0);
return rgb;
}
vec3 heat(float x)
{
return hueToRGB(2.0/3.0-(2.0/3.0)*clamp(x,0.0,1.0));
}
and then
float discrete = floor(pass_Value * steps + 0.5) / steps; //0.5 to round
out_Color = vec4(heat(discrete), 1.0);
where in float in_Value
is 0 to 1.
Just expanding on Nico Schertler's comment: you can modify your fragment shader to:
void main(void) {
out_Color = vec4(pass_Color, 1.0);
out_Color = floor(color * steps)/steps;
}
where steps
in the number of color steps you want. The floor
function will indeed work on a vector, however, the steps will be calculated separately for every color, so the result might not be exactly what you want (the steps might not be as nice as in your example).
Alternatively, you can use some form of "toon shading" (see for example here). That means that you only pass a single number (think a color in grayscale) to your shader, then use your shader to select a color from a color table. The table can either be hardcoded in the shader or selected from a 1-dimensional texture.