Water Shader for Realistic Look

This shader is used on a MeshInstance3D’s ShaderMaterial. The shader is based off the tutorial provided in the Godot Documenation with minor configerations to give it a more realistic look.

You will need to create a noise texture texture. Make the noise texture unique so you can save the texture to use for normal texture. Once you saved a texture use that for normal and also make it unique so you can check mark “normal” to turn normal mapping on. 

Any suggestions to this script please leave in the comments and I will surely update the script juding apon the needed changes. 

Shader code
shader_type spatial;
render_mode diffuse_toon, specular_toon;

uniform float height_scale = 0.5;
uniform sampler2D noise;
uniform sampler2D normalmap;

varying vec2 tex_position;

// Pre-calculate constants for use in height function
const float wave_scale = 0.4;
const float wave_scale2 = 0.3;
const float wave_scale3 = 0.5;
const float wave_scale4 = 0.6;
const float wave_pow = 0.65;
const float wave_pow2 = 4.0;

float wave(vec2 position){
  position += texture(noise, position / 64.0).x * 2.0 - 1.0;
  vec2 wv = 1.0 - abs(sin(position));
  return pow(1.0 - pow(wv.x * wv.y, wave_pow), wave_pow2);
}

float height(vec2 position, float time) {
  float d = wave((position + time) * wave_scale) * 0.3;
  d += wave((position - time) * wave_scale2) * 0.3;
  d += wave((position + time) * wave_scale3) * 0.2;
  d += wave((position - time) * wave_scale4) * 0.2;
  return d;
}

void vertex() {
  // Get the current vertex position
  vec3 pos = VERTEX;

  // Get the height of the terrain at this position
  float k = height(pos.xz, TIME);

  // Set the Y position of the vertex to the terrain height
  VERTEX.y = k * height_scale;

  // Calculate the normal vector using nearby terrain heights
  NORMAL = normalize(vec3(
    k - height(pos.xz + vec2(0.1, 0.0), TIME),
    0.1,
    k - height(pos.xz + vec2(0.0, 0.1), TIME)
  ));

  // Apply the normal map to the normal vector
  NORMAL = normalize(texture(normalmap, tex_position).rgb * 2.0 - 1.0 + NORMAL);
}

void fragment() {
  // Calculate the fresnel factor
  float fresnel = sqrt(1.0 - dot(NORMAL, VIEW));

  // Set material properties
  RIM = 0.2;
  METALLIC = 0.0;
  ROUGHNESS = 0.01 * (1.0 - fresnel);
  ALBEDO = vec3(0.1, 0.3, 0.5) + (0.1 * fresnel);
}
Tags
flow, island, lake, landscape, nature, ocean, river, water, watercycle
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Realistic Water

Transparent Water Shader supporting SSR and Refraction

(Another) Water Shader

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments