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.
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.
The final, distorted mask is then used to blend between material attributes in the surface shader to make it look suitably bloody and gory!