Downhill Water Flow

Shader that simulates the flow of water depending on the normal of the mesh.

Shader code
shader_type spatial;
render_mode specular_schlick_ggx;

uniform sampler2D ground_albedo;
uniform sampler2D ground_normal_map : hint_normal;
uniform sampler2D ground_roughness;
uniform sampler2D rain_splash : hint_normal;
uniform sampler2D rain_wet_normal : hint_normal;
uniform sampler2D noise;

uniform float blend_raining;

uniform vec3 world_up;

varying vec3 normal_vec;

float bias(float value,float power){
	return pow(value,power);

void vertex(){
	normal_vec = NORMAL;

void fragment(){
	float fresnel = sqrt(1.0 - dot(NORMAL, VIEW));
	float offset = texture(noise,UV).r*0.5;
	vec3 water_travel_direction = world_up - normal_vec;
	vec2 compressed_water_travel_direction = water_travel_direction.xz;
	ROUGHNESS = (1.0 - blend_raining) + fresnel*0.1;
	METALLIC = bias(blend_raining,0.5)/2.0+0.3;
	SPECULAR = 1.0;
	float mix_factor = -((2.0*(0.5))/3.141592)*asin(sin((2.0*3.141592)*(TIME+0.25+offset)))+0.5;
	vec3 newnormal = mix(texture(rain_wet_normal,UV+compressed_water_travel_direction*mod(TIME+0.5+offset,1.0)).rgb,texture(rain_wet_normal,UV+compressed_water_travel_direction*mod(TIME+offset,1.0)).rgb,mix_factor);
	NORMALMAP = mix(texture(ground_normal_map,UV).rgb,newnormal,bias(blend_raining,0.4));
	ALBEDO = texture(ground_albedo,UV+(newnormal.xz*bias(blend_raining,8.0)/50.0)).rgb + fresnel*0.1;
	RIM = blend_raining / 10.0;
downhill, flow, Shiny, 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

Pixelated animated water/clouds

(Another) Water Shader

Pixel Animated Water

Notify of

Newest Most Voted
Inline Feedbacks
View all comments
Elefantastique Games
2 years ago

Thank you for sharing! This shader is very useful

2 months ago

Looks great, thanks!