PhysX winch
Tuesday, April 12th, 2016Another cool one, just because.
Let’s debunk some more.
—
Trying out some more of the APE’s scenes. PhysX version is here. Original is here.
I didn’t put the crane itself yet but the cables are the hard part. Also I made the capsules thinner, to make it more difficult to simulate.
In the Unity thread you can read that:
“This new crane model was pushed to the extreme with the following modifications:
1) Reduce from 5 ropes weight attachments to 4 ropes
2) Increased the main rope’s length for an additional 5 segments
3) Increased the mass ratio between a single rope segment and the cargo box to 1:1000. No commercial physics engines I’ve used before handle such HUGE mass ratio between joined rigid bodies. The common guideline from PhysX and Havok is less than 1:10. Literally you’re lifting a ton with a kilogram ! This is probably overkill for most games. However if you do want to simulate extremely heavy weight sensation, here you go!”
So the mass ratio is 1000:1 in my test, and as you can see it works just fine. You simply must use the right PhysX feature (articulations) for the job.
—
Bonus:
I was at the playground with my kid and we were doing this with the swing set. I wondered if it would work in PhysX. It did
Capsules have a mass of 1. The box has a mass of 1000. Timestep is 1/60. This is again using PhysX’s articulations feature.
It somehow reminds me of these “rubber effects” we did in demos on the Atari ST
Trying out more of the APE scenes.
https://www.youtube.com/watch?v=8TZ9_B_tvLk&feature=youtu.be
What I said before for ropes still apply: it is correct that you don’t always get something working flawlessly out of the box, but that’s more a side-effect of the iterative solver than a bug or defect in the software. And most importantly, there are often several ways to make things work anyway. I think the APE guys didn’t try very hard because in this case it took 3 API calls to make things work better:
j->setProjectionLinearTolerance(0.0f);
j->setProjectionAngularTolerance(0.0f);
j->setConstraintFlag(PxConstraintFlag::ePROJECTION, true);
The video is using regular joints. But I suspect that, as for ropes, this is a case for the articulations feature. They probably would give even better results - I may try later.
Speaking of PhysX joints and ropes…. It can do that.
After GDC 2016 some people asked me about this video:
https://www.youtube.com/watch?v=ezTOYSms9us
I didn’t know this engine, but some googling revealed that it has been around since 2014 at least:
http://forum.unity3d.com/threads/ape-advanced-physics-engine-for-robust-joints-and-powerful-motors.259889/
First: welcome! Physics is fun and one more competitor is always healthy for end users. Also, your engine looks very nice so far.
Second: unfortunately your claims are slightly misleading and perhaps a bit unfair.
It is certainly correct that the PhysX joints are not perfect. It is certainly correct that PhysX does not handle high mass ratio differences very well. But that is just a side effect of using iterative solvers instead of the real thing. You can use PEEL to verify that Havok, Bullet, Newton, etc, all suffer from the same issue.
But this was not a random design decision, or something that we did not expect. We all started with “perfect” solvers a while ago (NovodeX 1.0 for example). They would solve everything by-the-book and behave much better in the presence of large mass ratio/etc. Unfortunately they were also very slow, and the customers didn’t care about accuracy. They cared about performance, and memory usage. To this date, most customer requests and feedback we get are still about exactly that: it’s never fast enough, and it’s always using too much memory. On the other hand, games get away with inaccurate solutions and imperfect solvers all the time, because they don’t use complex physics. Iterative solvers work fine for ragdolls, and most games don’t use more complex physics than that. So they don’t want to pay the price for a proper solver, when a cheaper one does the job just fine.
Now, when that solver is indeed not enough, we usually have dedicated solutions to specific problems. For example characters will use a character controller module. And vehicles will use a dedicated vehicle library. Contrary to what I read at least twice on different forums, recreating a car using rigid bodies connected by joints will not give you the “most realistic” vehicle, far from it. If nothing else, tires are not rigid bodies at all. If you want the most realistic driving behavior, you need a dedicated simulation just for the tire model (as they did in Project Cars for example). Using raycasts is not a problem per-se, because the contact information it gives you is in fact pretty much the same as what a rigid body cylinder would give you: contact point(s) and normal(s). Contrary to what people claim, PhysX is perfectly capable of simulating a “monster truck”. In fact, we were the first ones simulating a monster truck with rigid bodies connected by joints, back in 2002 with NovodeX 2.0. (And we also did the tank-with-hinge-joints in Rocket, remember?). But we eventually dropped that approach because it is too crude, it doesn’t give you enough control over the driving behavior, and ultimately it does not look realistic enough. The current PhysX vehicle library is way more advanced, with models for the gearbox, clutch, suspension, wheels, anti-roll bars, and so on. It is not easy to use and we don’t have a good demo/sample for it, but the resulting cars are quite fun and pleasant to drive - much more than the NovodeX monster truck ever was. I’m not saying that as the PhysX guy, I’m saying that as the guy who logged hundreds of hours in the Forza games.
It is the same for joints. Most game physics engines have an extra dedicated solution for articulated systems, because they are perfectly aware that regular joints won’t work well there. Thus if you are trying to do an articulated character, there is a dedicated solution in PhysX called, well, “articulations”. There are equivalent solutions in Havok/Bullet/etc. Somebody pointed this out in the forum thread above but it was ignored, maybe because it didn’t fit the desired narrative.
I am not saying that the current PhysX articulations are a perfect solution to all problems (they certainly have their limitations as well), but if you are not even trying them then you are comparing apples to oranges. Just to prove my point I went ahead and recreated one of the scenes in PEEL (I might try other ones later). The forum thread says:
“If you tried this kind of setup with PhysX you should have known that PhysX can’t sustain this sort of load and complexity.”
This is wrong. It works just fine, as long as you use articulations:
To be fair and to give you the benefits of the doubt, it is true that Unity does not expose articulations to their users, so this was probably not possible to try there.
However, even with regular joints, you can get much better results than what got presented. For example here is a short list of things to try to improve ropes:
Yes, I realize that some people will consider this “cheating”. Well, game physics is a lot about cheating. Which brings me back nicely to what I was saying first: welcome! There is certainly room here for new engines that favor exactness over performance.
Conventional wisdom says that you should use a profiler, find the bottleneck, optimize the bottleneck, repeat until the profile is flat.
Conventional wisdom says that you should not waste time with minor optimizations that won’t make a dent in the framerate. The gains must be “significant” to justify the time and effort spent optimizing.
Oh fuck off now. Conventional wisdom is stupid.
In terms of optimization I usually say that “everything matters”. All the minor insignificant gains eventually add up to something very valuable in the end. I’ve seen it on the ST. I’ve seen it on PC. I’ve seen it (a lot) on consoles.
And I just saw it again today. Here’s what 3 months of insignificant optimizations look like when you ignore conventional wisdom and keep doing them anyway. First changelist was at the end of last year, last changelist was last week. Scene is “ConvexGalore2″ in PEEL (bunch of convexes falling in a pile).
Granted: there is in fact a “significant” optimization in there that accounts for 1/3 of the gains. But the remaining 2/3 are from supposedly insignificant ones.
And that’s not even an April Fools joke
I already mentioned GRB on this blog (e.g. in the posts about PEEL). Here is some news about it fresh from GDC.
(This is a copy of PEEL’s User Manual’s Appendix A. I am re-posting it here since people rarely bother reading docs anyway)
Benchmarking on PC is a black art. Benchmarking physics engines is even harder. Use the following notes to avoid the most basic mistakes.
Use the proper power options.
This is typically found in Control Panel => System and security => Power Options. Select the “High performance” power plan. Running benchmarks with the “Balanced” or “Power saver” plans produces unreliable results.
Close all programs except PEEL. Unplug the internet.
Do not let programs like Outlook, Winamp, antivirus software, etc, run in the background. They can start random tasks at random times that will interfere with your benchmarks.
Ideally, start the Task Manager and kill all unnecessary processes. There are so many here that listing them all is impossible, but with some experience you should be able to know which ones can be killed, and which ones are worth killing.
It is of course very tedious to do this each time. So ideally you would take a radical step and use a dedicated PC with a fresh Windows installation and no internet connection. That is exactly what I do, and PEEL’s benchmark results at home are a lot more stable than PEEL’s benchmark results at work. Even when I do unplug the internet cable on the work PC…
Be aware of each engine’s “empty” operating overhead.
In theory, when you run a physics update on an empty scene, all engines should take the same amount of time, i.e no time at all since there is nothing to do.
In practice, of course, this is not the case. PEEL’s first test scene measures this operating cost.
Avoid benchmarks with just one object.
As a consequence, avoid running benchmarks with just a few objects or even a single object. The simulation time for just one object is likely to be lower than the engine’s empty operating overhead, because the main internal algorithms are usually a lot more optimized than the glue code that connects them all together. Thus, such benchmarks actually measure this operating overhead more than anything else. While it is an interesting thing to measure, it does not reflect the engines’ performance in real cases: the empty overhead is a constant time cost which is going to be lost in the noise of an actual game.
Thus, for example, it would be very wrong to run a benchmark with a single object and conclude that “engine A is faster than engine B” based on such results.
Try small scenes and large scenes.
Not all engines scale well. Some engines may be faster with small scenes, but collapse completely with large scenes – because large scenes have a tendency to expose O(N^2) parts of an engine.
Traditionally it is wise to “optimize for the worst case”, so benchmarks involving large scenes tend to have a higher weight than those involving small scenes. Note that “small” and “large” are vague terms on purpose: a large scene in a game today might be considered a small scene in a game tomorrow. And at the end of the day, if it is fast enough for your game, it does not matter that an engine does not scale beyond that. It may matter for your next game though.
The point is: here again it is difficult to conclude from a limited set of benchmarks that “engine A is faster than engine B”. You may have to refine your conclusions on a case-by-case basis.
Be aware of sleeping.
Virtually all physics engines have “sleeping” algorithms in place to disable work on non-moving, sleeping objects.
While the performance of an engine simulating sleeping objects is important, it is usually not the thing benchmarks should focus on. In the spirit of optimizing the worst case again, what matters more is the engine’s performance when all these objects wake up: they must do so without killing the game’s framerate.
Thus, PEEL typically disable sleeping algorithms entirely in its benchmarks, in order to capture the engines’ ‘real’ performance figures. Unfortunately some physics engines may not let users disable these sleeping mechanisms, and benchmarks can appear biased as a result – giving an unfair advantage to the engines that put all objects to sleep.
Obviously, concluding that engine A (with sleeping objects) is faster than engine B (with non-sleeping objects) is foolish. Keep your eyes open for this in your experiments and benchmarks.
Be aware of solver iteration counts.
Most physics engines have a fast iterative solver that uses a default number of iterations. That default value may be different in each engine. For fair comparisons, make sure compared engines use the same number of iterations.
Alternatively, tweak the number of iterations in each engine until they all use roughly the same amount of time, then check which one produces the best simulation quality for the same CPU budget.
If a complex scene e.g. with joints does not work well by default in engine A, but works well with engine B, think about increasing the number of iterations for engine A. It might make it work while still remaining cheaper overall than engine B. And so on.
Comparing how engines behave out-of-the-box, with their default values, is only the tip of the iceberg.
Artificial benchmarks are not an actual game.
What works in the lab does not always work in the field. A good result in an artificial benchmark may not translate to a similarly good result in the final game. Good results in artificial benchmarks are just hints and good signs, not definitive conclusions. Take the results with the proverbial grain of salt.
Benchmarks are often artificial because they capture situations that would not actually happen in a game. At the same time, situations that would actually happen in a game often aren’t complicated enough to expose significant differences between engine A and engine B, or they are too complicated to recreate in a benchmark environment.
Similarly, physics usually only takes a fraction of the game’s frame. Thus, if engine A is “2X faster” than engine B in benchmarks, it does not mean that using engine A will make your game 2X faster overall. If your physics budget is 5% of the frame, even if you switch to an incredible physics engine that takes absolutely no time, you still only save 5% of the game’s frame. Thus, it might actually be reasonable and acceptable to switch to a slower engine if it offers other benefits otherwise (better support, open source, etc).
Benchmarks are never “done”.
There is always some possible scenario that you missed. There is always a case that you did not cover. There is maybe a different way to use the engine that you did not think about. There is always the possibility that an engine shining in all available benchmarks performs poorly in some other cases that were not captured.
There are more than 300 tests in PEEL, and still it only scratches the surface of what supported physics engines can do. Already though, in the limited set of available tests, no single engine always ends up “fastest”. Sometimes engine A wins. Sometimes engine B wins.
Version 1.01 has been released. Download link.
Release notes:
* april 2015: v1.01 - the Bullet single-triangle-mesh issue
- the Bullet plugin was crashing or behaving oddly in all scenes featuring the “single triangle” mesh. This has been fixed. The reason was that the triangle’s data was not persistent (contrary to what happens for other meshes), and since Bullet does not copy the data, bad things happened. It looks like all the other engines copy the data, since they were working fine. Thanks to Erwin Coumans for figuring out the root of the problem.
- Opcode2 plugins will not crash anymore in raycast scenes without meshes (they won’t do anything though).