Default camera moves awkwardly when dragged with mouse

I don’t know if this applies to other input methods as well, but I find that the out-of-the-box FreeCamera / UniversalCamera camera behave really poorly when dragged with the mouse.

As I drag the camera around, the sensitivity will occasionally plummet along either the x axis or the y axis, causing the camera to “stick” to the x or y axis. Sometimes it happens to both axis simultaneously and movement in any direction becomes very sluggish. If I set the camera inertia to 0, the problem goes away and it moves much smoother.

https://www.babylonjs-playground.com/

I notice this in the default playground scene and almost every time I go to move the camera in any playground using FreeCamera or UniversalCamera.

I’ve attempted to record the issue here. Note that I am holding down the left mouse button the whole time.

And for comparison, here is what it looks like with inertia off and the sensitivity turned up (angularSensibility = 500).

It is sooooooooooo much smoother.

I can’t quite reproduce that! I just tried playing around with the free camera, but it seems to behave as expected - including the way inertia should influence the camera.

If you don’t need the inertia simply set it to 0. It can feel a bit weird that the camera “continues” after you are done with your movement, and this is why it is a public variable :slight_smile:

2 Likes

It seems like it might actually be frame rate dependent? When I switch my monitor to 60Hz from 144Hz, it’s less noticeable but I still see it sometimes, especially when making tiny mouse circles. The inertia is also much more noticeable at 60Hz.

It doesn’t affect my project since I’m using custom camera code anyway, it’s just a slight annoyance when looking at playgrounds.

that’s interesting to know that it behaves so differently on higher FPS. I have to admit that I use 60 FPS screens only (not religiously, it is simply what I have :slight_smile: ) so I can’t test that at all. Maybe someone else with the same experience can chip in?

I don’t see any difference between the 2 videos :smiley:
I must be too slow :smiley:

The camera inertia is definitely frame rate dependent, as all it does (in the case of the free camera) is multiple the camera direction vector by the inertia each frame (so total distance moved for an initial vector of length n will be n / (1 - inertia)). There is also speed for the free camera, which is used to set that initial camera direction vector.

The number of frames it takes until the movement is finished will be 1 if inertia is 0 (move n / 1 distance), infinite if inertia is >= 1 (move infinite distance), or log(epsilon / n) / log(inertia) frames (move n / (1 - inertia) distance) where epsilon is the cutoff for distance remaining after which the direction vector is set to 0. Epsilon defaults to 0.001, and for the free camera is multiplied by speed when checking for the set to 0.

Plugging numbers into this, if you have a free camera at (0, 10, 0) looking at the origin with inertia 0.9 (the default), and set the direction vector to (0, 1, 0), it will move 1 / 0.1 distance, so 10 (to (0, 20, 0)), and take log(0.001 * 2 / 1) / log(0.9) frames, so 58.98 -> 59 frames (2 here is the default speed). I’ve set up a playground here that shows this scenario.

This means the time taken depends on refresh rate, and in turn so does the feel of the camera controls.

Hey @sable, would you be willing to make a PR for it, I am unfortunately not really able to test on higher FPS ?

@sebavan I could attempt it, though I also don’t have access to a high fps display.

I’ve just looked it up, and it turns out you can disable the fps limit in chrome/chromium with:
chromium --args --disable-gpu-vsync --disable-frame-rate-limit
or with a new instance of chromium:
chromium --user-data-dir=emptyDir --args --disable-gpu-vsync --disable-frame-rate-limit
which lets you observe behaviour at high frame rates.

I assume you’re thinking of normalising inertia to give the same effect it currently does at 60fps for all frame rates, and do this for all cameras? I don’t think this would be a breaking change (as distance moved would remain the same), though camera handling at lower frame rates (I’m thinking mobile devices here mainly) would certainly feel different, so there should perhaps be some discussion regarding that.

Yup I am thinking to exactly that and I would consider it a bug fix more than a breaking change :slight_smile: