Zoom in/out becomes slow or stuck when rendering 3D Tiles with ScreenSpaceEventHandler (mouse move) and globe hidden
What happened?
In iTwin Experience, when loading a scene with 3D Tiles and setting "viewer.scene.globe.show = false" (hiding the globe), attaching a ScreenSpaceEventHandler for MOUSE_MOVE causes zooming (right-click + drag) to become very slow and unresponsive. The zoom amount is significantly smaller than expected, which makes navigation difficult.
This behavior only occurs when the globe is hidden (viewer.scene.globe.show = false) and MOUSE_MOVE handler is active.
If the globe is visible (viewer.scene.globe.show = true) and the MOUSE_MOVE event handler is removed, zooming works smoothly as expected.
Note: The issue specifically occurs with right-click + drag zooming. Zooming with the mouse wheel continues to work as expected.
Reproduction steps
- Load a scene with 3D Tiles.
- Set "viewer.scene.globe.show = false" to hide the globe
- Attach a ScreenSpaceEventHandler for MOUSE_MOVE.
- Use right-click + drag to zoom in/out.
https://github.com/user-attachments/assets/614e6d06-c76e-40d9-bb17-a048576df88b
Sandcastle example
https://sandcastle.cesium.com/#c=fVRtb9s2EP4rRLAONmBRfBMlpnG21EnQDkuzIGmGFQZSWqITthLpkrQzt8h/H/XiLunSfZHI43PPHe8eXmmND2Cj1b1yYAqMugcz5fW6gdedbTTfK7v9zJogtVFuvjcBX+cGgKCci5b9ncNVv4dLZ5s/raurwTAaT+bmYfxybuYmuG3vXHZxg66VVyEGlvdShx1T/6PHV/1xx/jO1TGXuxBWfj9NfXAyWJ8sVJCJWkO7UqbUQSu/qqWJWcKFMqFWW1jaJpWoQAJLFeEVTpgolkmxwGWi8GJRciVzQklaoiUTDPGES8ESRjlKBC9wslzQPO6WlRAoJRkqSHGDUYaz/AbnGad5QXFOSZ565TY6FiulVXevtFJLua5DOtwSfvTW/PLZ3/gwJYhkCRIJxleIv6BHJI8fhmGWccYKnpH3P0fgRrmIxBjTduf1rZlez05vP8Iv4e1f9dbLt9vjahY0L49enf72eVZfXJzi16+2x9n1BUZJ6+SUny7bxcrZMG3L94LMuiq2RmWqPhVMnksl3hsJ8v5bxwFo5N+6WTeXpVPKXK5kqU6cs24fsPa8azIY1AR9qYyCK6eb2JiN8lBW1WioRQt8AKUM5R0YqZZi/K8ubK1gbW9HHzpuUFtZaXO7E8s++Olr5/HwoWNpZTVELGWjnITLentlRx1dpXzQRgZto04fiXsmXYgraegoYZzlnHPIRc6Q4JxOAMmyXAgGCc1zVmDG8glIaMZ4QRBEucgzEdtEW2EDYJ2OWhtiDHWqtFPl/0VFMCcZjnE4FogykuMYAUEqRFzmMXgmsqKIRgQjBLEo4IzwNlPWRwVgvfrhlaITppFXFJRTRgkWLREhRcYERbGxnGFUtLaC8IIRTHFGqWAiH3d97CJUazdcCn17v09ae1vbhYL+zt7HB7yUtVc9RjpwJ01Vfz9RHqtmE0v2ugeNnpCWMhL4NtrAAWPP35jVOhx1BR0t16ZbAGvO7EaNmvhpItt4V/t+tKys1x1sCnYIGOX+x2B+2WPbXCMygp6KVpefRjuGXtQPkx9d42q7UvDs/N3lyc3Z+fXJPDrsTfYOfNjW6rAPA8CvullZF8A6jjEI06CaOKhiv9LFuvwUZ0Pp/XjI6SB97HpQ6Q3Q1fSZOQzKWnofT5brur7UX9R87/Agjfj/uA5P6DwOlFpuW9gdPvy9N0IID9K4fd4zWFsvpPuO+R8
Environment
Browser: Microsoft Edge Version 140.0.3485.54 (Official build) (64-bit) CesiumJS Version: 1.133 Operating System: Windows 11
The following captures a mouse drag from the top to the bottom of the window, once with a maximum screen space error of 2, and once with a maximum screen space error of 16:
The zoom speed depends on the level of detail that is displayed. Note that I did not say that it depends on the maximum screen space error! You can see a sudden change in the zooming speed (for any MSSE) when the LOD switches. Why did I capture this in this strange "widescreen mode"? Well ... in a ~4:3 window, this doesn't happen. I know, everything is connected to everything in the ScreenSpaceCameraController and elsewhere. But the depth of mutual influences between totally unrelated things never ceases to surprise me.
@javagl any idea why we don't see this behaviour if we turn off the seemingly unrelated scene.pick()-ing in the onMove handler?
OK. That's a detail that wasn't immediately apparent. The short answer is "No, I have no (not the slightest) idea what might be the issue here".
(For the LOD, I could have guessed, handwavingly. For example, that some aspect of the zooming tries to be "smart", and implements a behavior like that ~"the zooming speed depends on the size of the object that the mouse was pressed on", which could at least explain (albeit not really justify) the different behavior for different LODs. But the fact that an unrelated pick call has an influence of that, is a clear (but subtle) bug)
EDIT: Another (wild) guess for the latter: This could be explained if there was some sort of
const zoomAmount = currentMouse.y - lastPickPosition.y;
where that lastPickPosition was erroneously a "shared" state between the ScreenSpaceCameraController-mouse-pressed handling, and the pick call. It sounds far fetched, but could explain the difference...
@javagl I also have the feeling that the picking erroneously updates the zoom snapping point (shared cache for last readpixels..?). Is this bug something we have time to look at? This could have other strange side effects throughout Cesium.js.
For now we are trying to workaround by modifying the minimumPickingTerrainHeight to basically disable proper terrain picking. This will give the side effect that we sometimes zoom through the terrain which is not ideal but better than having the unreliable zoom speed. We cannot disable the scene picking as that is used by other parts of the application.
@alarkbentley I wonder if you can debounce the event listener? p.s. I am also able to reproduce this with the mouse wheel, zooming in slows down while new data is loaded and then gets fast and then slow again
@zoran995 we are investigating if we can limit the amount of calls to scene picking (for other performance reasons). However that would just be a sketchy workaround for the actual problem reproduced here.
@psingh311 can you confirm if this is still an issue? I can reproduce the issue in Cesium v1.133, but not in 1.135.
There have been a few changes that improved picking and event performance, such as https://github.com/CesiumGS/cesium/pull/12896.
@jjhembd Thank you for the update. I re-tested the Zoom In/Out issue using the Sandcastle demo link provided at the top of the GitHub issue.
Based on my investigation, the issue is still reproducible. Zooming performance remains noticeably slow when picking is enabled and maximumScreenSpaceError = 4. Reducing the maximumScreenSpaceError value to 1.25 results in a slight improvement, but the slow zooming and dragging behavior persists when moving close to the ground.
In contrast, when picking is completely disabled, zooming works smoothly at any maximumScreenSpaceError value.
The videos below show the different scenarios, Picking enabled with maximumScreenSpaceError = 1.25: https://github.com/user-attachments/assets/df98017a-67d4-41ea-8866-a36d6e364249 Picking enabled with maximumScreenSpaceError = 4: https://github.com/user-attachments/assets/632b4ef8-9e7e-4a57-a71a-a6ed5e281b41 Picking Disabled: https://github.com/user-attachments/assets/cedb1043-5b58-403a-92d9-75696fbd8ac7
@jjhembd To reproduce:
-
Open the sandcastle that was linked in the first post.
-
Do RIGHT-mouse drags, up and down. The movement is very slow. When zooming in far enough (i.e. moving down) for the next LOD to pop in, the zooming speed suddendly becomes much faster
-
Comment out the line in the event handler:
//var pos = viewer.scene.pick(position); -
Do RIGHT-mouse drags, up and down. The movement is fast (I think as fast as it should be). The movement speed does no longer change when the next LOD pops in.
Aside: This is not really about "performance" - it's always "fast" in terms of ~"frames per second" and whatnot. It's just a squeaky wheel in the Rube-Goldberg-Machine of the ScreenSpaceCameraController, and that wheel is somehow connected to ~"picking"...