Jitter - anything else I can do?

Post Reply
Simdin
Posts: 4
Joined: Thu Dec 16, 2021 11:33 am

Jitter - anything else I can do?

Post by Simdin »

Hi,

Problem:
Simple rigidbody flying (not collisions) pushed by applyForce. When object is moving it jitters from time to time when delta increases a bit.

Setup:
  • No extreme values: mass=1, dimension around 5
  • I call stepSimulation(delta,5, 1/60f) where delta is the time passed since the previous call (variable step time).
  • Below you can see logs with exact delta value and the subSteps (value returned from stepSimulation method)
  • I do use motionState to get interpolated transformation.
Question:
I can see that jitter occurs when delta increases and subSteps>1. I think it makes sense since it means that the object needs to jump a bit to keep up and get the next position calculated by bullet3d. My question is: shouldn't it be somehow compensated (smoothed) by the motionstate? Is there anything else I can do to avoid jitter in such situation?

Remarks:
  • The problem disappears on faster machine (in fact: mobile device) where delta is more stable
  • Despite delta fluctuations the average FPS is very stable (59-60fps)
  • When I do fixed-step stepSimulation(1/60f,5, 1/60f) just for test purposes obviously jitter disappears completely but the simulation slows down which I cannot accept.

Code: Select all

delta=0.016896928 sub-steps=1
delta=0.016967967 sub-steps=1
delta=0.01683651 sub-steps=1
delta=0.016881146 sub-steps=1
delta=0.017019168 sub-steps=1
delta=0.016781718 sub-steps=1
delta=0.017037189 sub-steps=1
delta=0.016864844 sub-steps=1
delta=0.016754063 sub-steps=1
delta=0.016927708 sub-steps=1
delta=0.037210155 sub-steps=2
delta=0.04002479 sub-steps=3
delta=0.021034636 sub-steps=1
delta=0.02222526 sub-steps=1
delta=0.014107449 sub-steps=1
delta=0.013185989 sub-steps=1
delta=0.008868437 sub-steps=0
delta=0.012251927 sub-steps=1
delta=0.016749792 sub-steps=1
delta=0.016905364 sub-steps=1
delta=0.01693323 sub-steps=1
delta=0.016905364 sub-steps=1
delta=0.016919114 sub-steps=1
delta=0.017383803 sub-steps=1
delta=0.017960938 sub-steps=1
delta=0.015491666 sub-steps=1
delta=0.016797813 sub-steps=1
delta=0.016913436 sub-steps=1
delta=0.01694099 sub-steps=1
delta=0.016899792 sub-steps=1
delta=0.01689474 sub-steps=1
delta=0.016905937 sub-steps=1
delta=0.016856091 sub-steps=1
delta=0.016874168 sub-steps=1
delta=0.016867656 sub-steps=1
delta=0.016853593 sub-steps=1
delta=0.017038854 sub-steps=1
delta=0.016922813 sub-steps=2
delta=0.016974635 sub-steps=1
delta=0.01679448 sub-steps=1
delta=0.01693552 sub-steps=1
delta=0.027392708 sub-steps=1
delta=0.016447134 sub-steps=1
delta=0.015894271 sub-steps=1
delta=0.012373229 sub-steps=1
delta=0.012696093 sub-steps=1
delta=0.01659125 sub-steps=1
delta=0.016859064 sub-steps=1
delta=0.016904948 sub-steps=1
delta=0.016802397 sub-steps=1
delta=0.016911302 sub-steps=1
delta=0.01698901 sub-steps=1
delta=0.016961146 sub-steps=1
delta=0.016827865 sub-steps=1
delta=0.01691427 sub-steps=1
delta=0.01726526 sub-steps=1
delta=0.016537448 sub-steps=1
delta=0.017371511 sub-steps=1
delta=0.029007915 sub-steps=2
delta=0.01858375 sub-steps=1
delta=0.009318802 sub-steps=0
delta=0.010406458 sub-steps=1
delta=0.016822552 sub-steps=1
delta=0.016907448 sub-steps=1
delta=0.01692474 sub-steps=1
delta=0.017141147 sub-steps=1
delta=0.016716197 sub-steps=1
delta=0.016926195 sub-steps=1
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Jitter - anything else I can do?

Post by drleviathan »

There is remainder time between a step and the integer number of substeps and Bullet will supply an extrapolated transform to MotionState::setWorldTransform() which incorporates that remainder. I believe this happens every substep rather than every step. So yes, in theory this is supposed to make for smoother visible motion when the render frame rate is not a multiple of the substep rate.

So my first question would be: When do you call applyForce()? Every step or every substep?

The effects of applyForce() only last for the substep so for smooth motion you should be calling it every substep. If you're doing it inside the updateAction() of an action instance (e.g. derived from btActionInterface) then it will be called every substep. Beware: if you do that be sure to only call applyForce() when the body is active, else activate the body before calling it, otherwise you will be surprised by a huge burst of speed when it does activate, because applyForce() accumulates on inactive objects.
Simdin
Posts: 4
Joined: Thu Dec 16, 2021 11:33 am

Re: Jitter - anything else I can do?

Post by Simdin »

Hm... I don't even know how is it possible to call anything within substep. Isn't it so that substeps calculations are located within stepSimulation method? It's very interesting I need get a bit deeper into Bullet specs.

I'm using LibGdx library on Android so it's likely some stuff is wrapped...
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Jitter - anything else I can do?

Post by drleviathan »

It is a tenant of the Bullet API: if you give the World an Action then the action's updateAction(world, delta_time) method will be called once per substep. All of that happens inside the stepSimulation() which is usually called explicitly by your App's code. If LibGdx exposes the Action interface then it should be possible to write custom logic that is invoked inside the substep.
Simdin
Posts: 4
Joined: Thu Dec 16, 2021 11:33 am

Re: Jitter - anything else I can do?

Post by Simdin »

Thank you! I'll definitely give it a try.
Simdin
Posts: 4
Joined: Thu Dec 16, 2021 11:33 am

Re: Jitter - anything else I can do?

Post by Simdin »

I have implemented InternalTickCallback and it works as expected, indeed. In case of subStep>1 internaltick is called multiple times per one frame. I call applyForce from inside.

Unfortunately it did not make any difference. I can observe a direct correlation between subSteps count and the jitter (the more frequent cases with subSteps>1, the more jitter). Setting linear velocity directly instead of applying force also does not make any difference.

There is one thing I still don't understand though. Assuming all setup is fine, how is it even theoretically possible to achieve smooth visual movement of an object, knowing the step time fluctuates and we want velocity to remain constant? If time step drops a bit, the object must jump to keep up, so the jitter is completely inevitable, isn't it so? What am I missing?
Post Reply