Working around Godot's 2D light limitations for a dark game

Here’s my 2D light setup, you can have as many lights as you want with little performance impact. There’s no normal map or shadow though.

Copy the code below and save it as a .tscn file:

[gd_scene load_steps=5 format=3 uid="uid://dros00nqhabix"]

[sub_resource type="Shader" id="Shader_lcjdq"]
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 vertex()
{
	// Disable modulate color.
	COLOR = vec4(1.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);
}"

[sub_resource type="ShaderMaterial" id="ShaderMaterial_0xacm"]
shader = SubResource("Shader_lcjdq")
shader_parameter/intensity = 3.0

[sub_resource type="Gradient" id="Gradient_krxn2"]
interpolation_color_space = 1
offsets = PackedFloat32Array(0, 0.930435)
colors = PackedColorArray(1, 0.655333, 0.53, 1, 0, 0, 0, 0)

[sub_resource type="GradientTexture2D" id="GradientTexture2D_vdn31"]
gradient = SubResource("Gradient_krxn2")
width = 1024
height = 1024
fill = 1
fill_from = Vector2(0.5, 0.5)
fill_to = Vector2(0.852761, 0.874233)

[node name="BackBufferLight" type="BackBufferCopy"]
z_index = 2000
z_as_relative = false
copy_mode = 2

[node name="light-texture" type="Sprite2D" parent="."]
material = SubResource("ShaderMaterial_0xacm")
texture = SubResource("GradientTexture2D_vdn31")
3 Likes