Advice on how to approach data-driven particle generation?

I would like to make a web-based http log visualizer that is somewhat similar to this native one:

The youtube video at the top of that page gives a demonstration of the type of visuals I’m looking for, though mine is intended to be far more basic. Essentially, I’d like to connect to a websocket and for each message received on that socket, I would like to emit a particle whose behavior depends on the data in the message. For simplicity sake, let’s say it should emit one green particle for every message that indicates a 200 http response code and a red particle for every non-200 http response code.

Particles seem to be the right approach for the type of effect I want and the sheer number that would be rendered at any given time, but they don’t seem to fit in with my need to generate them one at a time individually corresponding to the act of receiving data. As far as I can tell, if I only want one particle generated per message received, then each emitter would be responsible for one particle at a time for the life of each particle. Given the number requests per second in the logs I’m trying to visualize, the number of emitters would spin out of control pretty fast if the particle life is even a mere few seconds.

The other option then would be to generate separate meshes for every incoming message and animate them individually, but I imagine this would be horrible for performance at the number of simultaneous particles I need to render - hundreds spawning per second, each with a lifetime of upwards of 5 seconds, meaning at any given time there could easily be several thousand meshes being rendered individually.

Which option makes sense? Is there a way to make particles work the way I want in a performant manner? Am I underestimating the capabilities of Three.js performance and thus should just create the meshes as needed outside of particles? Or is there another approach entirely that I should look at?

Any general advice or points in the right direction would be really appreciated. It’s been a fun learning experience so far with ThreeJS, but I feel stuck.

You could try a similar approach like in this demo:

Especially the basic implementation of GPUParticleSystem might be interesting for you. The idea is to maintain a single BufferGeometry with a predefined size. Every time when your application receives a new message, you add a new set of particle data to the buffer. You are doing this in a cyclic way. That means when the buffer is full, you restart at the beginning.

In this way, you just have a single instance of THREE.Points in your application You can render all data with a single draw call which is good for performance. The geometry of your points object is the mentioned geometry object from above. The material would be a custom THREE.ShaderMaterial.

In each animation step, you update the position of the particles and probably other stuff like colors or opacity.

Also read:

This document explains how you correctly update your geometry when you’ve added new data. Besides, the usage of BufferAttribute.updateRange might be important to you since it allows the definition of partial updates of a WebGLBuffer (good for performance). GPUParticleSystem uses this approach, too.

@Mugen87 Thanks! I’ll take a look. It seems, then, that my gut instinct of utilizing the particle system is correct, I just need to learn how to utilize it in this manner. That’s good to know.