Color manipulator

This is a simple color manipulator, it support brightness, contrast, saturation, tint and more.

Simple copy past it in shader in canvas item material.

Shader code
shader_type canvas_item;
render_mode blend_mix,unshaded;

uniform float brightness : hint_range(-1, 1) = 0;
uniform float contrast : hint_range(0, 3) = 1.0;
uniform float saturation : hint_range(0, 3) = 1.0;

uniform float redVal : hint_range(0, 1) = 1.0;
uniform float greenVal : hint_range(0, 1) = 1.0;
uniform float blueVal : hint_range(0, 1) = 1.0;

uniform vec4 tint_color : hint_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform float tint_effect_factor : hint_range(0, 1) = 0.0;
//---------------------------------------------
//CONTRAST
//---------------------------------------------
mat4 contrastMatrix( float _contrast ){
	float t = ( 1.0 - _contrast ) / 2.0;
    return mat4( 
		vec4(_contrast, 0, 0, 0),
		vec4(0, _contrast, 0, 0),
		vec4(0, 0, _contrast, 0),
		vec4(t, t, t, 1));
}
//---------------------------------------------
//BRIGHTNESS
//---------------------------------------------
mat4 brightnessMatrix( float _brightness ){
    return mat4( vec4(1, 0, 0, 0),
                 vec4(0, 1, 0, 0),
                 vec4(0, 0, 1, 0),
                 vec4(_brightness, _brightness, _brightness, 1));
}
//---------------------------------------------
//SATURATION
//---------------------------------------------
mat4 saturationMatrix( float _saturation ){
    vec3 luminance = vec3( 0.3086, 0.6094, 0.0820 );
    float oneMinusSat = 1.0 - _saturation;
	
    vec3 red = vec3( luminance.x * oneMinusSat );
    red+= vec3(_saturation, 0, 0)*redVal;
    vec3 green = vec3( luminance.y * oneMinusSat );
    green += vec3( 0,_saturation, 0 )*greenVal;
    vec3 blue = vec3( luminance.z * oneMinusSat );
    blue += vec3( 0, 0,_saturation )*blueVal;
	
    return mat4(vec4(red, 0),vec4(green,0),vec4(blue,0),vec4(0, 0, 0, 1));
}

//---------------------------------------------
//fragment
//---------------------------------------------
void fragment() {
	vec4 c = texture(TEXTURE, UV);
	vec4 c2 = c * tint_color;
	COLOR = brightnessMatrix( brightness ) * contrastMatrix( contrast ) *saturationMatrix( saturation ) * mix(c, c2, tint_effect_factor);
}
Tags
brightness, color manipulator, contrast, saturation, tint
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from randomDam

Color vignette

Related shaders

color splash (show only one color)

Fog of war with alpha cut off as white color

3D Post-Processing: Dithering + Color Palettes

Subscribe
Notify of
guest

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
kiniber
kiniber
2 years ago

I tried this because I was curious, thanks for the nice work.
I used it with a ColorRect that covers the whole screen. In order to do that, I had to change from TEXTURE to SCREEN_TEXTURE
The next problem was, that everything was upside down (mirrored around the horizontal axis), so I inverted it.
So I replaced this line:

vec4 c = texture(TEXTURE, UV);

with this line:
vec4 c = texture(SCREEN_TEXTURE, vec2(UV.x,(1.0-UV.y)));
I’m not so good with matrices, Maybe there is a more elegant way to do this.

Axell
Axell
2 years ago
Reply to  kiniber

I think the SCREEN_TEXTURE is made to be used with SCREEN_UV, if you write
vec4 c = texture(SCREEN_TEXTURE, SCREEN_UV);
you don’t have to invert it

nonomiyo
nonomiyo
10 months ago

in Godot4 : hint_color has been renamed to source_color

Thank you so much for this shader. It’s really useful to beginners like me ! 🙂

GourabSN
GourabSN
6 months ago

For Godot 4, use this.

shader_type canvas_item;
render_mode blend_mix,unshaded;

uniform float brightness : hint_range(-1, 1) = 0;
uniform float contrast : hint_range(0, 3) = 1.0;
uniform float saturation : hint_range(0, 3) = 1.0;

uniform float redVal : hint_range(0, 1) = 1.0;
uniform float greenVal : hint_range(0, 1) = 1.0;
uniform float blueVal : hint_range(0, 1) = 1.0;

uniform vec4 tint_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform float tint_effect_factor : hint_range(0, 1) = 0.0;

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture;

//———————————————
//CONTRAST
//———————————————
mat4 contrastMatrix( float _contrast )
{
    float t = ( 1.0 – _contrast ) / 2.0;
    return mat4(
        vec4(_contrast, 0, 0, 0),
        vec4(0, _contrast, 0, 0),
        vec4(0, 0, _contrast, 0),
        vec4(t, t, t, 1));
}
//———————————————
//BRIGHTNESS
//———————————————
mat4 brightnessMatrix( float _brightness )
{
    return mat4( vec4(1, 0, 0, 0),
                 vec4(0, 1, 0, 0),
                 vec4(0, 0, 1, 0),
                 vec4(_brightness, _brightness, _brightness, 1));
}
//———————————————
//SATURATION
//———————————————
mat4 saturationMatrix( float _saturation )
{
    vec3 luminance = vec3( 0.3086, 0.6094, 0.0820 );
    float oneMinusSat = 1.0 – _saturation;
    
    vec3 red = vec3( luminance.x * oneMinusSat );
    red+= vec3(_saturation, 0, 0)*redVal;
    vec3 green = vec3( luminance.y * oneMinusSat );
    green += vec3( 0,_saturation, 0 )*greenVal;
    vec3 blue = vec3( luminance.z * oneMinusSat );
    blue += vec3( 0, 0,_saturation )*blueVal;
    
    return mat4(vec4(red, 0),vec4(green,0),vec4(blue,0),vec4(0, 0, 0, 1));
}

//———————————————
//fragment
//———————————————
void fragment()
{
    vec4 c = texture(SCREEN_TEXTURE, SCREEN_UV);
    vec4 c2 = c * tint_color;
    COLOR = brightnessMatrix( brightness ) * contrastMatrix( contrast ) *saturationMatrix( saturation ) * mix(c, c2, tint_effect_factor);
}

Last edited 6 months ago by GourabSN