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:

@sebavan @RaananW

Any updates on this? I just found out that inertia is FPS dependant which is kinda bad, because I like inertia.

You can easily test with the chrome extension: FPS Control and limit it at 10fps, inertia goes crazy, even the camera movement speed breaks through the gravity. As someone working on 140hz/fps, I was quite surprised that none of my camera settings were the same on 60hz/fps.

Adding @PolygonalSun who is taking care of camera and input a lot at the moment as I can not remember if @sable made the PR go through for this one ?

I noticed a “hitch” in the camera inertia speed when going from very slow mouse movement speed to very fast mouse speed. If you set inertia to 1 it is very noticeable:


Edit: This is Windows/Firefox, I have enhanced pointer precision disabled and the MarkC mouse acceleration fix

Maybe this hitch happens more often when FPS is low, resulting in a mix of control feels. I was trying to figure out why Classic Minecraft, Morterra, and other first person cameras feel bad on Firefox. Removing inertia and running on Chrome feels very good though :smiley:

Yup I ll add the fix for FF today or tomorrow.

@sebavan I never made a PR for this. I could probably have a look sometime next month, though it may make sense for @PolygonalSun to do this seeing as they’ve been taking care of a lot of input related stuff as of late.

Perfect and yup, @PolygonalSun ???

So just to make sure that I’m caught up to speed, inertia looks like it’s tied to FPS and we’re looking to fix that so that the camera has a smoother and more uniform movement for all configs?

Yes. Inertia should be FPS independent.

At the moment inertia 0.9 behaves very differently on 30fps vs 144fps.
You can easily test with the chrome extension: FPS Control

For me inertia is the ease-out effect on both the camera sensitivity (mouse) and position (keyboard), similar to the way scrolling slowly fades out on phones.