Light shader

Godot’s Light2D has an annoying limit of 16, and while the official documentation recommends using Sprite2D with additive blending mode, it ends up not looking very good in a dark environment.

Here is a simple shader which was provided by HaruYou27!

No 16 limit, no performance issue, you can place as many lights as you want in a dark environment!

The final effect is as follows:

Shader code
shader_type canvas_item;
render_mode blend_add, unshaded;
// 2D light shader by HaruYou27.

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, repeat_disable, filter_nearest;

uniform float intensity = 10.0;

void fragment() {
    // Sample the underlying screen color
    vec3 under_color = texture(SCREEN_TEXTURE, SCREEN_UV).rgb;

    // Make it brighter
    vec3 final_color = under_color * COLOR.rgb * intensity;

    // Don't forget the alpha value
    COLOR = vec4(final_color, COLOR.a);
}
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Custom 2D Light

fireball fire ball with light

Modulate Before Light

Subscribe
Notify of
guest

5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Tz0322
Tz0322
3 months ago

Cool, it works for me

LeifInTheWind
1 month ago

How are you achieving the dark environment and what are you adding the light to? I was originally using a canvas modulate with point lights for my lava rivers, but that quickly became performance heavy.

I’ve added this shader to a sprite with a gradient, but that doesn’t work with the canvas modulate.

Thanks!

LeifInTheWind
1 month ago
Reply to  LeifInTheWind

The canvas modulate does work, just can’t be completely dark so that the shader can properly sample the color of the sprites beneath the canvas modulate.

New issue though is how this interacts with point lights. It seems to increase the brightness quite a bit since it is essentially adding on top of the point light.

tedoriki
25 days ago
Reply to  LeifInTheWind

if it is too bright for you, just clamp the final color like so:

uniform float max_brightness : hint_range(0.0, 2.0) = 2.0;
final_color = clamp(final_color, 0.0, max_brightness)