High-performance physics in Unity 5
We’d like to highlight some of the 3D physics changes you can look forward to in Unity 5.0.
We’ve been using PhysX 2.8.3 for a while now. We’ve not just used the plain stock PhysX, but extended it with numerous patches made by Unity engineers over the years. It’s been so long, and we say thanks to PhysX 2 for all the fish. As announced at GDC’14, Unity 5.0 features an upgrade to PhysX 3.3. Let’s give it a closer look.
PhysX SDK 3 is a radical redesign of the good old PhysX SDK 2.x. Basically, the PhysX team have taken the best ideas and best approaches from 2.x and rewritten the whole SDK from scratch. That means the entire codebase is different, all the interfaces are different and most of the functionality is different.
Now let’s give you a taste of how it feels to use Unity 5.0 physics.
To start with something simple, we’ve made the adaptive force switchable and off by default. Adaptive force is a special technique in PhysX to compensate for numerical errors when simulating stacks. However, feedback from Unity developers tells us that adaptive force contributes a lot to overall instability in game content. Expect your stack-like things to behave better in future.
Moving Static Colliders
Moving Static Colliders will be a lot less expensive. A Static Collider is just a gameobject with a collider component on it, but without a Rigidbody component. Previously, since the SDK assumed that Static Colliders aren’t moved, moving a Static Collider would trigger an expensive AABB tree rebuild that affected overall performance badly.
In Unity 5, we’ll use the same data structure to handle the movement of both dynamic and static colliders. Unfortunately, we’ll lose the benefit of Static Colliders consuming less memory than dynamic ones. However, right now, the cost associated with moving Static Colliders is one of the top 3 causes of performance issues in Unity games. We wanted to change that.
Continuous collision detection has been improved by an order of magnitude. Continuous collision detection is used to prevent fast-moving bodies from going through other bodies without any collisions detected. Imagine a bullet shot at a piece of paper, or a game of pool where some balls will move faster than others.
In Unity 5.0, the SDK generates all the data required to handle fast movement. You just enable continuous collision detection and it works. PhysX3 features an algorithm used to detect whether the expensive CCD simulation is actually needed given the current body velocity or a default discreet would do just fine. It’s activated once you enable the CCD.
Rigidbodies on the broadphase
PhysX3 supports more Rigidbodies on the broadphase. In fact, you’ll be able to have several hundred thousand bodies on a single frame on desktop and desktop-like platforms. Previously, there was a fixed 64k limit on bodies. That wasn’t a constant that we could easily increase – it was a consequence of saving a lot on bits all over the SDK. Some console targets, such as PlayStation 3 will still have this limitation. There’s also a limit on physics materials: at the time of writing, you can’t have more than 64k of materials on any platform.
Scaling Mesh Colliders is free (more or less)
In Unity 5.0 we’ve reduced the cost of scaling Mesh Colliders. Previously, when scaling a Mesh Collider, you would have to create a new mesh with scale baked into the vertices, and that required valuable time and memory. With PhysX3 we are able to support non-negative scaling without any baking. It’s basically free.
Next, let’s take a look at two subsystems that differ so much from the Unity 4.x version that you can think of them as new: the cloth and vehicles modules.
Let’s start with cloth. In Unity 4 cloth simulation is supported via InteractiveCloth and SkinnedCloth components. InteractiveCloth has a cloth-like mesh behaviour i.e. “physical cloth” that interacts with other physics bodies, can apply forces and so on. InteractiveCloth is computationally expensive, so Unity 4 has another one, SkinnedCloth, for character clothing.
Since SkinnedCloth is decoupled from the main simulation pipeline, it is able to perform better than InteractiveCloth. The main problem with cloth is that both components were quite unstable and cost a lot. With PhysX3 integration coming, we have decided to drop support for InteractiveCloth and only have one cloth component, called simply Cloth, designed with character clothing in mind.
In Unity 5.0, Cloth no longer reacts to all colliders in a scene, nor does it apply forces back to the world. Instead, we have a faster, multithreaded, more stable character clothing solution. When you add it the new Cloth component no longer reacts to any bodies at all.
Thus, Cloth and the world do not recognise or see each other until you manually add colliders from the world to the Cloth component. Even after that, the simulation is still one-way: cloth reacts to those bodies but doesn’t apply forces back. Additionally, you can only use three types of colliders with cloth: a sphere, a capsule, and conical capsule colliders, constructed using two sphere colliders. These changes have all been introduced to boost performance.
The authoring interface in Unity 5.0 is similar to the SkinnedCloth one, and we are working hard on improving that in 5.x. Expect to see things like integration with Mecanim avatars added during the 5.x cycle.
The new Cloth component supports the GPU via CUDA internally, but we’ve decided to release this later in the 5.x cycle for several reasons. Firstly, CUDA only works on Windows on NVIDIA hardware, and we have a big presence on Mac & Linux. Secondly, we really want to focus our bug fixing efforts on core stuff first and move on to integrate fancy things after that.
New Vehicle SDK
Now, a few words about vehicles. PhysX3 has a shiny new Vehicle SDK which we’ve used to implement our WheelCollider component. The new component delivers much more realistic suspension and tire friction. Plus, it fixes a number of other long-standing issues.
In Unity 5.0, the new component can be used out of the box to generate a simple behaviour. I only expect developers to go for vehicle packages on the Asset Store when they want something that is already fine-tuned, realistic or advanced, like Edy’s Vehicle Package.
Look at what I’ve been able to set up in a couple of hours using a free mesh downloaded from the web (most of that time was spent in Blender preparing the model):
And here is one of the SUVs from Edy’s Vehicle Package:
Edy is currently working on the new version of his package which will bring more amazing stuff. Contact him directly for more details.
The are a lot of fantastic technical details about vehicles I’d like to share with you, but, for now, let’s just take a look at the new WheelCollider gizmos. This will give you an idea of how suspension is going to work as well.
In the above picture the wheel circle and wheel diameter are marked in green, the suspension travel segment in orange and the force application point sphere in green. On the suspension travel segment, there are marks for maximum compression position, maximum droop position and target position.
As you’d expect, the wheel can only travel between the max compression and max droop positions. The target position (also referred to as the rest position in technical talks) is located exactly where the sprung weight is balanced by the spring force; i.e. the position where the wheel is located when the vehicle is just standing on a flat surface. It might seem tricky to tune, but, actually, the max compression position is where your wheel is located originally in the mesh.
Next, you specify the suspension distance and target position as a fraction of suspension distance. Just two floats to rule them all, not a big deal! Have I told you that the new wheel gizmo now updates the rotation and position from the simulation data out of the box? You don’t even have to add actual wheel geometry and write the wheel positioning code to preview your settings. It’s all just built in.
PhysX3 is now prepared to run on multicores as the internal computation model is organised in tasks that can be executed on different cores. The SDK does all the multithreading, taking care of all the dependencies itself and granting optimal job decomposition.
From what we’ve seen so far, it’s reasonable to expect a doubling in performance generally just as a result of having a better code base and improved multithreading. In some instances, the improvement is dramatic, with up to tenfold improvements.
Performance ninjas interested in more data should visit Pierre Terdiman’s blog. He’s the core developer behind the PhysX SDK.
The new functions look and feel Unity-like, but there are still cases where the behaviour is different, parameters mean different things or, in some cases, old behaviours are no longer supported. Thus, Unity 5.0 physics is not 100% compatible with Unity 4.x. Be prepared to retune your old projects and rewrite some of your physics code when migrating from previous Unity releases.
There are many more details about physics in Unity 5 than I can share in this post. Please feel free to ask questions in the comments, or if you’re visiting our Unite 2014 developer conference this year, catch my in-depth talk on physics in Unity 5.0 and come say hi and have a chat.