Simulating smoke with particles

Smoke is characterized by many small particles that float away from the source, and spread out as they move through the air. We can simulate the floatation effect with particles by using a small upwards acceleration (or constant velocity), but simulating the diffusion of each small smoke particle would be too expensive. Instead, we can simulate the diffusion of many small particles by making our simulated particles change their size (grow) over time.

The following image shows an example of the results:

Simulating smoke with particles

The texture for each particle is a very light "smudge" of grey or black color.

To make the particles grow over time, we'll make use of the GL_PROGRAM_POINT_SIZE functionality in OpenGL, which allows us to modify the point size within the vertex shader.

Note

Alternatively, we could draw quads, or use the geometry shader to generate the quads using the technique demonstrated in Chapter 6, Using Geometry and Tessellation Shaders.

Getting ready

Start with the basic particle system presented in the recipe Creating a particle system using transform feedback.

Set the uniform variable Accel to a small upward value like (0.0, 0.1, 0.0).

Set the uniform variable ParticleLifetime to about six seconds.

Create and load a texture for the particles that looks like just light grey smudge. Bind it to texture unit zero, and set the uniform ParticleTex to zero.

Set the uniform variables MinParticleSize and MaxParticleSize to 10 and 200 respectively.

How to do it...

Use the following steps:

  1. Set the initial positions to the origin. Define the initial velocities in the same way as described in the recipe Creating a particle system using transform feedback. However, it looks best when you use a large variance in theta.
  2. Within the vertex shader, add the following uniforms:
    uniform float MinParticleSize;
    uniform float MaxParticleSize;
  3. Also within the vertex shader, use the following code for the render function:
    subroutine (RenderPassType)
    void render() {
      float age = Time - VertexStartTime;
      Transp = 0.0;
      if( Time >= VertexStartTime ) {
        float agePct = age/ParticleLifetime;
        Transp = 1.0 - agePct;
        gl_PointSize =   
          mix(MinParticleSize,MaxParticleSize,agePct);
      }
      gl_Position = MVP * vec4(VertexPosition, 1.0);
    }
  4. In the main OpenGL application, before rendering your particles, make sure to enable GL_PROGRAM_POINT_SIZE:
    glEnable(GL_PROGRAM_POINT_SIZE);

How it works...

The render subroutine function sets the built-in variable gl_PointSize to a value between MinParticleSize and MaxParticleSize, determined by the age of the particle. This causes the size of the particles to grow as they evolve through the system.

Note that the variable gl_PointSize is ignored by OpenGL unless GL_PROGRAM_POINT_SIZE is enabled.

See also

  • The Creating a particle system using transform feedback recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.76.0