Terrain tiles not culled during offscreen pick pass
- Dominant language
- JavaScript
- Stars
- 15.7k
- Forks
- 3.9k
- Avg merge
- 4d 6h
- Merged PRs (30d)
- 34
Description
Not much of a bug, but possibly a potenial improvement. `Picking.js`' [getRayIntersection](https://github.com/CesiumGS/cesium/blob/44ac2ff1293fc89cccfb58fc70f372123215261b/Source/Scene/Picking.js#L729) renders the scene from an offscreen camera, typically for clamping or height sampling.
In this process, the 3D tilesets are updated once and non-visible tiles are culled. However, terrain-tile commands are copied as is, although many aren't visible from the offscreen camera. Especially in case of clamping or height sampling, where typically only 1 tile is expected to intersect the orthographic top-down frustum.
The straightforward benefit of culling these tiles, though not major, is saving some rendering work.
Another benefit is that this will allow tighter frustum near/far bounds when executing the commands, and thus better precision. For standard users the precision should be good enough regardless, but while testing a cheap Android device, I had precision issues in the [Clamp to 3D Tiles](https://sandcastle.cesium.com/gallery/Clamp%20to%203D%20Tiles.html) and [Sample Height from 3D Tiles](https://sandcastle.cesium.com/gallery/Sample%20Height%20from%203D%20Tiles.html) sandcastles. What triggered the precision problems is that low-level terrain tiles were spanning over large depth ranges and forcing a maximally-spaced multifrustum. The fact that the offscreen camera is far away from the scene (9000.0m high, the `defaultMaxTerrainHeight`) also didn't help.
If someone would like to look into it, [GlobeSurfaceTileProvider.updateForPick](https://github.com/CesiumGS/cesium/blob/44ac2ff1293fc89cccfb58fc70f372123215261b/Source/Scene/GlobeSurfaceTileProvider.js#L512) is where the commands are copied. Perhaps a solution would be to check there the tile visibility if `passes.pick && passes.offscreen`.
If visibility is checked using the bounding volume (like [GlobeSurfaceTileProvider.computeTileVisibility](https://github.com/CesiumGS/cesium/blob/686a9f5e1f20dbf539679e8635536546e07f8f50/Source/Scene/GlobeSurfaceTileProvider.js#L578) does) it will help, but it's still likely that some low-level tiles will be rendered because of big bounding volumes. In the clamping/sampling case we can do better by checking if the camera's cartographic is contained in the tile's rectangle and that should eliminate all rogue tiles and allow tight frustum bounds. But this might be too cumbersome.
Contributor guide
Research direction
Start with GlobeSurfaceTileProvider.updateForPick, then read Picking.js getRayIntersection and GlobeSurfaceTileProvider.computeTileVisibility to understand the offscreen pick path. Compare terrain commands copied for normal and offscreen passes, and validate the change with the Clamp to 3D Tiles and Sample Height from 3D Tiles sandcastles. Done means unnecessary terrain commands are excluded during offscreen picking and the reported precision problem is improved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100