2D Topdown Shadow that goes out of bounds

Shader code
shader_type canvas_item;

uniform float r = 0.0;
uniform float offset: hint_range(0.0, 1.0) = 0.0;

void vertex() {
	VERTEX.xy *= 3.;
}

void fragment() {
	mat2 rotation_matrix = mat2(vec2(cos(r), sin(r)), vec2(-sin(r), cos(r)));
	mat2 scale_matrix = mat2(vec2(1.0, 0.0),vec2(0.0, TEXTURE_PIXEL_SIZE.x/TEXTURE_PIXEL_SIZE.y));
	vec2 uv = (((UV * 2.0 - 1.0)*3.+1.0)/2.0-vec2(0.5))*scale_matrix;
	vec2 uv_normal = uv * rotation_matrix * inverse(scale_matrix) + vec2(0.5);
	uv = (uv * rotation_matrix + vec2(0.25)*offset*rotation_matrix)*inverse(scale_matrix)+vec2(0.5);
	vec4 shadow;
	vec4 real;
	if(offset != 0.0 && uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) {
		vec4 c = texture(TEXTURE, uv);
		shadow = vec4(0.,0.,0.,c.a-0.6);
	}
	if(uv_normal.x >= 0.0 && uv_normal.x <= 1.0 && uv_normal.y >= 0.0 && uv_normal.y <= 1.0) {
		real = texture(TEXTURE,uv_normal);
	}
	COLOR = mix(shadow,real,real.a);
}
Tags
2d, bounds, offset, rotate, rotation, shadow, topdown
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 Bettiold

Ripple effect

Related shaders

2D shadow out of bounds

Topdown wind shader

Sprite Cut-Out/Cut-In Mask

Subscribe
Notify of
guest

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Rakun
Rakun
7 months ago

I have this awfule effect
https://ibb.co/Rb2xFRd

Last edited 7 months ago by Rakun
Guille
Guille
6 months ago
Reply to  Rakun

I have some similar https://ibb.co/ZfFJ2t2 do you find a solution?

Rakun
Rakun
6 months ago
Reply to  Guille

Nope.Just forgot about it.

schneed.
schneed.
6 months ago
Reply to  Guille

It seems it’s an issue with the Rendering set-up. I had the exact same issues, but when I changed my renderer to Compatibility (top right) it worked.

This isn’t viable – it means you cannot run a lot of other visual effects properly just to make the drop shadow work.

ghst
ghst
7 months ago

I get error in Line 18, tried to fix it but no success

Direct floating-point comparison (this may not evaluate to true as you expect). Instead, use abs(a - b) < 0.0001 for an approximate but predictable comparison.

Crumblebit
Crumblebit
5 months ago

If the above shader is not working, you can achieve the same effect with sprites. Just add a Node2D to your scene, call it Shadow and attach a script with this code:

@export var shadow_offset = Vector2(8,8)

func _process(_delta):
    global_position = get_parent().global_position + shadow_offset

Now you can add as many shadow Sprite2Ds as children to this “Shadow” node as you want. The benefit is that the shadow can be sprites, so no limit to how it looks. And the code is very simple, just offset the global position and inherit the rotation. 🙂

Laki
Laki
2 months ago
Reply to  Crumblebit

I think that the idea of the shader is to avoid drawing all the shadow sprites.