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);
}
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:
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.
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
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 ! 🙂
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);
}
Amazing work, thank you for sharing!