How can I use a Tilemap as a Mask (for Player reflection)?

153 Views Asked by At

I am using Godot 4.2 Mono version with C# code.

My Goal: I want to make the player's reflection visible only on water.

I am using a Tilemap for my water layer. The water texture has shapes that match the stone edge geometry of the pond. The Tilemap uses a vertex shader for smooth water wobbling, as demonstrated in the video.

Now, I need to ensure that the Sprite2D (Player Reflection) is visible only inside the water area and not on the walls. I cannot use Z-layering, I believe, because the water is above other objects, and everything under the water is affected by a distortion created by a fragment shader.

Normally, in Unity, I would use a mask to display the Sprite2D "inside the mask." However, in Godot, there is no masking option apart from Child Clipping. Unfortunately, this doesn't work with Tilemaps. If I place the Reflection into a Polygon2D Node and use Child Clipping, the shape of the Polygon2D will act as a mask.

Does anyone have an idea on how I could solve this?

Here is the video for reference: https://www.youtube.com/watch?v=hML5vmxi01A

Below are the shaders I am using on the "WaterBounce" Tilemap node:

shader_type canvas_item;

uniform float time_factor = 1;
uniform vec2 amplitude = vec2(10.0, 10.0);

void vertex() {
    VERTEX.x += cos(TIME * time_factor + VERTEX.x + VERTEX.y) * amplitude.x;
    VERTEX.y += sin(TIME * time_factor + VERTEX.y + VERTEX.x) * amplitude.y;
}

void fragment() {
    vec4 water = texture(TEXTURE, UV);
    COLOR = water;
    COLOR.a = water.a * 0.6;
}

I'm unsure if it's possible to achieve my goal by working solely on the shader. Based on my understanding, the shader only interacts with the node it is applied to and cannot include elements from other nodes.

PS: I am not highly proficient in coding; I am not a trained developer. It took me hours to create this shader. However, now I am running out of ideas and knowledge.

Edit: My last backup solution would be to create a full water Texture for every Pond with a different shape as Sprite2D and parent of the reflection. This would work with Clip Children... But this solution isn't elegant :D I would have to create the water for every river and pond.

enter image description here

0

There are 0 best solutions below