Tutorial 4: Collisions - tiagodinis/GParticles GitHub Wiki

Tutorial 4 covers how we can make particles interact with the world with collision detection. Here's our goal: create a system whose particles fall into the ground and bounce from it with decreased velocity.

After making a copy of the "/Tutorial_3" folder in the same directory and changing every reference to "Tutorial_4", we open the project xml file and define our colliders. Colliders are the primitives that we'll test particles against for collision. Lets start by adding a floor to our scene with the colliders tag, inside psystem, right below our maxParticles uniform override, for example.

<colliders>
    <static type="plane" x=0 y=1 z=0 d=3 />
</colliders>

Notice we defined our floor with a static tag, since our collider will never change position (only this collider type is supported as of right now). Now, we need to change our "updateMain.glsl" reference to "updateCollisionMain.glsl", so we use a template file that includes the generic collision logic - every particle is tested against every primitive, and the appropriate collider function is called if there is a collision. We also need to reference the file with our collision functions, "collision.glsl".

<update>
    <file path="modules/utilities.glsl" />
    <file path="projects/Tutorial_4/update.glsl" />
    <file path="projects/Tutorial_4/collision.glsl" />
    <file path="templates/updateCollisionMain.glsl" />
</update>

Then, in the emission and update functions, we increase our particles initial lifetime to 10 and add a constant gravity force to their velocity vector:

// emission.glsl
void emission()
{
    @lifetimes[gid] = 10;
    ...
}

-----------------------------------------------------------------------------------
// update.glsl
void update()
{
    @velocities[gid].y -= 0.4 * @deltaTime;
    @positions[gid].xyz += @velocities[gid].xyz * @deltaTime;
}

Next, we move on to the "collision.glsl" file. The new template being referenced calls two functions: sphereCollision and planeCollision. Even if we only use one type of primitive, meaning the other function is never called, we still have to provide its definition. With that in mind, we define these functions like so:

void sphereCollision(vec4 sphere, vec3 collisionPoint, vec3 normal){}

void planeCollision(vec4 plane, vec3 collisionPoint, vec3 normal, float distance)
{
    @positions[gid].xyz = collisionPoint;
    @velocities[gid].xyz = reflect(@velocities[gid].xyz, normal) * 0.85;
}

We just set our particle position to the point of collision and change their velocity vector so they appear to bounce from the floor surface, now with only 85% of its former intensity. Also, note that reflect is not a function from a GParticle file, but from the glsl language. We should run the project and see what we've got.

Now, this is all really nice, but you'd be fooling yourself if you thought colliders can only be used to simulate physical collisions. We can use them as triggers or effect volumes, for example, setting in motion certain processing operations while particles remain inside the collider volume. We'll explore this by adding a new static sphere collider and have particles change color while inside it.

<colliders>
    <static type="plane" x=0 y=1 z=0 d=3 />
</colliders>

We can see inside the "updateCollisionMain.glsl" template that collision processing takes place after update. So, we can accomplish the desired effect if we always set the original color in update and override it to red when the particle is inside the sphere collider and sphereCollision is called.

// update.glsl
void update()
{
    ...
    @colors[gid].xyz = vec3(0.1, 0.9, 0.1);
}

-----------------------------------------------------------------------------------
// collision.glsl
void sphereCollision(vec4 sphere, vec3 collisionPoint, vec3 normal)
{
    @colors[gid].xyz = vec3(0.9, 0.1, 0.1);
}

void planeCollision(vec4 plane, vec3 collisionPoint, vec3 normal, float distance)
{
    ...
}

Awesome! This concludes the tutorial series and it's now up to you to come up with interesting effects using GParticles. Stay tuned, however, as more stuff is coming out soon!


Exercises:

  • Create two particle systems with a model so our colliders can have a visual representation;

  • Try to build a waterfall particle system where particles collide with multiple primitives until they reach the floor;

  • Run the project once again. Get lost in the marvelous beauty of your creation and imagine the infinite possibilities. You might also realize you haven't starred the repository yet, to which you act upon with haste.

⚠️ **GitHub.com Fallback** ⚠️