Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Jolt physics example #28023

Merged
merged 4 commits into from
Apr 18, 2024
Merged

Added Jolt physics example #28023

merged 4 commits into from
Apr 18, 2024

Conversation

mrdoob
Copy link
Owner

@mrdoob mrdoob commented Mar 28, 2024

Description

Just found out about Jolt which seems to be faster and more reliable than Rapier.

Made a JoltPhysics.js wrapper for it:

https://raw.githack.com/mrdoob/three.js/physics/examples/physics_jolt_instancing.html

Screenshot 2024-03-29 at 00 15 46

Looks pretty good! Although the boxes seem to be overlapping 🤔

/fyi @jrouwe

@mrdoob mrdoob added this to the r163 milestone Mar 28, 2024
@jrouwe
Copy link

jrouwe commented Mar 28, 2024

To me it looks like there is a mismatch between the visual box size and the physics box size (although I don't spot the code bug), a simple shape like this should not penetrate.

@mrdoob mrdoob changed the title Added Jost physics example Added Jolt physics example Mar 29, 2024
@mrdoob
Copy link
Owner Author

mrdoob commented Mar 29, 2024

Hmm... I'm going to have to investigate this further...

@mrdoob mrdoob modified the milestones: r163, r164 Mar 29, 2024
@DennisSmolek
Copy link

What kind of FPS were you getting?
I can't tell if it's just my computer but it was around 30fps.
I did a similar build for a react-three-jolt library and was staying around 60 until 800 or so but I was only using boxes and no shadows...

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 8, 2024

I've compared the demos physics_ammo_instancing, physics_rapier_instancing and the new physics_jolt_instancing on two devices. A mac mini with a M2 Pro runs all demos with 60 FPS. A Pixel 4a however does not:

  • physics_ammo_instancing: 7 FPS
  • physics_rapier_instancing: 30 FPS
  • physics_jolt_instancing: 20 FPS

So it seems rapier is the fastest.

I did a similar build for a react-three-jolt library and was staying around 60 until 800 or so but I was only using boxes and no shadows...

We can only make a comparison if the example uses the exact same setup like the three examples mentioned above. Otherwise a performance comparison isn't valid. If you can share a live example with for testing, we might have a chance to find out why you see a performance difference between physics_jolt_instancing and a react-three-jolt demo.

@ycw
Copy link
Contributor

ycw commented Apr 12, 2024

boxes seem to be overlapping 🤔

box collision shape's convex radius (0.05) is too large for the visual cubes(side=0.075) 🤔

return new Jolt.BoxShape( new Jolt.Vec3( sx, sy, sz ), 0.05, null );

fyi, its less pronounced with smaller convex radius, e.g. 5% of min halfextent:

1

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 18, 2024

@ycw I've added your approach to the branch. It looks indeed much better!

@Mugen87 Mugen87 merged commit 01ee1a7 into dev Apr 18, 2024
11 checks passed
@Mugen87 Mugen87 deleted the physics branch April 18, 2024 14:51
@ycw
Copy link
Contributor

ycw commented Apr 18, 2024

nice

@@ -18,7 +18,7 @@ function getShape( geometry ) {
const sy = parameters.height !== undefined ? parameters.height / 2 : 0.5;
const sz = parameters.depth !== undefined ? parameters.depth / 2 : 0.5;

return new Jolt.BoxShape( new Jolt.Vec3( sx, sy, sz ), 0.05, null );
return new Jolt.BoxShape( new Jolt.Vec3( sx, sy, sz ), 0.05 * Math.min( sx, sy, sz ), null );
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrouwe What do you think about this solution?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the example uses boxes of 0.075, a convex radius of 0.05 is indeed too big (the debug version of Jolt will assert because it is bigger than half the size of the box). So this solution is better as it reduces the convex radius to 0.00375.

The default allowed penetration in Jolt is 0.02 (PhysicsSettings.mPenetrationSlop) which means the boxes can still sink into each other by this amount. Also, this will not help performance as the allowed penetration is bigger than the convex radius which causes a more expensive code path to trigger more often. You can update the physics settings through PhysicsSystem.SetPhysicsSettings.

@jrouwe
Copy link

jrouwe commented Apr 25, 2024

@Mugen87

  • physics_ammo_instancing: 7 FPS
  • physics_rapier_instancing: 30 FPS
  • physics_jolt_instancing: 20 FPS

So it seems rapier is the fastest.

There's at least one big difference between the Rapier and Jolt tests. Rapier is configured to use the delta time from the browser as timestep:

world.timestep = clock.getDelta();
world.step();

while Jolt is configured to try to not make steps bigger than 1/60th of a second:

let deltaTime = clock.getDelta();
// Don't go below 30 Hz to prevent spiral of death
deltaTime = Math.min( deltaTime, 1.0 / 30.0 );
// When running below 55 Hz, do 2 steps instead of 1
const numSteps = deltaTime > 1.0 / 55.0 ? 2 : 1;
// Step the physics world
jolt.Step( deltaTime, numSteps );

So when the frame rate is below 55 fps (as is the case in your test), Jolt is configured to do 2 simulation steps while Rapier is configured to do 1 (if I understand the Rapier code correctly).

@mrdoob
Copy link
Owner Author

mrdoob commented May 27, 2024

We should probably change it so both of them use the same approach.

@jrouwe What approach would you think would be better for someone starting? (better = causes less headaches)

@DennisSmolek
Copy link

For more basic/straightforward approach I'd just use the deltaTime. Drop the numSteps and just do one frame.

@jrouwe
Copy link

jrouwe commented May 27, 2024

The danger of using deltaTime directly is that if the browser has a hiccup and deltaTime is suddenly a second, then the simulation will explode (this will happen on any physics engine that I know of). Removing numSteps is fine, but I would at least make sure that deltaTime is never bigger than 1/60th (although for simple scenes you may get away with 1/30th too).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants