I’m currently working on a native code module for Thrive that includes an integration to the Jolt physics engine. As preliminary work I did a specific benchmark scene to validate that it is a good idea.
Here’s how that looks:
And here are the test results (note that the scene setup / rendering performance has been a bit problematic so these initial results are with just 64 microbe placeholder physics bodies at once. I plan on trying bigger tests next week):
Jolt single convex shape per microbe (UPDATE: may actually be the spheres case):
Physics time: 0.006744191 Physics FPS limit: 148.2758, FPS: 1
Physics time: 0.004203023 Physics FPS limit: 237.924, FPS: 30
Physics time: 0.002538978 Physics FPS limit: 393.8593, FPS: 30
Physics time: 0.001526676 Physics FPS limit: 655.018, FPS: 308
Physics time: 0.0006721547 Physics FPS limit: 1487.753, FPS: 361
Physics time: 0.0003296497 Physics FPS limit: 3033.523, FPS: 361
Physics time: 0.0001993665 Physics FPS limit: 5015.888, FPS: 360
Physics time: 0.0001796981 Physics FPS limit: 5564.891, FPS: 360
Physics time: 0.0001652893 Physics FPS limit: 6049.998, FPS: 360
Physics time: 0.0001341461 Physics FPS limit: 7454.556, FPS: 360
Physics time: 0.0001477947 Physics FPS limit: 6766.141, FPS: 360
Jolt combined shape from spheres:
Physics time: 0.0008753056 Physics FPS limit: 1142.458, FPS: 1
Physics time: 0.001244984 Physics FPS limit: 803.2229, FPS: 75
Physics time: 0.001221391 Physics FPS limit: 818.7385, FPS: 75
Physics time: 0.001119852 Physics FPS limit: 892.9752, FPS: 329
Physics time: 0.001057841 Physics FPS limit: 945.3221, FPS: 329
Physics time: 0.00107415 Physics FPS limit: 930.9684, FPS: 316
Physics time: 0.000895411 Physics FPS limit: 1116.806, FPS: 313
Physics time: 0.0009229564 Physics FPS limit: 1083.475, FPS: 313
Physics time: 0.0008093275 Physics FPS limit: 1235.594, FPS: 326
Physics time: 0.0006260973 Physics FPS limit: 1597.196, FPS: 326
Physics time: 0.0005499413 Physics FPS limit: 1818.376, FPS: 355
Physics time: 0.0005800998 Physics FPS limit: 1723.841, FPS: 355
Physics time: 0.0004281088 Physics FPS limit: 2335.855, FPS: 360
Physics time: 0.0005050105 Physics FPS limit: 1980.157, FPS: 360
Godot physics (Bullet) convex shape:
Physics time: 0.003198 Physics FPS limit: 312.6954, FPS: 1
Physics time: 0.004069 Physics FPS limit: 245.7606, FPS: 121
Physics time: 0.004069 Physics FPS limit: 245.7606, FPS: 121
Physics time: 0.003704 Physics FPS limit: 269.9784, FPS: 328
Physics time: 0.003704 Physics FPS limit: 269.9784, FPS: 328
Physics time: 0.002906 Physics FPS limit: 344.1156, FPS: 343
Physics time: 0.002906 Physics FPS limit: 344.1156, FPS: 343
Physics time: 0.001898 Physics FPS limit: 526.8704, FPS: 361
Physics time: 0.001898 Physics FPS limit: 526.8704, FPS: 361
Physics time: 0.001539 Physics FPS limit: 649.7726, FPS: 360
Physics time: 0.001539 Physics FPS limit: 649.7726, FPS: 360
Physics time: 0.001116 Physics FPS limit: 896.0574, FPS: 360
Physics time: 0.001116 Physics FPS limit: 896.0574, FPS: 360
Physics time: 0.001397 Physics FPS limit: 715.8196, FPS: 323
Physics time: 0.001397 Physics FPS limit: 715.8196, FPS: 323
Physics time: 0.000698 Physics FPS limit: 1432.665, FPS: 360
Physics time: 0.000698 Physics FPS limit: 1432.665, FPS: 360
Physics time: 0.001458 Physics FPS limit: 685.871, FPS: 360
Physics time: 0.000517 Physics FPS limit: 1934.236, FPS: 360
Physics time: 0.000517 Physics FPS limit: 1934.236, FPS: 360
Physics time: 0.000629 Physics FPS limit: 1589.825, FPS: 360
Physics time: 0.000629 Physics FPS limit: 1589.825, FPS: 360
Physics time: 0.001151 Physics FPS limit: 868.8097, FPS: 360
Physics time: 0.001151 Physics FPS limit: 868.8097, FPS: 360
Physics time: 0.000678 Physics FPS limit: 1474.926, FPS: 360
Physics time: 0.000678 Physics FPS limit: 1474.926, FPS: 360
Physics time: 0.000968 Physics FPS limit: 1033.058, FPS: 361
Physics time: 0.000968 Physics FPS limit: 1033.058, FPS: 361
Physics time: 0.001221 Physics FPS limit: 819.0009, FPS: 360
Physics time: 0.001221 Physics FPS limit: 819.0009, FPS: 360
Physics time: 0.000909 Physics FPS limit: 1100.11, FPS: 360
Physics time: 0.000909 Physics FPS limit: 1100.11, FPS: 360
Physics time: 0.000792 Physics FPS limit: 1262.626, FPS: 360
Physics time: 0.000792 Physics FPS limit: 1262.626, FPS: 360
Physics time: 0.001548 Physics FPS limit: 645.9948, FPS: 360
Physics time: 0.001548 Physics FPS limit: 645.9948, FPS: 360
Physics time: 0.000693 Physics FPS limit: 1443.001, FPS: 360
Physics time: 0.000693 Physics FPS limit: 1443.001, FPS: 360
Physics time: 0.000644 Physics FPS limit: 1552.795, FPS: 360
Physics time: 0.000644 Physics FPS limit: 1552.795, FPS: 360
Physics time: 0.000998 Physics FPS limit: 1002.004, FPS: 360
Godot physics (Bullet) combined spheres (currently the approach used in the game):
Physics time: 0.011677 Physics FPS limit: 85.63844, FPS: 1
Physics time: 0.006466 Physics FPS limit: 154.6551, FPS: 29
Physics time: 0.006466 Physics FPS limit: 154.6551, FPS: 29
Physics time: 0.00437 Physics FPS limit: 228.8329, FPS: 353
Physics time: 0.000726 Physics FPS limit: 1377.411, FPS: 360
Physics time: 0.000726 Physics FPS limit: 1377.411, FPS: 360
Physics time: 0.000945 Physics FPS limit: 1058.201, FPS: 360
Physics time: 0.000945 Physics FPS limit: 1058.201, FPS: 360
Physics time: 0.000448 Physics FPS limit: 2232.143, FPS: 360
Physics time: 0.000448 Physics FPS limit: 2232.143, FPS: 360
Physics time: 0.000415 Physics FPS limit: 2409.639, FPS: 360
Physics time: 0.000415 Physics FPS limit: 2409.639, FPS: 360
Physics time: 0.000362 Physics FPS limit: 2762.431, FPS: 360
Physics time: 0.000362 Physics FPS limit: 2762.431, FPS: 360
Physics time: 0.000373 Physics FPS limit: 2680.965, FPS: 360
Physics time: 0.000373 Physics FPS limit: 2680.965, FPS: 360
Physics time: 0.000396 Physics FPS limit: 2525.253, FPS: 361
Physics time: 0.000396 Physics FPS limit: 2525.253, FPS: 361
Physics time: 0.001432 Physics FPS limit: 698.324, FPS: 360
Physics time: 0.001432 Physics FPS limit: 698.324, FPS: 360
Physics time: 0.000391 Physics FPS limit: 2557.545, FPS: 360
Physics time: 0.000391 Physics FPS limit: 2557.545, FPS: 360
Physics time: 0.000474 Physics FPS limit: 2109.705, FPS: 360
Physics time: 0.000474 Physics FPS limit: 2109.705, FPS: 360
Physics time: 0.001289 Physics FPS limit: 775.7952, FPS: 360
Physics time: 0.001289 Physics FPS limit: 775.7952, FPS: 360
Physics time: 0.000606 Physics FPS limit: 1650.165, FPS: 360
Physics time: 0.000606 Physics FPS limit: 1650.165, FPS: 360
Physics time: 0.000629 Physics FPS limit: 1589.825, FPS: 360
Physics time: 0.000629 Physics FPS limit: 1589.825, FPS: 360
Physics time: 0.000572 Physics FPS limit: 1748.252, FPS: 360
Physics time: 0.000572 Physics FPS limit: 1748.252, FPS: 360
Physics time: 0.000557 Physics FPS limit: 1795.332, FPS: 360
Physics time: 0.000557 Physics FPS limit: 1795.332, FPS: 360
Physics time: 0.000478 Physics FPS limit: 2092.05, FPS: 360
Physics time: 0.000478 Physics FPS limit: 2092.05, FPS: 360
Physics time: 0.000465 Physics FPS limit: 2150.538, FPS: 361
Physics time: 0.000465 Physics FPS limit: 2150.538, FPS: 361
Physics time: 0.000934 Physics FPS limit: 1070.664, FPS: 360
Physics time: 0.000934 Physics FPS limit: 1070.664, FPS: 360
Physics time: 0.00044 Physics FPS limit: 2272.727, FPS: 360
Physics time: 0.00044 Physics FPS limit: 2272.727, FPS: 360
Physics time: 0.000498 Physics FPS limit: 2008.032, FPS: 360
Physics time: 0.000498 Physics FPS limit: 2008.032, FPS: 360
Physics time: 0.005362 Physics FPS limit: 186.4976, FPS: 353
Physics time: 0.005362 Physics FPS limit: 186.4976, FPS: 353
Physics time: 0.000357 Physics FPS limit: 2801.12, FPS: 360
Jolt single thread (instead of 2) convex:
Physics time: 0.00504744 Physics FPS limit: 198.1202, FPS: 1
Physics time: 0.004344175 Physics FPS limit: 230.1933, FPS: 66
Physics time: 0.002714122 Physics FPS limit: 368.4433, FPS: 66
Physics time: 0.001554479 Physics FPS limit: 643.3024, FPS: 317
Physics time: 0.0006783324 Physics FPS limit: 1474.203, FPS: 317
Physics time: 0.0003822733 Physics FPS limit: 2615.929, FPS: 360
Physics time: 0.0002402095 Physics FPS limit: 4163.032, FPS: 360
Physics time: 0.0002077179 Physics FPS limit: 4814.221, FPS: 360
Physics time: 0.0001857197 Physics FPS limit: 5384.457, FPS: 360
Physics time: 0.0001746437 Physics FPS limit: 5725.942, FPS: 360
Physics time: 0.0001679698 Physics FPS limit: 5953.45, FPS: 360
Physics time: 0.0001844394 Physics FPS limit: 5421.835, FPS: 360
Physics time: 0.000174993 Physics FPS limit: 5714.515, FPS: 360
Here’s my quick thoughts:
Turns out that our approach of using combined spheres to make microbe collisions is faster than convex shapes in Godot when nothing is colliding (0.000362 vs 0.000698). Whereas then when shapes are colliding a bunch the convex shape is much faster (0.006466 vs 0.003704).
In Jolt the combined sphere shape is much faster when there are a ton of collisions (0.0008753056 vs 0.006744191) but then it doesn’t reach the maximum performance of the convex shape (0.0004281088 vs 0.0001341461). So it seems a bigger test / testing with microbe colonies will be necessary to pick which is overall the better approach for Thrive: combined sphere collision shape or a convex shape (this disallows holes and concave parts of microbes).
And luckily for me, Jolt is faster (even when running with a single thread, and Jolt scales up to speed up at least to 8 threads). Funnily enough it seems the single thread mode of Jolt is faster when literally all of the bodies are colliding in a big clump, as this likely prevents parallel processing.
As a summary here’s the first frame (a ton of collisions) and then basically the top performance of each test to give a quick overlook of which approaches are good when there’s an absolute ton of collisions and which work well when collisions are rare:
Jolt single convex shape per microbe (UPDATE: may actually be the spheres case):
Physics time: 0.006744191 Physics FPS limit: 148.2758, FPS: 1
Physics time: 0.0001341461 Physics FPS limit: 7454.556, FPS: 360
Jolt combined shape from spheres:
Physics time: 0.0008753056 Physics FPS limit: 1142.458, FPS: 1
Physics time: 0.0004281088 Physics FPS limit: 2335.855, FPS: 360
Godot physics (Bullet) convex shape:
Physics time: 0.003198 Physics FPS limit: 312.6954, FPS: 1
Physics time: 0.000678 Physics FPS limit: 1474.926, FPS: 360
Godot physics (Bullet) combined spheres (currently the approach used in the game):
Physics time: 0.011677 Physics FPS limit: 85.63844, FPS: 1
Physics time: 0.000362 Physics FPS limit: 2762.431, FPS: 360
Jolt single thread (instead of 2) convex:
Physics time: 0.00504744 Physics FPS limit: 198.1202, FPS: 1
Physics time: 0.0001679698 Physics FPS limit: 5953.45, FPS: 360
Some non-microbe findings: Godot is pretty slow at rendering a ton of multimesh parts that all need to update constantly. Individual Godot nodes have pretty good frustrum culling and gives pretty nice FPS bonus. Need to investigate which is the optimal way to setup microbe graphics to move around based on Jolt computed data.
Edit: I just realized I probably mixed up the sphere and convex body creation for Jolt, so mentally flip the numbers.