The Art of Damping

This is a Deep Tech post, it does require some notion of mathematics and gameplay engineering

Unity Scene & C# Code

You can download and use the Unity code from this article on the Art of Damping GitHub Repository.

Real-time Damping

Damping is the art of mathematical motion. Its purpose is to create a transition, over time, from one value to another. For example if you had a moving character in a game you could add damping to its speed to slowly increase it, in a smooth but reactive way. You could decide not to use damping and instantly change the speed (in one frame) but it usually doesn’t feel as good. Damping is also called Tweening, mostly because of Flash in the early days of vector animation interpolation.

A lot of things depend on good damping. Camera, animation, movement, color gradients, UI transitions, and many many more… it’s used everywhere! Understanding damping is key to achieve great polish, damping alone can make the difference between a bad or a good experience.

One particular requirement of damping functions for games is that the goal position (and speed) can change while the damping happens. For example if I have a camera following a character, I want to be able to apply damping to my camera movement and rotation while my character is moving.

As a result a damping function cannot be a fixed curve. It’s a math function trying to reach a goal in a smooth way, always adapting to what’s happening in real-time.

Unity SmoothDamp & Programming Gems #4

In Unity there are a few different implementations of damping, but the most commonly used function is SmoothDamp. We can find its code in Mathf.cs from the UnityCsReference:

This is advanced math code.

It implements Game Programming Gem 4 : Critically Damped Ease-In/Ease-Out Smoothing by Thomas Lowe, an incredibly well written article about springs physics and how to to use it and implement it to achieve good damping. Some extracts:

ProgammingGem4_1.jpg
ProgammingGem4_2.jpg

Comparing Damping Functions

There was another article recently from Daniel Holden that also describes springs very well and their use for damping: Spring-It-On: The Game Developer's Spring-Roll-Call. It’s a long read, but made very accessible.

He implements different kinds of springs in C++, so I decided to port the code to Unity in C# and compare them to the built-in Unity spring, and see if I could learn something.

In total I compared 6 different damping functions:

  1. Unity built-in SmoothDamp

  2. Simple damper (not spring related) with rough & fast ease-in but great ease-out

  3. Advanced spring damper that can oscillate, great for car suspension or fake ball physics

  4. Critical spring damper (similar to SmoothDamp) with optimized movement toward the goal

  5. Another simplified critical spring damper where we assume the goal to reach has no speed itself

  6. Double damper where we damp both the follower and the goal to achieve super smoothness

There is no winning damping function, they’re all useful in certain situations. The Unity built-in from Gem #4 is very generic and works in a vast majority of cases, but shouldn’t be used all the time. It does not oscillate, it does not rush to the goal, and it does not smooth the ease-in a lot.

They are many ways to compare damping functions. Here I created some curves from a basic case of a goal (in red) changing from one value to the next in one frame. The red curve represents the value we’re trying to match, it’s our goal. The blue curve is our current value that we’re slowly changing over time, we’re damping it.

Result-UnitySmoothDamp.jpg

Unity built-in SmoothDamp really has beautiful ease-in and ease-out, and it reacts very well to goal value change. As every other damping function here it is also frame rate independent.

Result-Normal.jpg

A simple damper function that does not use a spring. The ease-in (bottom part) is very abrupt, but ease-out is super good. This kind of easing is still useful in many cases, for example for quick feedback.

Result-Springf1.jpg

A typical spring, with lots of oscillation and over shooting.

Result-Springf3.jpg

The same spring with even more oscillation. Super good to have in some rare cases.

Result-CritNoGoalSpeed.jpg

This one is still the spring damper, but we force it to be critically damped, meaning it returns to the goal as fast as possible without extra oscillation. It’s very similar to SmoothDamp because that’s what SmoothDamp does!

We also pretend that the goal has no velocity, it makes the damping smoother and prevent overshooting.

Result-Critical.jpg

This is also a critically damped spring but there is overshooting because we take into account the goal velocity.

Result-DoubleDamped.jpg

And the double damper, one of my favorite because this one has a lot of use case. Look at that ease-in, it’s hyper smooth!

Here we use the previous damping on both our value and the goal. As a result the goal takes some time to reach its real objective value, and the ease-in is more smooth.

Some extra curves with moving goals:

Result-Moving-DoubleDamper.jpg

Another curve using the double damper with a goal changing over multiple frames. See how the blue curve removes all noise from the red, and smooth each of its crest.

Result-Moving-Spring.jpg

Using the spring that can overshoot can achieve some beautiful results (if overshooting is not a problem).

Result-Moving-Spring2.jpg

The spring has a lot of rare use case that can be beneficial, but it’s hard to master!

Previous
Previous

Per-triangle occlusion on the GPU in 1ms with Unity

Next
Next

Using Bolt To Improve Game Development