2D Drop Shadow

Duplicates everything rendered in a solid color by an offset, behind the actual render. (Including Sprites, Particles, etc…).

Create a ColorRect and apply the shader to it, It needs to be rendered after everything you want to have a shadow for, otherwise everything rendered after the ColorRect won’t have a shadow. (Put it at the bottom of nodes).

You need to set the window mode to “Viewport”, Change the shadow offset to your liking.

Define the background color you need the shader to display on, then change the shadow color.

To use in Godot 3 change source_color to hint_color

Shader code
shader_type canvas_item;

uniform vec4 background_color : source_color;
uniform vec4 shadow_color : source_color;
// Currently pixels always in application size, so zooming in further wouldn't increase the size of the dropdown
// but changing that would also be relatively trivial
uniform vec2 offset_in_pixels;

void fragment() {
	
	// Read screen texture
	vec4 current_color = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0);
	
	// Check if the current color is our background color
	if (length(current_color - background_color) < 0.01) {
		
		vec4 offset_color = textureLod(SCREEN_TEXTURE, SCREEN_UV - offset_in_pixels * SCREEN_PIXEL_SIZE, 0.0);
		
		// Check if at our offset position we have a color which is not the background (meaning here we need a shadow actually)
		if (length(offset_color - background_color) > 0.01) {
			// If so set it to our shadow color
			current_color = shadow_color;
		}
	}
	
	COLOR = current_color;
}
Tags
2d, canvas item, dropshadow, pixel, pixelart, 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 Drop Shadow using alpha

Drop-in PBR 2d lighting system with soft shadows and ambient occlusion

Moon Shader 2D All Phases and Roughened Shadow

Subscribe
Notify of
guest

9 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
The2AndOnly
The2AndOnly
1 year ago

There is a major flaw with this that makes it basically unusable, and it’s that the background HAS to be a solid color, and the sprite can’t contain the background color, and the color you choose to have the shadows on has to be that exact specific color.

GorEldeen
GorEldeen
1 year ago

Hello there, There’s a problem in the shader script and it says that “source_color” doesn’t exist
[EDIT] i forgot i was using godot 3, Sorry!

Last edited 1 year ago by GorEldeen
Nubux
Nubux
1 year ago
error(12): SCREEN_TEXTURE has been removed in favor of using hint_screen_texture with a uniform.
To continue with minimal code changes add 'uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;' near the top of your shader.

I added the line, the error is gone but the shader doesn’t seem to work.

I’m in Godot 4.b16.

yellowBalloon
yellowBalloon
1 year ago

I couldn’t get this to work as well in Godot 4 on a ColorRect.

However if anyone wants to put the shadow on a specific sprite (this is what I wanted) you can easily reuse this script and replace SCREEN_TEXTURE with TEXTURE and SCREEN_UV with UV.

schneed.
schneed.
7 months ago

Do you have any ideas as to how to reconfigure this shader to work in renderer modes other than Compatibility? Like Forward+ and Mobile?

Shadowblitz16
Shadowblitz16
3 months ago

Please fix this shader it doesn’t work with rich text label

Last edited 3 months ago by Shadowblitz16