Hello! My name is Christopher Pavlovski and I'm a visual effects artist working at Velan Studios. I wanted to write a little about a subject that is very dear to me and my art, as well as demonstrate some of it with a relatively simple effect. The effect in question is this smoke poof:
This effect uses no actual textures, is performant, is relatively simple to reproduce, and is made ENTIRELY within Unreal 4. The individual cloud particles can be used for any number of different effects and their versatility was a key goal I had when making them. By the end of this all, I hope you’ll become a little more familiar with using some of the methods I employed making this and you’ll be able to create a similar looking smoke-puff style yourself.
First, a bit of context. As an FX artist, I have always tried to pull as much from technologies available to me as I can. Good ol’ fashioned artist know-how dictates every action I make, but when I can use technology to do something better, faster, more efficient, etc., I use it.
I’m a believer that visual effects and tech art are two sides of the same coin, and the more I can blur the line that separates them, the more it benefits my art. So let’s take a look at the shader I created in my smoke puff example and see a little bit of what I mean.
Here is the shadergraph for the poof. It’s not SUPER complex, but it is doing a few neat things. Essentially, I’m distorting the UVs of a perfect radial gradient, then changing its shape as its opacity fades. Let’s start with the UVs: what exactly am I doing with them and why? Well, I’ll tell ya:
The very first thing I’m doing is creating noise within Unreal and then rendering it to a texture. The shape of the noise will dictate the shape of your smoke puff, so swapping the texture out for different noise types will give you DRAMATICALLY different results. That is because I am adding noise to the UVs of an otherwise PERFECT circular gradient, so the shape of the noise will skew the gradient to the noise’s shape based on how intense it is when it’s added. Something else I’m doing (which we'll get back to in a bit) is randomizing the UVs of both noise textures for every particle. By doing this, it ensures that EVERY particle has a unique shape, and there is absolutely ZERO repetition. This is done by setting random parameter values in the particle system using a ‘dynamic’ node, like below:
Now we have an infinite number of randomly-shaped cloud poofs. Great! But we gotta make ‘em move. There are tons of ways you could do this, but I decided to use the particle color’s opacity to distort certain parts of the shader. Namely: the intensity of the noise UV distortion, the softness of the radial gradient, and the rotation value plugged into the gradient.
As an example, here is what lerping the noise intensity looks like. I am taking the noisy UVs, multiplying them by a float, and adding that outcome to a set of normal UVs. BUT, the value I am multiplying is a lerp between 0.2 and 0.5 over the particle’s lifetime. This means that as the particle grows older and its opacity fades, the noise becomes more intense and the perfect circular gradient gets more broken up. This gives the impression of the smoke dissipating in the air as the big chunks fade into smaller and smaller bits.
At the same time that’s happening, the particle’s opacity is setting the time value for a rotator node, so as the particles break apart and fade out they are also rotating along their noisy UVs. This helps give them a “roiling” look, like the wind around the smoke is blowing it around.
By now, we've demonstrated how one could use the opacity value to do a lot of interesting things over a particle’s lifetime. I’m also using it to soften the radial gradient over its lifetime, so the particle cloud starts off opaque and defined, but dies extremely soft and translucent. You could also alter the size of the noise over life, adjust the particle’s color, change the intensity of depth fade, and TONS more.
So what are the benefits of building FX this way instead of using static textures, renders from something like Houdini, or hand-animated flipbooks? Primarily: style, versatility, and unique movement. Having an infinite number of uniquely-moving sprites can do wonders for FX you see constantly, like running dust from a character. But a system like this can also be altered and warped to create numerous different looks. What if we took this smoke and tried to make fire with it? With minimal work, we can achieve effects like this:
All of these different looks can be achieved by adjusting the noise type, intensity, color, and parameters within the particle system itself. But what is one meant to do with all this information? Experiment! After I opened my heart to the idea that I can create really useful and beautiful art using shaders and code/blueprints, the door opened to a TON of amazing FX that were never possible before. Grass that reacts to object proximity, impact FX that grow based on damage dealt, dust that follows a player based on distance traveled, and so much more.
I hope this quick demonstration has given you an idea of how technology can be used to create beautiful art, and has inspired you to try messing around with some more complex shaders and code-based FX yourself. The constantly-evolving world of game tech delivers endless tools; one should not shy away from using it for their own art. Thanks for reading!