Pixelated animated water/clouds

Works with Godot 4.0

This is meant to be used as a ShaderMaterial on anything.

For background use colorRect, for specific shapes use spites.

With some changes in colors and lowered dithering can produce clouds

Was made by combining:

water – https://godotshaders.com/shader/pixel-ghibli-water/

noise – https://godotshaders.com/snippet/2d-noise/

Shader code
shader_type canvas_item;

uniform float transparency : hint_range(0, 1) = 1.0;

uniform vec4 color0 : source_color = vec4(0.01, 0.0, 1.0, 1.0);
uniform vec4 color1 : source_color = vec4(0.32, 0.2, 1.0, 1.0);
uniform vec4 color2 : source_color = vec4(0.34, 0.41, 1.0, 1.0);
uniform vec4 color3 : source_color = vec4(0.39, 0.52, 1.0, 1.0);

uniform vec2 Direction = vec2(1, 1); 
uniform float Speed = 1.00;

uniform float thresholds[3];
//my values: [0.6, 0.66, 0.75]

uniform int OCTAVE = 6;
uniform int pixel_size;
uniform float dithering = 2.5;

vec2 random(vec2 uv){
    uv = vec2( dot(uv, vec2(127.1,311.7) ),
               dot(uv, vec2(269.5,183.3) ) );
    return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
}

float noise(vec2 uv) {
    vec2 uv_index = floor(uv);
    vec2 uv_fract = fract(uv);

    vec2 blur = smoothstep(0.0, 1.0, uv_fract);

    return mix( mix( dot( random(uv_index + vec2(0.0,0.0) ), uv_fract - vec2(0.0,0.0) ),
                     dot( random(uv_index + vec2(1.0,0.0) ), uv_fract - vec2(1.0,0.0) ), blur.x),
                mix( dot( random(uv_index + vec2(0.0,1.0) ), uv_fract - vec2(0.0,1.0) ),
                     dot( random(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) + 0.5;
}

float fbm(vec2 input){
	float value = 0.0;
	float scale = 0.2;
	
	input *= TIME/3000.0 + 1.0;
	
	for(int i = 0; i < OCTAVE; i++){
		value += noise(input)*scale;
		input *= dithering;
	}
	
	return clamp(value, 0.0, 1.0);
}

float get_pixelated_moving_colors(vec2 uv, vec2 direction, float speed) {
	speed = speed / 1000.0;
	direction*=-1.0;
	vec2 moving_uv = uv + (direction * TIME * speed) + vec2(0.5/float(pixel_size));
	vec2 pixel_uv = round((moving_uv) * float(pixel_size)) / float(pixel_size);
	float pixelated_color = fbm(pixel_uv);
	return pixelated_color;
}

vec4 smooth_extreme_colors(float color) {
	// Dark to light
	if (color<=thresholds[0]) {
        return color0;
    } else if (thresholds[0]<color && color<=thresholds[1]) {
        return color1;
    } else if (thresholds[1]<color && color<=thresholds[2]) {
        return color2;
    } else if (thresholds[2]<=color) {
        return color3;
	}
}

void fragment(){
	if (COLOR.a > 0.0001){
	float pixelated_color = get_pixelated_moving_colors(UV, Direction, Speed);
	vec4 smoothed_color = smooth_extreme_colors(pixelated_color);
	
	COLOR = smoothed_color * transparency;
	}
}
Tags
2d, clouds, pixel, water
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

Volumetric Raymarched (animated) Clouds v2

Pixel Animated Water

3D Pixelated Planet

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments