Five years ago, we wrote about how the visual effects in Returnal came to life, including the real-time voxeliser that dissolved Phrike into volumetric fog. If you haven’t read it, that post is a good companion to this one.
This is how that story continues.
With Saros, we didn’t just extend what we’d built for Returnal. We stepped back, looked at thirty years of accumulated engine development, and rebuilt it as a unified framework: Graphite.
What we had, and why we changed it
Our proprietary particle engine, NGP (Next-Gen Particles), started as a prototype for Resogun in 2013 and grew with every game since, all the way to Returnal. By SAROS, NGP was mature, but it was also a product of twelve years of incremental decisions, each one made in the context of a specific, isolated game.
Then something else changed: us. Joining PlayStation Studios meant delivering experiences at the level our players expect, and our tools, and the names we’d given them, no longer matched the studio we were becoming.
Enter Graphite. It brings GPU simulation, rendering, tooling, and DCC integration under one architecture, built directly for PlayStation hardware. NGP didn’t disappear, it became part of Graphite, evolved and more capable than ever.
Every Housemarque game has a visual identity players recognise immediately. Graphite is what makes that possible.
And what it actually does, frame by frame, is best explained by the incredible people who built it:
Housemarque Graphics Architect Sharman Jagadeesan and Senior Graphics Programmer Konsta Toivanen will walk you through the volumetric fog in Saros: how it evolved from Returnal, and the two systems we built to make Carcosa’s atmosphere feel alive.
Risto Jankkila (VFX Architect) will explain how we extended Graphite with data from Houdini, including a full breakdown of the player spawn sequence.
Volumetric fog
Fog in games is often an afterthought, something that fills empty space and hides draw distances. In Saros, we wanted it to be a living part of the world, reacting to everything happening in it.
In Returnal, our volumetric fog was already reactive, but too low frequency, and heavy temporal filtering kept it from showing fine detail. For Saros we built two complementary solutions: low frequency fog for ambient atmosphere, and high frequency fog for the character effects seen in special story rooms in Carcosa.
Low frequency fog
We took Unreal Engine’s froxel fog, a frustum-aligned voxel grid, as a starting point and rebuilt significant parts of it to meet our vision.
The first challenge was temporal stability. The hysteresis coefficient controls how much of the previous frame’s data the fog holds onto: Unreal’s default of 90% keeps the image stable but makes the fog sluggish on fast-moving cameras and lights. We pushed it down to 50%, using blue noise jitter and depth clamping to keep the resulting aliasing under control.
Saros also needed fog that could represent everything from low density ambient mist to high density ground fog. To render these faithfully we used:
- A dual Henyey-Greenstein phase function, modelling how light scatters forward and backward through the fog depending on viewing angle.
- A coloured absorption coefficient, determining how much light is absorbed as it travels through a medium, for a far wider range of colours than traditional monochromatic solutions.
- A self shadowing system that aggregates incoming light sources into a dominant shadowing direction and ray-marches toward it.
- A physically based sky lighting integral, for accurate distant lighting without sacrificing performance.
Together these gave Carcosa’s atmosphere a grounded, physical quality.
Finally, the low frequency fog is fully interactive. Advection from our player-following fluid simulation feeds directly into the density hysteresis step, making every player movement, projectile, explosion, and enemy readable in the fog in real time.
High frequency fog
For the high-frequency fog we built a custom ray marcher. To keep performance in check while preserving fidelity, we cluster the scatter data into 8x8x8 voxel groups before marching, drawing only the clusters that contain data, with a user-defined threshold keeping their number in check. While marching, empty regions between clusters get skipped, letting the marcher take larger steps where it can.
For lighting, we evaluated a light volume per scatter volume, containing irradiance from all light sources, with pre-marched self-shadowing for every light voxel. We exposed parameters for albedo, absorbance, density, and shadowing, letting artists balance visuals against performance for each volume.
The two fog systems are then merged: we sample the low frequency fog’s scatter data during the high frequency march, and feed results back so both stay consistent with each other.
Use cases
We used the high frequency volumetric fog in a few scenarios. One use case was in the Prologue in the form of a smoky skull with cables attached to it. Another use case was with what we call Mirages. In four of our biomes there are specific narrative rooms where Arjun is faced with smoke creatures.
Reactivity is key to all the VFX we make, and these effects were no exception. Since impact data doesn’t need high resolution, we store it in a separate, low resolution volume, which for the skull also holds its low frequency velocity field.
The videos below show that volume on the left, and combined with the skull on the right. Impacts are evaluated as a Signed Distance Field that closes back up over time, while velocity is shown in colour, you can see both the impact holes and the turbulence they create.
Here’s the final skull effect without the cables and other secondaries and in a different environment.
The mirage effect is similar to the skull effect. The difference is that there are so called mirage “scenes” that rotate. We also used our real-time skeletal mesh voxelizer to bring existing meshes into the scenes. The video below shows a sweep between the voxelized result and the final result with advecting data from the previous frame.
Here’s the final effect with rotating two mirage scenes in a test environment. For reactivity, we used the same method described for the skull effect.
Extending Graphite with data from Houdini
In addition to improving the rendering quality of our volumetric effects we wanted to introduce new ways for our artists to author them.
Previously, volumetric effects were created by writing per-voxel expressions for density emission, combined with fluid simulations driving the advection (the directional movement) of the density field. Because this grid-and-voxel approach is the industry standard for film VFX, it was our natural first step as well.
From Returnal days: voxelising Phrike into a grid for density emission
During Returnal’s development, we realized we needed tighter control over exactly where density is generated. Per-voxel logic let us emit density on nearby surfaces or voxelised meshes, but anything more complex came with severe runtime overhead. Emitting density from just a character’s arm, rather than their whole voxelised body, was very difficult to do efficiently in real time.
Also from Returnal: full body density emission from the voxelised mesh
To solve this, we turned to particles to drive volumetric density emission. Graphite’s fully programmable particle system gave us a solid foundation for tightly controlled volumes, resulting in two new tools:
An Offline Houdini Data Pipeline: lets artists pre-compute complex, high-fidelity data in Houdini that would be too expensive to generate at runtime.
A Runtime Point Cloud Rasterizer: a high-performance component that takes simulated points and rasterizes them directly into a volume in real time.
Together, these freed us from stateless per-voxel expressions and rigid fluid simulations. Particles can now precisely follow a character’s animated mesh, giving artists full control over an effect’s behavior and lifecycle.
In practice, an artist imports an animated Saros character into Houdini and uses its tools to compute starting positions and attributes for an effect. That baked data feeds into the game engine, where real-time simulation takes over. In the video below, points generated in Houdini closely match the in-game character, and custom runtime logic detaches them from the enemy on bullet impact, so initial positions come from Houdini, but the behavior reacts dynamically to the player in real time.
Creating point data in Houdini
Using point data from Houdini in engine
Since artists can export any kind of data from Houdini to Graphite, it’s easy to go beyond static particles attached to characters. Below, particles flow across the surface of an animated mesh: the surface was unfolded in Houdini into a 2D simulation space, then exported and mapped back onto the animated mesh in real time.
Particle flow on Arjun’s body on the left. In the middle we extract an ISO surface from the particles. On the right we have volumetric fog emitted from the particle flow.
A prime in-game example of this technology in action is the player spawn sequence in Saros. This complex effect is built in multiple layers, starting offline in Houdini, where we generate splines directly onto the player’s skeletal mesh. When exporting these splines into Graphite, we treat each control point along the spline as an individual particle.
Simulating particle positions in Houdini. These are only used as target positions in the engine and the growth motion will be re-simulated dynamically during runtime.
At runtime, our programmable particle system controls how these elements behave over time. At first, the splines drift freely in space, then gradually guide back toward their target positions on the character mesh.
We wanted the player to look like they’re physically reforming from a pool of shifting “goo.” Marching Cubes gave us that viscous, solid-surface look, and controlling it with particles let us build a sequence where the player forms from separate strands into a character.
Marching cubes constructed from particle splines
Much like the splines that generated the goo surface, we can also emit volumetric density as well. In the spawn sequence we placed a number of particle splines near the player location and spawn volumetric fog from them to simulate rising steam or smoke.
Volumetric fog emitted from particle splines
As a final touch, we added spark particles that collide with the player character, using a signed distance field computed from the player’s collision capsules. The programmable particle system again gave us flexibility here: the player attracts particles, but once they get too close, the player mesh repels them, helping sell the look of emerging from hot, lava-like liquid.
Particles colliding with player capsule SDFs
Here’s everything combined. Every element is simulated at runtime, at 60 fps on base PS5, with no baked simulation assets. This lets us ship multiple spawn animations, each with slight randomization so it looks a little different every time the player wakes up.
Final player spawn sequence
An ever-evolving development journey
Reading through what Risto, Sharman, and Konsta broke down here, the goal for us and our technology has always been the same: every simulation, every effect, every rendering decision exists to make you feel something when you play.
Making games means believing in something you can’t yet prove, and the only people who can ever confirm it are the players themselves. Saros players told us, in their own words, that what we built mattered. And that means everything to us.
Our games will keep informing the technology we develop for Graphite, always showcasing what PlayStation as a platform can do. We can’t wait to share that future with you.







