2D Light Z-Depth

This shader allows you to fake light depth in 2D. By default Godot treats all game objects as being on the same plane.  The Light2D range height can go above or below this plane. When the light is above it fully lights the game objects, no matter the distance. With this shader I have added “height” to nodes that allow them to exist in a virtual z-space, as well as the ability to fade the light at a distance.

A limitation is that it is per node, not per light, so it will treat all lights the same.

Shader Param:

  • Fake Light Depth – Enables the fading or shrinking of light at a set height distance.

    • Obj Height – Sets the light height for this object.

    • Light Change Thresh – Sets the threshold for where the light is to start being affected by depth. For example: If the Light2D range_height is 500, the Obj Height is 0, and the Light Change Thresh is 500; then the fake depth activates if Light2D height increases any further.

    • Light Fade – Activates fading or dimming of light values.

      • Light Fade End – Sets the distance for the transition from lit to unlit.

Shader code
shader_type canvas_item;

// Light height variables
uniform bool fake_light_depth = false;
uniform float obj_height : hint_range(-2048.0, 2048.0) = 0.0; 
uniform float light_change_thresh : hint_range(0.0, 4080.0) = 0.0;
uniform bool light_fade = false;
uniform float light_fade_end : hint_range(0.0, 4080.0) = 0.0;

void light() {
	if (fake_light_depth) {
		float base_height = LIGHT_HEIGHT;
		float new_height = base_height - obj_height;
		LIGHT_HEIGHT = new_height;
		if (light_fade && new_height > light_change_thresh) {
			float n_height_safety = new_height;
			if (n_height_safety == 0.0) { n_height_safety += 0.01; }
			float light_dist_safety = light_change_thresh;
			if (light_dist_safety == 0.0) { light_dist_safety += 0.001; }
			float new_intens = 1.0;
			float dark_distance = light_fade_end;
			if (dark_distance == 0.0) {dark_distance = 1.0;}
			new_intens = 1.0 - abs(abs(light_dist_safety) - abs(n_height_safety)) / dark_distance;
			float light_drop_a = clamp(LIGHT_COLOR.a * new_intens, 0.0, 1.0);
			LIGHT_COLOR *= light_drop_a;
depth, height, light2d
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 MightyMochiGames

Modulate Before Light

2D Cel / Toon Shader v2 +Plus

Toon Shading for 2D Sprites v1

Related shaders

Modulate Before Light

2D Rim Light

Inline Feedbacks
View all comments