A fascinating look into how the game’s tentacle tech, volumetric fog, and more came to be.
Besides captivating gameplay, Housemarque is known for over the top particle effects. Titles such as Resogun, Alienation, Matterfall and Nex Machina all used proprietary VFX technology to bring colorful explosions to the screen in order to reward players for destroying enemies or completing levels. In Returnal, Housemarque switched from top down to a third person camera, but also to a more grounded and darker art style than before. In this article, Risto Jankkila, Lead VFX Artist, and Sharman Jagadeesan, Senior Graphics Programmer, give us a closer look at how they utilized their VFX tech to make the alien planet of Atropos and its inhabitants come to life.
Below you can find the full breakdown video covering some of the showcase VFX features of Returnal. In addition to that, we’ll go a bit more into detail with some of those features in this article.
The history of our VFX tech
We have been working on our proprietary VFX tech since Resogun (2013 PS4 launch title), where the first prototype of our current particle system was used on some of the showcase effects. After Resogun, the particle system got a graphical user interface and we started referring to it as Next Gen Particle System (NGP). In 2014 we made the decision to produce all of the particle effects for Alienation with NGP. After shipping Alienation, the system was used for Nex Machina and ported to Unreal Engine for Matterfall.
NGP is designed to be a GPU-only VFX authoring system with minimal CPU overhead. Focus is on good performance and flexibility. Particle authoring is done by VFX artists who write compute shader snippets that define particle behaviour and data. NGP takes care of memory allocation and most of the boilerplate code, while artists can focus on behaviour and visuals.
Currently NGP is not intended to handle only particle effects. It can also be used for controlling voxel behaviour in volumes or for generating dynamic procedural geometry. We also have several modules that generate data to be used as an input for effects.
For example, we have our own fluid simulation module that can feed its simulation data to NGP. Another example is a module called voxeliser which can convert an animated mesh to voxels. That data can be then used for volumetric character effects. Other resources like textures, bone matrices and vertex buffers can also be used as inputs for particle effects.
The VFX magic behind enemy tentacles and bullet trails: node particles
From early on in Returnal’s development, it was clear that we wanted to do something special with enemy creatures on Atropos. Game director Harry Krueger wanted them to resemble deep-sea creatures with properties like bioluminescence and tentacles.
Our enemy team animators briefly experimented doing tentacles using traditional rigid body physics to simulate chains of bones attached to enemy skeletons. This approach seemed a little too limited since the performance cost of doing multiple very long chains was too high, but also because we lacked means of expressing enemy states via physics simulations only. VFX was then assigned the task to create dynamic tentacles that could be attached to enemy meshes and skeletons.
Luckily we already had a solution in mind. The team had been experimenting with particle vegetation for earlier projects and a special particle type had been developed for branching vegetation such as trees. We named this particle type “Node Particle” to reflect its properties and behavior.
This particle type allows us to create one-directional, parent-child connections. A particle can be a parent to multiple children but a particle can have only one parent. When reading the parent particle the parent data is one frame old, i.e. not the data that is being written to in the current frame. This makes it impossible to “follow” the parent strictly and results in a side effect which makes the motion of the particles appear “organic”. This side effect is used widely in particle effects in Returnal, and it was especially useful for things like tentacles.
But before we started working on the tentacle behavior, we needed to decide how we would render them. First, we experimented with rendering flat strips of polygons. The quality was close to acceptable, but lacking in some areas like shadows. After a while, we settled on rendering the tentacles as cylindrical meshes that were constructed from NGP during runtime.
After settling on tube rendering we could start focusing on the behavior of the tentacles. Being able to control particle behavior, we were no longer constrained by just physics simulations but could conveniently change the tentacle movement based on the state of the enemy. This made it easy for us to experiment with things like forcing the tentacles to move in a certain way when the enemy is preparing for an attack. We iterated on the timings with the enemy team and designers to ensure that the tentacle behavior would help in telegraphing enemy states along with animation and other VFX.
Node particles also came in handy for the numerous ribbons and trails we have in game. We wanted some of the homing bullets to have a long trail that would linger on the screen for a while behind the bullet. Also enemy melee attack trails used node particles. Below you can see a video of node particles following their parent, creating a ribbon trail, followed by a homing bullet attack by Phrike.
Fluid simulations
One of our key principles at Housemarque regarding visual effects is to simulate as much as possible during runtime, using as little pre-baked data as possible. As we had used fluid simulations in our previous titles like Alienation and Matterfall, it was clear to us from the beginning that we shouldn’t settle for pre-baked velocity fields for Returnal.
Instead we use a real time fluid simulation around the player to simulate air flow that affects movement of the particles, vegetation and other VFX elements. In addition to that simulation (which we refer to as Global Fluid Simulation), we can have additional simulations attached to different actors in the game.
Any gameplay event can be scripted to add forces to the fluid simulation causing nearby VFX elements to react. For example, these forces can be included into enemy animations so that when an enemy lands a jump attack, we add a radial impulse to the fluid simulation in that moment and at that location. This causes nearby particles like leaves or sparks to fly away from the impact point. In the video below you can see fluid impulses triggered from enemy animations and player actions affecting particle vegetation.
While using only fluid velocities was enough for things like vegetation, in cases where one can see discrete point particles, it felt that the global fluid simulation velocity field was lacking detail. To get more detail we chose to implement optional vorticity calculations for the fluid simulation and in the particle update added a noise field to particle velocity, proportional to the magnitude of the fluid velocity at the location of the particle. In-game this technique was utilized for Xeno-archive holograms and in the player teleporting effect, which you can see below.
Voxeliser and volumetric effects
One of the environment elements we wanted to have in the opening biome of Returnal (Overgrown Ruins) was thick, volumetric graveyard-like fog. Due to the height differences in our levels, the procedural placement of the fog turned out to be problematic. Instead, we decided to place the fog volumes manually. With a high number of volumes to be placed by the environment team, we had to make the process as straightforward as possible.
The flexibility of our particle system allowed us to construct these volumes in NGP. Since particle data and behavior can be completely customized, we can store a three dimensional index for a number of particles and have them represent a volume. Volume bounds can be passed as constant data from CPU to NGP. Along with the three dimensional index, we can store any other data per voxel as well. This gives us the possibility to store different states for each voxel inside a volume. In addition to being able to store voxel states, we can also change their update logic based on their position in the game world or inside the volume.
Having voxels that are aware of their state and position, we could have them automatically emit more density near surfaces like floors and walls but also fade out smoothly near edges of the volumes. This made the process of placing fog volumes a lot faster, since the fog adapted automatically to its surroundings. We could also sample the global fluid simulation at the voxel position, and have the fog be moved around by things like wind, bullets and player actions. In the video below, you can see one of these NGP fog-volumes placed into a level. The fog density is adaptively created only near surfaces, and advected by fluid simulation in game.
Putting it all together to create that Phrike boss battle
For the Phrike boss encounter, we wanted to be able to emit volumetric fog from Phrike’s skeletal mesh. This posed a problem since volumetric fog and skeletal meshes are constructed from different kinds of elements. Skeletal mesh is a set of vertices, animated points in 3D space that are ordered to form triangles that can be rendered. Vertices can be placed arbitrarily to form all kinds of different shapes from trees to humanoids. Volumetric fog on the other hand uses boxes that are referred to as volumes. These volumes consist of smaller elements called voxels. In contrast to skeletal meshes, fog volumes in Unreal Engine are always shaped like boxes and so are the voxels they’re built from.
If we wanted to use Phrike’s vertices to emit volumetric fog, we would have to find out in which voxel of the fog volume each vertex of the skeletal mesh is in. This was trivial to solve, but the bigger problem was the fact that we could only handle one vertex per voxel. Having two vertices occupying the same voxel would lead to undefined behaviour and possibly crash the game. To make things worse, it was far more likely to have multiple vertices inside a single voxel than it was to have just one.
The solution to this was a real-time voxelizer. The voxelizer takes a skeletal mesh as an input and outputs a volume where each voxel that is inside the skeletal mesh is marked as occupied. This made the process of emitting fog simple as we only had to check the voxelizer output and see if the given voxel is marked as occupied or not. In the video below you can see the output of the voxelizer using Phrike’s mesh as an input.
With the ability to emit fog from Phrike’s mesh, we were able to blend the character better with the environment when she was moving. It also made Phrike’s special actions like teleporting and spawning easier to execute since we could hide these transitions with the fog. Below you can find a comparison video of Phrike’s spawn sequence with volumetric fog and other effects and without them.
This concludes our deep dive into the visual effects of Returnal. We hope that you enjoyed reading this and wish to share more of our tricks and techniques in the future.
Comments are closed.
11 Comments
Loading More Comments