Applying shader to entire tilemap

Godot Version

4.3

Question

I need to apply a shader to a single tilemaplayer, and none of the nodes below it. Additionally, the shader needs to affect the tilemap as a whole, not just the individual tiles. As well, the positioning of the shader needs to be relative to the tilemap, not the screen.

Adding this shader code:

shader_type canvas_item;

uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
uniform float frequency = 60;
uniform float depth = 0.005;

void fragment() {
	vec2 uv = SCREEN_UV;
	uv.x += sin(uv.y * frequency + TIME) * depth;
	uv.x = clamp(uv.x, 0.0, 1.0);
	vec3 c = textureLod(screen_texture, uv, 0.0).rgb;

	COLOR.rgb = c;
}

to a TextureRect almost gets me there, but it also applies to everything behind the tilemaplayer, which isn’t what I want. The waves are also fixed to the screen, so it changes when the camera moves. And I tried a modified version:

shader_type canvas_item;

uniform float frequency = 60;
uniform float depth = 0.005;

void fragment() {
	vec2 uv = UV;
	uv.x += sin(uv.y * frequency + TIME) * depth;
	uv.x = clamp(uv.x, 0.0, 1.0);
	vec4 c = textureLod(TEXTURE, uv, 0.0);

	COLOR = c;
}

as a shader on the tilemap itself, but this applies the shader seperately to each tile, so the distort isn’t consistent across them.

How can I do this properly??? Applying a shader to a tilemap seems like it should be basic functionality, it baffles me that I’m struggling so hard with this.

My intuition would be to keep applying the shader on individual tiles, but offset the entire effect based on screen UV

This would have the effect’s position end up being relative to the screen though, right? then when my camera moves the effect would move with it, which isn’t what I want. Do you know if there’s a way to get the tile’s world position so I can shift the effect relative to that?

You can pass it as an instance uniform to the shader