Particles sit on a sphere, each with a small random offset so the surface has some thickness. A bias force pulls each particle back toward its resting radius, competing with the flow field. The competing forces keep particles near the surface without fixing them there.
The flow field is four-dimensional simplex noise (x, y, z, time). Stepping through the fourth dimension keeps the field evolving smoothly. Three separate samples with different position offsets drive the x, y, and z forces independently.
The particles use a custom ShaderMaterial. The vertex shader reads a per-vertex size attribute for perspective-correct scaling, and the fragment shader clips each point to a circle so you get clean round sprites.
Every few seconds a pulse wave expands outward from a random point on the surface. Particles near the wavefront get a spring force damped by outward velocity, so they oscillate and settle back. They flash white and grow during the wave, then fade back over several frames.