Billboards on terrain - some problems
- Dominant language
- JavaScript
- Stars
- 15.7k
- Forks
- 3.9k
- Avg merge
- 4d 6h
- Merged PRs (30d)
- 34
Description
Current implementation of billboard on terrain is well written and I have learned a lot from reading it.
However I found some problems while working on #4622:
1. I think the billboard height should be computed also if the level of the scene getting lower (`zoom-out`). Currently the height is computed only in one direction. (` if (tile.level > data.level)` in this [link](https://github.com/AnalyticalGraphicsInc/cesium/blob/1.27/Source/Scene/QuadtreePrimitive.js#L628)).
However, sometimes lower levels have higher terrain at a given point so the billboard disappears.
2. In the following code the `isChildAvailable` is invoked on the grandparent of the child, instead of on `tile`
```
var parentTile = tile.parent;
if ((defined(tileDataAvailable) && !tileDataAvailable) ||
(defined(parentTile) && defined(parentTile.data) && defined(parentTile.data.terrainData) &&
!parentTile.data.terrainData.isChildAvailable(parentTile.x, parentTile.y, child.x, child.y))) {
data.removeFunc();
}
```
([link](https://github.com/AnalyticalGraphicsInc/cesium/blob/1.27/Source/Scene/QuadtreePrimitive.js#L666)).
3. If the tile is upsampled the `data.terrainData.isChildAvailable` in the lines above would always return `false` (see this [line](https://github.com/AnalyticalGraphicsInc/cesium/blob/1.27/Source/Core/QuantizedMeshTerrainData.js#L458)). So, in such case the billboard wouldn't be updated after some zooming.
I found that this is the reason to this behavior (the billboard should be clamped to the ground):

4. I'm not sure at this point but I think the billboard height must be recomputed if the original data of the tile was a result of an upsampling process, and the tile was later loaded.
5. Please consider depth offset in the `BillboardCollectionVS.glsl`. In previous versions there were the following lines:
```
#ifdef CLAMPED_TO_GROUND
// move slightly closer to camera to avoid depth issues.
positionEC.z *= 0.995;
```
It would be great if, in addition to `eyeOffset` paramter in `billboard` and `label`, there will be a `depthOffset` which will be expressed as a fraction of the camera distance to the vertex (0-1).
6. Currently if the terrain provider is replaced by another one, clamped billboards would disappear.
~~Maybe that because the `QuadtreePrimitive.prototype.invalidateAllTiles` treat only `levelZeroTiles`'s `customData` but I didn't enter into it~~
Contributor guide
Research direction
Start with the referenced terrain and billboard paths in Source/Scene/QuadtreePrimitive.js, Source/Core/QuantizedMeshTerrainData.js, and BillboardCollectionVS.glsl. Reproduce the listed behavior across zooming, upsampled tiles, terrain-provider replacement, and clamped billboard depth handling. Done means the six reported cases have defined behavior and the affected billboards remain correctly clamped and rendered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100