Trending
Opinion: How will Project 2025 impact game developers?
The Heritage Foundation's manifesto for the possible next administration could do great harm to many, including large portions of the game development community.
'Try simple approaches first; in many cases, such an approach will already yield amazing results, leaving you more time to iterate on the more complex areas.'
December 12, 2024
Game Developer Deep Dives are an ongoing series with the goal of shedding light on specific design, art, or technical features within a video game in order to show how seemingly simple, fundamental design decisions aren’t really that simple at all.
Earlier installments cover topics such as cover topics such as how camera effects, sound FX, and VFX created a smooth and high octane movement system in Echo Point Nova, the technical process behind bringing The Cycle: Frontier to Unreal Editor for Fortnite, and how the developers at ROAR Games designed three distinct, overlapping game worlds within one cohesive narrative in Tenet of the Spark.
In this edition, Frontier Developments render programmer John Wigg explains their methods for creating effects that authentically mimic the behavior of real water.
Hi everyone, I’m John Wigg, a render programmer at the UK-based studio Frontier Developments. We just released Planet Coaster 2, the sequel to 2016’s genre-defining creative management simulation game. Planet Coaster 2 allows players to reach new heights of creativity, management and sharing as they construct the coaster and water parks of their dreams, combining epic water rides and coasters to delight and thrill guests.
Waterparks are a highly requested new addition for Planet Coaster 2. We wanted to give the same attention to detail and level of immersion to this new area of the game that players have come to expect from the previous Planet games. In this deep dive, we will explain how we crafted all the different systems that go hand in hand to achieve this.
Creative freedom is at the core of Planet Coaster 2. For water parks, this means our players can:
Use free-form building tools to create pools in any shape imaginable
Place wave machines to create wave pools with interesting wave patterns
Explore their parks up close, using the new first-person camera
It is very important that the systems we create are highly dynamic and can respond to a wide range of situations.
We also had to be aware of how park visitors will interact with the water. A park can have thousands of guests at the same time. Our talented animators authored thousands of unique pool animations for these guests. We wanted to ensure that all these affect water surfaces in a realistic manner.
A splash fight and swimming guests create ripples. Image and caption via Frontier Developments.
This high level of detail is one of the pillars of the Planet games and something we consider in all areas of development.
Traditionally, many games render water as a flat plane and create the illusion of an uneven surface by using lighting tricks, e.g., normal or bump maps. These techniques, however, break down when viewed up close.
We wanted the water to feel alive and three-dimensional at any distance. To achieve this, we use a dynamic level-of-detail system. This system works by subdividing the triangles of the water mesh based on the camera distance. This ensures that we always have roughly the same amount of geometry on the screen, achieving a constant rendering cost down to the centimeter scale. This approach is very popular for rendering terrain in open-world games, but it is rare to see it applied to water surfaces in such detail.
The subdivision of a water surface. Image and caption via Frontier Developments.
This subdivision allows us to move the geometry of the water surface up and down with the waves and ripples. This adds a lot of plasticity to the water, which is especially noticeable when observing the surface from a shallow angle, e.g., when taking a dip in the first-person camera.
Water ripples in the first-person camera. Image and caption via Frontier Developments.
We also put a lot of thought into the transition that happens when moving the camera underwater. By rendering the water line on the screen, we achieve something termed a "split-shot" in photography; in a screen-space shader, we transform the pixel position to world coordinates and populate a low-resolution texture with the vertical distance to the water surface. We then threshold this distance texture to render a smooth water line. I recommend giving Improved Alpha-Tested Magnification for Vector Textures and Special Effects by Chris Green (2007) a read if you’d like to know more about using distance fields for similar effects.
The rendering pipeline for the water line effect. Image and caption via Frontier Developments.
In our first full update for the game post-launch, we’ll also be adding a fun water droplet effect to the camera as it enters and exits the water.
Now that we can render highly detailed water surfaces, we will look at how we animate them.
Each guest type (kids, teens, and adults) has hundreds of different animations for different pool interactions. All these animations disturb the water in different ways, e.g., a swimming guest will create a wake and pull swirls behind them, and someone cannonballing into a pool may create a big splash. Park guests can also participate in splash fights. Our solution for animating the water surface must dynamically react to these interactions in a plausible manner.
Humans have a very intuitive understanding of the motion of water, so a fun and lively water animation should be as true to life as possible. To achieve this, we utilize a state-of-the-art fluid simulation. This allows the water to realistically flow around guests, creating swirls and ripples in the process.
There exist plenty of different models for fluid simulations for different use-cases. (As you’re about to see, we utilize two different fluid simulations for this very reason.) Some of these models may focus more on certain characteristics of fluids, some are fully three dimensional, while others operate in two dimensions.
For pools, we are interested in three characteristics of the water: Its vertical displacement (up-and-down motion), its flow (e.g., swirls and vortices), and foam. Our fluid simulation is two-dimensional since we are only interested in surface effects but not the water’s deeper layers.
Displacement, flow, and foam in action. Image and caption via Frontier Developments.
On a high level, our fluid simulation works like this: for each frame, we populate a grid of data, stored as a texture on the GPU, with the current displacement and flow vectors. If we detect that a guest, or any other physics collider, intersects the water surface, we override the corresponding grid positions with a displacement amount and the velocity of the object. The resulting displacement and velocity values are our so-called initial conditions. Using our simulation code, we evolve these initial conditions and render the output. We then use this output as the initial conditions for the next frame, and so on.
The data flow of our fluid simulation. Image and caption via Frontier Developments.
For our simulation code, we needed to choose a mathematical model that matches the requirements of the game. For a simple simulation, one may just use the standard wave equation. Instead, we chose the so-called shallow water equations, which also model displacement and flow. This allows us to animate even more effects, such as swirls.
Turning these equations into a computer program is an art in itself, and a plethora of materials on the topic exist, ranging from beginner-friendly YouTube tutorials to highly technical scientific papers. The choice again will depend on the requirements of your game. My advice is to err on the side of simplicity and not get lost in the mathematical intricacies early on.
For the technically inclined, I’ll throw in some jargon (feel free to skip this part): we use a semi-Langrangian formulation of the shallow water equations, which we integrate using the Crank-Nicolson method. Our numerical solver is the Preconditioned Conjugate Gradient (PCG) method. Some works we referenced are “A numerically efficient and stable algorithm for animating water waves” by Anita Layton and Michiel van de Panne (2002), “A Parallel Preconditioned Conjugate Gradient Solver for the Poisson Problem on a Multi-GPU Platform” by Marco Ament et al. (2010), and the talk “Real-Time Fluid Simulation in Shadow of the Tomb Raider” by Peter Sikachev (2018). Chapter 38 of “GPU Gems” (2004) also gives a good introduction to the topic.
It took us a lot of research as well as some trial and error to arrive at this solution, and it gives us very stable and accurate results. This is important as the player can control the game speed up to five times as fast as real-time.
We do all this work on the GPU using compute shaders. GPUs are well suited for this task, as they are extremely efficient in updating each grid point in parallel.
We also simulate a foam layer on top of the surface, using the outputs from the fluid simulation to dynamically add foam and transport it with the flow of the water.
All this gives us a fully dynamic water simulation that naturally reacts to whatever we or the player may throw at it.
In addition to the ripples created by park guests, we also allow our players to build wave pools by placing wave machines on the sides of pools. Our players can create interesting and fun wave patterns in this way, and we’ve already seen many creative uses of this tool.
A wave machine at the end of the pool creates waves in the water. Image and caption via Frontier Developments.
Since the waves from wave machines are much bigger than the ripples created by guest interactions, we utilized an additional, different fluid simulation.
The model we used here is much simpler than the one used for the guest interactions. We based it on the so-called "hydrostatic pipe model" introduced in “Dynamic Simulation of Splashing Fluids” by James O’Brien and Jessica Hodgins (1995): we subdivide each pool into a grid of one-by-one meter cells. Each cell is then connected to its four neighbors by imaginary "pipes," through which water flows freely, based on the height difference between each pair of neighbors. Creating waves then becomes trivial: we periodically remove some water from the pool and then add it back, creating troughs and peaks in the process. This is close to how some wave machines work in the real world!
The hydrostatic pipe model: Each cell has four flow pipes to its neighbors. Image and caption via Frontier Developments.
As this simulation affects gameplay (guests react to waves), we decided to implement it on the CPU. Each pool runs its own simulation, so we can easily distribute the work across different threads when there are multiple pools in a park. Things become a little trickier when we have a very big pool, however: the only limit to the size of a pool is the size of the playable area. We also need to update the simulation every frame in real-time.
Distributing a single simulation onto multiple threads would require complex synchronization code. Instead, we heavily utilize SIMD instruction sets. SIMD is short for single instruction, multiple data and allows us to perform the same operation (e.g., multiplication) on multiple values in just one CPU instruction. This means we can update multiple grid points in parallel in just one operation! A lot of this code has been hand-tuned and continuously performance-tested to make sure the game always runs smoothly, even in large parks with huge pools.
The SIMD instructions can compute eight cells in one go! Image and caption via Frontier Developments.
In fact, the wave simulation ended up being so efficient that we decided to use it for the shore waves on our island and coastline levels as well.
In this deep dive, we spoke about several systems, each modeling a different aspect of water: we implemented highly-detailed water surface rendering, allowing us to display water surfaces in three dimensions, even when viewed up close. A state-of-the-art fluid simulation dynamically and naturally animates ripples, flow, and foam. And finally, a simple but efficient wave simulation brings wave pools, and even shorelines, to life.
All these systems have their own focus, and their strengths go hand in hand to create highly detailed, immersive, and creative water parks.
Thank you so much for reading and we hope you enjoyed this little dip in the water rendering and physics in Planet Coaster 2! Hopefully, you have a clearer picture of how our different water systems work and interact, and maybe some of the techniques we outlined will be useful in your own endeavors or can serve as an inspiration.
We’d also like you to take away from this article that games are complicated machines that consist of many moving parts. Some of these parts will be more complex than others, but they all work together to create the final experience. Do not get discouraged early on. Instead, identify the individual components of your game and iterate on them. Try simple approaches first; in many cases, such an approach will already yield amazing results, leaving you more time to iterate on the more complex areas.
You May Also Like