Underwater Camera effect

I modified this:

2D water effect

To work with 3d and have a customizable tint.

To use: put this shader on a plane, put the plane over the camera your using.

Shader code
shader_type spatial;
render_mode unshaded;

uniform vec4 tint : hint_color; // tint effect
uniform float wave_speed = 3.0; // wave loop speed
uniform float wave_freq = 10.0; // wave vertical freq
uniform float wave_width = 1; // wave width 

void fragment(){
	vec2 scale_UV = SCREEN_UV;
	vec2 wave_uv_offset;
	wave_uv_offset.x = cos((TIME*wave_speed)+UV.x+UV.y*wave_freq*2.0)*wave_width*0.01;
	ALBEDO = texture(SCREEN_TEXTURE, SCREEN_UV+wave_uv_offset).rgb*tint.rgb;
}
Tags
blur, ocean, underwater, water, wave
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Move object’s DEPTH value relative to camera

Camera Distance UV Scaling

sine wave camera view shader

Subscribe
Notify of
guest

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
AdrKacz
AdrKacz
2 years ago

Hi! Cool shader but I don’t understand how to use it. What do you mean by “on a plane”? Is it a Quad Mesh? A 2D Rect? Thank you

James Washington
James Washington
2 years ago
Reply to  AdrKacz

Create a meshinstance, in the “Mesh” slot inside it, give it a “PlaneMesh” (the same way you would make a box or a sphere).
Then give it a shader material, put this shader in the material you just added to the meshinstance, put the mesh in front of the camera and you should see the effect.

Last edited 2 years ago by James Washington
James Washington
James Washington
2 years ago

For anyone wanting to use this: Note that this shader doesn’t handle transparency correctly. Not sure why.

Last edited 2 years ago by James Washington
SneaK1ng
2 years ago

Set ALPHA = 0.3;

John Doe
John Doe
1 year ago

does not work in Godot 4, big sad.

Jake
Jake
1 year ago
Reply to  John Doe
shader_type spatial;
render_mode blend_mix, unshaded;

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
uniform vec4 tint : source_color; // tint effect
uniform float wave_speed = 3.0; // wave loop speed
uniform float wave_freq = 10.0; // wave vertical freq
uniform float wave_width = 1; // wave width 
uniform float blur = 2.0; // Defines the blur strength. Increase for a larger blur radius.

void fragment(){
	vec2 wave_uv_offset;
	wave_uv_offset.y = 0.0;
	wave_uv_offset.x = cos((TIME*wave_speed)+UV.x+UV.y*wave_freq*2.0)*wave_width*0.01;
	
	float blur_strength = blur / 100.0;
	vec3 blurred_color = vec3(0.0);
    int sample_count = 0;
    for (float x = -blur_strength; x <= blur_strength; x += blur_strength / 10.0) {
        for (float y = -blur_strength; y <= blur_strength; y += blur_strength / 10.0) {
            blurred_color += texture(SCREEN_TEXTURE, SCREEN_UV + wave_uv_offset + vec2(x, y)).rgb;
            sample_count++;
        }
    }
    blurred_color /= float(sample_count);
	
	ALBEDO = blurred_color * tint.rgb;
	ALPHA = tint.a;
}