 ** Hue, saturation, luminance
 */
 
-vec3 RGBToHSL(vec3 color)
+vec3 RGBToHSL(in vec3 color)
 {
 	vec3 hsl; // init to 0 to avoid warnings ? (and reverse if + remove first part)
 	

** Desaturation
*/

vec4 Desaturate(vec3 color, float Desaturation)
{
	vec3 grayXfer = vec3(0.3, 0.59, 0.11);
	vec3 gray = vec3(dot(grayXfer, color));

#define BlendOpacity(base, blend, F, O) 	(F(base, blend) * O + blend * (1.0 - O))

// Hue Blend mode creates the result color by combining the luminance and saturation of the base color with the hue of the blend color.
float BlendHue1(in float base, in float blend)
{
	return base;
}

vec3 BlendHue3(in vec3 base, in vec3 blend)
{
	vec3 baseHSL = RGBToHSL(base);
	return HSLToRGB(vec3(RGBToHSL(blend).r, baseHSL.g, baseHSL.b));
}

vec4 BlendHue4(in vec4 base, in vec4 blend)
{
	vec3 hue = BlendHue3(base.xyz, blend.xyz);
	return vec4(hue.x, hue.y, hue.z, BlendHue1(base.w, blend.w));
}

// Saturation Blend mode creates the result color by combining the luminance and hue of the base color with the saturation of the blend color.
float BlendSaturation1(in float base, in float blend)
{
	return base;
}

vec3 BlendSaturation3(in vec3 base, in vec3 blend)
{
	vec3 baseHSL = RGBToHSL(base);
	return HSLToRGB(vec3(baseHSL.r, RGBToHSL(blend).g, baseHSL.b));
}

vec4 BlendSaturation4(in vec4 base, in vec4 blend)
{
	vec3 hue = BlendSaturation3(base.xyz, blend.xyz);
	return vec4(hue.x, hue.y, hue.z, BlendSaturation1(base.w, blend.w));
}

// Color Mode keeps the brightness of the base color and applies both the hue and saturation of the blend color.
float BlendColor1(in float base, in float blend)
{
	return base;
}

vec3 BlendColor3(in vec3 base, in vec3 blend)
{
	vec3 blendHSL = RGBToHSL(blend);
	return HSLToRGB(vec3(blendHSL.r, blendHSL.g, RGBToHSL(base).b));
}

vec4 BlendColor4(in vec4 base, in vec4 blend)
{
	vec3 hue = BlendColor3(base.xyz, blend.xyz);
	return vec4(hue.x, hue.y, hue.z, BlendColor1(base.w, blend.w));
