fix(geo-layers): TerrainLayer GlobeView support#10250
Merged
Merged
Conversation
Add a grid tesselator option to TerrainLayer and route the rendered mesh
through the correct coordinate system for each projection. Three pieces:
1. `tesselator: 'grid'` emits a fixed-resolution lng/lat/elev mesh in-process
(no worker), keeping the same cached mesh valid on both MapView and
GlobeView. The default `'auto'` path continues to use Martini/Delatin via
`@loaders.gl/terrain`. Grid rows are uniform in Mercator-y so they line
up with heightmap rows at any latitude (no polar sampling warp).
Two quality touches on the grid path:
- Elevation samples are clamped to [-500, 9000]m. Terrain-RGB encodes into
24 bits across three channels, so one corrupt pixel decodes to millions
of meters and renders as a specular star.
- Edge-vertex skirts are clamped to ≤1% of the in-tile grid step so the
seam slope stays imperceptible at any zoom (default 8m skirt over a
~0.6m grid step at z=21 was a visible cliff).
2. renderSubLayers picks the coordinate system per path: LNGLAT for the grid
tesselator (vertices are lng/lat) and on GlobeView for the legacy path
(GlobeViewport.projectFlat is identity so bounds land in lng/lat degrees),
CARTESIAN on MapView for the legacy path (bounds in Mercator world units).
Fixes the MapView→GlobeView case where legacy cartesian meshes landed
inside the sphere and were invisible.
3. Default material changes from `true` (PBR with specular) to a matte
configuration. Specular on terrain meshes catches as star-shaped glints
on skirt edges and elevation discontinuities — a matte surface reads as
a fluid landscape.
Also adds horizon culling in the tile-2d traversal used by the internal
TileLayer. The frustum test accepts tiles on the far hemisphere of the
globe; without a horizon check, low-zoom traversal fans out across the
entire globe. A point on the sphere is visible from camera C iff
dot(P, C) > |P|² — apply to the tile-vs-camera closest point (with lng
wrap so the clamp is angular, not Euclidean).
Docs updated for the new `tesselator` and `gridSize` props.
This was referenced Apr 19, 2026
25 tasks
6 tasks
This was
linked to
issues
Apr 20, 2026
felixpalmer
requested changes
Apr 22, 2026
Collaborator
felixpalmer
left a comment
There was a problem hiding this comment.
This PR is doing 2 separate things: fixing TerrainLayer in GlobeView and adding a tesselator. Could you just restrict it to the first fix? I think we should consider tesselation in general (see my other comment)
This comment has been minimized.
This comment has been minimized.
50bee70 to
41ae4a2
Compare
Collaborator
Author
|
Updated the example to default to |
This was referenced Apr 23, 2026
# Conflicts: # modules/geo-layers/src/terrain-layer/terrain-layer.ts
This was referenced May 12, 2026
25 tasks
felixpalmer
approved these changes
May 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes tiled
TerrainLayermeshes render correctly inGlobeViewby usingCOORDINATE_SYSTEM.LNGLATwhen the active viewport is globe-backed.This keeps the existing
@loaders.gl/terrainmesh generation path intact. The only layer behavior change is coordinate-system selection at render time plus a projection-mode update trigger so cached terrain tiles are rebuilt when switching betweenMapViewandGlobeView.Also defaults the existing terrain website example to
GlobeView, keeps the current pitch/bearing values in place, increases the default zoom from11.5to12.5, and enables Deck-level back-face culling withparameters={{cull: true}}.Why
GlobeViewport.projectFlatis identity, so terrain tile bounds are already in lng/lat degrees underGlobeView. Rendering those meshes asCARTESIANputs them in the wrong coordinate frame.LNGLATmatches the generated vertex positions and makes the terrain visible on the globe.Test plan
yarn vitest run --project headless test/modules/geo-layers/terrain-layer.spec.ts test/modules/geo-layers/terrain-layer-loading.spec.tsexamples/website/terrainrenders by default inGlobeViewat zoom12.5Companion PRs