From 0a45963270458b2945a7a1a2ee129145a28590be Mon Sep 17 00:00:00 2001 From: charlieforward9 Date: Sun, 19 Apr 2026 14:59:00 -0400 Subject: [PATCH 1/2] feat(extensions): TerrainExtension GlobeView support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make TerrainExtension's draped rendering (height-map and terrain-cover FBOs) work on GlobeView as well as MapView. The existing implementation packed layer bounds into the live viewport's common space, which on GlobeView is sphere cartesian — incomparable with screen-space bounds, and invalid as a UV basis for the draped sampler. All bounds are now expressed in ABSOLUTE Web Mercator common space, regardless of the active projection. The FBO is rendered via a WebMercatorViewport in both cases, so the cover/height-map texture is projection-invariant and a projection toggle no longer requires re-rendering. Changes: - projection-utils: new `MERCATOR_REFERENCE_VIEWPORT` plus helpers `lngLatToMercatorCommon` and `getMercatorReferenceViewport` so other modules can compute bounds in the shared absolute-Mercator basis. - terrain-cover, height-map-builder: project layer bounds through the Mercator reference viewport; on globe, skip the viewport-bounds intersection in `getRenderBounds` (which would yield sphere cartesian coords) and use full layer bounds. - shader-module: compute `terrainMercPos` per-fragment by unprojecting globe cartesian back to lng/lat and forward-projecting through project_mercator_, so USE_HEIGHT_MAP / USE_COVER samples against the absolute-Mercator bounds uniform on any projection. The project module's helpers are VS-only, so the value is passed via varying; terrain meshes are fine enough that interpolation error is negligible. Bounds uniform is packed as absolute Mercator (no commonOrigin subtract), since the shader computes absolute xy itself. Example updated with a GlobeView toggle so the terrain-extension demo exercises both projections (requires TerrainLayer's grid tesselator from the companion geo-layers PR. EOF ) --- .../extensions/terrain-extension.md | 2 + examples/website/terrain-extension/app.tsx | 49 +++++++++++---- .../src/terrain/height-map-builder.ts | 47 +++++++++++--- .../extensions/src/terrain/shader-module.ts | 62 +++++++++++++------ .../extensions/src/terrain/terrain-cover.ts | 37 +++++++++-- .../extensions/src/utils/projection-utils.ts | 50 +++++++++++++-- 6 files changed, 200 insertions(+), 47 deletions(-) diff --git a/docs/api-reference/extensions/terrain-extension.md b/docs/api-reference/extensions/terrain-extension.md index 6bcca82c531..04c1114348e 100644 --- a/docs/api-reference/extensions/terrain-extension.md +++ b/docs/api-reference/extensions/terrain-extension.md @@ -9,6 +9,8 @@ To use this extension, first define a terrain source with the prop `operation: ' For each layer that should be fitted to the terrain surface, add the `TerrainExtension` to its `extensions` prop. +The extension works on both `MapView` and `GlobeView`. Terrain cover and height-map FBOs are computed in absolute Mercator common space so the same draw target can be sampled from either projection without re-rendering when the user toggles between them. When pairing with a `TerrainLayer` source on `GlobeView`, set the source's `tesselator: 'grid'` so its mesh is valid on both projections. +