CesiumGS / CesiumGS/cesium

Terrain tiles not culled during offscreen pick pass

Open
#9,032 1 comment 0 reactions 0 assignees View on GitHub
category - graphics type - enhancement
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.