Procedural Window Rain Drop Shader

A procedural window rain drop shader.

It has dripping rain and static rain.

Shader code
/*
	動的窓の雨 水滴シェーダー for Godot Engine by あるる(きのもと 結衣) @arlez80
	Procedural Window Raindrop Shader by Yui Kinomoto @arlez80

	MIT License
*/
shader_type spatial;

const float PI = 3.1415926535;

uniform float dripping_speed = 1.0;
uniform vec2 dripping_wave_size = vec2( 20.0, 4.0 );
uniform vec2 dripping_wave_freq = vec2( 47.0, 15.0 );
uniform vec2 dripping_wave_power = vec2( 0.045, 1.0 );

uniform float static_interval = 10.0;
uniform vec2 static_shift = vec2( 4.8, 0.8 );
uniform vec2 static_wave_size = vec2( 81.432143, 85.45453 );
uniform vec2 static_wave_freq = vec2( 38.0, 92.0 );
uniform vec2 static_wave_power = vec2( 1.8, 2.8 );

vec2 distance_line_point( vec2 a, vec2 b, vec2 p )
{
	vec2 v = b - a;
	vec2 vp = p - a;
	float r = clamp( dot( v, vp ) / dot( v, v ), 0.0, 1.0 );

	return mix(
		a - p
	,	b - p
	,	r
	);
}

void fragment( )
{
	vec2 uv_drip = UV * dripping_wave_size + vec2( cos( UV.y * dripping_wave_freq.x ), sin( UV.x * dripping_wave_freq.y ) ) * dripping_wave_power + vec2( 0.0, -TIME * dripping_speed );
	vec2 n = vec2( 0.5, 0.5 );

	// 動的雨粒
	vec2 v = distance_line_point( vec2( 0.5, 0.2 ), vec2( 0.5, 0.8 ), mod( uv_drip, 1.0 ) );
	n = mix( n, n - v * 10.0, float( length( v ) < mod( uv_drip.y, 1.0 ) * 0.1 ) );

	// 静的雨粒
	// n = mix( n, n )
	vec2 uv_static = static_shift + UV * static_wave_size + vec2( sin( cos( UV.y * static_wave_freq.x ) ), cos( sin( UV.x ) * static_wave_freq.y ) ) * static_wave_power;
	vec2 sv = mod( uv_static, static_interval ) - vec2( 0.5, 0.5 );
	n = mix( n, n + sv, float( length( sv ) < 0.5 ) );

	vec3 nv = normalize( vec3( n, 1.0 ) );

	ALBEDO = texture( SCREEN_TEXTURE, SCREEN_UV ).rgb;
	NORMALMAP = nv;
}
Tags
Procedural, rain, Window
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.

More from arlez80

Glitch Effect Shader for Godot Engine 4

Outline Silhouette Shader

Magical Shield Shader #4

Related shaders

Basic Skyscraper Window Lights

Simple rain/snow shader

Rain and Snow with Parallax Effect

Subscribe
Notify of
guest

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
FakiAZer
1 year ago

Damn that looks good !

Mazander
Mazander
9 months ago

Amazing shader! I updated it for ya for godot 4.2:
/*
   動的窓の雨 水滴シェーダー for Godot Engine by あるる(きのもと 結衣)
   Procedural Window Raindrop Shader by Yui Kinomoto

   MIT License
*/
shader_type spatial;

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;

uniform float dripping_speed = 1.0;
uniform vec2 dripping_wave_size = vec2( 20.0, 4.0 );
uniform vec2 dripping_wave_freq = vec2( 47.0, 15.0 );
uniform vec2 dripping_wave_power = vec2( 0.045, 1.0 );

uniform float static_interval = 10.0;
uniform vec2 static_shift = vec2( 4.8, 0.8 );
uniform vec2 static_wave_size = vec2( 81.432143, 85.45453 );
uniform vec2 static_wave_freq = vec2( 38.0, 92.0 );
uniform vec2 static_wave_power = vec2( 1.8, 2.8 );

vec2 distance_line_point( vec2 a, vec2 b, vec2 p )
{
   vec2 v = b – a;
   vec2 vp = p – a;
   float r = clamp( dot( v, vp ) / dot( v, v ), 0.0, 1.0 );

   return mix(
      a – p
   ,   b – p
   ,   r
   );
}

void fragment( )
{
   vec2 uv_drip = UV * dripping_wave_size + vec2( cos( UV.y * dripping_wave_freq.x ), sin( UV.x * dripping_wave_freq.y ) ) * dripping_wave_power + vec2( 0.0, -TIME * dripping_speed );
   vec2 n = vec2( 0.5, 0.5 );

   // 動的雨粒
   vec2 v = distance_line_point( vec2( 0.5, 0.2 ), vec2( 0.5, 0.8 ), mod( uv_drip, 1.0 ) );
   n = mix( n, n – v * 10.0, float( length( v ) < mod( uv_drip.y, 1.0 ) * 0.1 ) );

   // 静的雨粒
   // n = mix( n, n )
   vec2 uv_static = static_shift + UV * static_wave_size + vec2( sin( cos( UV.y * static_wave_freq.x ) ), cos( sin( UV.x ) * static_wave_freq.y ) ) * static_wave_power;
   vec2 sv = mod( uv_static, static_interval ) – vec2( 0.5, 0.5 );
   n = mix( n, n + sv, float( length( sv ) < 0.5 ) );

   vec3 nv = normalize( vec3( n, 1.0 ) );

   ALBEDO = texture( SCREEN_TEXTURE, SCREEN_UV ).rgb;
   NORMAL = nv;
}

DangerMike
DangerMike
1 month ago

It works great, thanks for the update. I did get an ‘-‘ unknown symbol error message. It’s supposed to be a minus sign, so if you just replace it with a minus sign, it works fine.