Godot Version
Godot 4.6.1.stable
Question
Is there a solid way to make ocean waves shader without distorting objects between shader material and viewport?
Hi, I’m working on a water shader using screen_texture for distortion, but I’m running into a rendering issue that I can’t resolve.
Problem
When my plane (mesh) is between the camera and the water, the water shader distorts the plane as well. This results in:
-
A “double” or wavy duplicate of the plane
-
Distorted shadows (appearing duplicated)
-
Even editor icons (like camera gizmos) appearing warped
However, without the ocean mesh, everything appears correct.
Expected Behavior
Only the water surface should be distorted.
Current Behavior
Objects in front of the water are also being distorted, suggesting incorrect depth handling. (maybe)
Shader Code
shader_type spatial;
uniform vec3 water_color : source_color;
uniform float uv_scale = 1.0;
uniform float time_scale = 1.0;
uniform sampler2D water_normal_noise;
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable;
uniform sampler2D depth_texture : hint_depth_texture;
void fragment() {
// Raw depths
float scene_depth = texture(depth_texture, SCREEN_UV).r;
float water_depth = FRAGCOORD.z;
// Add bias to stabilize comparison
float distort_mask = step(water_depth - 0.01, scene_depth);
// UVs
vec2 _uv = UV * uv_scale;
vec2 base_suv = SCREEN_UV;
// Wave motion (normals)
_uv.x += sin(TIME * time_scale + (_uv.x + _uv.y) * 25.0) * 0.01;
_uv.y += cos(TIME * time_scale + (_uv.x - _uv.y) * 25.0) * 0.01;
// Distorted screen UV
vec2 distorted_suv = base_suv;
distorted_suv.x += sin(TIME * time_scale + (base_suv.x + base_suv.y) * 25.0) * 0.01;
distorted_suv.y += cos(TIME * time_scale + (base_suv.x - base_suv.y) * 25.0) * 0.01;
// Blend instead of branching
vec2 final_suv = mix(base_suv, distorted_suv, distort_mask);
ALBEDO = texture(screen_texture, final_suv).rgb;
NORMAL_MAP = texture(water_normal_noise, _uv).rgb;
NORMAL *= 0.7;
ROUGHNESS = 0.2;
}
Thanks in advance!
Pictures of the problem:
in tree is hidden. (OceanLayer2 is collision and flat visual layer)
is visible
See the double shadow and double plane? even the camera gizmo is doubled and wavy.


