Particle simulations - this time in parallel! Since the simulation is run as a shader on the GPU, it can handle millions of particles at once!
Due to WebGL issues, the simulation does not work on your device
Each particle is being represented as a pixel in a simulation texture. Because every pixel has 4 color channels, 4 floating point numbers can be stored per particle. The first two represent the 2D position (x and y coordinate), the second two usually get used for velocity. Since the particles in this particular simulation will be travelling at constant speeds, I decided to only store the direction instead and keep a free channel for additional data, like mass. At each time step we use a fragment shader to update the simulation texture, by calculating the new velocity and position using a simple Euler integration step. The updated colors are written to one of two framebuffers, that get swapped each frame (Ping-Pong Shader).
Obviously we don't want a noisy image like in the figure above, so how do we draw the particles to the
screen? That happens in the Vertex Shader. For each pixel of the simulation texture, a vertex is created,
whose coordinates get read from the red and green channels of the according pixel. Since the simulation is only
2D, the z coordinate of all particles is set to 0. Using the handy
GL_POINTS rendering mode, these
vertecies can then be drawn to the screen as points!
What happened? The particles should be moving outwards in a straight line, but instead they are all collecting in the upper right corner! This error is caused by the numeric precision of the texture. By default, textures store color values as unsigned 8bit integers - that means only 256 values ranging [0, 1] are available. That might be fine for the typical color data stored in textures, but a simulation requires both higher precision and range. I opted for 32bit floating point textures, which allow for arbitrary unclamped values with very high numeric precision.
This looks a lot more like it! With the basic simulation up and running, many other concepts can be explored. One possibility would be to add force fields or interactions between particles. In the demo above, the particles get initialized with different starting directions and turn towards the center when they're outside of a predefined circle. Depending on the initial conditions, interesting geometric patterns can form. One other example I'll be exploring soon, are agent based simulations of slime molds.