I am rendering a quad with up to 4 different vertex colours.
My vertex shader is super simple:
#version 330
layout(location=0) in vec2 inVertexPosition;
layout(location=1) in vec4 inColor;
out vec4 color;
void main()
{
gl_Position = vec4(inVertexPosition.x,-inVertexPosition.y, 0.0, 1.0);
color = inColor;
}
The fragment shader:
#version 330
layout(location=0) out vec4 frag_colour;
in vec4 color;
void main()
{
frag_colour = color;
}
also super simple. The results are a smooth gradient from corner to corner. However, I would like to produce an effect similar to the background of the text in this image:
where there is a limited palette so there's intentional banding in the gradient. My attempt to create this same style is a combination of Gradient with fixed number of levels and From RGB to HSV in OpenGL GLSL which has given me a fragment shader like this:
#version 330
layout(location=0) out vec4 frag_colour;
in vec4 color;
uniform bool uBand = false;
uniform float uBandingSteps;
vec3 rgb2hsv(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
void main()
{
if(uBand)
{
vec3 hsv = rgb2hsv(color.rgb);
float h = floor(hsv.x * (uBandingSteps*3+1) + 0.5) / (uBandingSteps*3+1);
float s = floor(hsv.y * (uBandingSteps*3+1) + 0.5) / (uBandingSteps*3+1);
float v = floor(hsv.z * (uBandingSteps*3+1) + 0.5) / (uBandingSteps*3+1);
frag_colour = vec4(hsv2rgb(vec3(h,s,v)),color.a);
}
else
frag_colour = color;
}
This works to a degree, however, for some reason I need to multiply uBandingSteps
to generate the right number of colours. The above works "okay", but the problem is that the banding seems fairly arbitrary:
You can see that the banding doesn't give a bevelled sort of look, but instead the first colour is narrow, then large, then narrow, then large etc. Rather than being gradually larger until it gets to the middle colour that's the widest part of the gradient, and then steadily retreats.
How can I modify what I have in order to produce the intended effect? (sort of bevelled, smooth, stepped gradient).