#How to adjust 2D light saturation

17 messages · Page 1 of 1 (latest)

steep ether
#

I want to create an effect in 2D where everything is black and white except the areas that are illuminated by lights, which should have color. I have edited an image to illustrate what I mean. I've checked light blend mode options but they don't affect saturation and I have used world environment to adjust saturation but then it also affects the lights. Could this be done with shaders?

rose marsh
#

I am pretty sure you can achieve this with a shader. I have a shader that makes things black and white. I am not sure I how to mask that though.

#

I am gonna try something here

rose marsh
#

I achieve this with a screen space shader

#

is a inverted circular mask

#

and this shader in the ColorRect

shader_type canvas_item;

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;

void fragment() {
    COLOR = texture(SCREEN_TEXTURE, SCREEN_UV);
    COLOR.rgb = vec3(COLOR.r + COLOR.g + COLOR.b) / 3.0;
}
steep ether
#

I'm giving this a try but I don't know how to set the inverted circular mask, how did you do it?

#

I got something similar passing a mast texture as uniform sampler2D mask_texture to the shader, but I need to find a way for it to work with more than one light

steep ether
rose marsh
#

Nice. I realize now that “inverted circular mask” doesn’t mean much. What I meant was a square with a circular hole in the middle.

#

You can look into shader options to tint your image.

steep ether
#

I was able to get what I wanted after a some trial and error and playing with the shaders. I don't know it's inefficient and I don't really understand why it works so it might be buggy. I'll share in case someone can explain, or maybe it will be useful if someone wants to do something similar in the future.

#

What I did was put the grayscale shader in a polygon2D, the poligon can be transparent, it has this shader: ```shader_type canvas_item;

uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
uniform sampler2D gradient: hint_default_black;

vec3 gradient_color(vec3 rgb) {
float grayscale = dot(rgb, vec3(0.299, 0.587, 0.114));
return texture(gradient, vec2(grayscale)).rgb;
}

void fragment() {
COLOR = texture(screen_texture, SCREEN_UV);
COLOR.rgb = gradient_color(COLOR.rgb);
}```The area inside the poligon will be grayscale, except for the lights (explained below), then the gradient parameter can be used to adjust the hue (blue, sepia, etc)

#

then for the lights I used sprite2d nodes with a black and white texture and this shader: ```shader_type canvas_item;

uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
uniform vec4 color : source_color = vec4(1.0);

void fragment() {
COLOR = texture(screen_texture, SCREEN_UV) * color * 1.5;
COLOR.a = texture(TEXTURE, UV).b;
}```

steep ether
#

I forgot to mention, I set the z-index of the polygon to be on top of everything that should be desaturated, then the lights on the next z-index to be on top of the polygon