The Batman Poster Rain Effect

Creating the rain for The Batman movie poster using GLSL

This was built using the TWGL library, and the relevant fragment shader code is as follows:

precision mediump float;
        
uniform vec2 resolution;
uniform float time;
uniform sampler2D bgTexture;

mat2 rotate(float a)
{
    return mat2(cos(a), -sin(a), sin(a), cos(a));
}

float random (vec2 uv)
{
    // bookofshaders.com
    return fract(sin(dot(uv, vec2(12.9898,78.233))) * 43758.5453123);
}

float rain(vec2 uv, float cols, float rows)
{
    vec2 uv2 = vec2(uv.x * cols, uv.y * rows);
    vec2 gv = fract(uv2) - 0.5;
    vec2 id = floor(uv2);
        
    float n = random(id) - 0.2 + sin(time + id.x) * 0.5;
    float r = smoothstep(0.05, 0.0, abs(gv.x + n));
    r *= smoothstep(n, n - 0.1, abs(gv.y));
    return r * n;
}

void main()
{
    vec2 uv = gl_FragCoord.xy / resolution;
    vec4 t = texture2D(bgTexture, uv);
    uv *= rotate(0.4);

    float y = uv.y + time * 2.;
    float r = rain(vec2(uv.x, y), 20., 16.) * 0.5;
    y = uv.y + time * 2.5;
    r += rain(vec2(uv.x, y), 25., 12.) * 0.5;
    y = uv.y + time * 3.;
    r += rain(vec2(uv.x, y), 26., 18.) * 0.5;
    r += rain(vec2(uv.x, y), 8., 6.) * 0.5;
    r *= 1.5;
    
    t.rgb += r * vec3(1., 0.25, 0.25); // red bias
    gl_FragColor = t;
}