1#version 150 2 3uniform UBO 4{ 5 mat4 MVP; 6 vec2 OutputSize; 7 float time; 8} global; 9 10layout(location = 0) out vec4 FragColor; 11 12const float baseScale = 3.5; // [1.0 .. 10.0] 13const float density = 0.7; // [0.01 .. 1.0] 14const float speed = 0.25; // [0.1 .. 1.0] 15 16float rand(vec2 co) 17{ 18 return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); 19} 20 21float dist_func(vec2 distv) 22{ 23 float dist = sqrt((distv.x * distv.x) + (distv.y * distv.y)) * (40.0 / baseScale); 24 dist = clamp(dist, 0.0, 1.0); 25 return cos(dist * (3.14159265358 * 0.5)) * 0.5; 26} 27 28float random_dots(vec2 co) 29{ 30 float part = 1.0 / 20.0; 31 vec2 cd = floor(co / part); 32 float p = rand(cd); 33 34 if (p > 0.005 * (density * 40.0)) 35 return 0.0; 36 37 vec2 dpos = (vec2(fract(p * 2.0) , p) + vec2(2.0, 2.0)) * 0.25; 38 39 vec2 cellpos = fract(co / part); 40 vec2 distv = (cellpos - dpos); 41 42 return dist_func(distv); 43} 44 45float snow(vec2 pos, float time, float scale) 46{ 47 // add wobble 48 pos.x += cos(pos.y * 1.2 + time * 3.14159 * 2.0 + 1.0 / scale) / (8.0 / scale) * 4.0; 49 // add gravity 50 pos += time * scale * vec2(-0.5, 1.0) * 4.0; 51 return random_dots(pos / scale) * (scale * 0.5 + 0.5); 52} 53 54void main(void) 55{ 56 float tim = global.time * 0.4 * speed; 57 vec2 pos = gl_FragCoord.xy / global.OutputSize.xx; 58 pos.y = 1.0 - pos.y; // Flip Y 59 float a = 0.0; 60 // Each of these is a layer of snow 61 // Remove some for better performance 62 // Changing the scale (3rd value) will mess with the looping 63 a += snow(pos, tim, 1.0); 64 a += snow(pos, tim, 0.7); 65 a += snow(pos, tim, 0.6); 66 a += snow(pos, tim, 0.5); 67 a += snow(pos, tim, 0.4); 68 a += snow(pos, tim, 0.3); 69 a += snow(pos, tim, 0.25); 70 a += snow(pos, tim, 0.125); 71 a = a * min(pos.y * 4.0, 1.0); 72 FragColor = vec4(1.0, 1.0, 1.0, a); 73} 74