Procedural Art with Unity3D Particle Systems and Vector Fields
In the past few days, I have been experimenting with creating patterns using the particle system in Unity Engine. Here are some of the examples of the shapes I came up with.
So in this post I am going to go through how to achieve something like this using Unity 3D. I am not going to go to the specifics regarding how I am achieving each effect, but more like the general idea on how to get there.
To start off we need a setup where we can draw on a canvas of some sort. There are many different ways to do this, the easiest way in Unity would be to set up an Orthogonal camera, and set its Clear Flag to Don’t Clear. In a standard application, you would want to draw everything on each frame from scratch, that’s why you would clear the background with a solid color each frame. This is not ideal for our use case, because we want to draw with objects, as if they are pens we are drawing with on a piece of paper. So the trail of the particle movement must remain on the canvas.
Once you setup the camera to not clear its buffer, you could easily create something like this. Notice how the particles are spawning randomly and building a texture overtime.
That was the underlining concept behind drawing shapes, now I can move any object in the scene and draw with it on the canvas, here would be an example of drawing a circle and a tringle.
It doesn’t really matter which object you take as your drawing tool. You could spawn tens of sprites and draw with that, or use shaded 3D objects. If you really want to go for the performance, you should do all these in a shader. But for my use case, the Particle System from Unity was more than enough.
To setup the Particle System, I created a script which bursts out a given number of particles at Begin Play event. These particles have no initial velocity and dont move on their own. Then the script gets the particles as an Array each frame, manually iterates through the array and sets the velocity, color or the position per particle.
So here comes the actual meat of the project. Now we need to move the particles around somehow. For example, the simplest is the circle. In the iteration we could say the following (This would create a set of rings).
Particle[i].position = new Vector3(Mathf.Cos(Time),Mathf.Sin(Time), someDisAwayFromCam) * (float) i;
There are many different movement types you can define, but you get the idea from this simple example. I used this to draw specific shapes on the patterns, but there is nothing procedural about this method. It would never create something I didn’t expect. So I decided to go for Vector Fields.
The idea behind a Vector Field is simple. You have a grid of Vectors distributed in the space:
For each given particle at a given time, depending on where it is, it receives a force from the vector field, in the same direction which the vector of the cell in the grid is pointing towards. That means the particles start flowing in a current over time. The easiest way to do this in Unity, is to add on top of the existing Velocity Vector of each particle. Note that you should clamp the magnitude of the Velocity to a give number.
Here is video of that as an example (think about how you want to pour the new particles in, and what happens with them after they leave the camera view):
We are almost done. Now all that remains is finding different ways to create these vector fields. To start off, you can use the Perlin Noise. Unity Mathf class actually has a Perlin noise function which returns a float between 0 and 1 based on a given X and Y coordinate, you can then use this float as the angle of the vector. The good thing about Perlin noise, is that it creates a random pattern, with smooth transitions from one random value to the next. Later on I created my own random functions like a 3D Gradient noise, to be able to slowly change the vector field over time.
Here are some interesting ways you can create the vector fields: Vornoi Noise, 3D Perlin Noise, fbm, from an Image or a data provided by NASA or similar organisations, vector fields data from physics which describe gravitational, magnetic and electric fields or weather current maps…
Here are some examples of those:
Here are some other things to think about. Add enough color variation to the particles to make them really stand out. You can also use all the classic advantages of Unity, for example you can use post processing effects, or in these examples I am using the trail render from the particles to create these effects.
Thank you for reading, if you have any questions, please let me know. I will leave a video at the end with some real time pattern generations.