Creating Procedural Water in GLSL

in #coding22 hours ago

Water is always moving.

Sometimes it forms gentle ripples across a lake.

Sometimes it crashes into waves.

Sometimes it reflects the sky so clearly that it almost looks like glass.

Although real water is incredibly complex, we can recreate many of its characteristics using simple mathematics.

What Makes Water Look Like Water?

Most procedural water begins with four simple ingredients.

Smooth waves.

Subtle distortion.

Continuous animation.

A cool color gradient.

The combination of these four ideas creates surprisingly convincing results.

Starting with the UV Coordinates

We'll begin with our familiar coordinates.

vec2 uv = vUv;

Everything in the shader will be built from these coordinates.

Creating the First Wave

The easiest way to make water is with a sine wave.

float wave =

sin(

uv.x * 12.0

);

This creates evenly spaced ripples.

At the moment they are perfectly straight.

Real water is never this perfect.

Animating the Ripples

Water is always moving.

We simply shift the wave over time.

float wave =

sin(

uv.x * 12.0 +

uTime * 2.0

);

The ripples now travel smoothly across the screen.

Adding Noise

Perfect waves still look artificial.

Let's distort them with FBM.

float n =

fbm(

uv * 3.0

);

This creates smooth variation.

Distorting the Waves

Add the noise into the sine function.

float water =

sin(

uv.x * 12.0 +

n * 4.0 +

uTime * 2.0

);

The waves now bend naturally instead of remaining perfectly straight.

Adding a Second Wave

Real water contains many overlapping waves.

Create another one.

water +=

sin(

uv.y * 18.0 -

uTime * 1.5

) * 0.5;

The two wave systems interact to create a richer surface.

Normalizing the Result

Bring everything back into the familiar range.

water =

water * 0.5 +

0.5;

Now the values are ready to use for colors.

Complete Shader

#ifdef GL_ES
precision mediump float;
#endif

uniform float uTime;
varying vec2 vUv;

void main(){

    vec2 uv = vUv;

    float n = fbm(uv * 3.0);

    float water =

        sin(

            uv.x * 12.0 +

            n * 4.0 +

            uTime * 2.0

        );

    water +=

        sin(

            uv.y * 18.0 -

            uTime * 1.5

        ) * 0.5;

    water = water * 0.5 + 0.5;

    gl_FragColor = vec4(vec3(water),1.0);

}

Even without colors, the animation already resembles moving water.

Adding Water Colours

Now apply a blue gradient.

vec3 color = mix(

vec3(0.05,0.15,0.45),

vec3(0.35,0.75,1.0),

water

);

Dark blue represents deeper areas.

Light blue highlights the wave peaks.

Making the Water Calmer

Reduce the animation speed.

uTime * 0.8

The water now resembles a quiet lake.

Creating Rough Water

Increase the FBM scale.

fbm(

uv * 6.0

);

The waves become much more detailed.

Adding Flow

Instead of moving only the waves, move the coordinates.

uv.x +=

uTime * 0.1;

The entire water surface begins to drift naturally.

Where Is Procedural Water Used?

Procedural water appears everywhere.

  • Oceans.
  • Rivers.
  • Lakes.
  • Swimming pools.
  • Waterfalls.
  • Fantasy environments.
  • Motion graphics.
  • Background animations.
  • User interfaces.
  • Video games.

Many professional water shaders begin with nothing more than animated sine waves and procedural noise.

Try These Experiments

Create gentle ripples.

Create stormy water.

Increase the distortion.

Slow the animation.

Speed it up.

Change the color gradient.

Combine three wave layers instead of two.

Observe how each adjustment changes the feeling of the water.

A Small Challenge

Can you create these effects?

  • A peaceful lake.

  • Ocean waves.

  • A magical glowing river.

  • Rain ripples.

  • A moving underwater background.

Every one of these begins with the same mathematical building blocks.

Posted Using INLEO

Sort:  

Congratulations @hey2d! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You published more than 70 posts.
Your next target is to reach 80 posts.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out our last posts:

Feedback from the July Hive Power Up Day
Hive Power Up Month Challenge - June 2026 Winners List
Be ready for the July edition of the Hive Power Up Month!