Processing Tutorial: How to Create Falling Snow Particles

Snow Particles in the Wind

This Processing tutorial shows you how to create snow particles which flow back and forth in the air. Learn how to simulate wind in a particle system, written using the Java programming language. The process is similar for creating rain, falling leaves and cherry blossom particles.

To complete this tutorial, you will need to have followed the previous waterfall particle tutorial here.

Scale

First off we are going to add new data member to the Particle class, so that we can scale the particles to different sizes. Go to the Particle tab and create a new data member called ‘scale’ inside the Particle class.

PVector scale = new PVector(1, 1);

Inside the OnSpawn function, set the scale value of each vector component to 1. This is the default size of the particle.

scale.set(1, 1);

Now we need to change how we render the particles to support scaling. It is possible to do it with the old method, but it creates jittery particles when they move (probably because of floating point numbers). This new way of rendering should be smoother.

P3D

Go to the main tab, and inside of the setup function, add another argument to the size function. This argument will select the P3D renderer, instead of the default renderer.

  size(720, 720, P3D);

More information on the P3D renderer here.

Particle Render

Now we will render the particles using the new renderer method. Go back to the Particle tab. Inside of the Particle class replace the code in the Render function with this code:

  void Render()
  {
    if(!active) return;
    
    tint(col);
    
    pushMatrix();
    translate(pos.x, pos.y);
    final float sw = image.width * scale.x;
    final float sh = image.height * scale.y;
    scale(sw, sh);
    textureMode(NORMAL);
    beginShape();
    texture(image);
    vertex(-0.5, -0.5, 0, 0);// top left
    vertex(0.5, -0.5, 1, 0);// top right
    vertex(0.5, 0.5, 1, 1);// bottom right
    vertex(-0.5, 0.5, 0, 1);// bottom left
    endShape();
    popMatrix();
  }

Like before we check if the particle is active or not before trying to render it.

    if(!active) return;

Then we tint the colour of the particle.

    tint(col);

Now we will call pushMatrix, which is later followed by a popMatrix. These functions are needed when calling translate and scale. Since it means we only want the translate and scale to affect one particle, not all of them.

    pushMatrix();
    // ...
    popMatrix();

Next we will position the particle on the screen using the translate function.

    translate(pos.x, pos.y);

We then scale the particle up or down based on the scale variable.

    final float sw = image.width * scale.x;
    final float sh = image.height * scale.y;
    scale(sw, sh);

Finally we will draw the shape. We want to draw a rectangle, hence why we are using 4 vertices. Since the vertices are the corners of the rectangle. The first 2 arguments of the vertex function refer to the x and y position.

The rectangle is defined using coordinates in the -0.5 to 0.5 range. This allows us to translate to the rectangle’s centre, then scale it to the size we want.

The 3rd and 4th arguments of the vertex function refer to the texture coordinates of the rectangle. Notice how the textureMode function is set to NORMAL. This means it expects the values of the texture coordinates to be in the 0 to 1 range.

We want to render the whole texture, so we specify 4 vertices like so:

  • top left
  • top right
  • bottom right
  • bottom left

We also pass the image to the texture function, so we can render the particle using our image.

    textureMode(NORMAL);
    beginShape();
    texture(image);
    vertex(-0.5, -0.5, 0, 0);// top left
    vertex(0.5, -0.5, 1, 0);// top right
    vertex(0.5, 0.5, 1, 1);// bottom right
    vertex(-0.5, 0.5, 0, 1);// bottom left
    endShape();

Snow Update

Now that we can scale the particles to any size we like, its time to write the snow particle function. Go back to the main tab and create a new function called SnowUpdate.

void SnowUpdate()
{
  final int spawnTime = 50;
  if(millis() - lastTime > spawnTime)
  {
    lastTime = millis();
    final int count = (int)random(5, 7);
    float scale = 0;
    for(int i=0; i<count; ++i)
    {
      Particle p = particleSpawner.Spawn();
      p.image = particleImage;
      
      p.lifeTime = 5000;
      p.pos.set(random(0, width * 1.35), -50);
      scale = random(0.5, 0.75);
      p.scale.set(scale, scale);
      
      p.velocity.set(0, 1.5);
      
      p.col = color(255, 255, 255, 255);
    }
  }
  
  // Gravity
  particleSpawner.AddForce(0, 0.01);
  
  // Wind
  final float s = sin(millis() * 1000);
  final float w = s < -0.8 ? random(0.05, 0.07) : random(0.01, 0.03);
  particleSpawner.AddForce(w * s, 0);
  
  particleSpawner.Update();
}

Like before, we are going to render a random number of particles every so many milliseconds. We also created a scale variable which we can reuse every time the for loop loops.

  final int spawnTime = 50;
  if(millis() - lastTime > spawnTime)
  {
    lastTime = millis();
    final int count = (int)random(5, 7);
    float scale = 0;
    for(int i=0; i<count; ++i)

So first we spawn a particle, set the image, then set the lifetime of the particle.

      Particle p = particleSpawner.Spawn();
      p.image = particleImage;
      
      p.lifeTime = 5000;

Next we set the position of the particle. We are going to set some of the particles to be outside the right edge of the screen and above the screen. This is so that the particles don’t just pop in from nowhere, and because the wind will mostly blow to the left, as you will see later.

      p.pos.set(random(0, width * 1.35), -50);

Next we will set the scale of the particles to a random number.

      scale = random(0.5, 0.75);
      p.scale.set(scale, scale);

Then we set the initial velocity of the particle to move straight downwards.

      p.velocity.set(0, 1.5);

Finally we set the colour of the particle. In this case, the particle will be pure white, since it is snow!

      p.col = color(255, 255, 255, 255);

Outside the for loop, we set the gravity of all particles to a small value.

  // Gravity
  particleSpawner.AddForce(0, 0.01);

Now we will set the wind, which will affect all the particles. We first create a variable called ‘s’. This variable is calculated using the current time in milliseconds. The time in milliseconds has been converted to seconds, since it has been multiplied by 1000.

  // Wind
  final float s = sin(millis() * 1000);

The sine wave function will return a value in the -1 to 1 range. Which is useful since we want the particles to move back and forth, but not to uniformly.

Next we create a variable called ‘w’, to represent the wind force. If the ‘s’ variable is less than -0.8, then we use a strong wind value, else we will use a weak wind value. The weak value will be selected most often. The values are also randomised, since the wind strength tends to go up and down in reality.

  final float w = s < -0.8 ? random(0.05, 0.07) : random(0.01, 0.03);

Then we just add our wind force variable to all the particles. Scaling by ‘s’ sets the direction of the wind.

  particleSpawner.AddForce(w * s, 0);

Lastly we call the ParticleSpawner Update function, to update all the particles.

  particleSpawner.Update();

Draw Function

Go to the draw function.

void draw();

Replace this:

WaterfallUpdate();

With this:

SnowUpdate();

Run the Sketch

Now it’s time to have some fun and run the sketch. Press CTRL + R or click on the triangle play symbol.

You should see snow particles falling from the sky and getting blown about by the wind.

Conclusion

Congratulations on completing this tutorial! Feel free to experiment with different particle shapes, colours, spawn rates and random number generation functions.

Thanks for reading this tutorial, let me know in the comments section if you enjoyed it.

4 responses to “Processing Tutorial: How to Create Falling Snow Particles”

Leave a reply to signalman Cancel reply