OpenGL badbuffer uses the RGB color space by default, which does not preserve explicit saturation. You need an approach to extract saturation, change it and change it.
My previous sentence, which simply used the length of an RGB vector to represent 0 in brightness, was incorrect, as it did not take scaling into account. I apologize.
The credit for the new short fragment goes to regular users "RTFM_FTW" from ## opengl and ## opengl3 to FreeNode / IRC, and it allows you to directly change the saturation without calculating the expensive conversion RGB-> HSV-> RGB, what exactly do you want. Although the HSV code is inferior in your question, I let it stay.
void main( void ) { vec3 R0 = texture2DRect( S, gl_TexCoord[0].st ).rgb; gl_FragColor = vec4( mix( vec3( dot( R0, vec3( 0.2125, 0.7154, 0.0721 ) ) ), R0, T ), gl_Color.a ); }
If you need more control than just saturation, you need to convert to HSL or HSV color space. As shown below, using the GLSL fragment shader.
Read the OpenGL 3.0 and GLSL 1.30 specifications available at http://www.opengl.org/registry to learn how to use GLSL v1.30 functionality.
#version 130 #define RED 0 #define GREEN 1 #define BLUE 2 in vec4 vertexIn; in vec4 colorIn; in vec2 tcoordIn; out vec4 pixel; Sampler2D tex; vec4 texel; const float epsilon = 1e-6; vec3 RGBtoHSV(vec3 color) { int sortindex[3] = {RED,GREEN,BLUE}; float rgbArr[3] = float[3](color.r, color.g, color.b); float hue, saturation, value, diff; float minCol, maxCol; int minIndex, maxIndex; if(color.g < color.r) swap(sortindex[0], sortindex[1]); if(color.b < color.g) swap(sortindex[1], sortindex[2]); if(color.r < color.b) swap(sortindex[2], sortindex[0]); minIndex = sortindex[0]; maxIndex = sortindex[2]; minCol = rgbArr[minIndex]; maxCol = rgbArr[maxIndex]; diff = maxCol - minCol; if( diff < epsilon){ hue = 0.0; } else if(maxIndex == RED){ hue = ((1.0/6.0) * ( (color.g - color.b) / diff )) + 1.0; hue = fract(hue); } else if(maxIndex == GREEN){ hue = ((1.0/6.0) * ( (color.b - color.r) / diff )) + (1.0/3.0); } else if(maxIndex == BLUE){ hue = ((1.0/6.0) * ( (color.r - color.g) / diff )) + (2.0/3.0); } if(maxCol < epsilon) saturation = 0; else saturation = (maxCol - minCol) / maxCol; value = maxCol; return vec3(hue, saturation, value); } vec3 HSVtoRGB(vec3 color) { float f,p,q,t, hueRound; int hueIndex; float hue, saturation, value; vec3 result; hue = color.r; saturation = color.g; value = color.b; hueRound = floor(hue * 6.0); hueIndex = int(hueRound) % 6; f = (hue * 6.0) - hueRound; p = value * (1.0 - saturation); q = value * (1.0 - f*saturation); t = value * (1.0 - (1.0 - f)*saturation); switch(hueIndex) { case 0: result = vec3(value,t,p); break; case 1: result = vec3(q,value,p); break; case 2: result = vec3(p,value,t); break; case 3: result = vec3(p,q,value); break; case 4: result = vec3(t,p,value); break; default: result = vec3(value,p,q); break; } return result; } void main(void) { vec4 srcColor; vec3 hsvColor; vec3 rgbColor; texel = Texture2D(tex, tcoordIn); srcColor = texel*colorIn; hsvColor = RGBtoHSV(srcColor.rgb); hsvColor.g = 0; rgbColor = HSVtoRGB(hsvColor); pixel = vec4(rgbColor.r, rgbColor.g, rgbColor.b, srcColor.a); }