Choppy camera movements with requestPointerLock

I noticed this problem since I migrated to 6.7.0. However, it looks like it’s also reproduceable in earlier versions. I am not sure when this problem appeared, maybe even on late 5.x.x versions. But I can say for sure I didn’t face it before 5.47.0 or earlier. I can’t migrate back to pre-6 version, because I already migrated physics to V2.

When I use requestPointerLock camera tends to do inconsistent dashes usually snapping your look strictly up or down. The issue is flaky, there could be several dashes in a very short time or it could be the whole minute of smooth movements. It happens much more often in my local environment than in PG, but I still can reproduce it in PG below.

Steps to reproduce:

  1. Open this PG.
  2. Click on canvas, so it will grab the cursor.
  3. Start to move around using WASD.
  4. While moving by WASD try the following mouse movements patterns. a) Slowly move the mouse in one direction (left or right) nodding up and down at the same time. So, it should look like a horizontal zig-zag, like this /\/\/\/\/\/\/\/\/\/\/\/\/\/\. Vertical amplitude should be high (move at least 70 degrees up and down). b) Draw circles with your mouse. Again, horizontal and vertical rotation angle should be high (at least 70 degrees in every direction) to increase the probability of bug to reveal itself.

Related observations:

  1. The bug only happens when we use requestPointerLock(). I don’t think we can avoid using it. It feels like an essential thing for First Person Shooters.
  2. When the bug happens, I don’t see any frame rate drops from browser rendering dev tools. So, it’s definitely not my local performance issues.
  3. I assume that it may happen when locked cursor virtually passes the canvas or screen borders. To me the problem looks like some miscalculation happens at camera rotation angle at some point. But I may be wrong.
  4. Happens on both FreeCamera and UniversalCamera.
  5. If you will be unable to preproduce in the Playground above I can record a screencapture.

I am sorry, but I think I found the solution myself. It’s not related to BabylonJS at all. This fixes issue:

this.canvas.requestPointerLock({unadjustedMovement: true});
2 Likes