Pixel Animated Water

Works in godot 3.5

This is meant to be used as a ShaderMaterial on a TextureRect

The TextureRect needs to have a scrolling noise texture to work (I know this is possible to generate via godot, but I like this noise generator here that lets you download the texture as a png instead: http://kitfox.com/projects/perlinNoiseMaker/)

Shader code
shader_type canvas_item;
render_mode blend_mix,unshaded;

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

uniform vec4 color0 : hint_color;
uniform vec4 color1 : hint_color;
uniform vec4 color2 : hint_color;
uniform vec4 color3 : hint_color;
uniform vec4 color4 : hint_color;
uniform vec4 color5 : hint_color;

uniform vec2 Direction1 = vec2(1, 0); 
uniform vec2 Direction2 = vec2(1, 1); 
uniform float Speed1 = 0.08;
uniform float Speed2 = 0.08;
uniform sampler2D noise;
uniform int pixel_size;

uniform float heatAmplitude : hint_range(0.0, 0.15);
uniform float heatPeriod;
uniform float heatPhaseShift;
uniform float heatUpperLimit : hint_range(0.5, 10.0);

vec4 get_pixelated_moving_colors(vec2 uv, vec2 direction, float speed) {
	speed = speed / 1000.0;
	vec2 moving_uv = uv + (direction * TIME * speed);
	vec2 pixel_uv = round((moving_uv) * float(pixel_size)) / float(pixel_size);
	vec4 pixelated_color = texture(noise, pixel_uv);
	return pixelated_color;
}

bool is_in_threshold(vec4 old_color, float threshold_low, float threshold_hi){
	if(threshold_low <= old_color.r + old_color.g + old_color.b && old_color.r + old_color.g + old_color.b < threshold_hi) {
        return true;
    } else {
		return false;
	}
}

vec4 smooth_extreme_colors(vec4 color) {
	// Lower numbers are darker
	float threshold_1 = 1.7;
	float threshold_2 = 1.9;
	float threshold_3 = 2.2;
	float threshold_4 = 2.25;
	float threshold_5 = 2.3;
	// Dark to light
	if (is_in_threshold(color, 0, threshold_1)) {
        color = color0;
    } else if (is_in_threshold(color, threshold_1, threshold_2)) {
        color = color1;
    } else if (is_in_threshold(color, threshold_2, threshold_3)) {
        color = color2;
    } else if (is_in_threshold(color, threshold_3, threshold_4)) {
        color = color3;
	} else if (is_in_threshold(color, threshold_4, threshold_5)) {
        color = color4;
    } else if (is_in_threshold(color, threshold_5, 3.0)) {
        color = color5;
    }
	
	return color;
}


void fragment(){
	
	vec4 pixelated_color = .5 * get_pixelated_moving_colors(UV, Direction1, Speed1);
	pixelated_color += .5 * get_pixelated_moving_colors(UV, Direction2, Speed2);
	vec4 smoothed_color = smooth_extreme_colors(pixelated_color);
	
	COLOR = smoothed_color * transparency;

}
Tags
ghibli, pixel, water
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

Pixelated animated water/clouds

Sub-Pixel Accurate Pixel-Sprite Filtering

Pixel Art Water

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Gluc
Gluc
1 year ago

Thank you for this great shader!
Would this work in Godot 4?

Kersten
Kersten
3 months ago
Reply to  Gluc

It actually does, with little adaption.
“hint_color” must be changed to “source_color”
and after adding a noise texture you need to
change “uniform sampler2D noise;” to “uniform sampler2D noise : repeat_enable;”

For me it works that way in Godot4.
But I am struggeling finding good colors and parameters.