Chapter 7: Visual Effects with Particle Systems and VFX Graph

Here, we will continue learning about visual effects for our game. We will be discussing particle systems, a way to simulate fire, waterfalls, smoke, and all kinds of fluids. Also, we will see the two Unity particle systems to create these kind of effects, Shuriken and VFX Graph, the latter being more powerful than the first, but requiring more hardware.

In this chapter, we will examine the following particle system concepts:

  • Introduction to particle systems
  • Creating fluid simulations
  • Creating complex simulations with VFX Graph

Introduction to particle systems

All graphics and effects we have created so far use static meshes, 3D models that can't be skewed, bent, or deformed in any way. Fluids such as fire and smoke clearly can't be represented using this kind of mesh, but actually, we can simulate these effects with a combination of static meshes, and this is where particle systems are useful.

Particle systems are objects that emit and animates lots of particles or billboards, which are simple quad meshes that face the camera. Each particle is a static mesh, but rendering, animating, and combining lots of them can generate the illusion of a fluid. In the next image you can see on the left a smoke effect using particle systems, and on the right, the Wireframe view of the same particles. There you can see the quads that create the illusion of smoke, which is done by applying a smoke texture to each of the particles and animating them so they spawn at the bottom and move up in random directions:

Figure 7.1 – Left side, a smoke particle system; right side, the wireframe of the same system

Figure 7.1 – Left side, a smoke particle system; right side, the wireframe of the same system

In this section, we will cover the following concepts related to particles:

  • Creating a basic particle system
  • Using advanced modules

Let's start discussing how to create our very first particle system.

Creating a basic particle system

To illustrate the creation of a particle system, let's create an explosion effect. The idea is to spawn lots of particles at once and spread them in all directions. Let's start creating the particle system and configuring the basic settings it provides to change its default behavior. To do so, follow these steps:

  1. Select the GameObject | Effects | Particle System option:
    Figure 7.2 – Particle system creation button

    Figure 7.2 – Particle system creation button

  2. You should see the effect in the following screenshot. The default behavior is a column of particles going up, like the smoke effect shown previously. Let's change that:
    Figure 7.3 – Default particle system appearance

    Figure 7.3 – Default particle system appearance

  3. Click the created object in the scene and look at the inspector.
  4. Open the Shape section by clicking on the title.
  5. Change the Shape property to Sphere. Now the particles should move in all possible directions instead of following the default cone:
    Figure 7.4 – Shape properties

    Figure 7.4 – Shape properties

  6. In the particle system module (usually known as Main) set Start Speed to 10. This will make the particles move faster.
  7. In the same module, set Start Lifetime to 0.5. This specifies how long a particle will live. In this case, we have given a lifetime of half a second. In combination 
with the speed (10 meters per second), this makes the particles disappear after moving 5 meters:
    Figure 7.5 – Main Particle System module

    Figure 7.5 – Main Particle System module

  8. Open the Emission module and set Rate Over Time to 0. This property specifies how many particles will be emitted per second, but for an explosion, we actually need a burst of particles, so we won't emit particles constantly over time in this case.
  9. In the Bursts list, click the + button at the bottom and in the created item in the list, set the count column to 100:
    Figure 7.6 – Emission module

    Figure 7.6 – Emission module

  10. In the Main module (the one titled Particle System) set Duration to 1 and uncheck Looping. In our case, the explosion won't repeat constantly; we just need one explosion:
    Figure 7.7 – Looping checkbox

    Figure 7.7 – Looping checkbox

  11. Now that the particle isn't looping, you need to manually hit the Play button that is shown in the Particle Effect window in the bottom-right part of the Scene View to see the system:
    Figure 7.8 – Particle system playback controls

    Figure 7.8 – Particle system playback controls

  12. Set Stop Action to Destroy. This will destroy the object when the Duration time has passed. This will just work when you are running the game, so you can safely use this configuration while editing your scene:
    Figure 7.9 – Stop Action set to Destroy

    Figure 7.9 – Stop Action set to Destroy

  13. Set the Start Size of the Main module to 3. This will make the particles bigger so they seem denser:
    Figure 7.10 – Particle system Start Size

    Figure 7.10 – Particle system Start Size

  14. Click on the down-pointing arrow at the right of the Start Rotation property of the Main module and select Random Between Two Constants.
  15. Set the Start Rotation to 0 and 360 in the two input values that appeared after the previous step. This allows us to give the particles a random rotation when they spawn to make them look slightly different from each other:
    Figure 7.11 – Random Start Rotation

    Figure 7.11 – Random Start Rotation

  16. Now the particles behave as expected, but they don't look as expected. Let's change that. Create a new material by clicking on the + icon in the Project View and selecting Material. Call it Explosion.
  17. Set its shader to Universal Render Pipeline/Particles/Unlit. This is a special shader that is used to apply a texture to the Shuriken particle system:
    Figure 7.12 – Particle system material shader

    Figure 7.12 – Particle system material shader

  18. Download a smoke particle texture from the internet or the Asset Store. In this case, it is important to download one with a black background; ignore the others:
    Figure 7.13 – Smoke particle texture

    Figure 7.13 – Smoke particle texture

  19. Set this texture as the Base Map of the material.
  20. Set the Surface Type to Transparent and the Blending Mode to Additive. Doing this will make the particles blend with each other, instead of being drawn on each other, to simulate a big mass of smoke instead of individual smoke puffs. We use Additive mode because our texture has a black background and because we want to create a lighting effect (the explosion will brighten the scene):
    Figure 7.14 – Surface options for particles

    Figure 7.14 – Surface options for particles

  21. Drag your material to the Material property of the Renderer module:
    Figure 7.15 – Particle material settings

    Figure 7.15 – Particle material settings

  22. Now your system should look like this:
