2D water with reflections
Highly customizable reflective 2D water.
inspired by “Kingdom Two Crowns”.
How to use:
– Add a ColorRect (make sure it is at the bottom of the scren tree).
– Add the shader to the ColorRect.
– For the parameter “noise_texture” just use a default simplex noise texture.
– For the parameter “noise_texture2” (used for the water texture, which can be turned off) use a simplex noise texture with the parameters shown in the screenshot below.
– Tweak the parameters to your liking and that’s it.
After applying the shader to the ColorRect, it will, by default, be split vertically into two sections:
– the upper section: which is what will be reflected in the bottom section. *
– the bottom section: which contains the water and the reflection of the upper section.
* Make sure that what you want to be reflected is inside of the upper layer of the ColorRect.
Shader code
shader_type canvas_item;
uniform float level : hint_range(0.0, 1.0) = 0.5;
uniform vec4 water_albedo : hint_color = vec4(0.26, 0.23, 0.73, 1.0);
uniform float water_opacity : hint_range(0.0, 1.0) = 0.35;
uniform float water_speed = 0.05;
uniform float wave_distortion = 0.2;
uniform int wave_multiplyer = 7;
uniform bool water_texture_on = true;
uniform float reflection_X_offset = 0.0;
uniform float reflection_Y_offset = 0.0;
uniform sampler2D noise_texture : hint_albedo;
uniform sampler2D noise_texture2 : hint_albedo;
void fragment() {
vec2 uv = UV;
COLOR = vec4(0.0);
if (uv.y >= level) {
COLOR.a = 1.0;
// distorted reflections
vec2 water_uv = vec2(uv.x, uv.y * float(wave_multiplyer));
float noise = texture(noise_texture, vec2(water_uv.x + TIME * water_speed, water_uv.y)).x * wave_distortion;
noise -= (0.5 * wave_distortion);
// water texture
if (water_texture_on) {
float water_texture_limit = 0.35;
vec4 water_texture = texture(noise_texture2, uv * vec2(0.5, 4.0) + vec2(noise, 0.0));
float water_texture_value = (water_texture.x < water_texture_limit) ? 1.0 : 0.0;
COLOR.xyz = vec3(water_texture_value);
}
// putting everything toghether
vec4 current_texture = texture(SCREEN_TEXTURE, vec2(SCREEN_UV.x + noise + reflection_X_offset, 1.0 - SCREEN_UV.y - (level - 0.5) * 2.0 + reflection_Y_offset));
COLOR = mix(COLOR, current_texture, 0.5);
COLOR = mix(COLOR, water_albedo, water_opacity);
}
}
Thank you! I’m trying to wrap my head around this. I’m having an issue where if my camera moves up, the reflection also moves. How would I make it so the reflection is fixed no matter where the camera goes?
Also have this problem and the wave just stops at the start. Did you ever find a solution?
Ok, found a solution for wave stopping, the noise has to be set to be repeated like so: uniform sampler2D noise_texture : repeat_enable;
Did you solve the problem with the camera?
Does this Work in godot 4 I changed the hint_color to source_color and changed the SCREEN_TEXTURE and it seemed to work but when I added noise it looked like a bunch of lines
I’m seeing the same thing
uniform sampler2D noise_texture : hint_albedo;
uniform sampler2D noise_texture2 : hint_albedo;
this line gives an error