137 lines
4.5 KiB
GLSL
137 lines
4.5 KiB
GLSL
#define PI 3.14159265
|
|
|
|
#pragma glslify: import("./imports/commonUniforms.glsl")
|
|
#pragma glslify: random = require("./requires/random1d")
|
|
|
|
extern vec2 u_mouse;
|
|
extern vec2 u_resolution;
|
|
extern float u_time;
|
|
|
|
float rand( float x )
|
|
{
|
|
// setup
|
|
float i = floor(x);
|
|
float f = fract(x);
|
|
float s = sign(fract(x/2.0)-0.5);
|
|
|
|
// use some hash to create a random value k in [0..1] from i
|
|
//float k = hash(uint(i));
|
|
//float k = 0.5+0.5*sin(i);
|
|
float k = fract(i*.1731);
|
|
|
|
// quartic polynomial
|
|
return s*f*(f-1.0)*((16.0*k-4.0)*f*(f-1.0)-1.0);
|
|
}
|
|
|
|
/*
|
|
* Returns a random drop position for the given seed value
|
|
*/
|
|
vec2 random_drop_pos(float val, vec2 screen_dim, vec2 velocity) {
|
|
float max_x_move = velocity.x * abs(screen_dim.y / velocity.y);
|
|
float x = -max_x_move * step(0.0, max_x_move) + (screen_dim.x + abs(max_x_move)) * rand(val);
|
|
float y = (1.0 + 0.05 * rand(1.234 * val)) * screen_dim.y;
|
|
|
|
return vec2(x, y);
|
|
}
|
|
|
|
/*
|
|
* Calculates the drop trail color at the given pixel position
|
|
*/
|
|
vec3 trail_color(vec2 pixel, vec2 pos, vec2 velocity_dir, float width, float size) {
|
|
vec2 pixel_dir = pixel - pos;
|
|
float projected_dist = dot(pixel_dir, -velocity_dir);
|
|
float tanjential_dist_sq = dot(pixel_dir, pixel_dir) - pow(projected_dist, 2.0);
|
|
float width_sq = pow(width, 2.0);
|
|
|
|
float line = step(0.0, projected_dist) * (1.0 - smoothstep(width_sq / 2.0, width_sq, tanjential_dist_sq));
|
|
float dashed_line = line * step(0.5, cos(0.3 * projected_dist - PI / 3.0));
|
|
float fading_dashed_line = dashed_line * (1.0 - smoothstep(size / 5.0, size, projected_dist));
|
|
|
|
return vec3(fading_dashed_line);
|
|
}
|
|
|
|
/*
|
|
* Calculates the drop wave color at the given pixel position
|
|
*/
|
|
vec3 wave_color(vec2 pixel, vec2 pos, float size, float time) {
|
|
vec2 pixel_dir = pixel - pos;
|
|
float distorted_dist = length(pixel_dir * vec2(1.0, 3.5));
|
|
|
|
float inner_radius = (0.05 + 0.8 * time) * size;
|
|
float outer_radius = inner_radius + 0.25 * size;
|
|
|
|
float ring = smoothstep(inner_radius, inner_radius + 5.0, distorted_dist)
|
|
* (1.0 - smoothstep(outer_radius, outer_radius + 5.0, distorted_dist));
|
|
float fading_ring = ring * (1.0 - smoothstep(0.0, 0.7, time));
|
|
|
|
return vec3(fading_ring);
|
|
}
|
|
|
|
/*
|
|
* Calculates the background color at the given pixel position
|
|
*/
|
|
vec3 background_color(vec2 pixel, vec2 screen_dim, float time) {
|
|
return vec3(0.0, 0.0, 1.0 - smoothstep(-1.0, 0.8 + 0.2 * cos(0.5 * time), pixel.y / screen_dim.y));
|
|
}
|
|
|
|
/*
|
|
* The main program
|
|
*/
|
|
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) {
|
|
// Set the total number of rain drops that are visible at a given time
|
|
const float n_drops = 20.0;
|
|
|
|
// Set the drop trail radius
|
|
float trail_width = 2.0;
|
|
|
|
// Set the drop trail size
|
|
float trail_size = 70.0;
|
|
|
|
// Set the drop wave size
|
|
float wave_size = 20.0;
|
|
|
|
// Set the drop fall time in seconds
|
|
float fall_time = 0.7;
|
|
|
|
// Set the drop total life time
|
|
float life_time = fall_time + 0.5;
|
|
|
|
// Set the drop velocity in pixels per second
|
|
vec2 velocity = vec2(u_mouse.x - 0.5 * u_resolution.x, -0.9 * u_resolution.y) / fall_time;
|
|
vec2 velocity_dir = normalize(velocity);
|
|
|
|
// Iterate over the drops to calculate the pixel color
|
|
vec3 pixel_color = vec3(0.0);
|
|
|
|
for (float i = 0.0; i < n_drops; ++i) {
|
|
// Offset the running time for each drop
|
|
float time = u_time + life_time * (i + i / n_drops);
|
|
|
|
// Calculate the time since the drop appeared on the screen
|
|
float ellapsed_time = mod(time, life_time);
|
|
|
|
// Calculate the drop initial position
|
|
vec2 initial_pos = random_drop_pos(i + floor(time / life_time - i) * n_drops, u_resolution, velocity);
|
|
|
|
// Add the drop to the pixel color
|
|
if (ellapsed_time < fall_time) {
|
|
// Calculate the drop current position
|
|
vec2 current_pos = initial_pos + ellapsed_time * velocity;
|
|
|
|
// Add the trail color to the pixel color
|
|
pixel_color += trail_color(gl_FragCoord.xy, current_pos, velocity_dir, trail_width, trail_size);
|
|
} else {
|
|
// Calculate the drop final position
|
|
vec2 final_pos = initial_pos + fall_time * velocity;
|
|
|
|
// Add the wave color to the pixel color
|
|
pixel_color += wave_color(gl_FragCoord.xy, final_pos, wave_size, ellapsed_time - fall_time);
|
|
}
|
|
}
|
|
|
|
// Add the background color to the pixel color
|
|
pixel_color += Texel(texture, texture_coords).xyz;
|
|
|
|
// Fragment shader output
|
|
return vec4(pixel_color, 1.0);
|
|
} |