Figure 7.16 – Result of the previous settings

Figure 7.16 – Result of the previous settings

In the previous steps, we have changed how the particles or billboards will spawn (using the Emission module), in which direction they will move (using the Shape module), how fast they will move, how long they will last, how big they will be (using the Main module), and what they will look like (using the Renderer module). Creating particle systems is a simple case of properly configuring their different settings. Of course, doing it properly is an art on its own; it requires creativity and knowledge of how to use all the settings and configurations they provide. So, to increase our configurations toolbox, let's discuss some advanced modules.

Using advanced modules

Our system looks nice, but we can improve it a lot, so let's enable some new modules to increase its quality:

  1. Check the checkbox on the left of the Color over Lifetime module to enable it:
    Figure 7.17 – Enabling the Color over Lifetime module

    Figure 7.17 – Enabling the Color over Lifetime module

  2. Open the module by clicking on the title and click the white bar on the right of the Color property. This will open the gradient editor.
  3. Click slightly to the right of the top-left white marker in the bar to create a new marker. Also, click slightly to the left of the top-right white marker to create the fourth marker. These markers will allow us to specify the transparency of the particles during its life:
    Figure 7.18 – Color over Lifetime gradient editor

    Figure 7.18 – Color over Lifetime gradient editor

  4. If you created unwanted markers, just drag them outside the window to remove them.
  5. Click on the top-left marker (not the one we created, the one that was already there) and set the Alpha slider at the bottom to 0. Do the same with the top-right marker, as shown in the following screenshot. Now you should see the particles fading away instead of popping out of existence when the explosion is finishing:
    Figure 7.19 – Fade-in and fade-out gradient

    Figure 7.19 – Fade-in and fade-out gradient

  6. Enable the Limit Velocity over Lifetime module by clicking on its checkbox.
  7. Set the Dampen setting to 0.1. This will make the particles slowly stop instead of continuing to move:
    Figure 7.20 – Dampen the velocity to make the particles stop

    Figure 7.20 – Dampen the velocity to make the particles stop

  8. Enable Rotation over Lifetime and set the Angular Velocity between -90 and 90. Remember that you should set the value in Random Between Two Constants by clicking on the down-pointing arrow to the right of the property. Now the particles should rotate slightly during their lives to simulate more motion:
Figure 7.21 – Random rotation velocity

Figure 7.21 – Random rotation velocity

As you can see, there are lots of extra modules that can be enabled and disabled to add layers of behavior on top of the existing ones, so again, use them creatively to create all kinds of effects. Remember that you can create Prefabs of these systems to replicate them all over your scene. I also recommend searching and downloading particle effects from the Asset Store to see how other people have used the same system to create amazing effects. That is the best way to learn how to create them, seeing a variety of different systems, and that is actually what we are going to do in the next section, create more systems!

