Underwater Camera effect

I modified this:

 

https://godotshaders.com/shader/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;
}
Live Preview
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

Comments 9

  1. AdrKacz

    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

    2
    1. 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.

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

    0
  3. John Doe

    does not work in Godot 4, big sad.

    1
    1. 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;
      }
      
      17
      1. zpecc

        For anyone using this shader code today, note that as of Godot 4.5, the editor crashes if you set 'blur' to 0.0. (Works great otherwise, though, so either just be careful with what you set blur to, or comment the blurring parts out)

        0
        1. > uses shader
          > doesn't work
          > sees this reply
          "ah well I backed up all my important stuff, may as well see if this is the case"
          > sets blur to 0
          > entire graphics card bugs out and kills the entire system

           

          understatement of a god damn lifetime

          1