Simple bounded particles using compute shaders in OpenGL

In an attempt to learn more about openGL, I wanted to create a minimal project to test the functionality of compute shaders in physics simulations. Here I’m further explaining my implementation which can be seen in the Github repo!

This project does the following:
1. Create 1024*1024 point particles with a random position and velocity
2. Simulate the particles using a compute shader. They bounce off the walls of the bounding box.
3. Render the particles and a bounding box

The tools used are:
– C++ and openGL
glm
GLFW for window and input management

Here’s a brief explanation of what I’ve got so far. I’m still learning OpenGL so if you have any feedback on better ways to do this, please let me know! Other than that, I assume you have a basic understanding of openGL concepts. The code provided does not make a complete project but you should be able to put it into your openGL project (hopefully) without anything breaking.

Please note that I have also used some helper modules for shader and camera functionality, but most of the interesting code is found in boundingBox.cpp and particleSystem.cpp.

Bounding box

To make it simpler to implement, the bounding box has no orientation. This means that we can define our bounding box using two points, relative to the origin:

This means that we can define a volume for our particles to live inside simply by inputting two vec3 as uniforms into our compute shader!

Bounding box: Creating the wireframe object

It took me a while to figure out how to correctly do this, but here’s a set of indices and vertices that displays the wireframe if you use glDrawElements(GL_LINES...)

unsigned int createWireframeCube(glm::vec3 scale)
{
    glm::vec3 points[8] = {
        {0, 0, 0},
        {1, 0, 0},
        {1, 1, 0},
        {0, 1, 0},
        {0, 0, 1},
        {1, 0, 1},
        {1, 1, 1},
        {0, 1, 1}};

    uint32_t indices[WIREFRAME_NUM_INDICES] = {
        0, 1,
        1, 2,
        2, 3,
        3, 0,
        0, 4,
        1, 5,
        2, 6,
        3, 7,
        4, 5,
        5, 6,
        6, 7,
        7, 4};
    
    for (int i = 0; i < 8; i++) {
        points[i] *= scale;
    }

    // Assign a VAO, VBO and indices as you would
    return vaoID;
}

Note that the scale of the box is calculated to be low-high. This gives the diagonal vector, and when the points all lie on either 0 or 1, multiplying by this diagonal vector will scale the box to the appropriate size!

Particle system

To understand how to implement compute shaders, this powerpoint proved to be really valuable. A lot of my implementation mimics what was done here!

The particles each have a position, velocity and color, all of which are manipulated in the compute shader. On the CPU side, the position, velocity and color are stored in each of their custom structs consisting of 4 floats. Why 4 floats, even for position and velocity? Because that’s what the powerpoint said ¯\_(ツ)_/¯

Further reading

In my search for information, I stumbled upon quite a few resources on the topic. Feel free to check them out!

How to Use and Teach OpenGL Compute Shaders by Mike Bailey
Sebastian Lague’s video on compute shaders
Compute shader presentation by Christian Hafner
Anton Gerdelan’s introduction to compute shaders

Ett svar til «Simple bounded particles using compute shaders in OpenGL»

  1. Interesting read!

    Liker

Legg igjen en kommentar