Creating fluid simulations

As we said, the best way to learn how to create particle systems is to keep looking for already-created particle systems and explore how people have used the various system settings to create completely different simulations.

In this section, we will see how to create the following effects using particle systems:

  • A waterfall effect
  • A bonfire effect

Let's start with the simplest one, the waterfall effect.

Creating a waterfall effect

In order to do this, follow these steps:

  1. Create a new particle system (GameObject | Effects | Particle System).
  2. Set Shape to Edge and its Radius to 5 in the Shape module. This will make the particles spawn along a line of emission:
    Figure 7.22 – Edge shape

    Figure 7.22 – Edge shape

  3. Set the Rate over Lifetime of the Emission module to 50.
  4. Set the Start Size of the Main module to 3 and the Start Lifetime to 3:
    Figure 7.23 – Main module settings

    Figure 7.23 – Main module settings

  5. Set the Gravity Modifier of the Main module to 0.5. This will make the particles fall down:
    Figure 7.24 – Gravity Modifier in the Main module

    Figure 7.24 – Gravity Modifier in the Main module

  6. Use the same Explosion material we created previously for this system:
    Figure 7.25 – Explosion particle material

    Figure 7.25 – Explosion particle material

  7. Enable Color Over Lifetime and open the Gradient editor.
  8. Click the bottom-right marker, and this time you should see a color picker instead of an alpha slider. The top markers allow you to change the transparency over time, while the bottom ones change the color of the particles over time. Set a light blue color in this marker:
Figure 7.26 – White to light blue gradient

Figure 7.26 – White to light blue gradient

As a challenge, I suggest you add a little particle system where this one ends to create some water splashes, simulating the water colliding with a lake at the bottom. Now we can add this particle system to one of the hills in our scene to decorate it, like in the following screenshot. I have adjusted the system a little bit to look better in this scenario. I challenge you to tweak it by yourself to make it look like this:

Figure 7.27 – The waterfall particle system being applied to our current scene

Figure 7.27 – The waterfall particle system being applied to our current scene

Now, let's create another effect, a bonfire.

Creating a bonfire effect

In order to create it, do the following:

  1. Create a particle system.
  2. Look for a Fire Particle Texture Sheet texture on the internet or the Asset Store. This kind of texture should look like a grid of different flame textures. The idea is to apply a flame animation to our particles swapping all those mini-textures:
    Figure 7.28 – Particles texture sprite sheet

    Figure 7.28 – Particles texture sprite sheet

  3. Create a particle material and set this texture as the Base Map. Set the color at the right of the Base Map to white. Then set this material as the particle material. Remember to set Surface Type to Transparent and Blending Mode to Additive:
    Figure 7.29 – A material with a particle sprite sheet

    Figure 7.29 – A material with a particle sprite sheet

  4. Enable the Texture Sheet Animation module and set the Tiles property according to your fire sheet. In my case, I have a grid of 4x4 sprites, so I put 4 in X and 4 in Y. After this, you should see the particles swapping textures:
    Figure 7.30 – Enabling Texture Sheet Animation

    Figure 7.30 – Enabling Texture Sheet Animation

  5. Set Start Speed to 0 and Start Size to 1.5 in the Main module.
  6. Set Radius to 0.5 in Shape.
  7. Create a second particle system and make it a child of the fire system:
    Figure 7.31 – Parenting particle systems

    Figure 7.31 – Parenting particle systems

  8. Apply the Smoke material from the explosion example.
  9. Set Angle to 0 and Radius to 0.5 in the Shape module.
  10. The system should look like this:
Figure 7.32 – Result of combining fire and smoke particle systems

Figure 7.32 – Result of combining fire and smoke particle systems

As you can see, you can combine several particle systems to create a single effect. Take care when doing this because it's easy to emit too many particles and affect the game's performance. Particles are not cheap and may cause a reduction in the game's FPS (Frames Per Second) if you are not cautious with them.

So far, we have explored one of the Unity systems that you can use to create these kinds of effects, and while this system is enough for most situations, Unity recently released a new one that can generate more complex effects, called VFX Graph. Let's see how to use it and see how it differs from Shuriken.

Creating complex simulations with VFX Graph

