A 3D application developed for my final project in my Computer Graphics class.
Below is a demo video, initially rendering 2,250,000 particles at 120 frames per second.

The general idea for this project is to use a compute shader to update the positions of all particles in the system on GPU hardware, without intervention from the CPU. For the most part this was implemented successfully, although the positions of heavy masses at the center, bounding spheres, and various other user-controllable elements are updated on the CPU through ImGui. Despite this portion of the calculations occurring on the CPU, any actual physics are calculated on the graphics card. This is accomplished through the use of a Shader Storage Buffer Object, which can be written to by a compute shader and read from as an array buffer by the vertex and fragment shaders. No other shaders are used, although perhaps use of an additional geometry or tesselation shader in the rendering pipeline could yield a more interesting scene.

Surprisingly enough the physics computations are very fast compared to OpenGL's rendering of the actual particles, so they are rendered as GL_POINTS to reduce frametimes there. In the future, I would like to modify this program so that each particle has mass in order to ensure that physics calculations are the constraint as opposed to simply putting the particles on screen.

Other future works to improve performance include testing various storage objects like textures or array buffers and interlacing data for each point within a single storage object to improve memory coherency. Future projects using similar techniques would include turbulent flow simulation, 3d flocking simulation, and allowing each particle to have mass to ensure the compute shader is the performance bottleneck.

Tools utilized: C++, OpenGL, GLEW, GLFW, GLM, ImGui, qrenderdoc