perf: replace the terrain coords framebuffer picking with a CPU raycast (#8158)
* Add a CPU terrain raycast Adds src/render/terrain_raycast.ts, which intersects the ray through a screen pixel with the terrain surface on the CPU for both mercator and globe, plus the transform ray primitives it needs. Not wired up yet. * Replace the terrain coords framebuffer picking with the CPU raycast pointCoordinate now raycasts the DEM on the CPU. Deletes the coords texture, its shaders, uniforms and draw pass, the coords framebuffer attachment and coordsDirty bookkeeping, and the exact-matrix depth refresh that only existed to serve them. Signature and null semantics are unchanged; hit positions are no longer quantized to 1024 steps per tile and are no longer capped at 255 renderable tiles. * Cover the raycast dispatch, ray delegation, and depth readback * Fix a shader filename typo in the depth decode comment * Reword the depth decode comment * Use currentTransform for the ray segment and move the ray-sphere notes into the tsdoc * Replace the delegation spy test with a behavioral one and drop the stub test * refactor: cache the terrain coverage index and expose the elevation sampler The raycast rebuilt its tile index on every call. Terrain now builds it on first use and drops it in resetElevationCache, which already fires after tile selection and on terrain source data events. getElevationSampler loses its underscore so the raycast stops reaching into an internal. * refactor: route terrain picking through the transforms Each transform now answers screenPointToTerrainCoordinate for its own projection, and GlobeTransform picks the implementation from its globeness the same way it does for every other screen-point query, so Terrain.pointCoordinate no longer inspects the style's transition state. getRaySegmentFromPixel is only meaningful for mercator, so it moves off the interface and onto MercatorTransform. * refactor: extract the raycast sampling helpers The per-call closures become module functions over a small ray record, and both projections share one bisection routine. * test: drop the GL context guard on pointCoordinate * docs: shorten the changelog entry * test: cover the terrain hit path of screenPointToMercatorCoordinate * refactor: move each projection raycast into its transform file * refactor: make the terrain raycast a transform method * refactor: rename screenPointToTerrainCoordinate to screenTerrainPointToMercatorCoordinate * refactor: move the shared terrain sampling into terrain.ts * Reorganize MercatorTransform constants and types Moved constants and type definitions for MercatorRay to the top of the file for better organization. * Refactor vertical_perspective_transform.ts Removed redundant constants and type definition for GlobeRay. * Update terrain.ts * refactor: remove Terrain.pointCoordinate in favor of the transform method * refactor: make the coverage index build a private Terrain method * refactor: keep the terrain hit epsilon private to terrain.ts * test: move the raycast tests and bench next to the transforms * refactor: address review feedback on the terrain raycast - rename TerrainCoverageIndex.tiles to samplerPerTile - make getRaySegmentFromPixel private and document the null returns - move the wrap/renderable-tiles cases out of terrain.test.ts, dropping the ones the transform tests already cover - consolidate the ray-miss tests and name the no-renderable-tiles case * refactor: tighten the raycast surface after a self-review pass - remove an orphaned tsdoc block left above depthAtPoint - restore the mid-gesture anchor assertion in handler_manager.test.ts (mockReturnValue had frozen the mocked elevation) - un-export RaySegment, make getElevationSampler private - name the sampling constants after the world-pixel space they use and document the units on the ray records - inheritDoc on the globe and vertical-perspective implementations - build the terrain test DEM from the shared createDEM fixture and drop a test duplicating transform coverage; unwrap the bench helpers * test: regenerate the bundle size baseline with the merged dependencies * Delete painter reading test from mercator_transform Removed test that checks if the painter is read during raycasting. * Remove unnecessary comment in mercator_transform.ts Remove comment about index being built lazily. --------- Co-authored-by: Harel M <harel.mazor@gmail.com>
J
John Carmack committed
8c274a9cd4c025c6749567eca3e8003754c7bc9b
Parent: 4949106
Committed by GitHub <noreply@github.com>
on 8/23/2026, 10:17:48 AM