The particle system we have used so far is called Shuriken, and it handles all calculations in the CPU. This has both pros and cons. A pro is that it can run on all possible devices that Unity supports, regardless of their capabilities (all of them have CPUs), but a con is that we can exceed CPU capabilities easily if we are not cautious with the number of particles we emit. Modern games require more complex particle systems to generate believable effects, and this kind of CPU-based particle system solution has started to reach its limits. This is where the VFX Graph comes in:

Figure 7.33 – On the left, a massive particle system, and on the right, an example of a VFX Graph

Figure 7.33 – On the left, a massive particle system, and on the right, an example of a VFX Graph

VFX Graph (Visual Effects Graph) is a GPU-based particle system solution, meaning that the system is executed on the video card instead of the CPU. That's because video cards are far more efficient at executing lots and lots of little simulations, like the ones each particle of a system needs, so we can reach far higher orders of magnitude in the number of particles with the GPU than we can with the CPU. The con here is that we need a fairly modern GPU that has compute shader capabilities to support this system, so we will exclude certain target platforms using this system (forget about most mobile phones), so only use it if your target platform supports it (mid to high-end PCs, consoles, and some high-end phones).

In this section, we will discuss the following concepts of VFX Graph:

  • Installing VFX Graph
  • Creating and analyzing a VFX Graph
  • Creating a rain effect

Let's start seeing how we can add support for VFX Graph in our project.

Installing VFX Graph

So far, we have used lots of Unity features that were already installed in our project, but Unity can be extended with a myriad of plugins, both official and third-party. VFX Graph is one of those features that needs to be independently installed if you are using Universal Render Pipeline (URP). We can do that using the Package Manager, a Unity window dedicated to managing official Unity plugins.

Something to think about when you are installing those packages is that each package or plugin has its own version, independent of the Unity version. That means that you can have Unity 2020.1 installed, but VFX Graph 7.1.5 or 7.1.2 or whatever version you want, and you can actually update the package to a newer version without upgrading Unity. This is important because some versions of these packages require a minimum version of Unity. Moreover, some packages depend on other packages, and actually specific versions of those packages, so we need to ensure we have the correct versions of every package to ensure compatibility. To be clear, the dependencies of a package are installed automatically, but sometimes we can have them installed separately, so in that scenario, we need to check the required version. It sounds complicated, but it is simpler than it sounds.

As the time of writing this book, I'm using get VFX Graph version 8.2.0, the same version as URP. Yes, URP is another feature you need to install using the Package Manager, but as we created the project using the URP template, it was already installed for us. Regarding versions, a piece of advice: never update your Unity version or a package version during the production of your game unless is really necessary. Upgrades generally come with lots of compatibility versions, meaning that some parts of your game may need to be fixed after the upgrade to comply with the way the new versions of those packages work. Also, consider that some packages has the Verified label, meaning that it was tested in our Unity version, and therefore is recommended to go with it.

Now, let's install the VFX Graph as follows:

  1. In the top menu of Unity, go to Window | Package Manager:
    Figure 7.34 – Package Manager location

    Figure 7.34 – Package Manager location

  2. Look for the Visual Effects Graph package on the left side of the window. Make sure you select version 8.2.0 or higher:
    Figure 7.35 – Visual Effect Graph package

    Figure 7.35 – Visual Effect Graph package

  3. Click at the button Install at the bottom-right of the window and wait for the package to install:
    Figure 7.36 – Install package button

    Figure 7.36 – Install package button

  4. It is recommended to restart Unity after installing packages, so save your changes and restart Unity.

Now that we have installed VFX Graph, let's create our first particle system using it.

Creating and analyzing a VFX Graph

The philosophy to create particle system using VFX Graph is similar to the regular Particle System. We will chain and configure modules as parts of the behavior of the particles, each module adding some specific behavior, but the way we do it is very different than with Shuriken. First, we need to create a Visual Effect Graph, an asset that will contain all the modules and configurations, and then make a GameObject play the Graph. Let's do that with the following steps:

  1. In the Project window, click on the + button and look for Visual Effects | Visual Effect Graph:
    Figure 7.37 – Visual Effect Graph

    Figure 7.37 – Visual Effect Graph

  2. Create an Empty GameObject using the Game Object | Create Empty option:
    Figure 7.38 – Empty GameObject creation

    Figure 7.38 – Empty GameObject creation

  3. Select the created object and look at the Inspector.
  4. Using the Add Component search bar, look for the Visual Effect component and click on it to add it to the object:
    Figure 7.39 – Adding a component to the Visual Effect Graph

    Figure 7.39 – Adding a component to the Visual Effect Graph

  5. Drag the VFX asset we created to the Asset Template property of the Visual Effect component in our GameObject:
    Figure 7.40 – Visual Effect using the previously created VFX asset

    Figure 7.40 – Visual Effect using the previously created VFX asset

  6. You should see clock particles being emitted from our object:
