CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.98k stars 3.5k forks source link

Scrolling to zoom in/out is way too fast on high refresh rate screens #12187

Open tigerchase96 opened 2 months ago

tigerchase96 commented 2 months ago

What happened?

If I use my scroll wheel to zoom in/out in Cesium, it scrolls extremely fast. It's much too sensitive to be usable. This behavior goes away if I intentionally lower my monitor's refresh rate to 60 Hz. Then scrolling behavior returns to normal.

My monitor's native refresh rate is 240 Hz. I've also tested setting my monitor to 120 Hz, and the problem still persists, but to a lesser extent.

I imagine there must be some logic in the source code that is dependent on the refresh rate of the webpage? I've only just started following the quickstart guide so I probably can't contribute to fixing the bug.

But I did discover a workaround in the meantime: If I decrease the ScreenSpaceCameraController's zoom factor, zoom behavior is seemingly identical to the 60 Hz example. Unfortunately, this fix means I have to know the refresh rate of the user's screen.

const refreshRate = 240;
viewer.scene.screenSpaceCameraController.zoomFactor *= 60 / refreshRate;

Running at 60 Hz: (expected behavior)

https://github.com/user-attachments/assets/13badc67-557e-4c83-96be-077031d57398

Running at 240 Hz

In this example I am only moving my scroll wheel a few clicks in each direction, and yet I reach ground level and infinite distance way too quickly.

https://github.com/user-attachments/assets/1bbb4f5a-3794-49b0-9122-b6e7188e07cd

Reproduction steps

  1. Use a monitor that supports refresh rates above/below 60 Hz
  2. Set the monitor to 60 Hz
  3. Run any instance of Cesium, e.g. https://cesium.com/platform/cesiumjs/
  4. Scroll in and out and observe how many clicks it takes to reach ground level
  5. Set the monitor to another value like 120 Hz or 24 Hz
  6. Go back to Cesium and scroll in and out again
  7. Observe that the scroll sensitivity is significantly different than before

Sandcastle example

No response

Environment

Browser: I've tested Chrome 128 and Firefox 130 and it occurs on both CesiumJS Version: the latest version on the website, and v1.121.1 locally Operating System: Windows 11

s3xysteak commented 2 months ago

I also found this problem and have done some research on it. I think fps is the cause of the problem. It can also be reproduced by changing the targetFrameRate: Sandcastle

You can clearly see the difference between 20fps and 60fps.

targetFrameRate: ... If undefined, the browser's requestAnimationFrame implementation determines the frame rate. ...

requestAnimationFrame: ... The frequency of calls to the callback function will generally match the display refresh rate. ...

ggetz commented 2 months ago

@tigerchase96 As a workaround, similar to what @s3xysteak brought up, you can set targetFrameRate to 60 to throttle the frame rate on devices with a higher refresh rate.

That being said, I agree that the zoom rate should take the current FPS into account – whether targetFrameRate is set or not.

To calculate this value, we could use the same logic as that in PerformanceDisplay.js. Having a generalized function that watches the current FPS could be useful for other features, such as reducing quality settings when performance is subar.