A character faces down monsters in ‘Let Them Come: Onslaught’.

Tech Blog

Interview

Optimizing blood and VFX systems in UE5 for Let Them Come: Onslaught

Blueprints

Games

Indies

Let Them Come: Onslaught

Niagara

Tuatara Games

tuatara-games-logo.png
Tuatara Games is a Vancouver-based collective of world-class artists providing cutting-edge VFX services for games and other real-time experiences. The studio has used its expertise to help major games firms, including Epic Games, as well as to develop its own IP with the original cult hit Let Them Come.
Hello Unreal Engine community. I’m Alex Underhill Technical Artist and VFX Artist at Tuatara Games. I’m part of a small team that just released our Unreal Engine 5-powered game, Let Them Come: Onslaught across PC and consoles. 

In our sci-fi bullet heaven game, players find themselves stranded on a hostile alien world fighting against never-ending hordes of monsters. Rather than your enemies disappearing from the screen, we wanted each kill to look spectacular and leave its mark on the battlefield—but given the scope of our swarms, this created some technical challenges that required us to experiment with Unreal's systems in order to solve them.

The original Let Them Come was built using Game Maker, but we switched to Unreal Engine for Let Them Come: Onslaught because we identified the engine as the best fit for our goals for the game. 

Unreal allowed us to throw lots of enemies onto the screen at the same time, plus lots of visual effects, and still ensure a smooth performance. We're also most familiar with the authoring tools for VFX, especially with Unreal Engine, due to our work as a VFX studio.

Our challenge: Bloody floors


A challenge with Let Them Come: Onslaught’s VFX was the number of enemies on screen at any time, and how many might be killed all at once. When we prototyped the game, originally the enemies would trigger a Burst Gameplay Cue which would spawn a decal for blood left on the ground and a bloody explosion for player feedback. We quickly found that you could trigger a lot of these deaths at once, especially with upgraded weapons, so we needed to do some optimization on these to ensure the action could get as chaotic as possible and not be bottlenecked by quantity.

For the blood decals, these were originally spawned to leave some sense of carnage and act as a breadcrumb trail for the player to show where they’d been (and what they’d left behind). The problem became that a lot of these would be spawned—and we’d want to leave them lingering for quite a while so they could be effective—which meant they would stack up quickly. There was also the problem of overlapping decals to be dealt with: you could kill lots of enemies in close proximity, which would also result in decals overlapping with each other, often causing a performance issue.

To spawn a large amount of blood (and acid!) markers on the floor, we used Niagara to create a system that would render an array of world-space areas to a render target. This array is fixed length at around 256 entries and loops—so once the 256 entries have been exhausted, the first entry will then be updated to be the 257th entry and so on. This amount felt like a good setting, where you can paint the ground in gore quite significantly before recycling entries.

Now when an enemy is killed, instead of spawning a decal, it will send data about itself (position, radius, material type) to a “Splat Manager” Blueprint actor we have that is persistent in the world. 
The final, distorted mask delivers a realistic gory result.
Courtesy of Tuatara Games
This manager then sends the data through to a global Niagara system, which then uses High-Level Shading Language (HLSL) to write these areas to a global render target mask, using the Grid2D data interface. This system was based heavily on work from Chris Zuko, Technical Director at Terrible Posture Games. We fill out the render target with the distance to each blood pool, with the distance range being defined by the incoming radius. All these distances are then combined together to create one consistent mask.
Blood pool masks for a battle scene in ‘Let Them Come: Onslaught’.
Courtesy of Tuatara Games
This mask contains a few layers, including one for blood and one for acid, that can then be sampled in the environmental surface shaders to apply the layer of gore where needed. 

The manager keeps track of origin position for the current rendered area in world space, as well as the world space unit size of the area. These variables are updated within a Material & Niagara Parameter collection to expose them to content.

The gore mask was exposed as a couple of material functions that automatically mapped the coordinates to where it needed to sit in the world, leaving the artists with just a 0.0-1.0 weight they could use to drive surface effects without worrying about recreating the coordinates. For most of the surfaces, we take the incoming distance map and run a few world-space noise samples to distort the shape, and make it blend into the environment more organically.
Blood pools blended organically into the environment.
Courtesy of Tuatara Games
The final, distorted mask is then used to blend between material attributes in the surface shader to make it look suitably bloody and gory!
Blood pool radiuses for a battle scene in ‘Let Them Come: Onslaught’.
Courtesy of Tuatara Games

Blood explosion FX


Another key optimization focus was cutting down on the amount of spawned particle systems, particularly for enemy deaths. In the same way the decals were a problem with quantity, so were the amount of death explosions on screen. It was less an issue with overdraw in this case, but more the amount of Niagara Systems that were being spawned and managed.

We upgraded to Unreal 5.3 during the project, and a large motivation for doing so was to utilize Niagara Data Channels. With a little bit of refactoring of VFX and Gameplay Cues, we were able to send every blood explosion event into a single Niagara system via a Data Channel, which then plays a blood explosion at the correct location instead of spawning a brand new Niagara system every time. It worked very similarly to the blood pools: upon death, an enemy would send information about itself to the manager system in the world, including location and size/magnitude of the event, and this in turn is sent to a Niagara Data Channel.

When it came time to implement a “goreless” version of the death FX, this approach made things simple—the goreless version of the effect was implemented alongside the bloody version, and switched to depending on the game options.

The Niagara Data Channel path for death effects does not cover 100% of all deaths, as we still wanted to do custom deaths for particular entities. It does cover around 80-90% of deaths whilst still enabling us to branch out and go bespoke where necessary.

The result is players can see the carnage they have created in their fight for survival, and the battlefield remembers your triumphs without impacting performance. We really hope you can see all of this in action for yourselves now that Let The Come: Onslaught has launched.

Want to build games in Unreal Engine?

With Unreal Engine, your ambition is the limit—not your team size. Discover how UE5 gives teams of every size the power to create stand-out games with the same visual sophistication as big-studio titles.
Find out more

Get updates on industry innovations and the latest free assets for

By submitting your information, you are agreeing to receive news, surveys, and special offers from Epic Games. Privacy policy