Figure 7.41 – Default VFX Asset results

Figure 7.41 – Default VFX Asset results

Now that we have a base effect, let's create something that requires a lot of particles, such as dense rain. Before doing so, let's explore some core concepts of VFX Graph. If you double-click the Visual Effect asset, you will see the following editor:

Figure 7.42 – Visual Effect Graph editor window

Figure 7.42 – Visual Effect Graph editor window

This window is composed of several interconnected nodes, generating a flow of actions to be executed. At first, it seems similar to the shader graph, but it works a little bit differently, so let's study each section of the default graph.

The first area to explore is the dotted one that contains three nodes. This is what Unity calls a System. A System is a set of nodes that defines how a particle will behave, and you can have as many as you want, which is the equivalent of having several particle system objects. Each System is composed of Contexts, the nodes inside the dotted area, and in this case, we have Initialize Particle, Update Particle, and Output Particle Quad. Each Context represents a different stage of the particle system logic flow, so let's define what each context in our graph does:

  • Initialize Particle: This defines the initial data of each emitted particle, such as position, color, speed, and size. It is similar to the Start properties in the Main module of the particle system we saw at the beginning of this chapter. The logic in this node will only execute when a new particle is emitted.
  • Update Particle: Here, we can apply modifications to the data of the living particles. We can change particle data such as the current velocity or size all the frames. This is similar to the Over Time nodes of the previous particle system.
  • Output Particle Quad: This Context will be executed when the particle needs to be rendered. It will read the particle data to see where to render, how to render, which texture and color to use, and different visual settings. This is similar to the Renderer module of the previous particle system.

Inside each Context, apart from some base configurations, we can add Blocks. Each Block is an action that will be executed in the context. We have actions that can be executed in any Context and then some specific Context actions. As an example, we can use an Add Position Block in the Initialize Particle Context to move the initial particle position, but if we use the same Block in the Update Particle Context, it will move the particle constantly. So basically, Contexts are different situations that happen in the life of the particle, and Blocks are actions that are executed in those situations:

Figure 7.43 – A Set Velocity Random Block inside the Initialize Particle Context. 
This sets the initial velocity of a particle

Figure 7.43 – A Set Velocity Random Block inside the Initialize Particle Context. This sets the initial velocity of a particle

Also, we can have Standalone Contexts, Contexts outside systems, such as Spawn. This Context is responsible for telling the system that a new particle needs to be created. We can add Blocks to specify when the context will tell the system to create the particle, such as at a fixed rate over time, bursts, and so on. The idea is that spawn will create particles according to its blocks, while a System is responsible for initializing, updating, and rendering each of them, again, according to the blocks we set up inside each one of those Contexts.

So, we can see that there are lots of similarities with Shuriken, but the way to create a system here is quite different. Let's reinforce this by creating a rain effect, which will require lots of particles, a nice use case for VFX Graph.

Creating a rain effect

