2D Cast shadow

This shader applies a dynamic shadow effect to 2D canvas items. The shadow’s direction can be controlled using the look_right parameter. The shader works by stretching the x-coordinates of the vertices horizontally and then calculating a shadow effect in the fragment shader. This allows for flexible shadow positioning and can create a more realistic depth effect for 2D elements.

As this shader only casts the shadow (which is intentional), the correct positioning must be managed using the z-index to ensure proper layering and visual effects.

Why the need to orient the shadow? Because if you horizontally flip your sprite, you don’t want the shadow to disengage from the other shadows’ direction. By controlling the shadow orientation, you maintain a consistent and realistic shadow direction relative to other objects in your scene.

Shader code
shader_type canvas_item;
uniform bool look_right = true;

void vertex() {
	VERTEX.x = VERTEX.x * { -1.0, 1.0 }[int(look_right)];
		
	float xSkewRatio = step(UV.y, .5);
	vec2 skewTransition = vec2(abs(VERTEX.x) * xSkewRatio, 0.0);
	vec2 skewScale = vec2(VERTEX.x, (VERTEX.y + abs(VERTEX.y)) / 2.0);
	
	VERTEX = skewScale;

	VERTEX = VERTEX + skewTransition;
}

void fragment() {
	COLOR = vec4(vec3(.0), .5 * COLOR.a);
}
Tags
2d, shadow
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.

Related shaders

2D Pixel Shadow/Outline

2D shadow out of bounds

2D Topdown Shadow that goes out of bounds

Subscribe
Notify of
guest

8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
DinoMC
DinoMC
2 months ago

Looks awesome!
I have two small questions:

Since the shader turns the sprite (or other node) into a shadow, I assume I have to duplicate my sprite and then apply the shader to the duplicate so that I have the character + the shadow. Is that correct?Any idea what could be causing this : link <– This is my sprite, then just the shadow, then both together. No clue what’s causing these 2 vertical and horizontal bars. I checked the sprite and it doesn’t have any invisible pixel. (Plus they would need to be outside the file canvas to appear so far)

Last edited 2 months ago by DinoMC
DexterFStone
DexterFStone
2 months ago

how can I change the direction of the shadow (aka rotate it)?

Last edited 2 months ago by DexterFStone
DexterFStone
DexterFStone
2 months ago
Reply to  DevSavvySerge

I want to use it for a top-down game and rotate the shadow based on the direction of the sun