A generic Particle Framework built for Shadertoy, supporting hundreds of thousands of particles in real time — all within the strict constraints of the Shadertoy environment, which proved a significant technical challenge.
Shadertoy consists of 5 fullscreen passes per frame, and you have access to the previous version of each buffer to read from. This project implements a spatial partitioning system that updates from frame to frame, based on the new positions of the particles.
Buffer A holds all the particle data, which can be easily extended to include more or less data (at the cost of fewer max particles). While rendering buffer A, we also perform whatever logic each particle implements. It uses the results of the spatial partitioning from the last frame to do quick checks against neighbouring particles, without the need to check all particles.
Buffer B divides the screen into tiles, and for each tile calculates how many particles are in it, checking all particles that were in neighbouring tiles in the previous frame.
Buffer C counts in each bucket of tiles what index a specific tile starts on. This way, in combination with the count of particles in a tile in Buffer B, we define a range in Buffer D where we will store the particles of this tile for easy lookup in the image and in Buffer A.
Buffer D contains the sorted list of particles per tile, based on the count in B and the offset in C.
Image visualizes the particles. Using the spatial partitioning, we only need to check a small subset of particles to figure out which will be visible in a certain pixel.