In order to create this effect, do the following:

  1. Set the Capacity property of the Initialize Particle Context to 10000:
    Figure 7.44 – Initialize Particle Context

    Figure 7.44 – Initialize Particle Context

  2. Set the Rate of the Constant Spawn Rate of the Spawn context to 10000:
    Figure 7.45 – Constant Spawn Rate Block

    Figure 7.45 – Constant Spawn Rate Block

  3. Set the A and B properties to (0, -50, 0) and (0, -75, 0) respectively in the Set Velocity Random Block in the Initialize Particle Context. This will set a random velocity pointing downward for our particles:
    Figure 7.46 – Set Velocity Random Block

    Figure 7.46 – Set Velocity Random Block

  4. Click the Initialize Particle title to select the context, and once it's highlighted press the Spacebar to show the Add Block window.
  5. Search for the Set Position Random block and click on it:
    Figure 7.47 – Adding blocks

    Figure 7.47 – Adding blocks

  6. Set the A and B properties of the Set Position Random Block to (-50 , 0, -50) and (50, 0, 50) respectively. This will define an initial area in which to randomly spawn the particle.
  7. Click the arrow at the left of the Bounds property of the Initialize Particle Block to display its properties, and set Center and Size to (0, -12.5, 0) and (100, 25, 100) respectively. This will define the area where the particles should live. Particles can actually move outside this area, but this is important for the system to work properly (search Frustum Culling on the internet for more information).
  8. Select the GameObject that is executing the system, and in the bottom-right window in the Scene view check the Show Bounds checkbox to see the previously defined Bounds:
    Figure 7.48 – Visual Effect Playback controls

    Figure 7.48 – Visual Effect Playback controls

  9. Set the object position to cover the whole base area. In my case, the position is (100, 37, 100). Remember that you need to change the Position of the Transform component for this:
    Figure 7.49 – Setting a transform position

    Figure 7.49 – Setting a transform position

  10. Set the A and B properties of the Set Lifetime Random Block in the Initialize Particle to 0.5. This will make the particles have a shorter life, ensuring that they are always inside the bounds:
    Figure 7.50 – Set Lifetime Random block

    Figure 7.50 – Set Lifetime Random block

  11. Change the Main Texture property of the Output Particle Quad Context to another texture. In this case, the previously downloaded smoke texture can work here, even though it's not water, because we will modify its appearance in a moment. Also, you can try to download a water droplet texture if you want to:
    Figure 7.51 – VFX Graph Main Texture

    Figure 7.51 – VFX Graph Main Texture

  12. Set Blend Mode of the Output Particle Quad Context to Additive:
    Figure 7.52 – Additive mode of VFX Graph

    Figure 7.52 – Additive mode of VFX Graph

  13. If you can't see the last change being applied, click the Compile button in the top-left of the window. Also, you can save your changes using Ctrl + S (Command + S on Mac):
    Figure 7.53 – VFX Asset Saving controls

    Figure 7.53 – VFX Asset Saving controls

  14. Now we need to stretch our particles a little bit to look like actual raindrops instead of falling balls. To do so, first we need to change the orientation of our particles so they don't point at the camera all the time. In order to do this, right-click on the Orient Block in the Output Particle Quad Context and select Delete (or press Delete on PC or Command + Backspace on Mac):
    Figure 7.54 – Deleting a block

    Figure 7.54 – Deleting a block

  15. We want to stretch our particles according to their velocity direction. To do this, select the title of the Output Particle Quad context and hit the space bar to look for a block to add. In this case, we need to search for the Orient Along Velocity block.
  16. Add a Set Scale Block to the Initialize Particle Context (click it and press the space bar) and set the Scale property to (0.25, 1.5, 0.25). This will stretch the particles to look like falling drops:
    Figure 7.55 – Set Scale Block

    Figure 7.55 – Set Scale Block

  17. Click the Compile button in the top-left window again to see the changes. Your system should look like this:
Figure 7.56 – Rain results

Figure 7.56 – Rain results

From here, you can experiment by adding and removing Blocks from the Contexts as you wish, and again, I recommend you look for already-created Visual Effects Graphs to find ideas for other systems. Actually, you can get ideas for VFX Graph by looking at effects made in Shuriken and using the analogous blocks. Also, I recommend you look for the VFX Graph documentation at https://docs.unity3d.com/Packages/[email protected]/manual/index.html to learn more about this system.

Summary

In this chapter, we discussed two different ways to create particle systems, using Shuriken and VFX Graph. We used them to simulate different fluid phenomena, such as fire, a waterfall, smoke, and rain. The idea is to combine particle systems with meshes to generate all the possible props needed for your scene. Also, as you can imagine, creating these kinds of effects professionally requires you to go deeper. If you want to dedicate yourself to this (another part of the job of a Technical Artist), you will need to learn how to create your own particle textures to get the exact look and feel you want, code scripts that control certain aspects of the systems, and several other aspects of particle creation. Again, that is outside the scope of the book.

Now that we have some rain in our scene, we can see that the sky and the lighting in the scene don't really reflect a rainy day, so let's fix that in the next chapter!

..................Content has been hidden....................

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