About the project
I like having projects that involve gameplay; not just making an effect for the sake of making an effect. I like to make it gameplay related. So I decided to use one of Epic Games’ characters from Paragon, and make effects for it; as if it was a revamped character. I studied the existing effects that Epic had made for the character I chose, and noticed that they used a lot of mesh particles with panning masks, that resulted in very interesting shapes. I also noticed that they had what seemed like two types of dark smoke, one soft and wispy, one that was hard and harsh. As I wanted my effects to fit in with the game, I tried to follow these practices as well as I could.
I decided to create three effects, a basic attack, a summon ability, and a dash ability. These abilities would be complimented by an imaginary passive ability of his, that would increase the damage he deals the more he attacks. This is visualized by the color on his body and abilities, that change from blue to red, depending on how much more damage he will deal. With these parameters in place, I could start working.
Creating the textures
I like using Substance Designer for most texture creation, whether it be alphas or tiling textures. Iteration times are low, exports are fast, and everything is procedural. Below are the four most important textures I used for this project, some magical textures, and of course a perlin noise. It was surprising how big of a difference using more interesting textures like these made to the effects. I had already prototyped most of the shaders using other basic noise or grunge textures, but all of the effects gained a significant edge after I replaced them with these textures.
Unfortunately, Designer is not great at everything. One of those things that are severely lacking is the creation of animated spritesheets. It is possible, by animating attributes using the time variable, and exporting the graph to Substance Player and then exporting the separate frames from there, but it is far to cumbersome to be worth the effort. Instead, I turned to Houdini to generate my animated textures. Even though Pyro simulations take significantly longer time to create compared to some tiling textures in Designer, I still made sure to make time for iteration, and I believe it shows in the final result. The difference between the first sim, and the final one is quite significant, and I am really happy I managed to get that result.
I set out to create a wispy looking smoke simulation, but it wasn’t entirely obvious how to achieve it. There is a shelf button called wispy smoke, but that was hardly the result I was looking for. Turns out, the key ingredients to a wispy smoke in Houdini is removing all diffusion (the blurring of the gas), using subtractive evaporation instead of it just being multiplicative, and finally adding plenty of turbulence and source velocity to the mix. That was the formula I came up with on my fourth and final attempt. Below are the different stages I had to go through to get to that final result.
In Houdini, I have a lot of microsolvers that give me access to these important attributes. As I mentioned above, the dissipate and turbulence solvers are the most important ones for this type of smoke. On the dissipate solver I kept the diffusion at 0, put the evaporation rate to a very low value, and checked the evaporate by subtraction checkbox. I put the value to a pretty large number, to get a lot of contrast.
Basic Attack: Breakdown
I started out making some basic concept art, since I was a bit unsure of what I was after. After conferring with a fellow TA, I decided on a projectile that was pointy and aggressive, compared to a lot of magic effects that tend to have a bulbous, round shape before the trail starts. In order to create that pointy shape, I decided to use a mesh with that shape, and add more particles around that core. The current character color is sent to the relevant emitters when a projectile is created.
The projectile blueprint uses the projectile movement component that has built in support for most of the functionality I needed. I added handling of the impact, where it spawns a particle effect and sends the reflect vector into the particle system. That lets me shoot the sparks off in that direction. Since the character would be changing colors, his attacks would have to do that too. I handle that by getting the color as soon as the projectile spawns, and send that color as a parameter too. Since I had thought about using dynamic colors from the start, this setup was easy to create.
For the summon effect, I started with making a shader for the portal. There were a few key features that I knew I wanted to have:
Some sort of depth, as if the portal goes through the ground
A dynamic edge that always looks unique
I had a couple of different ideas for how to achieve the depth, by either using parallax mapping or bump offset. In hindsight, I would’ve tried to use a custom depth mask to do it instead, but I have a suspicion that it might have been the most expensive solution. I had to decide between parallax mapping or bump offset, and in my case, this decision was super simple. Bump offset works well at large angles, but when looking at shallow angles (i.e. most of the time when you look at a plane on the ground from a character’s point of view), the illusion completely breaks. Parallax mapping was my best choice even though it is more expensive, and it needs to be passed a texture object instead of a height map. These are two serious drawbacks that needed to be considered, but I still felt like it was best choice.
The dynamic edge was affected by this choice too. Since bump offset doesn’t need to sample a texture multiple times, it can be passed a height map instead of a texture object. This in turn means that it is possible to modify the height map dynamically, whereas parallax requires a static texture. This dilemma lead me down the wrong path, as I created a very static looking effect because I wanted the height map to match the rest of the effect. In reality, that wasn’t necessary at all. What I noticed when I went back to polish the effect was that the shape of the height map was less important, as long as there was some sort of depth. Here is a comparison between the first, static version to the left and the second version the right.
I wrote a simple material function that let me pan a texture radially, that basically works the same as Unreal’s built in Panner node, but pans radially instead. With it, I sample three textures and blend them together to get the main shape. I also sample a fourth texture with it to get the dark smoke that comes out from below the portal. All in all, I really enjoy the look of the portal, since it feels very dynamic and fluid. The two things I would change with it if I had to do it again would be, as I mentioned before, use a custom depth mask to allow objects to pass into the portal properly, and also improve the inside of the portal, since it’s quite obvious that it is just some panning textures.
The teleport effect has changed a lot over the course of the project. Initially it was just a button press that allowed the player to move forward quickly. It turns out, however, that it looks a lot cooler if the character moves in an arc, so that’s what I did. The indicator is a beam particle, an emitter type that I had never used before. It was difficult to get to work properly, but when I finally figured it out, it worked really well. When the teleport is activated, the whole character blueprint starts moving in an arc, with a trailing particle system attached. When the player lands, a final effect is played.
Probably the biggest thing I learned this project was just how important it was to spend time on creating the textures. I iterated heavily on the wispy smoke textures, and I think that it shows. The tiling textures are no different; having one that works well really make the effects stand out.