This is a Javascript demo that simulates ray-traced raindrops.

Night scene

You can click to add new raindrops.

Each raindrop is represented using Gaussian metaballs centered at positions \vec{x}_i = (u_i, v_i). A pixel at position \vec{x} = (u,v) is part of a raindrop if:

1 \displaystyle{\begin{align}\sum_{i=0}^n \operatorname{exp}\left(\frac{\|\vec{x}-\vec{x}_i\|^2}{\sigma}\right) > \text{threshold}\end{align}}

If the pixel is within a raindrop, it has a corresponding surface normal that is the gradient of the above function. To get the refracted image, we then query the colour of the image a point offset from the pixel by some constant times the normal vector. Some shading is also done with luminosity dependent on normal.

Background image credit: Matanaka farm buildings by Karora, Public Domain