Any easy way to draw 2d shadows over sprites but not to the background?

Godot Version

4.2

Question

I’m not talking about shadows generated by lights, but simple shadows drawn as a mask on background objects, like this:

I found a simple shader that does this. The problem is that it draws shadows both over objects behind and over the background. An undesirable behavior if the background is a blue sky or the starry space. I think the problem is not in the shader, but that there is no way not to apply it to lower layers.

Here’s an example of what I’m talking about:

Above is the desired behavior, below is the undesired behavior.

The solution I found is a bit trichy. I have to put the scene with all sprites in a SubViewport with transparent bg flag set, then apply to the foreground objects a modified version of the shader that takes into account the background color of the viewport. Then the scene is draw over the background using a TextureRect whose texture is get from the SubViewport.

Here is my version of the shader:

shader_type canvas_item;
uniform vec2 offset = vec2(8.0, 8.0);
uniform vec4 modulate : source_color;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, repeat_disable, filter_nearest;
uniform vec4 background_color: source_color;

void fragment() {
	vec4 texture_col = texture(TEXTURE, UV);
	vec4 screen_col = texture(SCREEN_TEXTURE, SCREEN_UV);

	vec4 shadow = vec4(modulate.rgb, texture(TEXTURE, UV - offset * TEXTURE_PIXEL_SIZE).a * modulate.a);
	vec4 shadow_over_bg = mix(screen_col, shadow, screen_col.a);
	vec4 bg_color = texture(SCREEN_TEXTURE, SCREEN_UV);
	if (bg_color.rgba == background_color) {
		COLOR = texture_col;
	} else {
		COLOR = mix(shadow_over_bg, texture_col, texture_col.a);
	}
}

It works. But I don’t like it.

I’m not very expert about Godot and game engines in general, so I imagine there might be a better solution. Anyone have a suggestion?