Box2D vs. PhysX. In many ways, this is a ridiculous matchup. An open-source 2D physics engine vs. Nvidia’s proprietary 3D physics engine. Why even compare them? Because, if you’re shopping for an iOS game engine, these two are your likely choices. Box2D comes with cocos2d and Corona. PhysX comes with Unity and Unreal. And, even if you’re making a 2D game, Unity has enough advantages to make it a tempting choice, even though its a 3D engine.
We chose Unity for our current 2D project, and you can read bout how we tricked it into doing 2D here. But we are making a physics-heavy game, and now are realizing that the game’s performance is physics-bottlenecked. After optimizing as much as we could in Unity, the game is chugging along at a pretty inconsistent 30 fps on an iPhone 4. We had to look into alternatives, and so I decided to benchmark the two engines. So, pick who you’re rooting for and let’s get these fuckers in the ring.
Um, Methodology, I Guess
The main goal of the this was to see which engine could handle the most rigidbodies without the frame rate dipping below 30fps. Each test consisted of increasing numbers of 1 by 3 meter rectangles, identical in mass, falling with lots of collisions. In both tests, all blocks were one batched draw call so that impact on performance by rendering would be minimal. The fps was averaged over each 10 second test. This was done on a first gen iPad.
Here is a summary of the respective settings.
|Version||Unity v3.4.0f5||Box2D v2.1.2|
|Solver Iterations||7||7 velocity, 7 position|
|Fixed Timestep||0.02 s||0.02 s|
|Max Timestep||0.333 s||0.333 s|
|Code Optimization||Fast, but no exceptions (Unity)||-Os (fastest, smallest) (Xcode)|
|Compile for thumb||No||No|
Box2D smoked PhysX. It could handle roughly twice as many rigidbodies at the same frame rate. Let me say that this is not meant to be a criticism of PhysX. I don’t know how much processing power you’re throwing away making a 3d engine do 2d physics, but apparently it’s significant. I’m sure PhysX is highly optimized, just not for 2d.
Compiler optimization was very important. PhysX was wildly outperforming Box2d before I realized I was running in debug and changed the optimization level in the Box2d Xcode project from -O0 to -Os. PhysX did not see a performance increase from making this change on Xcode, since Unity does its own static compiling.
I was hoping that tinkering with solver counts and timesteps would milk a good amount of performance out of the engines, but the changes were small. Strangley, PhysX’s performance was affected more by reducing the solver count, while Box2D’s responded more to increasing the timestep.
I have found that being pretty aggressive with reducing the max allowed timestep can be very helpful. Especially if you have infrequent spikes of physics-heavy processing.
This was not the result I was hoping for. Developing in Unity has been quick. Putting together this test took 3 times as long in cocos2d as it did in Unity. Porting three months of work to cocos2d, and losing all the the cross-platform goodness in the meantime makes my kidneys hurt. Maybe it’s time for some whiteboarding…