maplibre-gl 6.7.0 → 6.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/dist/maplibre-gl-dev.mjs +1357 -898
  2. package/dist/maplibre-gl-dev.mjs.map +1 -1
  3. package/dist/maplibre-gl-shared-dev.mjs +6945 -6876
  4. package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
  5. package/dist/maplibre-gl-shared.mjs +2 -2
  6. package/dist/maplibre-gl-shared.mjs.map +1 -1
  7. package/dist/maplibre-gl-worker-dev.mjs +19 -21
  8. package/dist/maplibre-gl-worker-dev.mjs.map +1 -1
  9. package/dist/maplibre-gl-worker.mjs +2 -2
  10. package/dist/maplibre-gl-worker.mjs.map +1 -1
  11. package/dist/maplibre-gl.d.ts +361 -239
  12. package/dist/maplibre-gl.mjs +75 -62
  13. package/dist/maplibre-gl.mjs.map +1 -1
  14. package/package.json +14 -14
  15. package/src/data/bucket/circle_bucket.ts +3 -0
  16. package/src/data/bucket/fill_bucket.test.ts +106 -13
  17. package/src/data/bucket/fill_bucket.ts +40 -4
  18. package/src/data/bucket/fill_extrusion_bucket.ts +3 -2
  19. package/src/data/bucket/line_bucket.ts +3 -2
  20. package/src/data/bucket/symbol_bucket.test.ts +2 -3
  21. package/src/data/bucket/symbol_bucket.ts +28 -19
  22. package/src/data/bucket.ts +23 -0
  23. package/src/data/dem_data.test.ts +14 -12
  24. package/src/data/dem_data.ts +16 -25
  25. package/src/geo/projection/covering_tiles.ts +71 -10
  26. package/src/geo/projection/globe_covering_tiles.test.ts +49 -0
  27. package/src/geo/projection/globe_covering_tiles_details_provider.ts +6 -1
  28. package/src/geo/projection/globe_transform.test.ts +117 -0
  29. package/src/geo/projection/globe_transform.ts +10 -3
  30. package/src/geo/projection/globe_utils.test.ts +21 -1
  31. package/src/geo/projection/globe_utils.ts +10 -1
  32. package/src/geo/projection/mercator_transform.test.ts +64 -1
  33. package/src/geo/projection/mercator_transform.ts +23 -4
  34. package/src/geo/projection/vertical_perspective_transform.test.ts +162 -1
  35. package/src/geo/projection/vertical_perspective_transform.ts +75 -13
  36. package/src/geo/transform_helper.ts +2 -10
  37. package/src/geo/transform_interface.ts +16 -0
  38. package/src/render/painter.test.ts +35 -1
  39. package/src/render/painter.ts +32 -33
  40. package/src/render/render_options.ts +38 -0
  41. package/src/render/render_to_texture_interface.ts +5 -1
  42. package/src/shaders/glsl/_prelude.fragment.glsl +20 -0
  43. package/src/shaders/glsl/_prelude.fragment.glsl.g.ts +1 -1
  44. package/src/shaders/glsl/_prelude.vertex.glsl +27 -6
  45. package/src/shaders/glsl/_prelude.vertex.glsl.g.ts +1 -1
  46. package/src/shaders/glsl/_projection_globe.fragment.glsl +1 -3
  47. package/src/shaders/glsl/_projection_globe.fragment.glsl.g.ts +1 -1
  48. package/src/shaders/glsl/_projection_globe.vertex.glsl +3 -0
  49. package/src/shaders/glsl/_projection_globe.vertex.glsl.g.ts +1 -1
  50. package/src/shaders/glsl/circle.vertex.glsl +0 -2
  51. package/src/shaders/glsl/circle.vertex.glsl.g.ts +1 -1
  52. package/src/shaders/glsl/collision_box.vertex.glsl +0 -3
  53. package/src/shaders/glsl/collision_box.vertex.glsl.g.ts +1 -1
  54. package/src/shaders/glsl/collision_circle.vertex.glsl +0 -3
  55. package/src/shaders/glsl/collision_circle.vertex.glsl.g.ts +1 -1
  56. package/src/shaders/glsl/color_relief.vertex.glsl +2 -2
  57. package/src/shaders/glsl/color_relief.vertex.glsl.g.ts +1 -1
  58. package/src/shaders/glsl/fill_outline.vertex.glsl +1 -2
  59. package/src/shaders/glsl/fill_outline.vertex.glsl.g.ts +1 -1
  60. package/src/shaders/glsl/fill_outline_pattern.fragment.glsl +13 -1
  61. package/src/shaders/glsl/fill_outline_pattern.fragment.glsl.g.ts +1 -1
  62. package/src/shaders/glsl/fill_outline_pattern.vertex.glsl +3 -2
  63. package/src/shaders/glsl/fill_outline_pattern.vertex.glsl.g.ts +1 -1
  64. package/src/shaders/glsl/fill_pattern.fragment.glsl +13 -1
  65. package/src/shaders/glsl/fill_pattern.fragment.glsl.g.ts +1 -1
  66. package/src/shaders/glsl/fill_pattern.vertex.glsl +2 -0
  67. package/src/shaders/glsl/fill_pattern.vertex.glsl.g.ts +1 -1
  68. package/src/shaders/glsl/heatmap_texture.vertex.glsl +1 -2
  69. package/src/shaders/glsl/heatmap_texture.vertex.glsl.g.ts +1 -1
  70. package/src/shaders/glsl/hillshade.fragment.glsl +3 -1
  71. package/src/shaders/glsl/hillshade.fragment.glsl.g.ts +1 -1
  72. package/src/shaders/glsl/hillshade_prepare.fragment.glsl +1 -1
  73. package/src/shaders/glsl/hillshade_prepare.fragment.glsl.g.ts +1 -1
  74. package/src/shaders/glsl/line.fragment.glsl +0 -2
  75. package/src/shaders/glsl/line.fragment.glsl.g.ts +1 -1
  76. package/src/shaders/glsl/line.vertex.glsl +0 -3
  77. package/src/shaders/glsl/line.vertex.glsl.g.ts +1 -1
  78. package/src/shaders/glsl/line_gradient.fragment.glsl +0 -1
  79. package/src/shaders/glsl/line_gradient.fragment.glsl.g.ts +1 -1
  80. package/src/shaders/glsl/line_gradient.vertex.glsl +0 -2
  81. package/src/shaders/glsl/line_gradient.vertex.glsl.g.ts +1 -1
  82. package/src/shaders/glsl/line_gradient_sdf.fragment.glsl +0 -1
  83. package/src/shaders/glsl/line_gradient_sdf.fragment.glsl.g.ts +1 -1
  84. package/src/shaders/glsl/line_gradient_sdf.vertex.glsl +0 -2
  85. package/src/shaders/glsl/line_gradient_sdf.vertex.glsl.g.ts +1 -1
  86. package/src/shaders/glsl/line_pattern.fragment.glsl +0 -1
  87. package/src/shaders/glsl/line_pattern.fragment.glsl.g.ts +1 -1
  88. package/src/shaders/glsl/line_pattern.vertex.glsl +0 -3
  89. package/src/shaders/glsl/line_pattern.vertex.glsl.g.ts +1 -1
  90. package/src/shaders/glsl/line_sdf.fragment.glsl +0 -2
  91. package/src/shaders/glsl/line_sdf.fragment.glsl.g.ts +1 -1
  92. package/src/shaders/glsl/line_sdf.vertex.glsl +0 -2
  93. package/src/shaders/glsl/line_sdf.vertex.glsl.g.ts +1 -1
  94. package/src/shaders/glsl/sky.fragment.glsl +11 -0
  95. package/src/shaders/glsl/sky.fragment.glsl.g.ts +1 -1
  96. package/src/shaders/glsl/sky.vertex.glsl +5 -0
  97. package/src/shaders/glsl/sky.vertex.glsl.g.ts +1 -1
  98. package/src/shaders/glsl/symbol_icon.vertex.glsl +1 -5
  99. package/src/shaders/glsl/symbol_icon.vertex.glsl.g.ts +1 -1
  100. package/src/shaders/glsl/symbol_sdf.fragment.glsl +0 -1
  101. package/src/shaders/glsl/symbol_sdf.fragment.glsl.g.ts +1 -1
  102. package/src/shaders/glsl/symbol_sdf.vertex.glsl +1 -5
  103. package/src/shaders/glsl/symbol_sdf.vertex.glsl.g.ts +1 -1
  104. package/src/shaders/glsl/symbol_text_and_icon.fragment.glsl +0 -2
  105. package/src/shaders/glsl/symbol_text_and_icon.fragment.glsl.g.ts +1 -1
  106. package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl +1 -5
  107. package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl.g.ts +1 -1
  108. package/src/source/image_source.ts +2 -0
  109. package/src/source/raster_dem_tile_source.test.ts +26 -0
  110. package/src/source/raster_dem_tile_source.ts +13 -6
  111. package/src/source/raster_dem_tile_worker_source.test.ts +2 -0
  112. package/src/source/raster_dem_tile_worker_source.ts +3 -3
  113. package/src/source/raster_tile_source.test.ts +42 -0
  114. package/src/source/raster_tile_source.ts +7 -2
  115. package/src/source/vector_tile_source.test.ts +25 -0
  116. package/src/source/vector_tile_source.ts +1 -0
  117. package/src/source/worker_tile.test.ts +2 -1
  118. package/src/source/worker_tile.ts +15 -21
  119. package/src/source/worker_tile_mlt.bench.ts +82 -0
  120. package/src/style/load_sprite.ts +5 -1
  121. package/src/style/style.test.ts +20 -0
  122. package/src/style/style.ts +9 -4
  123. package/src/symbol/symbol_layout.ts +13 -15
  124. package/src/symbol/symbol_size.ts +8 -0
  125. package/src/tile/tile.ts +2 -1
  126. package/src/tile/tile_manager.test.ts +70 -1
  127. package/src/tile/tile_manager.ts +44 -0
  128. package/src/ui/camera.test.ts +0 -70
  129. package/src/ui/camera.ts +2 -30
  130. package/src/ui/map.ts +36 -6
  131. package/src/ui/map_tests/map_canvas.test.ts +16 -0
  132. package/src/ui/map_tests/map_render.test.ts +21 -0
  133. package/src/ui/map_tests/map_style.test.ts +29 -0
  134. package/src/ui/marker.test.ts +31 -0
  135. package/src/ui/marker.ts +72 -95
  136. package/src/util/graphemes.ts +12 -9
  137. package/src/util/image_request.test.ts +20 -2
  138. package/src/util/image_request.ts +10 -1
  139. package/src/util/task_queue.test.ts +20 -0
  140. package/src/util/task_queue.ts +11 -1
  141. package/src/util/test/null_gl.ts +5 -0
  142. package/src/util/test/util.ts +2 -2
  143. package/src/util/util.ts +1 -4
  144. package/src/webgl/context.ts +14 -0
  145. package/src/webgl/draw/draw_background.ts +3 -2
  146. package/src/webgl/draw/draw_circle.ts +3 -2
  147. package/src/webgl/draw/draw_collision_debug.ts +2 -4
  148. package/src/webgl/draw/draw_color_relief.ts +12 -6
  149. package/src/webgl/draw/draw_custom.test.ts +6 -4
  150. package/src/webgl/draw/draw_custom.ts +4 -3
  151. package/src/webgl/draw/draw_fill.test.ts +6 -5
  152. package/src/webgl/draw/draw_fill.ts +10 -9
  153. package/src/webgl/draw/draw_fill_extrusion.ts +4 -3
  154. package/src/webgl/draw/draw_heatmap.ts +6 -5
  155. package/src/webgl/draw/draw_hillshade.ts +9 -8
  156. package/src/webgl/draw/draw_line.ts +3 -2
  157. package/src/webgl/draw/draw_raster.ts +3 -2
  158. package/src/webgl/draw/draw_sky.ts +5 -18
  159. package/src/webgl/draw/draw_symbol.test.ts +14 -13
  160. package/src/webgl/draw/draw_symbol.ts +3 -2
  161. package/src/webgl/draw/draw_terrain.ts +3 -2
  162. package/src/webgl/frame_uniform_buffer.ts +44 -0
  163. package/src/webgl/program/circle_program.ts +0 -6
  164. package/src/webgl/program/fill_program.ts +11 -15
  165. package/src/webgl/program/heatmap_program.ts +0 -6
  166. package/src/webgl/program/line_program.ts +0 -30
  167. package/src/webgl/program/program_uniforms.ts +9 -8
  168. package/src/webgl/program/sky_program.ts +11 -1
  169. package/src/webgl/program/symbol_program.ts +0 -35
  170. package/src/webgl/program/terrain_program.ts +1 -10
  171. package/src/webgl/program.ts +20 -19
  172. package/src/webgl/projection_uniform_buffer.ts +33 -0
  173. package/src/webgl/render_to_texture.test.ts +95 -11
  174. package/src/webgl/render_to_texture.ts +28 -8
  175. package/src/webgl/rtt_fingerprint.test.ts +25 -0
  176. package/src/webgl/rtt_fingerprint.ts +35 -0
  177. package/src/webgl/terrain_uniform_buffer.ts +29 -0
  178. package/src/webgl/texture.test.ts +46 -0
  179. package/src/webgl/texture.ts +28 -10
  180. package/src/webgl/uniform_buffer.test.ts +62 -0
  181. package/src/webgl/uniform_buffer.ts +103 -0
  182. package/src/webgl/program/collision_program.ts +0 -34
  183. package/src/webgl/program/projection_program.ts +0 -34
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * MapLibre GL JS
3
- * @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.7.0/LICENSE.txt
3
+ * @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.8.0/LICENSE.txt
4
4
  */
5
- import { $ as maxMercatorHorizonAngle, $n as createVec3f64, $r as multiply$1, $t as DataConstantProperty, A as evaluateSizeForFeature, Ai as multiply, An as getJSON, Ar as rayPlaneIntersection, At as isCircleStyleLayer, Bi as create$2, Bn as isAbortError, Br as uniqueId, Bt as UniformFloatArray, C as isCustomStyleLayer, Ci as copy, Cn as latest, Cr as mapObject, Ct as Texture, D as SymbolBucket, Di as fromScaling, Dn as AJAXError, Dr as pick, Dt as renderColorRamp, E as isSymbolStyleLayer, Ei as exactEquals, En as Evented, Er as parseCacheControl, Et as isHeatmapStyleLayer, F as ImagePosition, Fi as rotateZ, Fn as addProtocol, Fr as scaleZoom, Ft as Uniform2f, Gi as offscreenCanvasSupported, Gn as arrayBufferToImage, Gr as EXTENT, Gt as LineStripIndexArray, H as collisionCircleLayout, Hi as invert, Hr as wrap, Ht as SegmentVector, I as potpack, Ii as scale, In as getProtocol, Ir as sphericalToCartesian, It as Uniform3f, J as calculateTileMatrix, Jn as clamp, Jr as scale$1, Jt as QuadTriangleArray, K as isFillExtrusionStyleLayer, Ki as Point, Kn as arrayBufferToImageBitmap, Kr as create$3, Kt as Pos3dArray, L as isStyleImageWebGLData, Li as translate, Ln as removeProtocol, Lr as subscribe, Lt as Uniform4f, Mi as perspective, Mn as getVideo, Mr as remapSaturate, Mt as toEvaluationFeature, N as getAnchorAlignment, Ni as rotateX, Nn as makeRequest, Nr as rollPitchBearingEqual, Nt as Uniform1f, O as addDynamicAttributes, Oi as identity, On as GLOBAL_DISPATCHER_ID, Or as pointPlaneSignedDistance, Ot as AlphaImage, Pi as rotateY$1, Pn as sameOrigin, Pr as rollPitchBearingToQuat, Pt as Uniform1i, Q as getMercatorHorizon, Qn as createMat4f64, Qr as fromValues, Qt as isRasterStyleLayer, R as renderStyleImage, Ri as create$4, Rn as config, Rr as threePlaneIntersection, Rt as UniformColor, S as createStyleLayer, Si as clone$1, Sn as derefLayers, Sr as lerp, T as isBackgroundStyleLayer, Ti as equals, Tn as Event, Tr as nextPowerOfTwo, Tt as HEATMAP_FULL_RENDER_FBO_KEY, U as isLineStyleLayer, Ui as rotate, Un as MAX_VALID_LATITUDE, Ur as zoomScale, Ut as CollisionBoxArray, V as isCluster, Vi as determinant, Vn as throwIfAborted, Vr as warnOnce, Vt as UniformMatrix4f, Wi as isOffscreenCanvasDistorted, Wn as angleToRotateBetweenVectors2D, Wr as pixelsToTileUnits, Wt as CollisionCircleLayoutArray, X as cameraMercatorCoordinate, Xn as createIdentityMat4f32, Xr as zero, Xt as TriangleIndexArray, Y as cameraDirectionFromPitchBearing, Yn as clone$2, Yr as sqrLen, Yt as RasterBoundsArray, Z as cameraMercatorCoordinateFromCenterAndRotation, Zn as createIdentityMat4f64, Zr as fromEuler, Zt as createLayout, _ as UnwrappedTileID, _i as sub, _n as interpolateFactory, _r as isPointableEvent, _t as NORTH_POLE_Y, a as clipLine, ai as clone, an as codePointUsesLocalIdeographFontFamily, ar as distanceOfAnglesRadians, at as latFromMercatorY, b as isInBoundsForZoomLngLat, bi as transformQuat, bn as ValidationError, br as isTouchableOrPointableType, bt as SubdivisionGranularitySetting, ci as len, cn as SPEC_SOURCE_TYPES, cr as extend, ct as mercatorYfromLat, di as normalize, dn as validateStyle, dr as getAABB, dt as earthRadius, ei as slerp, en as Properties, er as createVec4f64, et as projectToWorldCoordinates, f as GEOJSON_TILE_LAYER_NAME, fi as rotateX$1, fn as validateStyleAndEmit, fr as getAngleDelta, g as OverscaledTileID, gi as scaleAndAdd, gr as isImageBitmap, h as CanonicalTileID, hi as scale$2, hn as featureFilter, hr as getRollPitchBearing, ht as isFillStyleLayer, ii as add, ir as differenceOfAnglesDegrees, it as altitudeFromMercatorZ, j as evaluateSizeForZoom, ji as ortho, jn as getReferrer, jr as readImageUsingVideoFrame, jt as polygonIntersectsPolygon, k as getOverlapMode, ki as invert$1, kn as getArrayBuffer, kr as radiansToDegrees, kt as RGBAImage, li as length$1, ln as emitValidationErrors, lr as filterObject, lt as mercatorZfromAltitude, mi as rotateZ$1, mt as Bounds, ni as scale$3, nn as Transitionable, nr as defaultEasing, nt as unprojectFromWorldCoordinates, oi as cross, on as ZoomHistory, or as ensureError, ot as lngFromMercatorX, pi as rotateY, pn as emptyStyle, pr as getEdgeTiles, pt as EXTENT_BOUNDS, qn as bezier, qr as length, qt as PosArray, r as TextAnchorEnum, ri as transformMat4, rn as EvaluationParameters, rr as degreesToRadians, rt as MercatorCoordinate, s as TileCache, si as dot, sr as evaluateZoomSnap, st as mercatorXfromLng, t as getAnchorJustification, ti as mul, tn as TRANSITION_SUFFIX, tr as deepEqual, tt as tileCoordinatesToMercatorCoordinates, u as GeoJSONFeature, ui as negate, un as validateAndEmit, ur as findLineIntersection, ut as LngLat, v as calculateTileKey, vi as transformMat3, vn as ProjectionDefinition, vr as isSafari, vt as SOUTH_POLE_Y, w as validateCustomStyleLayer, wi as create$1, wn as ErrorEvent, wr as mod, wt as isHillshadeStyleLayer, x as Actor, xi as zero$1, xn as diff, xr as isWorker, xt as isColorReliefStyleLayer, y as compareTileId, yi as transformMat4$1, yn as Color, yr as isTouchableEvent, yt as SubdivisionGranularityExpression, z as parseGlyphPbf, zi as fromRotation, zn as AbortError, zr as translatePosition, zt as UniformColorArray } from "./maplibre-gl-shared-dev.mjs";
5
+ import { $ as unprojectFromWorldCoordinates, $n as degreesToRadians, $r as transformMat4, $t as EvaluationParameters, A as evaluateSizeForZoom, Ai as perspective, An as sameOrigin, Ar as rollPitchBearingToQuat, At as Uniform1i, B as isCluster, Bi as invert, Bn as angleToRotateBetweenVectors2D, Br as pixelsToTileUnits, Bt as CollisionCircleLayoutArray, C as addDynamicAttributes, Ci as equals, Cn as AJAXError, Cr as pick, Ct as renderColorRamp, Di as invert$1, Dn as getReferrer, Dr as readImageUsingVideoFrame, Dt as polygonIntersectsPolygon, E as TextAnchorEnum, Ei as identity, En as getJSON, Er as rayPlaneIntersection, Et as isCircleStyleLayer, F as potpack, Fi as translate, Fn as AbortError, Fr as translatePosition, Ft as UniformColorArray, G as calculateTileMatrix, Gn as clone$2, Gr as sqrLen, Gt as RasterBoundsArray, H as isLineStyleLayer, Hi as isOffscreenCanvasDistorted, Hn as arrayBufferToImageBitmap, Hr as create$3, Ht as Pos3dArray, I as isStyleImageWebGLData, Ii as create$4, In as isAbortError, Ir as uniqueId, It as UniformFloatArray, J as cameraMercatorCoordinateFromCenterAndRotation, Jn as createMat4f64, Jr as fromValues, Jt as isRasterStyleLayer, K as cameraDirectionFromPitchBearing, Kn as createIdentityMat4f32, Kr as zero, Kt as TriangleIndexArray, L as renderStyleImage, Li as fromRotation, Ln as throwIfAborted, Lr as warnOnce, Lt as UniformMatrix4f, M as getAnchorAlignment, Mi as rotateY$1, Mn as getProtocol, Mr as sphericalToCartesian, Mt as Uniform3f, Ni as rotateZ, Nn as removeProtocol, Nr as subscribe, Nt as Uniform4f, O as clipLine, Oi as multiply, On as getVideo, Or as remapSaturate, Ot as toEvaluationFeature, P as ImagePosition, Pi as scale, Pn as config, Pr as threePlaneIntersection, Pt as UniformColor, Q as tileCoordinatesToMercatorCoordinates, Qn as defaultEasing, Qr as scale$2, Qt as Transitionable, R as parseGlyphPbf, Ri as create$2, Rr as wrap, Rt as SegmentVector, S as SymbolBucket, Si as create$1, Sn as Evented, Sr as parseCacheControl, St as isHeatmapStyleLayer, T as getAnchorJustification, Ti as fromScaling, Tn as getArrayBuffer, Tr as radiansToDegrees, Tt as RGBAImage, Ui as offscreenCanvasSupported, Un as bezier, Ur as length$1, Ut as PosArray, V as collisionCircleLayout, Vi as rotate, Vn as arrayBufferToImage, Vr as EXTENT, Vt as LineStripIndexArray, W as isFillExtrusionStyleLayer, Wi as Point, Wn as clamp, Wr as scale$3, Wt as QuadTriangleArray, X as maxMercatorHorizonAngle, Xn as createVec4f64, Xr as slerp, Xt as Properties, Y as getMercatorHorizon, Yn as createVec3f64, Yr as multiply$1, Yt as DataConstantProperty, Z as projectToWorldCoordinates, Zn as deepEqual, Zr as mul, Zt as TRANSITION_SUFFIX, _ as createStyleLayer, _i as transformMat4$1, _n as diff, _r as isWorker, _t as isColorReliefStyleLayer, a as GeoJSONFeature, ai as len, an as emitValidationErrors, ar as filterObject, at as mercatorYfromLat, b as isBackgroundStyleLayer, bi as clone$1, bn as ErrorEvent, br as mod, bt as isHillshadeStyleLayer, ci as normalize, cn as validateStyleAndEmit, cr as getAngleDelta, ct as earthRadius, d as OverscaledTileID, di as rotateZ$1, dn as featureFilter, dr as getRollPitchBearing, dt as Bounds, ei as add, er as differenceOfAnglesDegrees, et as MercatorCoordinate, f as UnwrappedTileID, fi as scale$1, fr as isImageBitmap, ft as isFillStyleLayer, g as Actor, gi as transformMat3, gn as ValidationError, gr as isTouchableOrPointableType, gt as SubdivisionGranularitySetting, h as isInBoundsForZoomLngLat, hi as subtract, hn as Color, hr as isTouchableEvent, ht as SubdivisionGranularityExpression, ii as dot, in as SPEC_SOURCE_TYPES, ir as extend, it as mercatorXfromLng, ji as rotateX, jn as addProtocol, jr as scaleZoom, jt as Uniform2f, k as evaluateSizeForFeature, ki as ortho, kn as makeRequest, kr as rollPitchBearingEqual, kt as Uniform1f, li as rotateX$1, ln as emptyStyle, lr as getEdgeTiles, m as compareTileId, mi as sub, mn as ProjectionDefinition, mr as isSafari, mt as SOUTH_POLE_Y, n as TileCache, ni as cross, nn as ZoomHistory, nr as ensureError, nt as latFromMercatorY, oi as length, on as validateAndEmit, or as findLineIntersection, ot as mercatorZfromAltitude, p as calculateTileKey, pi as scaleAndAdd, pn as interpolateFactory, pr as isPointableEvent, pt as NORTH_POLE_Y, q as cameraMercatorCoordinate, qn as createIdentityMat4f64, qr as fromEuler, qt as createLayout, ri as distance, rr as evaluateZoomSnap, rt as lngFromMercatorX, s as GEOJSON_TILE_LAYER_NAME, si as negate, sn as validateStyle, sr as getAABB, st as LngLat, ti as clone, tn as codePointUsesLocalIdeographFontFamily, tr as distanceOfAnglesRadians, tt as altitudeFromMercatorZ, u as CanonicalTileID, ui as rotateY, ut as EXTENT_BOUNDS, v as isCustomStyleLayer, vi as transformQuat, vn as derefLayers, vr as lerp, w as getOverlapMode, wi as exactEquals, wn as GLOBAL_DISPATCHER_ID, wr as pointPlaneSignedDistance, wt as AlphaImage, x as isSymbolStyleLayer, xi as copy, xn as Event, xr as nextPowerOfTwo, xt as HEATMAP_FULL_RENDER_FBO_KEY, y as validateCustomStyleLayer, yi as zero$1, yn as latest, yr as mapObject, yt as Texture, zi as determinant, zn as MAX_VALID_LATITUDE, zr as zoomScale, zt as CollisionBoxArray } from "./maplibre-gl-shared-dev.mjs";
6
6
  //#region package.json
7
- var version$2 = "6.7.0";
7
+ var version$2 = "6.8.0";
8
8
  //#endregion
9
9
  //#region src/util/browser.ts
10
10
  let linkEl;
@@ -358,6 +358,13 @@ let ImageRequest;
358
358
  if (typeof createImageBitmap === "function") return arrayBufferToImageBitmap(data, imageBitmapOptions);
359
359
  else return arrayBufferToImage(data);
360
360
  };
361
+ /**
362
+ * Runs one queued image request.
363
+ *
364
+ * An empty response body (e.g. HTTP 204 for a tile without content) resolves with
365
+ * `data: null`, keeping the expiry headers, so callers can handle the absence
366
+ * explicitly and re-request when the headers say so.
367
+ */
361
368
  const doImageRequest = async (itemInQueue) => {
362
369
  itemInQueue.state = "running";
363
370
  const { requestParameters, supportImageRefresh, imageBitmapOptions, onError, onSuccess, abortController } = itemInQueue;
@@ -369,7 +376,12 @@ let ImageRequest;
369
376
  delete itemInQueue.abortController;
370
377
  itemInQueue.state = "completed";
371
378
  if (response.data instanceof HTMLImageElement || isImageBitmap(response.data)) onSuccess(response);
372
- else if (response.data) onSuccess({
379
+ else if (!response.data || response.data.byteLength === 0) onSuccess({
380
+ data: null,
381
+ cacheControl: response.cacheControl,
382
+ expires: response.expires
383
+ });
384
+ else onSuccess({
373
385
  data: await arrayBufferToCanvasImageSource(response.data, imageBitmapOptions),
374
386
  cacheControl: response.cacheControl,
375
387
  expires: response.expires
@@ -731,7 +743,9 @@ async function doOnceCompleted(jsonsMap, imagesMap) {
731
743
  const result = {};
732
744
  for (const spriteName in jsonsMap) {
733
745
  result[spriteName] = {};
734
- const context = browser.getImageCanvasContext((await imagesMap[spriteName]).data);
746
+ const image = (await imagesMap[spriteName]).data;
747
+ if (!image) throw new Error(`Could not load sprite image for ${spriteName}: the response is empty`);
748
+ const context = browser.getImageCanvasContext(image);
735
749
  const json = (await jsonsMap[spriteName]).data;
736
750
  for (const id in json) {
737
751
  const { width, height, x, y, sdf, pixelRatio, stretchX, stretchY, content, textFitWidth, textFitHeight } = json[id];
@@ -2878,6 +2892,7 @@ var VectorTileSource = class extends Evented {
2878
2892
  */
2879
2893
  setTiles(tiles) {
2880
2894
  this.setSourceProperty(() => {
2895
+ this.tiles = tiles;
2881
2896
  this._options.tiles = tiles;
2882
2897
  });
2883
2898
  return this;
@@ -3111,6 +3126,7 @@ var RasterTileSource = class extends Evented {
3111
3126
  */
3112
3127
  setTiles(tiles) {
3113
3128
  this.setSourceProperty(() => {
3129
+ this.tiles = tiles;
3114
3130
  this._options.tiles = tiles;
3115
3131
  });
3116
3132
  return this;
@@ -3162,14 +3178,17 @@ var RasterTileSource = class extends Evented {
3162
3178
  tile.state = "unloaded";
3163
3179
  return;
3164
3180
  }
3165
- if (response?.data) {
3181
+ if (response) {
3166
3182
  if (this.map._refreshExpiredTiles && (response.cacheControl || response.expires)) tile.setExpiryData({
3167
3183
  cacheControl: response.cacheControl,
3168
3184
  expires: response.expires
3169
3185
  });
3170
3186
  const context = this.map.painter.context;
3171
3187
  const gl = context.gl;
3172
- const img = response.data;
3188
+ const img = response.data ?? new RGBAImage({
3189
+ width: 1,
3190
+ height: 1
3191
+ }, /* @__PURE__ */ new Uint8Array(4));
3173
3192
  tile.texture = this.map.painter.getTileTexture(img.width);
3174
3193
  if (tile.texture) tile.texture.update(img, {
3175
3194
  useMipmap: true,
@@ -3247,12 +3266,16 @@ var RasterDEMTileSource = class extends RasterTileSource {
3247
3266
  tile.state = "unloaded";
3248
3267
  return;
3249
3268
  }
3250
- if (response?.data) {
3251
- const img = response.data;
3269
+ if (response) {
3252
3270
  if (this.map._refreshExpiredTiles && (response.cacheControl || response.expires)) tile.setExpiryData({
3253
3271
  cacheControl: response.cacheControl,
3254
3272
  expires: response.expires
3255
3273
  });
3274
+ if (!response.data) {
3275
+ tile.state = "loaded";
3276
+ return;
3277
+ }
3278
+ const img = response.data;
3256
3279
  const rawImageData = isImageBitmap(img) && offscreenCanvasSupported() ? img : await this.readImageNow(img);
3257
3280
  const params = {
3258
3281
  type: this.type,
@@ -3288,16 +3311,16 @@ var RasterDEMTileSource = class extends RasterTileSource {
3288
3311
  }
3289
3312
  async readImageNow(img) {
3290
3313
  if (typeof VideoFrame !== "undefined" && isOffscreenCanvasDistorted()) {
3291
- const width = img.width + 2;
3292
- const height = img.height + 2;
3314
+ const width = img.width + 4;
3315
+ const height = img.height + 4;
3293
3316
  try {
3294
3317
  return new RGBAImage({
3295
3318
  width,
3296
3319
  height
3297
- }, await readImageUsingVideoFrame(img, -1, -1, width, height));
3320
+ }, await readImageUsingVideoFrame(img, -2, -2, width, height));
3298
3321
  } catch {}
3299
3322
  }
3300
- return browser.getImageData(img, 1);
3323
+ return browser.getImageData(img, 2);
3301
3324
  }
3302
3325
  _getNeighboringTiles(tileID) {
3303
3326
  const canonical = tileID.canonical;
@@ -4379,7 +4402,7 @@ var ImageSource = class extends Evented {
4379
4402
  this._setImage(image.data);
4380
4403
  if (newCoordinates) this.coordinates = newCoordinates;
4381
4404
  this._finishLoading();
4382
- }
4405
+ } else this.fire(new ErrorEvent(/* @__PURE__ */ new Error(`Could not load image ${this.url}: the response is empty`)));
4383
4406
  } catch (err) {
4384
4407
  if (isAbortError(err)) return;
4385
4408
  this._abortController = null;
@@ -5494,213 +5517,575 @@ var SourceFeatureState = class {
5494
5517
  }
5495
5518
  };
5496
5519
  //#endregion
5497
- //#region src/geo/projection/covering_tiles.ts
5498
- /**
5499
- * A simple/heuristic function that returns whether the tile is visible under the current transform.
5500
- * @returns an {@link IntersectionResult}.
5501
- */
5502
- function isTileVisible(frustum, tileBoundingVolume, plane) {
5503
- const frustumTest = tileBoundingVolume.intersectsFrustum(frustum);
5504
- if (!plane || frustumTest === 0) return frustumTest;
5505
- const planeTest = tileBoundingVolume.intersectsPlane(plane);
5506
- if (planeTest === 0) return 0;
5507
- if (frustumTest === 2 && planeTest === 2) return 2;
5508
- return 1;
5509
- }
5510
- /**
5511
- * Definite integral of cos(x)^p. The analytical solution is described in `developer-guides/covering-tiles.md`,
5512
- * but here the integral is evaluated numerically.
5513
- * @param p - the power to raise cos(x) to inside the integral
5514
- * @param x1 - the starting point of the integral.
5515
- * @param x2 - the ending point of the integral.
5516
- * @return the integral of cos(x)^p from x=x1 to x=x2
5517
- */
5518
- function integralOfCosXByP(p, x1, x2) {
5519
- const numPoints = 10;
5520
- let sum = 0;
5521
- const dx = (x2 - x1) / numPoints;
5522
- for (let i = 0; i < numPoints; i++) {
5523
- const x = x1 + (i + .5) / numPoints * (x2 - x1);
5524
- sum += dx * Math.pow(Math.cos(x), p);
5525
- }
5526
- return sum;
5527
- }
5528
- function createCalculateTileZoomFunction(maxZoomLevelsOnScreen, tileCountMaxMinRatio) {
5529
- return function(requestedCenterZoom, distanceToTile2D, distanceToTileZ, distanceToCenter3D, cameraVerticalFOV) {
5530
- /**
5531
- * Controls how tiles are loaded at high pitch angles. Higher numbers cause fewer, lower resolution
5532
- * tiles to be loaded. Calculate the value that will result in the selected number of zoom levels in
5533
- * the worst-case condition (when the horizon is at the top of the screen). For more information, see
5534
- * `developer-guides/covering-tiles.md`
5535
- */
5536
- const pitchTileLoadingBehavior = 2 * ((maxZoomLevelsOnScreen - 1) / scaleZoom(Math.cos(degreesToRadians(maxMercatorHorizonAngle - cameraVerticalFOV)) / Math.cos(degreesToRadians(maxMercatorHorizonAngle))) - 1);
5537
- const centerPitch = Math.acos(distanceToTileZ / distanceToCenter3D);
5538
- const tileCountPitch0 = 2 * integralOfCosXByP(pitchTileLoadingBehavior - 1, 0, degreesToRadians(cameraVerticalFOV / 2));
5539
- const highestPitch = Math.min(degreesToRadians(maxMercatorHorizonAngle), centerPitch + degreesToRadians(cameraVerticalFOV / 2));
5540
- const lowestPitch = Math.min(highestPitch, centerPitch - degreesToRadians(cameraVerticalFOV / 2));
5541
- const tileCount = integralOfCosXByP(pitchTileLoadingBehavior - 1, lowestPitch, highestPitch);
5542
- const thisTilePitch = Math.atan(distanceToTile2D / distanceToTileZ);
5543
- const distanceToTile3D = Math.hypot(distanceToTile2D, distanceToTileZ);
5544
- let thisTileDesiredZ = requestedCenterZoom;
5545
- thisTileDesiredZ = thisTileDesiredZ + scaleZoom(distanceToCenter3D / distanceToTile3D / Math.max(.5, Math.cos(degreesToRadians(cameraVerticalFOV / 2))));
5546
- thisTileDesiredZ += pitchTileLoadingBehavior * scaleZoom(Math.cos(thisTilePitch)) / 2;
5547
- thisTileDesiredZ -= scaleZoom(Math.max(1, tileCount / tileCountPitch0 / tileCountMaxMinRatio)) / 2;
5548
- return thisTileDesiredZ;
5549
- };
5550
- }
5551
- const defaultCalculateTileZoom = createCalculateTileZoomFunction(9.314, 3);
5552
- /**
5553
- * Return what zoom level of a tile source would most closely cover the tiles displayed by this transform.
5554
- * @param options - The options, most importantly the source's tile size.
5555
- * @returns An integer zoom level at which all tiles will be visible.
5556
- */
5557
- function coveringZoomLevel(transform, options) {
5558
- const z = (options.roundZoom ? Math.round : Math.floor)(transform.zoom + scaleZoom(transform.tileSize / options.tileSize));
5559
- return Math.max(0, z);
5560
- }
5561
- /**
5562
- * Without terrain, `getTileBoundingVolume` has no knowledge of extruded features
5563
- * (eg. 3D buildings): every tile's bounding box is flat at the camera's `elevation`.
5564
- * That's a fine approximation of what's visible for most views, but it breaks down
5565
- * as the frustum's bottom edge approaches horizontal (which depends on both `pitch`
5566
- * and `fov`, not pitch alone) - a tall building can still be poking up into view
5567
- * long after its tile's ground point has dropped out of the frustum.
5568
- *
5569
- * This is an assumed upper bound on real-world feature height (in metres), used to
5570
- * grow the elevation used for tile culling as that bottom edge nears horizontal, so
5571
- * such tiles are not dropped too early. It has no effect away from that edge case.
5572
- */
5573
- const ASSUMED_MAX_FEATURE_HEIGHT_METERS = 500;
5574
- /**
5575
- * Angle between the frustum's bottom edge and the mercator horizon below which
5576
- * the culling elevation starts to grow.
5577
- */
5578
- const TILE_CULLING_HORIZON_ONSET_DEGREES = 15;
5579
- /**
5580
- * Returns the elevation to use when computing tile bounding volumes for culling:
5581
- * `transform.elevation`, growing by up to `ASSUMED_MAX_FEATURE_HEIGHT_METERS` as
5582
- * the frustum's bottom edge approaches the horizon, where a ground-level bounding
5583
- * box would cull tiles whose extruded features are still visible.
5584
- */
5585
- function getElevationForTileCulling(transform) {
5586
- const bottomEdgeDegreesAboveHorizontal = maxMercatorHorizonAngle - transform.pitch - transform.fov / 2;
5587
- const proximityToHorizon = clamp((TILE_CULLING_HORIZON_ONSET_DEGREES - bottomEdgeDegreesAboveHorizontal) / TILE_CULLING_HORIZON_ONSET_DEGREES, 0, 1);
5588
- return transform.elevation + proximityToHorizon * ASSUMED_MAX_FEATURE_HEIGHT_METERS;
5589
- }
5590
- /**
5591
- * Returns a list of tiles that optimally covers the screen. Adapted for globe projection.
5592
- * Correctly handles LOD when moving over the antimeridian.
5593
- * @param transform - The transform instance.
5594
- * @param frustum - The covering frustum.
5595
- * @param plane - The clipping plane used by globe transform, or null.
5596
- * @param cameraCoord - The x, y, z position of the camera in MercatorCoordinates.
5597
- * @param centerCoord - The x, y, z position of the center point in MercatorCoordinates.
5598
- * @param options - Additional coveringTiles options.
5599
- * @param details - Interface to define required helper functions.
5600
- * @returns A list of tile coordinates, ordered by ascending distance from camera.
5601
- */
5602
- function coveringTiles(transform, options) {
5603
- const frustum = transform.getCameraFrustum();
5604
- const plane = transform.getClippingPlane();
5605
- const cameraCoord = cameraMercatorCoordinate(transform);
5606
- const centerCoord = MercatorCoordinate.fromLngLat(transform.center, transform.elevation);
5607
- const elevationForTileCulling = getElevationForTileCulling(transform);
5608
- const detailsProvider = transform.getCoveringTilesDetailsProvider();
5609
- const allowVariableZoom = detailsProvider.allowVariableZoom(transform, options);
5610
- const desiredZ = coveringZoomLevel(transform, options);
5611
- const minZoom = options.minzoom || 0;
5612
- const maxZoom = options.maxzoom !== void 0 ? options.maxzoom : transform.maxZoom;
5613
- const nominalZ = Math.min(Math.max(0, desiredZ), maxZoom);
5614
- const numTiles = Math.pow(2, nominalZ);
5615
- const cameraPoint = [
5616
- numTiles * cameraCoord.x,
5617
- numTiles * cameraCoord.y,
5618
- 0
5619
- ];
5620
- const centerPoint = [
5621
- numTiles * centerCoord.x,
5622
- numTiles * centerCoord.y,
5623
- 0
5624
- ];
5625
- const distanceToCenter2d = Math.hypot(centerCoord.x - cameraCoord.x, centerCoord.y - cameraCoord.y);
5626
- const distanceZ = Math.abs(centerCoord.z - cameraCoord.z);
5627
- const distanceToCenter3d = Math.hypot(distanceToCenter2d, distanceZ);
5628
- const newRootTile = (wrap) => {
5629
- return {
5630
- zoom: 0,
5631
- x: 0,
5632
- y: 0,
5633
- wrap,
5634
- fullyVisible: false
5635
- };
5636
- };
5637
- const stack = [];
5638
- const result = [];
5639
- if (transform.renderWorldCopies && detailsProvider.allowWorldCopies()) for (let i = 1; i <= 3; i++) {
5640
- stack.push(newRootTile(-i));
5641
- stack.push(newRootTile(i));
5520
+ //#region src/util/primitives/aabb.ts
5521
+ var Aabb = class Aabb {
5522
+ constructor(min_, max_) {
5523
+ this.min = min_;
5524
+ this.max = max_;
5525
+ this.center = scale$1([], add([], this.min, this.max), .5);
5642
5526
  }
5643
- stack.push(newRootTile(0));
5644
- while (stack.length > 0) {
5645
- const it = stack.pop();
5646
- const x = it.x;
5647
- const y = it.y;
5648
- let fullyVisible = it.fullyVisible;
5649
- const tileID = {
5650
- x,
5651
- y,
5652
- z: it.zoom
5653
- };
5654
- const boundingVolume = detailsProvider.getTileBoundingVolume(tileID, it.wrap, elevationForTileCulling, options);
5655
- if (!fullyVisible) {
5656
- const intersectResult = isTileVisible(frustum, boundingVolume, plane);
5657
- if (intersectResult === 0) continue;
5658
- fullyVisible = intersectResult === 2;
5527
+ quadrant(index) {
5528
+ const split = [index % 2 === 0, index < 2];
5529
+ const qMin = clone(this.min);
5530
+ const qMax = clone(this.max);
5531
+ for (let axis = 0; axis < split.length; axis++) {
5532
+ qMin[axis] = split[axis] ? this.min[axis] : this.center[axis];
5533
+ qMax[axis] = split[axis] ? this.center[axis] : this.max[axis];
5659
5534
  }
5660
- const distToTile2d = detailsProvider.distanceToTile2d(cameraCoord.x, cameraCoord.y, tileID, boundingVolume);
5661
- let thisTileDesiredZ = desiredZ;
5662
- if (allowVariableZoom) thisTileDesiredZ = (options.calculateTileZoom || defaultCalculateTileZoom)(transform.zoom + scaleZoom(transform.tileSize / options.tileSize), distToTile2d, distanceZ, distanceToCenter3d, transform.fov);
5663
- thisTileDesiredZ = (options.roundZoom ? Math.round : Math.floor)(thisTileDesiredZ);
5664
- thisTileDesiredZ = Math.max(0, thisTileDesiredZ);
5665
- const z = Math.min(thisTileDesiredZ, maxZoom);
5666
- it.wrap = detailsProvider.getWrap(centerCoord, tileID, it.wrap);
5667
- if (it.zoom >= z) {
5668
- if (it.zoom < minZoom) continue;
5669
- const dz = nominalZ - it.zoom;
5670
- const dx = cameraPoint[0] - .5 - (x << dz);
5671
- const dy = cameraPoint[1] - .5 - (y << dz);
5672
- const overscaledZ = options.reparseOverscaled ? Math.max(it.zoom, thisTileDesiredZ) : it.zoom;
5673
- result.push({
5674
- tileID: new OverscaledTileID(it.zoom === maxZoom ? overscaledZ : it.zoom, it.wrap, it.zoom, x, y),
5675
- distanceSq: sqrLen([centerPoint[0] - .5 - x, centerPoint[1] - .5 - y]),
5676
- tileDistanceToCamera: Math.sqrt(dx * dx + dy * dy)
5677
- });
5678
- continue;
5535
+ qMax[2] = this.max[2];
5536
+ return new Aabb(qMin, qMax);
5537
+ }
5538
+ distanceX(point) {
5539
+ return Math.max(Math.min(this.max[0], point[0]), this.min[0]) - point[0];
5540
+ }
5541
+ distanceY(point) {
5542
+ return Math.max(Math.min(this.max[1], point[1]), this.min[1]) - point[1];
5543
+ }
5544
+ /**
5545
+ * Performs a frustum-aabb intersection test.
5546
+ */
5547
+ intersectsFrustum(frustum) {
5548
+ let fullyInside = true;
5549
+ for (const plane of frustum.planes) {
5550
+ const planeIntersection = this.intersectsPlane(plane);
5551
+ if (planeIntersection === 0) return 0;
5552
+ if (planeIntersection === 1) fullyInside = false;
5679
5553
  }
5680
- for (let i = 0; i < 4; i++) {
5681
- const childX = (x << 1) + i % 2;
5682
- const childY = (y << 1) + (i >> 1);
5683
- const childZ = it.zoom + 1;
5684
- stack.push({
5685
- zoom: childZ,
5686
- x: childX,
5687
- y: childY,
5688
- wrap: it.wrap,
5689
- fullyVisible
5690
- });
5554
+ if (fullyInside) return 2;
5555
+ if (frustum.aabb.min[0] > this.max[0] || frustum.aabb.min[1] > this.max[1] || frustum.aabb.min[2] > this.max[2] || frustum.aabb.max[0] < this.min[0] || frustum.aabb.max[1] < this.min[1] || frustum.aabb.max[2] < this.min[2]) return 0;
5556
+ return 1;
5557
+ }
5558
+ /**
5559
+ * Performs a halfspace-aabb intersection test.
5560
+ */
5561
+ intersectsPlane(plane) {
5562
+ let distMin = plane[3];
5563
+ let distMax = plane[3];
5564
+ for (let i = 0; i < 3; i++) if (plane[i] > 0) {
5565
+ distMin += plane[i] * this.min[i];
5566
+ distMax += plane[i] * this.max[i];
5567
+ } else {
5568
+ distMax += plane[i] * this.min[i];
5569
+ distMin += plane[i] * this.max[i];
5691
5570
  }
5571
+ if (distMin >= 0) return 2;
5572
+ if (distMax < 0) return 0;
5573
+ return 1;
5692
5574
  }
5693
- return result.sort((a, b) => a.distanceSq - b.distanceSq).map((a) => a.tileID);
5694
- }
5575
+ };
5695
5576
  //#endregion
5696
- //#region src/tile/tile_manager_raster.ts
5697
- function isRasterType(type) {
5698
- return type === "raster" || type === "image" || type === "video";
5699
- }
5700
- /**
5701
- * Designate fading bases and parents using a many-to-one relationship where the lower children fade in/out
5702
- * with their parents. Raster shaders are not currently designed for a one-to-many fade relationship.
5703
- *
5577
+ //#region src/util/primitives/frustum.ts
5578
+ var Frustum = class Frustum {
5579
+ constructor(points, planes, aabb) {
5580
+ this.points = points;
5581
+ this.planes = planes;
5582
+ this.aabb = aabb;
5583
+ }
5584
+ static fromInvProjectionMatrix(invProj, worldSize = 1, zoom = 0, horizonPlane, flippedNearFar) {
5585
+ const clipSpaceCorners = [
5586
+ [
5587
+ -1,
5588
+ 1,
5589
+ -1,
5590
+ 1
5591
+ ],
5592
+ [
5593
+ 1,
5594
+ 1,
5595
+ -1,
5596
+ 1
5597
+ ],
5598
+ [
5599
+ 1,
5600
+ -1,
5601
+ -1,
5602
+ 1
5603
+ ],
5604
+ [
5605
+ -1,
5606
+ -1,
5607
+ -1,
5608
+ 1
5609
+ ],
5610
+ [
5611
+ -1,
5612
+ 1,
5613
+ 1,
5614
+ 1
5615
+ ],
5616
+ [
5617
+ 1,
5618
+ 1,
5619
+ 1,
5620
+ 1
5621
+ ],
5622
+ [
5623
+ 1,
5624
+ -1,
5625
+ 1,
5626
+ 1
5627
+ ],
5628
+ [
5629
+ -1,
5630
+ -1,
5631
+ 1,
5632
+ 1
5633
+ ]
5634
+ ];
5635
+ const frustumPlanePointIndices = flippedNearFar ? [
5636
+ [
5637
+ 6,
5638
+ 5,
5639
+ 4
5640
+ ],
5641
+ [
5642
+ 0,
5643
+ 1,
5644
+ 2
5645
+ ],
5646
+ [
5647
+ 0,
5648
+ 3,
5649
+ 7
5650
+ ],
5651
+ [
5652
+ 2,
5653
+ 1,
5654
+ 5
5655
+ ],
5656
+ [
5657
+ 3,
5658
+ 2,
5659
+ 6
5660
+ ],
5661
+ [
5662
+ 0,
5663
+ 4,
5664
+ 5
5665
+ ]
5666
+ ] : [
5667
+ [
5668
+ 0,
5669
+ 1,
5670
+ 2
5671
+ ],
5672
+ [
5673
+ 6,
5674
+ 5,
5675
+ 4
5676
+ ],
5677
+ [
5678
+ 0,
5679
+ 3,
5680
+ 7
5681
+ ],
5682
+ [
5683
+ 2,
5684
+ 1,
5685
+ 5
5686
+ ],
5687
+ [
5688
+ 3,
5689
+ 2,
5690
+ 6
5691
+ ],
5692
+ [
5693
+ 0,
5694
+ 4,
5695
+ 5
5696
+ ]
5697
+ ];
5698
+ const scale = Math.pow(2, zoom);
5699
+ const frustumCoords = clipSpaceCorners.map((v) => unprojectClipSpacePoint(v, invProj, worldSize, scale));
5700
+ if (horizonPlane) adjustFarPlaneByHorizonPlane(frustumCoords, frustumPlanePointIndices[0], horizonPlane, flippedNearFar);
5701
+ const frustumPlanes = frustumPlanePointIndices.map((p) => {
5702
+ const a = sub([], frustumCoords[p[0]], frustumCoords[p[1]]);
5703
+ const b = sub([], frustumCoords[p[2]], frustumCoords[p[1]]);
5704
+ const n = normalize([], cross([], a, b));
5705
+ const d = -dot(n, frustumCoords[p[1]]);
5706
+ return n.concat(d);
5707
+ });
5708
+ const min = [
5709
+ Number.POSITIVE_INFINITY,
5710
+ Number.POSITIVE_INFINITY,
5711
+ Number.POSITIVE_INFINITY
5712
+ ];
5713
+ const max = [
5714
+ Number.NEGATIVE_INFINITY,
5715
+ Number.NEGATIVE_INFINITY,
5716
+ Number.NEGATIVE_INFINITY
5717
+ ];
5718
+ for (const p of frustumCoords) for (let i = 0; i < 3; i++) {
5719
+ min[i] = Math.min(min[i], p[i]);
5720
+ max[i] = Math.max(max[i], p[i]);
5721
+ }
5722
+ return new Frustum(frustumCoords, frustumPlanes, new Aabb(min, max));
5723
+ }
5724
+ };
5725
+ function unprojectClipSpacePoint(point, invProj, worldSize, scale) {
5726
+ const v = transformMat4([], point, invProj);
5727
+ const s = 1 / v[3] / worldSize * scale;
5728
+ return mul(v, v, [
5729
+ s,
5730
+ s,
5731
+ 1 / v[3],
5732
+ s
5733
+ ]);
5734
+ }
5735
+ /**
5736
+ * Modifies points in the supplied `frustumCoords` array so that the frustum's far plane only lies as far as the horizon,
5737
+ * which improves frustum culling effectiveness.
5738
+ * @param frustumCoords - Points of the frustum.
5739
+ * @param nearPlanePointsIndices - Which indices in the `frustumCoords` form the near plane.
5740
+ * @param horizonPlane - The horizon plane.
5741
+ */
5742
+ function adjustFarPlaneByHorizonPlane(frustumCoords, nearPlanePointsIndices, horizonPlane, flippedNearFar) {
5743
+ const nearPlanePointsOffset = flippedNearFar ? 4 : 0;
5744
+ const farPlanePointsOffset = flippedNearFar ? 0 : 4;
5745
+ let maxDist = 0;
5746
+ const cornerRayLengths = [];
5747
+ const cornerRayNormalizedDirections = [];
5748
+ for (let i = 0; i < 4; i++) {
5749
+ const dir = sub([], frustumCoords[i + farPlanePointsOffset], frustumCoords[i + nearPlanePointsOffset]);
5750
+ const len = length(dir);
5751
+ scale$1(dir, dir, 1 / len);
5752
+ cornerRayLengths.push(len);
5753
+ cornerRayNormalizedDirections.push(dir);
5754
+ }
5755
+ for (let i = 0; i < 4; i++) {
5756
+ const dist = rayPlaneIntersection(frustumCoords[i + nearPlanePointsOffset], cornerRayNormalizedDirections[i], horizonPlane);
5757
+ if (dist !== null && dist >= 0) maxDist = Math.max(maxDist, dist);
5758
+ else maxDist = Math.max(maxDist, cornerRayLengths[i]);
5759
+ }
5760
+ const nearPlaneNormalized = getNormalizedNearPlane(frustumCoords, nearPlanePointsIndices);
5761
+ const idealFarPlaneDistanceFromNearPlane = getIdealNearFarPlaneDistance(horizonPlane, nearPlaneNormalized);
5762
+ if (idealFarPlaneDistanceFromNearPlane !== null) {
5763
+ const idealCornerRayLength = idealFarPlaneDistanceFromNearPlane / dot(cornerRayNormalizedDirections[0], nearPlaneNormalized);
5764
+ maxDist = Math.min(maxDist, idealCornerRayLength);
5765
+ }
5766
+ for (let i = 0; i < 4; i++) {
5767
+ const targetLength = Math.min(maxDist, cornerRayLengths[i]);
5768
+ frustumCoords[i + farPlanePointsOffset] = [
5769
+ frustumCoords[i + nearPlanePointsOffset][0] + cornerRayNormalizedDirections[i][0] * targetLength,
5770
+ frustumCoords[i + nearPlanePointsOffset][1] + cornerRayNormalizedDirections[i][1] * targetLength,
5771
+ frustumCoords[i + nearPlanePointsOffset][2] + cornerRayNormalizedDirections[i][2] * targetLength,
5772
+ 1
5773
+ ];
5774
+ }
5775
+ }
5776
+ /**
5777
+ * Returns the near plane equation with unit length direction.
5778
+ * @param frustumCoords - Points of the frustum.
5779
+ * @param nearPlanePointsIndices - Which indices in the `frustumCoords` form the near plane.
5780
+ */
5781
+ function getNormalizedNearPlane(frustumCoords, nearPlanePointsIndices) {
5782
+ const nearPlaneA = sub([], frustumCoords[nearPlanePointsIndices[0]], frustumCoords[nearPlanePointsIndices[1]]);
5783
+ const nearPlaneB = sub([], frustumCoords[nearPlanePointsIndices[2]], frustumCoords[nearPlanePointsIndices[1]]);
5784
+ const nearPlaneNormalized = [
5785
+ 0,
5786
+ 0,
5787
+ 0,
5788
+ 0
5789
+ ];
5790
+ normalize(nearPlaneNormalized, cross([], nearPlaneA, nearPlaneB));
5791
+ nearPlaneNormalized[3] = -dot(nearPlaneNormalized, frustumCoords[nearPlanePointsIndices[0]]);
5792
+ return nearPlaneNormalized;
5793
+ }
5794
+ /**
5795
+ * Returns the ideal distance between the frustum's near and far plane so that the far plane only lies as far as the horizon.
5796
+ */
5797
+ function getIdealNearFarPlaneDistance(horizonPlane, nearPlaneNormalized) {
5798
+ const horizonPlaneLen = len(horizonPlane);
5799
+ const normalizedHorizonPlane = scale$2([], horizonPlane, 1 / horizonPlaneLen);
5800
+ const projectedViewDirection = sub([], nearPlaneNormalized, scale$1([], normalizedHorizonPlane, dot(nearPlaneNormalized, normalizedHorizonPlane)));
5801
+ const projectedViewLength = len(projectedViewDirection);
5802
+ if (projectedViewLength > 0) {
5803
+ const horizonCircleRadius = Math.sqrt(1 - normalizedHorizonPlane[3] * normalizedHorizonPlane[3]);
5804
+ const horizonCircleCenter = scale$1([], normalizedHorizonPlane, -normalizedHorizonPlane[3]);
5805
+ const pointFurthestOnHorizonCircle = add([], horizonCircleCenter, scale$1([], projectedViewDirection, horizonCircleRadius / projectedViewLength));
5806
+ return pointPlaneSignedDistance(nearPlaneNormalized, pointFurthestOnHorizonCircle);
5807
+ } else return null;
5808
+ }
5809
+ //#endregion
5810
+ //#region src/geo/projection/covering_tiles.ts
5811
+ /**
5812
+ * A simple/heuristic function that returns whether the tile is visible under the current transform.
5813
+ * @returns an {@link IntersectionResult}.
5814
+ */
5815
+ function isTileVisible(frustum, tileBoundingVolume, plane) {
5816
+ const frustumTest = tileBoundingVolume.intersectsFrustum(frustum);
5817
+ if (!plane || frustumTest === 0) return frustumTest;
5818
+ const planeTest = tileBoundingVolume.intersectsPlane(plane);
5819
+ if (planeTest === 0) return 0;
5820
+ if (frustumTest === 2 && planeTest === 2) return 2;
5821
+ return 1;
5822
+ }
5823
+ /**
5824
+ * Definite integral of cos(x)^p. The analytical solution is described in `developer-guides/covering-tiles.md`,
5825
+ * but here the integral is evaluated numerically.
5826
+ * @param p - the power to raise cos(x) to inside the integral
5827
+ * @param x1 - the starting point of the integral.
5828
+ * @param x2 - the ending point of the integral.
5829
+ * @return the integral of cos(x)^p from x=x1 to x=x2
5830
+ */
5831
+ function integralOfCosXByP(p, x1, x2) {
5832
+ const numPoints = 10;
5833
+ let sum = 0;
5834
+ const dx = (x2 - x1) / numPoints;
5835
+ for (let i = 0; i < numPoints; i++) {
5836
+ const x = x1 + (i + .5) / numPoints * (x2 - x1);
5837
+ sum += dx * Math.pow(Math.cos(x), p);
5838
+ }
5839
+ return sum;
5840
+ }
5841
+ function createCalculateTileZoomFunction(maxZoomLevelsOnScreen, tileCountMaxMinRatio) {
5842
+ return function(requestedCenterZoom, distanceToTile2D, distanceToTileZ, distanceToCenter3D, cameraVerticalFOV) {
5843
+ /**
5844
+ * Controls how tiles are loaded at high pitch angles. Higher numbers cause fewer, lower resolution
5845
+ * tiles to be loaded. Calculate the value that will result in the selected number of zoom levels in
5846
+ * the worst-case condition (when the horizon is at the top of the screen). For more information, see
5847
+ * `developer-guides/covering-tiles.md`
5848
+ */
5849
+ const pitchTileLoadingBehavior = 2 * ((maxZoomLevelsOnScreen - 1) / scaleZoom(Math.cos(degreesToRadians(maxMercatorHorizonAngle - cameraVerticalFOV)) / Math.cos(degreesToRadians(maxMercatorHorizonAngle))) - 1);
5850
+ const centerPitch = Math.acos(distanceToTileZ / distanceToCenter3D);
5851
+ const tileCountPitch0 = 2 * integralOfCosXByP(pitchTileLoadingBehavior - 1, 0, degreesToRadians(cameraVerticalFOV / 2));
5852
+ const highestPitch = Math.min(degreesToRadians(maxMercatorHorizonAngle), centerPitch + degreesToRadians(cameraVerticalFOV / 2));
5853
+ const lowestPitch = Math.min(highestPitch, centerPitch - degreesToRadians(cameraVerticalFOV / 2));
5854
+ const tileCount = integralOfCosXByP(pitchTileLoadingBehavior - 1, lowestPitch, highestPitch);
5855
+ const thisTilePitch = Math.atan(distanceToTile2D / distanceToTileZ);
5856
+ const distanceToTile3D = Math.hypot(distanceToTile2D, distanceToTileZ);
5857
+ let thisTileDesiredZ = requestedCenterZoom;
5858
+ thisTileDesiredZ = thisTileDesiredZ + scaleZoom(distanceToCenter3D / distanceToTile3D / Math.max(.5, Math.cos(degreesToRadians(cameraVerticalFOV / 2))));
5859
+ thisTileDesiredZ += pitchTileLoadingBehavior * scaleZoom(Math.cos(thisTilePitch)) / 2;
5860
+ thisTileDesiredZ -= scaleZoom(Math.max(1, tileCount / tileCountPitch0 / tileCountMaxMinRatio)) / 2;
5861
+ return thisTileDesiredZ;
5862
+ };
5863
+ }
5864
+ const defaultCalculateTileZoom = createCalculateTileZoomFunction(9.314, 3);
5865
+ /**
5866
+ * Return what zoom level of a tile source would most closely cover the tiles displayed by this transform.
5867
+ * @param options - The options, most importantly the source's tile size.
5868
+ * @returns An integer zoom level at which all tiles will be visible.
5869
+ */
5870
+ function coveringZoomLevel(transform, options) {
5871
+ const z = (options.roundZoom ? Math.round : Math.floor)(transform.zoom + scaleZoom(transform.tileSize / options.tileSize));
5872
+ return Math.max(0, z);
5873
+ }
5874
+ /**
5875
+ * Without terrain, `getTileBoundingVolume` has no knowledge of extruded features
5876
+ * (eg. 3D buildings): every tile's bounding box is flat at the camera's `elevation`.
5877
+ * That's a fine approximation of what's visible for most views, but it breaks down
5878
+ * as the frustum's bottom edge approaches horizontal (which depends on both `pitch`
5879
+ * and `fov`, not pitch alone) - a tall building can still be poking up into view
5880
+ * long after its tile's ground point has dropped out of the frustum.
5881
+ *
5882
+ * This is an assumed upper bound on real-world feature height (in metres), used to
5883
+ * grow the elevation used for tile culling as that bottom edge nears horizontal, so
5884
+ * such tiles are not dropped too early. It has no effect away from that edge case.
5885
+ */
5886
+ const ASSUMED_MAX_FEATURE_HEIGHT_METERS = 500;
5887
+ /**
5888
+ * Angle between the frustum's bottom edge and the mercator horizon below which
5889
+ * the culling elevation starts to grow.
5890
+ */
5891
+ const TILE_CULLING_HORIZON_ONSET_DEGREES = 15;
5892
+ /**
5893
+ * Returns the elevation to use when computing tile bounding volumes for culling:
5894
+ * `transform.elevation`, growing by up to the greater of
5895
+ * `ASSUMED_MAX_FEATURE_HEIGHT_METERS` and `maxContentElevation` (when provided)
5896
+ * as the frustum's bottom edge approaches the horizon, where a ground-level
5897
+ * bounding box would cull tiles whose extruded features are still visible.
5898
+ */
5899
+ function getElevationForTileCulling(transform, maxContentElevation) {
5900
+ const bottomEdgeDegreesAboveHorizontal = maxMercatorHorizonAngle - transform.pitch - transform.fov / 2;
5901
+ const proximityToHorizon = clamp((TILE_CULLING_HORIZON_ONSET_DEGREES - bottomEdgeDegreesAboveHorizontal) / TILE_CULLING_HORIZON_ONSET_DEGREES, 0, 1);
5902
+ const maxFeatureHeight = Math.max(ASSUMED_MAX_FEATURE_HEIGHT_METERS, maxContentElevation ?? 0);
5903
+ return transform.elevation + proximityToHorizon * maxFeatureHeight;
5904
+ }
5905
+ /**
5906
+ * Returns a copy of the frustum with its far plane moved away from the camera by `distance`.
5907
+ * Each far corner travels along its own camera ray until it reaches the pushed plane, so the
5908
+ * result stays a pyramid and the corners stay consistent with the side planes. The globe
5909
+ * frustum's far plane is fitted to the surface horizon, so elevated content beyond it would
5910
+ * otherwise be culled while still visible.
5911
+ */
5912
+ function pushFrustumFarPlane(frustum, distance, cameraPos) {
5913
+ const far = frustum.planes[1];
5914
+ const points = frustum.points.map((p) => {
5915
+ const distanceToFar = far[0] * p[0] + far[1] * p[1] + far[2] * p[2] + far[3];
5916
+ if (Math.abs(distanceToFar) > 1e-6) return p;
5917
+ const ray = [
5918
+ p[0] - cameraPos[0],
5919
+ p[1] - cameraPos[1],
5920
+ p[2] - cameraPos[2]
5921
+ ];
5922
+ const rayDotNormal = far[0] * ray[0] + far[1] * ray[1] + far[2] * ray[2];
5923
+ if (rayDotNormal >= -1e-9) return p;
5924
+ const scale = distance / -rayDotNormal;
5925
+ return [
5926
+ p[0] + ray[0] * scale,
5927
+ p[1] + ray[1] * scale,
5928
+ p[2] + ray[2] * scale,
5929
+ p[3]
5930
+ ];
5931
+ });
5932
+ const planes = frustum.planes.map((p, i) => i === 1 ? [
5933
+ p[0],
5934
+ p[1],
5935
+ p[2],
5936
+ p[3] + distance
5937
+ ] : p);
5938
+ const min = [
5939
+ Number.POSITIVE_INFINITY,
5940
+ Number.POSITIVE_INFINITY,
5941
+ Number.POSITIVE_INFINITY
5942
+ ];
5943
+ const max = [
5944
+ Number.NEGATIVE_INFINITY,
5945
+ Number.NEGATIVE_INFINITY,
5946
+ Number.NEGATIVE_INFINITY
5947
+ ];
5948
+ for (const p of points) for (let i = 0; i < 3; i++) {
5949
+ min[i] = Math.min(min[i], p[i]);
5950
+ max[i] = Math.max(max[i], p[i]);
5951
+ }
5952
+ return new Frustum(points, planes, new Aabb(min, max));
5953
+ }
5954
+ /**
5955
+ * Returns a list of tiles that optimally covers the screen. Adapted for globe projection.
5956
+ * Correctly handles LOD when moving over the antimeridian.
5957
+ *
5958
+ * The horizon culling plane and the frustum's far plane both assume content sits on the
5959
+ * surface. When `options.maxContentElevation` is set, a point elevated to radius r (in planet
5960
+ * radii) stays visible up to acos(1/r) beyond the surface horizon and up to sqrt(r^2-1)
5961
+ * farther away, so both are pushed back accordingly; without this, tiles under highly
5962
+ * elevated symbols would be dropped while the symbols are still in view.
5963
+ * @param transform - The transform instance.
5964
+ * @param frustum - The covering frustum.
5965
+ * @param plane - The clipping plane used by globe transform, or null.
5966
+ * @param cameraCoord - The x, y, z position of the camera in MercatorCoordinates.
5967
+ * @param centerCoord - The x, y, z position of the center point in MercatorCoordinates.
5968
+ * @param options - Additional coveringTiles options.
5969
+ * @param details - Interface to define required helper functions.
5970
+ * @returns A list of tile coordinates, ordered by ascending distance from camera.
5971
+ */
5972
+ function coveringTiles(transform, options) {
5973
+ let frustum = transform.getCameraFrustum();
5974
+ let plane = transform.getClippingPlane();
5975
+ if (plane && options.maxContentElevation > 0) {
5976
+ const len = Math.hypot(plane[0], plane[1], plane[2]);
5977
+ if (len > 0) {
5978
+ const shellRadius = 1 + options.maxContentElevation / earthRadius;
5979
+ const horizonCos = clamp(-plane[3] / len, -1, 1);
5980
+ const shellCos = Math.cos(Math.acos(horizonCos) + Math.acos(1 / shellRadius));
5981
+ plane = [
5982
+ plane[0],
5983
+ plane[1],
5984
+ plane[2],
5985
+ -shellCos * len
5986
+ ];
5987
+ frustum = pushFrustumFarPlane(frustum, Math.sqrt(shellRadius * shellRadius - 1), transform.cameraPosition);
5988
+ }
5989
+ }
5990
+ const cameraCoord = cameraMercatorCoordinate(transform);
5991
+ const centerCoord = MercatorCoordinate.fromLngLat(transform.center, transform.elevation);
5992
+ const elevationForTileCulling = getElevationForTileCulling(transform, options.maxContentElevation);
5993
+ const detailsProvider = transform.getCoveringTilesDetailsProvider();
5994
+ const allowVariableZoom = detailsProvider.allowVariableZoom(transform, options);
5995
+ const desiredZ = coveringZoomLevel(transform, options);
5996
+ const minZoom = options.minzoom || 0;
5997
+ const maxZoom = options.maxzoom !== void 0 ? options.maxzoom : transform.maxZoom;
5998
+ const nominalZ = Math.min(Math.max(0, desiredZ), maxZoom);
5999
+ const numTiles = Math.pow(2, nominalZ);
6000
+ const cameraPoint = [
6001
+ numTiles * cameraCoord.x,
6002
+ numTiles * cameraCoord.y,
6003
+ 0
6004
+ ];
6005
+ const centerPoint = [
6006
+ numTiles * centerCoord.x,
6007
+ numTiles * centerCoord.y,
6008
+ 0
6009
+ ];
6010
+ const distanceToCenter2d = Math.hypot(centerCoord.x - cameraCoord.x, centerCoord.y - cameraCoord.y);
6011
+ const distanceZ = Math.abs(centerCoord.z - cameraCoord.z);
6012
+ const distanceToCenter3d = Math.hypot(distanceToCenter2d, distanceZ);
6013
+ const newRootTile = (wrap) => {
6014
+ return {
6015
+ zoom: 0,
6016
+ x: 0,
6017
+ y: 0,
6018
+ wrap,
6019
+ fullyVisible: false
6020
+ };
6021
+ };
6022
+ const stack = [];
6023
+ const result = [];
6024
+ if (transform.renderWorldCopies && detailsProvider.allowWorldCopies()) for (let i = 1; i <= 3; i++) {
6025
+ stack.push(newRootTile(-i));
6026
+ stack.push(newRootTile(i));
6027
+ }
6028
+ stack.push(newRootTile(0));
6029
+ while (stack.length > 0) {
6030
+ const it = stack.pop();
6031
+ const x = it.x;
6032
+ const y = it.y;
6033
+ let fullyVisible = it.fullyVisible;
6034
+ const tileID = {
6035
+ x,
6036
+ y,
6037
+ z: it.zoom
6038
+ };
6039
+ const boundingVolume = detailsProvider.getTileBoundingVolume(tileID, it.wrap, elevationForTileCulling, options);
6040
+ if (!fullyVisible) {
6041
+ const intersectResult = isTileVisible(frustum, boundingVolume, plane);
6042
+ if (intersectResult === 0) continue;
6043
+ fullyVisible = intersectResult === 2;
6044
+ }
6045
+ const distToTile2d = detailsProvider.distanceToTile2d(cameraCoord.x, cameraCoord.y, tileID, boundingVolume);
6046
+ let thisTileDesiredZ = desiredZ;
6047
+ if (allowVariableZoom) thisTileDesiredZ = (options.calculateTileZoom || defaultCalculateTileZoom)(transform.zoom + scaleZoom(transform.tileSize / options.tileSize), distToTile2d, distanceZ, distanceToCenter3d, transform.fov);
6048
+ thisTileDesiredZ = (options.roundZoom ? Math.round : Math.floor)(thisTileDesiredZ);
6049
+ thisTileDesiredZ = Math.max(0, thisTileDesiredZ);
6050
+ const z = Math.min(thisTileDesiredZ, maxZoom);
6051
+ it.wrap = detailsProvider.getWrap(centerCoord, tileID, it.wrap);
6052
+ if (it.zoom >= z) {
6053
+ if (it.zoom < minZoom) continue;
6054
+ const dz = nominalZ - it.zoom;
6055
+ const dx = cameraPoint[0] - .5 - (x << dz);
6056
+ const dy = cameraPoint[1] - .5 - (y << dz);
6057
+ const overscaledZ = options.reparseOverscaled ? Math.max(it.zoom, thisTileDesiredZ) : it.zoom;
6058
+ result.push({
6059
+ tileID: new OverscaledTileID(it.zoom === maxZoom ? overscaledZ : it.zoom, it.wrap, it.zoom, x, y),
6060
+ distanceSq: sqrLen([centerPoint[0] - .5 - x, centerPoint[1] - .5 - y]),
6061
+ tileDistanceToCamera: Math.sqrt(dx * dx + dy * dy)
6062
+ });
6063
+ continue;
6064
+ }
6065
+ for (let i = 0; i < 4; i++) {
6066
+ const childX = (x << 1) + i % 2;
6067
+ const childY = (y << 1) + (i >> 1);
6068
+ const childZ = it.zoom + 1;
6069
+ stack.push({
6070
+ zoom: childZ,
6071
+ x: childX,
6072
+ y: childY,
6073
+ wrap: it.wrap,
6074
+ fullyVisible
6075
+ });
6076
+ }
6077
+ }
6078
+ return result.sort((a, b) => a.distanceSq - b.distanceSq).map((a) => a.tileID);
6079
+ }
6080
+ //#endregion
6081
+ //#region src/tile/tile_manager_raster.ts
6082
+ function isRasterType(type) {
6083
+ return type === "raster" || type === "image" || type === "video";
6084
+ }
6085
+ /**
6086
+ * Designate fading bases and parents using a many-to-one relationship where the lower children fade in/out
6087
+ * with their parents. Raster shaders are not currently designed for a one-to-many fade relationship.
6088
+ *
5704
6089
  * Tiles that are candidates for fading out must be loaded and rendered tiles, as loading a tile to then
5705
6090
  * fade it out would not appear smoothly. The first source of truth for tile fading always starts at the
5706
6091
  * ideal tile, which continually changes on map adjustment. The state of the previously rendered ideal
@@ -5946,6 +6331,7 @@ var TileManager = class TileManager extends Evented {
5946
6331
  }
5947
6332
  constructor(id, options, dispatcher) {
5948
6333
  super();
6334
+ this._maxContentElevationSeen = 0;
5949
6335
  this.id = id;
5950
6336
  this.dispatcher = dispatcher;
5951
6337
  this.on("data", (e) => {
@@ -6211,6 +6597,33 @@ var TileManager = class TileManager extends Evented {
6211
6597
  }
6212
6598
  }
6213
6599
  /**
6600
+ * The highest elevation this source's symbols may reach, in meters: `symbol-height-offset`
6601
+ * constants read from the visible symbol layers, data-driven maxima tracked by the loaded
6602
+ * buckets at layout time. The value is a high-water mark: a maximum seen once is kept even
6603
+ * after its tile unloads, otherwise dropping the tile would also drop the reason to keep it,
6604
+ * and the tile could not come back while its content is still visible. The mark resets with
6605
+ * the tiles in `clearTiles`.
6606
+ */
6607
+ _updateMaxContentElevation() {
6608
+ let maxElevation = this._maxContentElevationSeen;
6609
+ const layers = this.map?.style?._layers;
6610
+ if (!layers) return maxElevation;
6611
+ const tiles = this._inViewTiles.getAllTiles();
6612
+ for (const layerId in layers) {
6613
+ const layer = layers[layerId];
6614
+ if (layer.type !== "symbol" || layer.source !== this.id || layer.isHidden(this.transform.zoom)) continue;
6615
+ const symbolLayer = layer;
6616
+ if (!symbolLayer.layout) continue;
6617
+ maxElevation = Math.max(maxElevation, symbolLayer.layout.get("symbol-height-offset").constantOr(0));
6618
+ for (const tile of tiles) {
6619
+ const bucket = tile.getBucket(layer);
6620
+ if (bucket && bucket.maxHeightOffset > maxElevation) maxElevation = bucket.maxHeightOffset;
6621
+ }
6622
+ }
6623
+ this._maxContentElevationSeen = maxElevation;
6624
+ return maxElevation;
6625
+ }
6626
+ /**
6214
6627
  * Removes tiles that are outside the viewport and adds new tiles that
6215
6628
  * are inside the viewport.
6216
6629
  */
@@ -6231,7 +6644,8 @@ var TileManager = class TileManager extends Evented {
6231
6644
  roundZoom: this.usedForTerrain ? false : this._source.roundZoom,
6232
6645
  reparseOverscaled: this._source.reparseOverscaled,
6233
6646
  terrain,
6234
- calculateTileZoom: this._source.calculateTileZoom
6647
+ calculateTileZoom: this._source.calculateTileZoom,
6648
+ maxContentElevation: this._updateMaxContentElevation()
6235
6649
  });
6236
6650
  if (this._source.hasTile) idealTileIDs = idealTileIDs.filter((coord) => this._source.hasTile(coord));
6237
6651
  }
@@ -6424,11 +6838,20 @@ var TileManager = class TileManager extends Evented {
6424
6838
  this._didEmitContent = true;
6425
6839
  }
6426
6840
  /**
6841
+ * Forgets the recorded maximum content elevation, so the next update recomputes it from the
6842
+ * current layers and loaded tiles. Called when a symbol layer is removed, since the removed
6843
+ * layer's heights would otherwise keep expanding tile coverage.
6844
+ */
6845
+ resetMaxContentElevation() {
6846
+ this._maxContentElevationSeen = 0;
6847
+ }
6848
+ /**
6427
6849
  * Remove all tiles from this pyramid
6428
6850
  */
6429
6851
  clearTiles() {
6430
6852
  this._shouldReloadOnResume = false;
6431
6853
  this._paused = false;
6854
+ this.resetMaxContentElevation();
6432
6855
  for (const id of this._inViewTiles.getAllIds()) this._removeTile(id);
6433
6856
  this._outOfViewCache.reset();
6434
6857
  }
@@ -6967,15 +7390,15 @@ function getTileSkewVectors(transform) {
6967
7390
  const vecSouth = create$3();
6968
7391
  vecSouth[0] = -cosBearing * cosPitch * sinRoll - sinBearing * cosRoll;
6969
7392
  vecSouth[1] = -sinBearing * cosPitch * sinRoll + cosBearing * cosRoll;
6970
- const vecSouthLen = length(vecSouth);
7393
+ const vecSouthLen = length$1(vecSouth);
6971
7394
  if (vecSouthLen < 1e-9) zero(vecSouth);
6972
- else scale$1(vecSouth, vecSouth, 1 / vecSouthLen);
7395
+ else scale$3(vecSouth, vecSouth, 1 / vecSouthLen);
6973
7396
  const vecEast = create$3();
6974
7397
  vecEast[0] = cosBearing * cosPitch * cosRoll - sinBearing * sinRoll;
6975
7398
  vecEast[1] = sinBearing * cosPitch * cosRoll + cosBearing * sinRoll;
6976
- const vecEastLen = length(vecEast);
7399
+ const vecEastLen = length$1(vecEast);
6977
7400
  if (vecEastLen < 1e-9) zero(vecEast);
6978
- else scale$1(vecEast, vecEast, 1 / vecEastLen);
7401
+ else scale$3(vecEast, vecEast, 1 / vecEastLen);
6979
7402
  return {
6980
7403
  vecEast,
6981
7404
  vecSouth
@@ -9035,10 +9458,10 @@ var CrossTileSymbolIndex = class {
9035
9458
  };
9036
9459
  //#endregion
9037
9460
  //#region src/shaders/glsl/_prelude.fragment.glsl.g.ts
9038
- var _prelude_fragment_glsl_g_default = "#ifdef GL_ES\nprecision mediump float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nout highp vec4 fragColor;";
9461
+ var _prelude_fragment_glsl_g_default = "#ifdef GL_ES\nprecision mediump float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nout highp vec4 fragColor;layout(std140) uniform ProjectionUBO {highp mat4 u_projection_matrix;highp mat4 u_projection_fallback_matrix;highp vec4 u_projection_tile_mercator_coords;highp vec4 u_projection_clipping_plane;highp float u_projection_transition;highp int u_projection_clip_antimeridian;};layout(std140) uniform FrameUBO {highp vec2 u_units_to_pixels;highp vec2 u_world_size;highp float u_camera_to_center_distance;highp float u_symbol_fade_change;highp float u_aspect_ratio;highp float u_device_pixel_ratio;highp vec2 u_viewport_size;highp vec2 u_pixel_extrude_scale;highp float u_pitch;};";
9039
9462
  //#endregion
9040
9463
  //#region src/shaders/glsl/_prelude.vertex.glsl.g.ts
9041
- var _prelude_vertex_glsl_g_default = "#ifdef GL_ES\nprecision highp float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nvec2 unpack_float(const float packedValue) {int packedIntValue=int(packedValue);int v0=packedIntValue/256;return vec2(v0,packedIntValue-v0*256);}vec2 unpack_opacity(const uint packedOpacity) {return vec2(float(packedOpacity >> 1u)/127.0,float(packedOpacity & 1u));}vec4 decode_color(const vec2 encodedColor) {return vec4(unpack_float(encodedColor[0])/255.0,unpack_float(encodedColor[1])/255.0\n);}float unpack_mix_vec2(const vec2 packedValue,const float t) {return mix(packedValue[0],packedValue[1],t);}vec4 unpack_mix_color(const vec4 packedColors,const float t) {vec4 minColor=decode_color(vec2(packedColors[0],packedColors[1]));vec4 maxColor=decode_color(vec2(packedColors[2],packedColors[3]));return mix(minColor,maxColor,t);}vec2 get_pattern_pos(const vec2 pixel_coord_upper,const vec2 pixel_coord_lower,const vec2 pattern_size,const float tile_units_to_pixels,const vec2 pos) {vec2 offset=mod(mod(mod(pixel_coord_upper,pattern_size)*256.0,pattern_size)*256.0+pixel_coord_lower,pattern_size);return (tile_units_to_pixels*pos+offset)/pattern_size;}mat3 rotationMatrixFromAxisAngle(vec3 u,float angle) {float c=cos(angle);float s=sin(angle);float c2=1.0-c;return mat3(u.x*u.x*c2+ c,u.x*u.y*c2-u.z*s,u.x*u.z*c2+u.y*s,u.y*u.x*c2+u.z*s,u.y*u.y*c2+ c,u.y*u.z*c2-u.x*s,u.z*u.x*c2-u.y*s,u.z*u.y*c2+u.x*s,u.z*u.z*c2+ c\n);}\n#ifdef TERRAIN3D\nuniform sampler2D u_terrain;uniform float u_terrain_dim;uniform mat4 u_terrain_matrix;uniform vec4 u_terrain_unpack;uniform float u_terrain_exaggeration;uniform highp sampler2D u_depth;\n#endif\nconst highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitShifts=vec4(1.)/bitSh;highp float unpack(highp vec4 color) {return dot(color,bitShifts);}highp float depthOpacity(vec3 frag) {\n#ifdef TERRAIN3D\nhighp float d=unpack(texture(u_depth,frag.xy*0.5+0.5))+0.0001-frag.z;return 1.0-max(0.0,min(1.0,-d*500.0));\n#else\nreturn 1.0;\n#endif\n}float calculate_visibility(vec4 pos) {\n#ifdef TERRAIN3D\nvec3 frag=pos.xyz/pos.w;highp float d=depthOpacity(frag);if (d > 0.95) return 1.0;return (d+depthOpacity(frag+vec3(0.0,0.01,0.0)))/2.0;\n#else\nreturn 1.0;\n#endif\n}float ele(ivec2 pos) {\n#ifdef TERRAIN3D\nvec4 rgb=(texelFetch(u_terrain,pos,0)*255.0)*u_terrain_unpack;return rgb.r+rgb.g+rgb.b-u_terrain_unpack.a;\n#else\nreturn 0.0;\n#endif\n}float get_elevation(vec2 pos) {\n#ifdef TERRAIN3D\n#ifdef GLOBE\nif ((pos.y <-32767.5) || (pos.y > 32766.5)) {return 0.0;}\n#endif\nvec2 coord=(u_terrain_matrix*vec4(pos,0.0,1.0)).xy*u_terrain_dim+1.0;vec2 f=fract(coord);ivec2 c=ivec2(floor(coord));ivec2 hi=textureSize(u_terrain,0)-1;float tl=ele(clamp(c,ivec2(0),hi));float tr=ele(clamp(c+ivec2(1,0),ivec2(0),hi));float bl=ele(clamp(c+ivec2(0,1),ivec2(0),hi));float br=ele(clamp(c+ivec2(1,1),ivec2(0),hi));float elevation=mix(mix(tl,tr,f.x),mix(bl,br,f.x),f.y);return elevation*u_terrain_exaggeration;\n#else\nreturn 0.0;\n#endif\n}const float PI=3.141592653589793;uniform mat4 u_projection_matrix;";
9464
+ var _prelude_vertex_glsl_g_default = "#ifdef GL_ES\nprecision highp float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nvec2 unpack_float(const float packedValue) {int packedIntValue=int(packedValue);int v0=packedIntValue/256;return vec2(v0,packedIntValue-v0*256);}vec2 unpack_opacity(const uint packedOpacity) {return vec2(float(packedOpacity >> 1u)/127.0,float(packedOpacity & 1u));}vec4 decode_color(const vec2 encodedColor) {return vec4(unpack_float(encodedColor[0])/255.0,unpack_float(encodedColor[1])/255.0\n);}float unpack_mix_vec2(const vec2 packedValue,const float t) {return mix(packedValue[0],packedValue[1],t);}vec4 unpack_mix_color(const vec4 packedColors,const float t) {vec4 minColor=decode_color(vec2(packedColors[0],packedColors[1]));vec4 maxColor=decode_color(vec2(packedColors[2],packedColors[3]));return mix(minColor,maxColor,t);}vec2 get_pattern_pos(const vec2 pixel_coord_upper,const vec2 pixel_coord_lower,const vec2 pattern_size,const float tile_units_to_pixels,const vec2 pos) {vec2 offset=mod(mod(mod(pixel_coord_upper,pattern_size)*256.0,pattern_size)*256.0+pixel_coord_lower,pattern_size);return (tile_units_to_pixels*pos+offset)/pattern_size;}mat3 rotationMatrixFromAxisAngle(vec3 u,float angle) {float c=cos(angle);float s=sin(angle);float c2=1.0-c;return mat3(u.x*u.x*c2+ c,u.x*u.y*c2-u.z*s,u.x*u.z*c2+u.y*s,u.y*u.x*c2+u.z*s,u.y*u.y*c2+ c,u.y*u.z*c2-u.x*s,u.z*u.x*c2-u.y*s,u.z*u.y*c2+u.x*s,u.z*u.z*c2+ c\n);}\n#ifdef TERRAIN3D\nuniform sampler2D u_terrain;uniform highp sampler2D u_depth;layout(std140) uniform TerrainUBO {highp mat4 u_terrain_matrix;highp vec4 u_terrain_unpack;highp float u_terrain_dim;highp float u_terrain_exaggeration;};\n#endif\nconst highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitShifts=vec4(1.)/bitSh;highp float unpack(highp vec4 color) {return dot(color,bitShifts);}highp float depthOpacity(vec3 frag) {\n#ifdef TERRAIN3D\nhighp float d=unpack(texture(u_depth,frag.xy*0.5+0.5))+0.0001-frag.z;return 1.0-max(0.0,min(1.0,-d*500.0));\n#else\nreturn 1.0;\n#endif\n}float calculate_visibility(vec4 pos) {\n#ifdef TERRAIN3D\nvec3 frag=pos.xyz/pos.w;highp float d=depthOpacity(frag);if (d > 0.95) return 1.0;return (d+depthOpacity(frag+vec3(0.0,0.01,0.0)))/2.0;\n#else\nreturn 1.0;\n#endif\n}float ele(ivec2 pos) {\n#ifdef TERRAIN3D\nvec4 rgb=(texelFetch(u_terrain,pos,0)*255.0)*u_terrain_unpack;return rgb.r+rgb.g+rgb.b-u_terrain_unpack.a;\n#else\nreturn 0.0;\n#endif\n}float get_elevation(vec2 pos) {\n#ifdef TERRAIN3D\n#ifdef GLOBE\nif ((pos.y <-32767.5) || (pos.y > 32766.5)) {return 0.0;}\n#endif\nvec2 coord=(u_terrain_matrix*vec4(pos,0.0,1.0)).xy*u_terrain_dim+2.0;vec2 f=fract(coord);ivec2 c=ivec2(floor(coord));ivec2 hi=textureSize(u_terrain,0)-1;float tl=ele(clamp(c,ivec2(0),hi));float tr=ele(clamp(c+ivec2(1,0),ivec2(0),hi));float bl=ele(clamp(c+ivec2(0,1),ivec2(0),hi));float br=ele(clamp(c+ivec2(1,1),ivec2(0),hi));float elevation=mix(mix(tl,tr,f.x),mix(bl,br,f.x),f.y);return elevation*u_terrain_exaggeration;\n#else\nreturn 0.0;\n#endif\n}const float PI=3.141592653589793;\n#define PROJECTION_UBO\nlayout(std140) uniform ProjectionUBO {highp mat4 u_projection_matrix;highp mat4 u_projection_fallback_matrix;highp vec4 u_projection_tile_mercator_coords;highp vec4 u_projection_clipping_plane;highp float u_projection_transition;highp int u_projection_clip_antimeridian;};layout(std140) uniform FrameUBO {highp vec2 u_units_to_pixels;highp vec2 u_world_size;highp float u_camera_to_center_distance;highp float u_symbol_fade_change;highp float u_aspect_ratio;highp float u_device_pixel_ratio;highp vec2 u_viewport_size;highp vec2 u_pixel_extrude_scale;highp float u_pitch;};";
9042
9465
  //#endregion
9043
9466
  //#region src/shaders/glsl/background.fragment.glsl.g.ts
9044
9467
  var background_fragment_glsl_g_default = "uniform vec4 u_color;uniform float u_opacity;void main() {fragColor=u_color*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}";
@@ -9056,7 +9479,7 @@ var background_pattern_vertex_glsl_g_default = "uniform vec2 u_pattern_size_a;un
9056
9479
  var circle_fragment_glsl_g_default = "in vec3 v_data;flat in float v_visibility;\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define mediump float radius\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 stroke_color\n#pragma maplibre: define mediump float stroke_width\n#pragma maplibre: define lowp float stroke_opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump float radius\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 stroke_color\n#pragma maplibre: initialize mediump float stroke_width\n#pragma maplibre: initialize lowp float stroke_opacity\nvec2 extrude=v_data.xy;float extrude_length=length(extrude);float antialiased_blur=v_data.z;float opacity_t=smoothstep(0.0,antialiased_blur,extrude_length-1.0);float color_t=stroke_width < 0.01 ? 0.0 : smoothstep(antialiased_blur,0.0,extrude_length-radius/(radius+stroke_width));fragColor=v_visibility*opacity_t*mix(color*opacity,stroke_color*stroke_opacity,color_t);const float epsilon=0.5/255.0;if (fragColor.r < epsilon && fragColor.g < epsilon && fragColor.b < epsilon && fragColor.a < epsilon) {discard;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}";
9057
9480
  //#endregion
9058
9481
  //#region src/shaders/glsl/circle.vertex.glsl.g.ts
9059
- var circle_vertex_glsl_g_default = "uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform highp float u_globe_extrude_scale;uniform lowp float u_device_pixel_ratio;uniform highp float u_camera_to_center_distance;uniform vec2 u_translate;layout(location=0) in ivec2 a_pos;out vec3 v_data;flat out float v_visibility;\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define mediump float radius\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 stroke_color\n#pragma maplibre: define mediump float stroke_width\n#pragma maplibre: define lowp float stroke_opacity\nvoid main(void) {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump float radius\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 stroke_color\n#pragma maplibre: initialize mediump float stroke_width\n#pragma maplibre: initialize lowp float stroke_opacity\nivec2 pos_raw=a_pos+32768;vec2 extrude=vec2(pos_raw & 7)/7.0*2.0-1.0;vec2 circle_center=vec2(pos_raw >> 3)+u_translate;float ele=get_elevation(circle_center);v_visibility=calculate_visibility(projectTileWithElevation(circle_center,ele));if (u_pitch_with_map) {\n#ifdef GLOBE\nvec3 center_vector=projectToSphere(circle_center);\n#endif\nfloat angle_scale=u_globe_extrude_scale;vec2 corner_position=circle_center;if (u_scale_with_map) {angle_scale*=(radius+stroke_width);corner_position+=extrude*u_extrude_scale*(radius+stroke_width);} else {\n#ifdef GLOBE\nvec4 projected_center=interpolateProjection(circle_center,center_vector,ele);\n#else\nvec4 projected_center=projectTileWithElevation(circle_center,ele);\n#endif\ncorner_position+=extrude*u_extrude_scale*(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);angle_scale*=(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);}\n#ifdef GLOBE\nvec2 angles=extrude*angle_scale;vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(corner_position,corner_vector,ele);\n#else\ngl_Position=projectTileWithElevation(corner_position,ele);\n#endif\n} else {gl_Position=projectTileWithElevation(circle_center,ele);if (gl_Position.z/gl_Position.w > 1.0) {gl_Position.xy=vec2(10000.0);}if (u_scale_with_map) {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*u_camera_to_center_distance;} else {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*gl_Position.w;}}float antialiasblur=-max(1.0/u_device_pixel_ratio/(radius+stroke_width),blur);v_data=vec3(extrude.x,extrude.y,antialiasblur);}";
9482
+ var circle_vertex_glsl_g_default = "uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform highp float u_globe_extrude_scale;uniform vec2 u_translate;layout(location=0) in ivec2 a_pos;out vec3 v_data;flat out float v_visibility;\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define mediump float radius\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 stroke_color\n#pragma maplibre: define mediump float stroke_width\n#pragma maplibre: define lowp float stroke_opacity\nvoid main(void) {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump float radius\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 stroke_color\n#pragma maplibre: initialize mediump float stroke_width\n#pragma maplibre: initialize lowp float stroke_opacity\nivec2 pos_raw=a_pos+32768;vec2 extrude=vec2(pos_raw & 7)/7.0*2.0-1.0;vec2 circle_center=vec2(pos_raw >> 3)+u_translate;float ele=get_elevation(circle_center);v_visibility=calculate_visibility(projectTileWithElevation(circle_center,ele));if (u_pitch_with_map) {\n#ifdef GLOBE\nvec3 center_vector=projectToSphere(circle_center);\n#endif\nfloat angle_scale=u_globe_extrude_scale;vec2 corner_position=circle_center;if (u_scale_with_map) {angle_scale*=(radius+stroke_width);corner_position+=extrude*u_extrude_scale*(radius+stroke_width);} else {\n#ifdef GLOBE\nvec4 projected_center=interpolateProjection(circle_center,center_vector,ele);\n#else\nvec4 projected_center=projectTileWithElevation(circle_center,ele);\n#endif\ncorner_position+=extrude*u_extrude_scale*(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);angle_scale*=(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);}\n#ifdef GLOBE\nvec2 angles=extrude*angle_scale;vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(corner_position,corner_vector,ele);\n#else\ngl_Position=projectTileWithElevation(corner_position,ele);\n#endif\n} else {gl_Position=projectTileWithElevation(circle_center,ele);if (gl_Position.z/gl_Position.w > 1.0) {gl_Position.xy=vec2(10000.0);}if (u_scale_with_map) {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*u_camera_to_center_distance;} else {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*gl_Position.w;}}float antialiasblur=-max(1.0/u_device_pixel_ratio/(radius+stroke_width),blur);v_data=vec3(extrude.x,extrude.y,antialiasblur);}";
9060
9483
  //#endregion
9061
9484
  //#region src/shaders/glsl/clipping_mask.fragment.glsl.g.ts
9062
9485
  var clipping_mask_fragment_glsl_g_default = "void main() {fragColor=vec4(1.0);}";
@@ -9065,40 +9488,40 @@ var clipping_mask_fragment_glsl_g_default = "void main() {fragColor=vec4(1.0);}"
9065
9488
  const shaders = {
9066
9489
  prelude: prepare(_prelude_fragment_glsl_g_default, _prelude_vertex_glsl_g_default),
9067
9490
  projectionMercator: prepare("\nvoid clipAntimeridian() {}", "float projectLineThickness(float tileY) {return 1.0;}float projectCircleRadius(float tileY) {return 1.0;}vec4 projectTile(vec2 p) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);return result;}vec4 projectTile(vec2 p,vec2 rawPos) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);if (rawPos.y <-32767.5 || rawPos.y > 32766.5) {result.z=-10000000.0;}return result;}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return u_projection_matrix*vec4(posInTile,elevation,1.0);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {return projectTileWithElevation(posInTile,elevation);}"),
9068
- projectionGlobe: prepare("uniform bool u_projection_clip_antimeridian;in highp float v_projection_tile_x;void clipAntimeridian() {if (u_projection_clip_antimeridian && (v_projection_tile_x < 0.0 || v_projection_tile_x >=8192.0)) {discard;}}", "#define GLOBE_RADIUS 6371008.8\nuniform highp vec4 u_projection_tile_mercator_coords;uniform highp vec4 u_projection_clipping_plane;uniform highp float u_projection_transition;uniform mat4 u_projection_fallback_matrix;out highp float v_projection_tile_x;vec3 globeRotateVector(vec3 vec,vec2 angles) {vec3 axisRight=vec3(vec.z,0.0,-vec.x);vec3 axisUp=cross(axisRight,vec);axisRight=normalize(axisRight);axisUp=normalize(axisUp);vec2 t=tan(angles);return normalize(vec+axisRight*t.x+axisUp*t.y);}mat3 globeGetRotationMatrix(vec3 spherePos) {vec3 axisRight=vec3(spherePos.z,0.0,-spherePos.x);vec3 axisDown=cross(axisRight,spherePos);axisRight=normalize(axisRight);axisDown=normalize(axisDown);return mat3(axisRight,axisDown,spherePos\n);}float circumferenceRatioAtTileY(float tileY) {float mercator_pos_y=u_projection_tile_mercator_coords.y+u_projection_tile_mercator_coords.w*tileY;float t=exp(PI-(mercator_pos_y*PI*2.0));return (2.0*t)/(t*t+1.0);}float projectLineThickness(float tileY) {float thickness=1.0/circumferenceRatioAtTileY(tileY);if (u_projection_transition < 0.999) {return mix(1.0,thickness,u_projection_transition);} else {return thickness;}}vec3 projectToSphere(vec2 translatedPos,vec2 rawPos) {vec2 mercator_pos=u_projection_tile_mercator_coords.xy+u_projection_tile_mercator_coords.zw*translatedPos;float spherical_x=mercator_pos.x*PI*2.0+PI;float t=exp(PI-(mercator_pos.y*PI*2.0));float t2=t*t;float denom=t2+1.0;float sin_sy=(t2-1.0)/denom;float cos_sy=(2.0*t)/denom;vec3 pos=vec3(sin(spherical_x)*cos_sy,sin_sy,cos(spherical_x)*cos_sy\n);if (rawPos.y <-32767.5) {pos=vec3(0.0,1.0,0.0);}if (rawPos.y > 32766.5) {pos=vec3(0.0,-1.0,0.0);}return pos;}vec3 projectToSphere(vec2 posInTile) {return projectToSphere(posInTile,vec2(0.0,0.0));}float globeComputeClippingZ(vec3 spherePos) {return (1.0-(dot(spherePos,u_projection_clipping_plane.xyz)+u_projection_clipping_plane.w));}vec4 interpolateProjection(vec2 posInTile,vec3 spherePos,float elevation) {v_projection_tile_x=posInTile.x;vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);globePosition.z=globeComputeClippingZ(elevatedPos)*globePosition.w;if (u_projection_transition > 0.999) {return globePosition;}vec4 flatPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);const float z_globeness_threshold=0.2;vec4 result=globePosition;result.z=mix(0.0,globePosition.z,clamp((u_projection_transition-z_globeness_threshold)/(1.0-z_globeness_threshold),0.0,1.0));result.xyw=mix(flatPosition.xyw,globePosition.xyw,u_projection_transition);if ((posInTile.y <-32767.5) || (posInTile.y > 32766.5)) {result=globePosition;const float poles_hidden_anim_percentage=0.02;result.z=mix(globePosition.z,100.0,pow(max((1.0-u_projection_transition)/poles_hidden_anim_percentage,0.0),8.0));}return result;}vec4 interpolateProjectionFor3D(vec2 posInTile,vec3 spherePos,float elevation) {v_projection_tile_x=posInTile.x;vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);if (u_projection_transition > 0.999) {return globePosition;}vec4 fallbackPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);return mix(fallbackPosition,globePosition,u_projection_transition);}vec4 projectTile(vec2 posInTile) {return interpolateProjection(posInTile,projectToSphere(posInTile),0.0);}vec4 projectTile(vec2 posInTile,vec2 rawPos) {return interpolateProjection(posInTile,projectToSphere(posInTile,rawPos),0.0);}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return interpolateProjection(posInTile,projectToSphere(posInTile),elevation);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {vec3 spherePos=projectToSphere(posInTile,posInTile);return interpolateProjectionFor3D(posInTile,spherePos,elevation);}"),
9491
+ projectionGlobe: prepare("in highp float v_projection_tile_x;void clipAntimeridian() {if (u_projection_clip_antimeridian !=0 && (v_projection_tile_x < 0.0 || v_projection_tile_x >=8192.0)) {discard;}}", "#define GLOBE_RADIUS 6371008.8\n#ifndef PROJECTION_UBO\nuniform highp vec4 u_projection_tile_mercator_coords;uniform highp vec4 u_projection_clipping_plane;uniform highp float u_projection_transition;uniform mat4 u_projection_fallback_matrix;\n#endif\nout highp float v_projection_tile_x;vec3 globeRotateVector(vec3 vec,vec2 angles) {vec3 axisRight=vec3(vec.z,0.0,-vec.x);vec3 axisUp=cross(axisRight,vec);axisRight=normalize(axisRight);axisUp=normalize(axisUp);vec2 t=tan(angles);return normalize(vec+axisRight*t.x+axisUp*t.y);}mat3 globeGetRotationMatrix(vec3 spherePos) {vec3 axisRight=vec3(spherePos.z,0.0,-spherePos.x);vec3 axisDown=cross(axisRight,spherePos);axisRight=normalize(axisRight);axisDown=normalize(axisDown);return mat3(axisRight,axisDown,spherePos\n);}float circumferenceRatioAtTileY(float tileY) {float mercator_pos_y=u_projection_tile_mercator_coords.y+u_projection_tile_mercator_coords.w*tileY;float t=exp(PI-(mercator_pos_y*PI*2.0));return (2.0*t)/(t*t+1.0);}float projectLineThickness(float tileY) {float thickness=1.0/circumferenceRatioAtTileY(tileY);if (u_projection_transition < 0.999) {return mix(1.0,thickness,u_projection_transition);} else {return thickness;}}vec3 projectToSphere(vec2 translatedPos,vec2 rawPos) {vec2 mercator_pos=u_projection_tile_mercator_coords.xy+u_projection_tile_mercator_coords.zw*translatedPos;float spherical_x=mercator_pos.x*PI*2.0+PI;float t=exp(PI-(mercator_pos.y*PI*2.0));float t2=t*t;float denom=t2+1.0;float sin_sy=(t2-1.0)/denom;float cos_sy=(2.0*t)/denom;vec3 pos=vec3(sin(spherical_x)*cos_sy,sin_sy,cos(spherical_x)*cos_sy\n);if (rawPos.y <-32767.5) {pos=vec3(0.0,1.0,0.0);}if (rawPos.y > 32766.5) {pos=vec3(0.0,-1.0,0.0);}return pos;}vec3 projectToSphere(vec2 posInTile) {return projectToSphere(posInTile,vec2(0.0,0.0));}float globeComputeClippingZ(vec3 spherePos) {return (1.0-(dot(spherePos,u_projection_clipping_plane.xyz)+u_projection_clipping_plane.w));}vec4 interpolateProjection(vec2 posInTile,vec3 spherePos,float elevation) {v_projection_tile_x=posInTile.x;vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);globePosition.z=globeComputeClippingZ(elevatedPos)*globePosition.w;if (u_projection_transition > 0.999) {return globePosition;}vec4 flatPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);const float z_globeness_threshold=0.2;vec4 result=globePosition;result.z=mix(0.0,globePosition.z,clamp((u_projection_transition-z_globeness_threshold)/(1.0-z_globeness_threshold),0.0,1.0));result.xyw=mix(flatPosition.xyw,globePosition.xyw,u_projection_transition);if ((posInTile.y <-32767.5) || (posInTile.y > 32766.5)) {result=globePosition;const float poles_hidden_anim_percentage=0.02;result.z=mix(globePosition.z,100.0,pow(max((1.0-u_projection_transition)/poles_hidden_anim_percentage,0.0),8.0));}return result;}vec4 interpolateProjectionFor3D(vec2 posInTile,vec3 spherePos,float elevation) {v_projection_tile_x=posInTile.x;vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);if (u_projection_transition > 0.999) {return globePosition;}vec4 fallbackPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);return mix(fallbackPosition,globePosition,u_projection_transition);}vec4 projectTile(vec2 posInTile) {return interpolateProjection(posInTile,projectToSphere(posInTile),0.0);}vec4 projectTile(vec2 posInTile,vec2 rawPos) {return interpolateProjection(posInTile,projectToSphere(posInTile,rawPos),0.0);}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return interpolateProjection(posInTile,projectToSphere(posInTile),elevation);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {vec3 spherePos=projectToSphere(posInTile,posInTile);return interpolateProjectionFor3D(posInTile,spherePos,elevation);}"),
9069
9492
  background: prepare(background_fragment_glsl_g_default, background_vertex_glsl_g_default),
9070
9493
  backgroundPattern: prepare(background_pattern_fragment_glsl_g_default, background_pattern_vertex_glsl_g_default),
9071
9494
  circle: prepare(circle_fragment_glsl_g_default, circle_vertex_glsl_g_default),
9072
9495
  clippingMask: prepare(clipping_mask_fragment_glsl_g_default, "layout(location=0) in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}"),
9073
9496
  heatmap: prepare("uniform highp float u_intensity;in vec2 v_extrude;\n#pragma maplibre: define highp float weight\n#define GAUSS_COEF 0.3989422804014327\nvoid main() {\n#pragma maplibre: initialize highp float weight\nfloat d=-0.5*3.0*3.0*dot(v_extrude,v_extrude);float val=weight*u_intensity*GAUSS_COEF*exp(d);fragColor=vec4(val,1.0,1.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform float u_extrude_scale;uniform float u_opacity;uniform float u_intensity;uniform highp float u_globe_extrude_scale;layout(location=0) in ivec2 a_pos;out vec2 v_extrude;\n#pragma maplibre: define highp float weight\n#pragma maplibre: define mediump float radius\nconst highp float ZERO=1.0/255.0/16.0;\n#define GAUSS_COEF 0.3989422804014327\nvoid main(void) {\n#pragma maplibre: initialize highp float weight\n#pragma maplibre: initialize mediump float radius\nivec2 pos_raw=a_pos+32768;vec2 unscaled_extrude=vec2(pos_raw & 7)/7.0*2.0-1.0;float S=sqrt(-2.0*log(ZERO/weight/u_intensity/GAUSS_COEF))/3.0;v_extrude=S*unscaled_extrude;vec2 extrude=v_extrude*radius*u_extrude_scale;vec2 circle_center=vec2(pos_raw >> 3);\n#ifdef GLOBE\nvec2 angles=v_extrude*radius*u_globe_extrude_scale;vec3 center_vector=projectToSphere(circle_center);vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(circle_center+extrude,corner_vector,0.0);\n#else\ngl_Position=projectTileFor3D(circle_center+extrude,get_elevation(circle_center));\n#endif\n}"),
9074
- heatmapTexture: prepare("uniform sampler2D u_image;uniform sampler2D u_color_ramp;uniform float u_opacity;in vec2 v_pos;void main() {float t=texture(u_image,v_pos).r;vec4 color=texture(u_color_ramp,vec2(t,0.5));fragColor=color*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(0.0);\n#endif\n}", "uniform mat4 u_matrix;uniform vec2 u_world;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos*u_world,0,1);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"),
9075
- collisionBox: prepare("flat in float v_placed;flat in float v_notUsed;void main() {float alpha=0.5;fragColor=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {fragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {fragColor*=.1;}}", "layout(location=0) in vec2 a_anchor_pos;layout(location=1) in vec2 a_placed;layout(location=2) in vec2 a_box_real;uniform vec2 u_pixel_extrude_scale;flat out float v_placed;flat out float v_notUsed;void main() {gl_Position=projectTileWithElevation(a_anchor_pos,get_elevation(a_anchor_pos));gl_Position.xy=((a_box_real+0.5)*u_pixel_extrude_scale*2.0-1.0)*vec2(1.0,-1.0)*gl_Position.w;if (gl_Position.z/gl_Position.w < 1.1) {gl_Position.z=0.5;}v_placed=a_placed.x;v_notUsed=a_placed.y;}"),
9076
- collisionCircle: prepare("flat in float v_radius;in vec2 v_extrude;flat in float v_collision;void main() {float alpha=0.5;float stroke_radius=0.9;float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);fragColor=color*alpha*opacity_t;}", "layout(location=0) in vec2 a_pos;layout(location=1) in float a_radius;layout(location=2) in vec2 a_flags;uniform vec2 u_viewport_size;flat out float v_radius;out vec2 v_extrude;flat out float v_collision;void main() {float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_collision=collision;gl_Position=vec4((a_pos/u_viewport_size*2.0-1.0)*vec2(1.0,-1.0),0.0,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}"),
9077
- colorRelief: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;uniform vec4 u_unpack;uniform sampler2D u_elevation_stops;uniform sampler2D u_color_stops;uniform int u_color_ramp_size;uniform float u_opacity;in vec2 v_pos;float getElevation(vec2 coord) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}float getElevationStop(int stop) {vec4 data=texelFetch(u_elevation_stops,ivec2(stop,0),0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {float el=getElevation(v_pos);int r=(u_color_ramp_size-1);int l=0;float el_l=getElevationStop(l);float el_r=getElevationStop(r);while(r-l > 1){int m=(r+l)/2;float el_m=getElevationStop(m);if(el < el_m){r=m;el_r=el_m;}else\n{l=m;el_l=el_m;}}float x=(float(l)+(el-el_l)/(el_r-el_l)+0.5)/float(u_color_ramp_size);fragColor=u_opacity*texture(u_color_stops,vec2(x,0));\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_pos/8192.0)*scale+epsilon;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),
9497
+ heatmapTexture: prepare("uniform sampler2D u_image;uniform sampler2D u_color_ramp;uniform float u_opacity;in vec2 v_pos;void main() {float t=texture(u_image,v_pos).r;vec4 color=texture(u_color_ramp,vec2(t,0.5));fragColor=color*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(0.0);\n#endif\n}", "uniform mat4 u_matrix;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos*u_world_size,0,1);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"),
9498
+ collisionBox: prepare("flat in float v_placed;flat in float v_notUsed;void main() {float alpha=0.5;fragColor=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {fragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {fragColor*=.1;}}", "layout(location=0) in vec2 a_anchor_pos;layout(location=1) in vec2 a_placed;layout(location=2) in vec2 a_box_real;flat out float v_placed;flat out float v_notUsed;void main() {gl_Position=projectTileWithElevation(a_anchor_pos,get_elevation(a_anchor_pos));gl_Position.xy=((a_box_real+0.5)*u_pixel_extrude_scale*2.0-1.0)*vec2(1.0,-1.0)*gl_Position.w;if (gl_Position.z/gl_Position.w < 1.1) {gl_Position.z=0.5;}v_placed=a_placed.x;v_notUsed=a_placed.y;}"),
9499
+ collisionCircle: prepare("flat in float v_radius;in vec2 v_extrude;flat in float v_collision;void main() {float alpha=0.5;float stroke_radius=0.9;float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);fragColor=color*alpha*opacity_t;}", "layout(location=0) in vec2 a_pos;layout(location=1) in float a_radius;layout(location=2) in vec2 a_flags;flat out float v_radius;out vec2 v_extrude;flat out float v_collision;void main() {float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_collision=collision;gl_Position=vec4((a_pos/u_viewport_size*2.0-1.0)*vec2(1.0,-1.0),0.0,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}"),
9500
+ colorRelief: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;uniform vec4 u_unpack;uniform sampler2D u_elevation_stops;uniform sampler2D u_color_stops;uniform int u_color_ramp_size;uniform float u_opacity;in vec2 v_pos;float getElevation(vec2 coord) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}float getElevationStop(int stop) {vec4 data=texelFetch(u_elevation_stops,ivec2(stop,0),0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {float el=getElevation(v_pos);int r=(u_color_ramp_size-1);int l=0;float el_l=getElevationStop(l);float el_r=getElevationStop(r);while(r-l > 1){int m=(r+l)/2;float el_m=getElevationStop(m);if(el < el_m){r=m;el_r=el_m;}else\n{l=m;el_l=el_m;}}float x=(float(l)+(el-el_l)/(el_r-el_l)+0.5)/float(u_color_ramp_size);fragColor=u_opacity*texture(u_color_stops,vec2(x,0));\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);highp vec2 epsilon=2.0/u_dimension;float scale=(u_dimension.x-4.0)/u_dimension.x;v_pos=(a_pos/8192.0)*scale+epsilon;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),
9078
9501
  debug: prepare("uniform highp vec4 u_color;uniform sampler2D u_overlay;in vec2 v_uv;void main() {vec4 overlay_color=texture(u_overlay,v_uv);fragColor=mix(u_color,overlay_color,overlay_color.a);}", "layout(location=0) in vec2 a_pos;out vec2 v_uv;uniform float u_overlay_scale;void main() {v_uv=a_pos/8192.0;gl_Position=projectTileWithElevation(a_pos*u_overlay_scale,get_elevation(a_pos));}"),
9079
9502
  depth: prepare(clipping_mask_fragment_glsl_g_default, "layout(location=0) in vec2 a_pos;void main() {\n#ifdef GLOBE\ngl_Position=projectTileFor3D(a_pos,0.0);\n#else\ngl_Position=u_projection_matrix*vec4(a_pos,0.0,1.0);\n#endif\n}"),
9080
9503
  fill: prepare("#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float opacity\nfragColor=color*opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float opacity\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}gl_Position=projectTile(a_pos+u_fill_translate,a_pos);}"),
9081
- fillOutline: prepare("in vec2 v_pos;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 outline_color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 outline_color\n#pragma maplibre: initialize lowp float opacity\nfloat dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=outline_color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_world;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 outline_color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 outline_color\n#pragma maplibre: initialize lowp float opacity\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n}"),
9082
- fillOutlinePattern: prepare("uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;in vec2 v_pos_a;in vec2 v_pos_b;in vec2 v_pos;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=mix(color1,color2,u_fade)*alpha*opacity;\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_world;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;out vec2 v_pos;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n}"),
9083
- fillPattern: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_fade)*opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}"),
9504
+ fillOutline: prepare("in vec2 v_pos;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 outline_color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 outline_color\n#pragma maplibre: initialize lowp float opacity\nfloat dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=outline_color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 outline_color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 outline_color\n#pragma maplibre: initialize lowp float opacity\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world_size;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n}"),
9505
+ fillOutlinePattern: prepare("uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;uniform bool u_sdf_pattern;in vec2 v_pos_a;in vec2 v_pos_b;in vec2 v_pos;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);if (u_sdf_pattern) {highp float sdf_edge=(256.0-64.0)/256.0;highp float sdf_gamma_a=max(fwidth(color1.a)*0.5,1.0/255.0/16.0);highp float sdf_gamma_b=max(fwidth(color2.a)*0.5,1.0/255.0/16.0);float sdf_alpha_a=smoothstep(sdf_edge-sdf_gamma_a,sdf_edge+sdf_gamma_a,color1.a);float sdf_alpha_b=smoothstep(sdf_edge-sdf_gamma_b,sdf_edge+sdf_gamma_b,color2.a);fragColor=mix(color*sdf_alpha_a,color*sdf_alpha_b,u_fade)*alpha*opacity;} else {fragColor=mix(color1,color2,u_fade)*alpha*opacity;}\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;out vec2 v_pos;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world_size;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n}"),
9506
+ fillPattern: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform vec2 u_texsize;uniform float u_fade;uniform bool u_sdf_pattern;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);if (u_sdf_pattern) {highp float sdf_edge=(256.0-64.0)/256.0;highp float sdf_gamma_a=max(fwidth(color1.a)*0.5,1.0/255.0/16.0);highp float sdf_gamma_b=max(fwidth(color2.a)*0.5,1.0/255.0/16.0);float sdf_alpha_a=smoothstep(sdf_edge-sdf_gamma_a,sdf_edge+sdf_gamma_a,color1.a);float sdf_alpha_b=smoothstep(sdf_edge-sdf_gamma_b,sdf_edge+sdf_gamma_b,color2.a);fragColor=mix(color*sdf_alpha_a,color*sdf_alpha_b,u_fade)*opacity;} else {fragColor=mix(color1,color2,u_fade)*opacity;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}"),
9084
9507
  fillExtrusion: prepare("in vec4 v_color;void main() {fragColor=v_color;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;layout(location=1) in ivec4 a_normal_ed;\n#ifdef TERRAIN3D\nlayout(location=2) in vec2 a_centroid;\n#endif\nout vec4 v_color;\n#pragma maplibre: define highp float base\n#pragma maplibre: define highp float height\n#pragma maplibre: define highp vec4 color\nvoid main() {\n#pragma maplibre: initialize highp float base\n#pragma maplibre: initialize highp float height\n#pragma maplibre: initialize highp vec4 color\nvec3 normal=vec3(a_normal_ed.xyz);\n#ifdef TERRAIN3D\nfloat height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);\n#else\nfloat height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;\n#endif\nbase=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=float(a_normal_ed.x & 1);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;\n#ifdef GLOBE\nvec3 spherePos=projectToSphere(posInTile,a_pos);gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);\n#else\ngl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);\n#endif\nfloat colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.0,0.0,0.0,1.0);vec4 ambientlight=vec4(0.03,0.03,0.03,1.0);color+=ambientlight;vec3 normalForLighting=normal/16384.0;float directional=clamp(dot(normalForLighting,u_lightpos),0.0,1.0);\n#ifdef GLOBE\nmat3 rotMatrix=globeGetRotationMatrix(spherePos);normalForLighting=rotMatrix*normalForLighting;directional=mix(directional,clamp(dot(normalForLighting,u_lightpos_globe),0.0,1.0),u_projection_transition);\n#endif\ndirectional=mix((1.0-u_lightintensity),max((1.0-colorvalue+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.0,0.3,1.0-u_lightcolor.r),1.0);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.0,0.3,1.0-u_lightcolor.g),1.0);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.0,0.3,1.0-u_lightcolor.b),1.0);v_color*=u_opacity;}"),
9085
9508
  fillExtrusionPattern: prepare("uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;in vec4 v_lighting;\n#pragma maplibre: define lowp float base\n#pragma maplibre: define lowp float height\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float base\n#pragma maplibre: initialize lowp float height\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);fragColor=mixedColor*v_lighting;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;layout(location=0) in vec2 a_pos;layout(location=1) in ivec4 a_normal_ed;\n#ifdef TERRAIN3D\nlayout(location=2) in vec2 a_centroid;\n#endif\n#ifdef GLOBE\nout vec3 v_sphere_pos;\n#endif\nout vec2 v_pos_a;out vec2 v_pos_b;out vec4 v_lighting;\n#pragma maplibre: define lowp float base\n#pragma maplibre: define lowp float height\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float base\n#pragma maplibre: initialize lowp float height\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec3 normal=vec3(a_normal_ed.xyz);float edgedistance=float(a_normal_ed.w);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;\n#ifdef TERRAIN3D\nfloat height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);\n#else\nfloat height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;\n#endif\nbase=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=float(a_normal_ed.x & 1);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;\n#ifdef GLOBE\nvec3 spherePos=projectToSphere(posInTile,a_pos);vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);v_sphere_pos=elevatedPos;gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);\n#else\ngl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);\n#endif\nvec2 pos=a_normal_ed.x==1 && a_normal_ed.y==0 && a_normal_ed.z==16384\n? a_pos\n: vec2(edgedistance,elevation*u_height_factor);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,pos);v_lighting=vec4(0.0,0.0,0.0,1.0);float directional=clamp(dot(normal/16383.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((0.5+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_lighting.rgb+=clamp(directional*u_lightcolor,mix(vec3(0.0),vec3(0.3),1.0-u_lightcolor),vec3(1.0));v_lighting*=u_opacity;}"),
9086
- hillshadePrepare: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(ivec2 texel) {vec4 data=texelFetch(u_image,texel,0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {ivec2 pos=ivec2(gl_FragCoord.xy)+ivec2(1);float tileSize=u_dimension.x-2.0;float a=getElevation(pos+ivec2(-1,-1));float b=getElevation(pos+ivec2(0,-1));float c=getElevation(pos+ivec2(1,-1));float d=getElevation(pos+ivec2(-1,0));float e=getElevation(pos);float f=getElevation(pos+ivec2(1,0));float g=getElevation(pos+ivec2(-1,1));float h=getElevation(pos+ivec2(0,1));float i=getElevation(pos+ivec2(1,1));float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))*tileSize/pow(2.0,exaggeration+(28.2562-u_zoom));fragColor=clamp(vec4(deriv.x/8.0+0.5,deriv.y/8.0+0.5,1.0,1.0),0.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform mat4 u_matrix;uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;layout(location=1) in vec2 a_texture_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}"),
9087
- hillshade: prepare("uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_latrange;uniform float u_exaggeration;uniform vec4 u_accent;uniform int u_method;uniform float u_altitudes[NUM_ILLUMINATION_SOURCES];uniform float u_azimuths[NUM_ILLUMINATION_SOURCES];uniform vec4 u_shadows[NUM_ILLUMINATION_SOURCES];uniform vec4 u_highlights[NUM_ILLUMINATION_SOURCES];\n#define PI 3.141592653589793\n#define STANDARD 0\n#define COMBINED 1\n#define IGOR 2\n#define MULTIDIRECTIONAL 3\n#define BASIC 4\nfloat get_aspect(vec2 deriv){return deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);}void igor_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float aspect=get_aspect(deriv);float azimuth=u_azimuths[0]+PI;float slope_stength=atan(length(deriv))*2.0/PI;float aspect_strength=1.0-abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);float shadow_strength=slope_stength*aspect_strength;float highlight_strength=slope_stength*(1.0-aspect_strength);fragColor=u_shadows[0]*shadow_strength+u_highlights[0]*highlight_strength;}void standard_hillshade(vec2 deriv){float azimuth=u_azimuths[0]+PI;float slope=atan(0.625*length(deriv));float aspect=get_aspect(deriv);float intensity=u_exaggeration;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadows[0],u_highlights[0],shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);fragColor=accent_color*(1.0-shade_color.a)+shade_color;}void basic_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor=u_highlights[0]*(2.0*shade-1.0);}else\n{fragColor=u_shadows[0]*(1.0-2.0*shade);}}void multidirectional_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;fragColor=vec4(0,0,0,0);for(int i=0; i < NUM_ILLUMINATION_SOURCES; i++){float cos_alt=cos(u_altitudes[i]);float sin_alt=sin(u_altitudes[i]);float cos_az=-cos(u_azimuths[i]);float sin_az=-sin(u_azimuths[i]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor+=u_highlights[i]*(2.0*shade-1.0)/float(NUM_ILLUMINATION_SOURCES);}else\n{fragColor+=u_shadows[i]*(1.0-2.0*shade)/float(NUM_ILLUMINATION_SOURCES);}}}void combined_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=acos((sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv)));cang=clamp(cang,0.0,PI/2.0);float shade=cang*atan(length(deriv))*4.0/PI/PI;float highlight=(PI/2.0-cang)*atan(length(deriv))*4.0/PI/PI;fragColor=u_shadows[0]*shade+u_highlights[0]*highlight;}void main() {vec4 pixel=texture(u_image,v_pos);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));vec2 deriv=((pixel.rg*8.0)-4.0)/scaleFactor;if (u_method==BASIC) {basic_hillshade(deriv);} else if (u_method==COMBINED) {combined_hillshade(deriv);} else if (u_method==IGOR) {igor_hillshade(deriv);} else if (u_method==MULTIDIRECTIONAL) {multidirectional_hillshade(deriv);} else if (u_method==STANDARD) {standard_hillshade(deriv);} else {standard_hillshade(deriv);}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform mat4 u_matrix;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);v_pos=a_pos/8192.0;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),
9088
- line: prepare("uniform lowp float u_device_pixel_ratio;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform vec2 u_units_to_pixels;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp float v_linesofar;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);v_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*2.0;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_width2=vec2(outset,inset);}"),
9089
- lineGradient: prepare("uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_width2=vec2(outset,inset);}"),
9090
- linePattern: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;in vec2 v_normal;flat in vec2 v_width2;in float v_linesofar;in float v_gamma_scale;flat in float v_width;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture(u_image,pos_a),texture(u_image,pos_b),u_fade);fragColor=color*alpha*opacity;\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform vec2 u_units_to_pixels;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_linesofar;out float v_gamma_scale;flat out float v_width;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}"),
9091
- lineSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform lowp float u_lineatlas_width;uniform sampler2D u_image;uniform float u_mix;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0/u_device_pixel_ratio)/min(dasharray_from.w,dasharray_to.w);alpha*=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out vec2 v_tex_a;out vec2 v_tex_b;out float v_gamma_scale;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
9092
- lineGradientSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform sampler2D u_image_dash;uniform float u_mix;uniform lowp float u_lineatlas_width;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);float sdfdist_a=texture(u_image_dash,v_tex_a).a;float sdfdist_b=texture(u_image_dash,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0)/min(dasharray_from.w,dasharray_to.w);float dash_alpha=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*dash_alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;out vec2 v_tex_a;out vec2 v_tex_b;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;float texel_height=1.0/u_image_height;float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
9509
+ hillshadePrepare: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(ivec2 texel) {vec4 data=texelFetch(u_image,texel,0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {ivec2 pos=ivec2(gl_FragCoord.xy)+ivec2(1);float tileSize=u_dimension.x-4.0;float a=getElevation(pos+ivec2(-1,-1));float b=getElevation(pos+ivec2(0,-1));float c=getElevation(pos+ivec2(1,-1));float d=getElevation(pos+ivec2(-1,0));float e=getElevation(pos);float f=getElevation(pos+ivec2(1,0));float g=getElevation(pos+ivec2(-1,1));float h=getElevation(pos+ivec2(0,1));float i=getElevation(pos+ivec2(1,1));float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))*tileSize/pow(2.0,exaggeration+(28.2562-u_zoom));fragColor=clamp(vec4(deriv.x/8.0+0.5,deriv.y/8.0+0.5,1.0,1.0),0.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform mat4 u_matrix;uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;layout(location=1) in vec2 a_texture_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}"),
9510
+ hillshade: prepare("uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_latrange;uniform float u_exaggeration;uniform vec4 u_accent;uniform int u_method;uniform float u_altitudes[NUM_ILLUMINATION_SOURCES];uniform float u_azimuths[NUM_ILLUMINATION_SOURCES];uniform vec4 u_shadows[NUM_ILLUMINATION_SOURCES];uniform vec4 u_highlights[NUM_ILLUMINATION_SOURCES];\n#define PI 3.141592653589793\n#define STANDARD 0\n#define COMBINED 1\n#define IGOR 2\n#define MULTIDIRECTIONAL 3\n#define BASIC 4\nfloat get_aspect(vec2 deriv){return deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);}void igor_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float aspect=get_aspect(deriv);float azimuth=u_azimuths[0]+PI;float slope_stength=atan(length(deriv))*2.0/PI;float aspect_strength=1.0-abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);float shadow_strength=slope_stength*aspect_strength;float highlight_strength=slope_stength*(1.0-aspect_strength);fragColor=u_shadows[0]*shadow_strength+u_highlights[0]*highlight_strength;}void standard_hillshade(vec2 deriv){float azimuth=u_azimuths[0]+PI;float slope=atan(0.625*length(deriv));float aspect=get_aspect(deriv);float intensity=u_exaggeration;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadows[0],u_highlights[0],shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);fragColor=accent_color*(1.0-shade_color.a)+shade_color;}void basic_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor=u_highlights[0]*(2.0*shade-1.0);}else\n{fragColor=u_shadows[0]*(1.0-2.0*shade);}}void multidirectional_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;fragColor=vec4(0,0,0,0);for(int i=0; i < NUM_ILLUMINATION_SOURCES; i++){float cos_alt=cos(u_altitudes[i]);float sin_alt=sin(u_altitudes[i]);float cos_az=-cos(u_azimuths[i]);float sin_az=-sin(u_azimuths[i]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor+=u_highlights[i]*(2.0*shade-1.0)/float(NUM_ILLUMINATION_SOURCES);}else\n{fragColor+=u_shadows[i]*(1.0-2.0*shade)/float(NUM_ILLUMINATION_SOURCES);}}}void combined_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=acos((sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv)));cang=clamp(cang,0.0,PI/2.0);float shade=cang*atan(length(deriv))*4.0/PI/PI;float highlight=(PI/2.0-cang)*atan(length(deriv))*4.0/PI/PI;fragColor=u_shadows[0]*shade+u_highlights[0]*highlight;}void main() {vec2 size=vec2(textureSize(u_image,0));vec2 texturePos=(v_pos*(size-2.0)+1.0)/size;vec4 pixel=texture(u_image,texturePos);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));vec2 deriv=((pixel.rg*8.0)-4.0)/scaleFactor;if (u_method==BASIC) {basic_hillshade(deriv);} else if (u_method==COMBINED) {combined_hillshade(deriv);} else if (u_method==IGOR) {igor_hillshade(deriv);} else if (u_method==MULTIDIRECTIONAL) {multidirectional_hillshade(deriv);} else if (u_method==STANDARD) {standard_hillshade(deriv);} else {standard_hillshade(deriv);}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform mat4 u_matrix;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);v_pos=a_pos/8192.0;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),
9511
+ line: prepare("flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp float v_linesofar;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);v_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*2.0;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_width2=vec2(outset,inset);}"),
9512
+ lineGradient: prepare("uniform sampler2D u_image;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform float u_image_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_width2=vec2(outset,inset);}"),
9513
+ linePattern: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;in vec2 v_normal;flat in vec2 v_width2;in float v_linesofar;in float v_gamma_scale;flat in float v_width;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture(u_image,pos_a),texture(u_image,pos_b),u_fade);fragColor=color*alpha*opacity;\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_linesofar;out float v_gamma_scale;flat out float v_width;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}"),
9514
+ lineSDF: prepare("uniform lowp float u_lineatlas_width;uniform sampler2D u_image;uniform float u_mix;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0/u_device_pixel_ratio)/min(dasharray_from.w,dasharray_to.w);alpha*=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out vec2 v_tex_a;out vec2 v_tex_b;out float v_gamma_scale;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
9515
+ lineGradientSDF: prepare("uniform sampler2D u_image;uniform sampler2D u_image_dash;uniform float u_mix;uniform lowp float u_lineatlas_width;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);float sdfdist_a=texture(u_image_dash,v_tex_a).a;float sdfdist_b=texture(u_image_dash,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0)/min(dasharray_from.w,dasharray_to.w);float dash_alpha=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*dash_alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform float u_image_height;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;out vec2 v_tex_a;out vec2 v_tex_b;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;float texel_height=1.0/u_image_height;float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
9093
9516
  layerOpacity: prepare("uniform sampler2D u_image;uniform float u_opacity;in vec2 v_pos;void main() {fragColor=texture(u_image,v_pos)*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(0.0);\n#endif\n}", "layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=vec4(a_pos.x*2.0-1.0,1.0-a_pos.y*2.0,0.0,1.0);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"),
9094
9517
  raster: prepare("uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in vec3 v_pos0;in vec3 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture(u_image0,v_pos0.xy/v_pos0.z);vec4 color1=texture(u_image1,v_pos1.xy/v_pos1.z);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);fragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;uniform vec3 u_image_warp;uniform vec4 u_coords_top;uniform vec4 u_coords_bottom;layout(location=0) in vec2 a_pos;out vec3 v_pos0;out vec3 v_pos1;void main() {vec2 fractionalPos=a_pos/8192.0;vec2 topLeft=u_coords_top.xy;vec2 topRight=u_coords_top.zw;vec2 bottomLeft=u_coords_bottom.xy;vec2 bottomRight=u_coords_bottom.zw;vec2 bilinearPos=mix(mix(topLeft,topRight,fractionalPos.x),mix(bottomLeft,bottomRight,fractionalPos.x),fractionalPos.y);float denominator=dot(u_image_warp.xy,fractionalPos)+1.0;vec2 acrossTop=topRight-topLeft+u_image_warp.x*topRight;vec2 downLeft=bottomLeft-topLeft+u_image_warp.y*bottomLeft;vec2 projectivePos=(acrossTop*fractionalPos.x+downLeft*fractionalPos.y+topLeft)/denominator;vec2 position=mix(projectivePos,bilinearPos,u_image_warp.z);gl_Position=projectTile(position,position);vec2 texturePos=((fractionalPos-0.5)/u_buffer_scale)+0.5;\n#ifdef GLOBE\nif (a_pos.y <-32767.5) {texturePos.y=0.0;}if (a_pos.y > 32766.5) {texturePos.y=1.0;}\n#endif\nfloat perspectiveRatio=mix(1.0/denominator,1.0,u_image_warp.z);v_pos0=vec3(texturePos*perspectiveRatio,perspectiveRatio);vec2 parentPos=(texturePos*u_scale_parent)+u_tl_parent;v_pos1=vec3(parentPos*perspectiveRatio,perspectiveRatio);}"),
9095
- symbolIcon: prepare("uniform sampler2D u_texture;in vec2 v_tex;flat in float v_total_opacity;void main() {fragColor=texture(u_texture,v_tex)*v_total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;layout(location=5) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec2 v_tex;flat out float v_total_opacity;\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float visibility=calculate_visibility(projectedPoint);v_total_opacity=opacity*max(0.0,min(visibility,fade_opacity[0]+fade_change));if (v_total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}gl_Position=finalPos;v_tex=a_tex/u_texsize;}"),
9096
- symbolSDF: prepare("#define SDF_PX 8.0\nuniform bool u_is_halo;uniform bool u_is_plain;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float total_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out_text,color_alpha_out_halo;if (u_is_plain){highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);color_alpha_out_text=total_opacity*alpha*fill_color;}if (u_is_halo) {float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);float inner_edge_halo=inner_edge+gamma_halo*gamma_scale;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(inner_edge_halo-gamma_scaled_halo,inner_edge_halo+gamma_scaled_halo,dist);highp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha_halo= min(smoothstep(halo_edge-gamma_scaled_halo,halo_edge+gamma_scaled_halo,dist),1.0-alpha_halo);color_alpha_out_halo=total_opacity*alpha_halo*halo_color;}if (u_is_plain && u_is_halo) {fragColor=color_alpha_out_text+(1.-color_alpha_out_text.a)*color_alpha_out_halo;} else if (u_is_halo){fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out_text;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;layout(location=5) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec2 v_data0;out vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy/16.0;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,total_opacity);}"),
9097
- symbolTextAndIcon: prepare("#define SDF_PX 8.0\n#define SDF 1.0\n#define ICON 0.0\nuniform bool u_is_halo;uniform bool u_is_text;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;in vec4 v_data0;in vec3 v_data1;flat in float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat total_opacity=v_data1[2];if (v_is_sdf==ICON) {vec2 tex_icon=v_data0.zw;fragColor=texture(u_texture_icon,tex_icon)*total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\nreturn;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out,color_alpha_out_halo;if (u_is_text) {highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);color_alpha_out=fill_color*(alpha*total_opacity);}if (u_is_halo) {highp float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);lowp float buff_halo=(6.0-halo_width/fontScale)/SDF_PX;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(buff_halo-gamma_scaled_halo,buff_halo+gamma_scaled_halo,dist);color_alpha_out_halo=halo_color*(alpha_halo*total_opacity);}if (u_is_text && u_is_halo) {fragColor=color_alpha_out+(1.-color_alpha_out.a)*color_alpha_out_halo;} else if (u_is_halo) {fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec3 a_projected_pos;layout(location=3) in uint a_fade_opacity;layout(location=4) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec4 v_data0;out vec3 v_data1;flat out float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);float is_sdf=float(a_data.z & 1u);float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map && !u_is_along_line) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec3(gamma_scale,size,total_opacity);v_is_sdf=is_sdf;}"),
9518
+ symbolIcon: prepare("uniform sampler2D u_texture;in vec2 v_tex;flat in float v_total_opacity;void main() {fragColor=texture(u_texture,v_tex)*v_total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;layout(location=5) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform bool u_rotate_symbol;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec2 v_tex;flat out float v_total_opacity;\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_symbol_fade_change :-u_symbol_fade_change;float visibility=calculate_visibility(projectedPoint);v_total_opacity=opacity*max(0.0,min(visibility,fade_opacity[0]+fade_change));if (v_total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}gl_Position=finalPos;v_tex=a_tex/u_texsize;}"),
9519
+ symbolSDF: prepare("#define SDF_PX 8.0\nuniform bool u_is_halo;uniform bool u_is_plain;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float total_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out_text,color_alpha_out_halo;if (u_is_plain){highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);color_alpha_out_text=total_opacity*alpha*fill_color;}if (u_is_halo) {float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);float inner_edge_halo=inner_edge+gamma_halo*gamma_scale;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(inner_edge_halo-gamma_scaled_halo,inner_edge_halo+gamma_scaled_halo,dist);highp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha_halo= min(smoothstep(halo_edge-gamma_scaled_halo,halo_edge+gamma_scaled_halo,dist),1.0-alpha_halo);color_alpha_out_halo=total_opacity*alpha_halo*halo_color;}if (u_is_plain && u_is_halo) {fragColor=color_alpha_out_text+(1.-color_alpha_out_text.a)*color_alpha_out_halo;} else if (u_is_halo){fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out_text;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;layout(location=5) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform bool u_rotate_symbol;uniform vec2 u_texsize;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec2 v_data0;out vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy/16.0;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_symbol_fade_change :-u_symbol_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,total_opacity);}"),
9520
+ symbolTextAndIcon: prepare("#define SDF_PX 8.0\n#define SDF 1.0\n#define ICON 0.0\nuniform bool u_is_halo;uniform bool u_is_text;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;in vec4 v_data0;in vec3 v_data1;flat in float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat total_opacity=v_data1[2];if (v_is_sdf==ICON) {vec2 tex_icon=v_data0.zw;fragColor=texture(u_texture_icon,tex_icon)*total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\nreturn;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out,color_alpha_out_halo;if (u_is_text) {highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);color_alpha_out=fill_color*(alpha*total_opacity);}if (u_is_halo) {highp float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);lowp float buff_halo=(6.0-halo_width/fontScale)/SDF_PX;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(buff_halo-gamma_scaled_halo,buff_halo+gamma_scaled_halo,dist);color_alpha_out_halo=halo_color*(alpha_halo*total_opacity);}if (u_is_text && u_is_halo) {fragColor=color_alpha_out+(1.-color_alpha_out.a)*color_alpha_out_halo;} else if (u_is_halo) {fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec3 a_projected_pos;layout(location=3) in uint a_fade_opacity;layout(location=4) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_rotate_symbol;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec4 v_data0;out vec3 v_data1;flat out float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);float is_sdf=float(a_data.z & 1u);float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_symbol_fade_change :-u_symbol_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map && !u_is_along_line) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec3(gamma_scale,size,total_opacity);v_is_sdf=is_sdf;}"),
9098
9521
  terrain: prepare("uniform sampler2D u_texture;uniform vec4 u_fog_color;uniform vec4 u_horizon_color;uniform float u_fog_ground_blend;uniform float u_fog_ground_blend_opacity;uniform float u_horizon_fog_blend;uniform bool u_is_globe_mode;in vec2 v_texture_pos;in float v_fog_depth;const float gamma=2.2;vec4 gammaToLinear(vec4 color) {return pow(color,vec4(gamma));}vec4 linearToGamma(vec4 color) {return pow(color,vec4(1.0/gamma));}void main() {vec4 surface_color=texture(u_texture,vec2(v_texture_pos.x,1.0-v_texture_pos.y));if (!u_is_globe_mode && u_fog_ground_blend_opacity > 0.0 && v_fog_depth > u_fog_ground_blend) {vec4 surface_color_linear=gammaToLinear(surface_color);float blend_color=smoothstep(0.0,1.0,max((v_fog_depth-u_horizon_fog_blend)/(1.0-u_horizon_fog_blend),0.0));vec4 fog_horizon_color_linear=mix(gammaToLinear(u_fog_color),gammaToLinear(u_horizon_color),blend_color);float factor_fog=max(v_fog_depth-u_fog_ground_blend,0.0)/(1.0-u_fog_ground_blend);fragColor=linearToGamma(mix(surface_color_linear,fog_horizon_color_linear,pow(factor_fog,2.0)*u_fog_ground_blend_opacity));} else {fragColor=surface_color;}}", "layout(location=0) in vec3 a_pos3d;uniform mat4 u_fog_matrix;uniform float u_ele_delta;out vec2 v_texture_pos;out float v_fog_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);vec4 pos=u_fog_matrix*vec4(a_pos3d.xy,ele,1.0);v_fog_depth=pos.z/pos.w*0.5+0.5;}"),
9099
9522
  terrainDepth: prepare("in float v_depth;const highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitMsk=vec4(0.,vec3(1./256.0));highp vec4 pack(highp float value) {highp vec4 comp=fract(value*bitSh);comp-=comp.xxyz*bitMsk;return comp;}void main() {fragColor=pack(v_depth);}", "layout(location=0) in vec3 a_pos3d;uniform float u_ele_delta;out float v_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);v_depth=gl_Position.z/gl_Position.w;}"),
9100
9523
  atmosphere: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nin vec3 view_direction;uniform vec3 u_sun_pos;uniform vec3 u_globe_position;uniform float u_globe_radius;uniform float u_atmosphere_blend;/**Shader use from https:*Made some change to adapt to MapLibre Globe geometry*/const float PI=3.141592653589793;const int iSteps=5;const int jSteps=3;/*radius of the planet*/const float EARTH_RADIUS=6371e3;/*radius of the atmosphere*/const float ATMOS_RADIUS=6471e3;vec2 rsi(vec3 r0,vec3 rd,float sr) {float a=dot(rd,rd);float b=2.0*dot(rd,r0);float c=dot(r0,r0)-(sr*sr);float d=(b*b)-4.0*a*c;if (d < 0.0) return vec2(1e5,-1e5);return vec2((-b-sqrt(d))/(2.0*a),(-b+sqrt(d))/(2.0*a));}vec4 atmosphere(vec3 r,vec3 r0,vec3 pSun,float iSun,float rPlanet,float rAtmos,vec3 kRlh,float kMie,float shRlh,float shMie,float g) {pSun=normalize(pSun);r=normalize(r);vec2 p=rsi(r0,r,rAtmos);if (p.x > p.y) {return vec4(0.0,0.0,0.0,1.0);}if (p.x < 0.0) {p.x=0.0;}vec3 pos=r0+r*p.x;vec2 p2=rsi(r0,r,rPlanet);if (p2.x <=p2.y && p2.x > 0.0) {p.y=min(p.y,p2.x);}float iStepSize=(p.y-p.x)/float(iSteps);float iTime=p.x+iStepSize*0.5;vec3 totalRlh=vec3(0,0,0);vec3 totalMie=vec3(0,0,0);float iOdRlh=0.0;float iOdMie=0.0;float mu=dot(r,pSun);float mumu=mu*mu;float gg=g*g;float pRlh=3.0/(16.0*PI)*(1.0+mumu);float pMie=3.0/(8.0*PI)*((1.0-gg)*(mumu+1.0))/(pow(1.0+gg-2.0*mu*g,1.5)*(2.0+gg));for (int i=0; i < iSteps; i++) {vec3 iPos=r0+r*iTime;float iHeight=length(iPos)-rPlanet;float odStepRlh=exp(-iHeight/shRlh)*iStepSize;float odStepMie=exp(-iHeight/shMie)*iStepSize;iOdRlh+=odStepRlh;iOdMie+=odStepMie;float jStepSize=rsi(iPos,pSun,rAtmos).y/float(jSteps);float jTime=jStepSize*0.5;float jOdRlh=0.0;float jOdMie=0.0;for (int j=0; j < jSteps; j++) {vec3 jPos=iPos+pSun*jTime;float jHeight=length(jPos)-rPlanet;jOdRlh+=exp(-jHeight/shRlh)*jStepSize;jOdMie+=exp(-jHeight/shMie)*jStepSize;jTime+=jStepSize;}vec3 attn=exp(-(kMie*(iOdMie+jOdMie)+kRlh*(iOdRlh+jOdRlh)));totalRlh+=odStepRlh*attn;totalMie+=odStepMie*attn;iTime+=iStepSize;}float opacity=exp(-(length(kRlh)*length(totalRlh)+kMie*length(totalMie)));vec3 color=iSun*(pRlh*kRlh*totalRlh+pMie*kMie*totalMie);return vec4(color,opacity);}void main() {vec3 scale_camera_pos=-u_globe_position*EARTH_RADIUS/u_globe_radius;vec4 color=atmosphere(normalize(view_direction),scale_camera_pos,u_sun_pos,22.0,EARTH_RADIUS,ATMOS_RADIUS,vec3(5.5e-6,13.0e-6,22.4e-6),21e-6,8e3,1.2e3,0.758\n);color.rgb=1.0-exp(-1.0*color.rgb);color=pow(color,vec4(1.0/2.2));fragColor=vec4(color.rgb,1.0-color.a)*u_atmosphere_blend;}", "layout(location=0) in vec2 a_pos;uniform mat4 u_inv_proj_matrix;out vec3 view_direction;void main() {view_direction=(u_inv_proj_matrix*vec4(a_pos,0.0,1.0)).xyz;gl_Position=vec4(a_pos,0.0,1.0);}"),
9101
- sky: prepare("uniform vec4 u_sky_color;uniform vec4 u_horizon_color;uniform vec2 u_horizon;uniform vec2 u_horizon_normal;uniform float u_sky_horizon_blend;uniform float u_sky_blend;void main() {float x=gl_FragCoord.x;float y=gl_FragCoord.y;float blend=(y-u_horizon.y)*u_horizon_normal.y+(x-u_horizon.x)*u_horizon_normal.x;if (blend > 0.0) {if (blend < u_sky_horizon_blend) {fragColor=mix(u_sky_color,u_horizon_color,pow(1.0-blend/u_sky_horizon_blend,2.0));} else {fragColor=u_sky_color;}}fragColor=mix(fragColor,vec4(vec3(0.0),0.0),u_sky_blend);}", "layout(location=0) in vec2 a_pos;void main() {gl_Position=vec4(a_pos,1.0,1.0);}")
9524
+ sky: prepare("uniform vec4 u_sky_color;uniform vec4 u_horizon_color;uniform vec2 u_horizon;uniform vec2 u_horizon_normal;uniform float u_sky_horizon_blend;uniform float u_sky_blend;uniform vec3 u_globe_position;uniform float u_globe_radius;in vec3 v_view_direction;void main() {float x=gl_FragCoord.x;float y=gl_FragCoord.y;float blend=(y-u_horizon.y)*u_horizon_normal.y+(x-u_horizon.x)*u_horizon_normal.x;if (u_sky_blend > 0.0) {vec3 ray=normalize(v_view_direction);float globe_distance=length(u_globe_position);float angle_to_globe_center=acos(clamp(dot(ray,u_globe_position)/globe_distance,-1.0,1.0));float horizon_angle=asin(min(u_globe_radius/globe_distance,1.0));blend=mix(blend,(angle_to_globe_center-horizon_angle)*u_camera_to_center_distance*u_device_pixel_ratio,u_sky_blend);}if (blend > 0.0) {if (blend < u_sky_horizon_blend) {fragColor=mix(u_sky_color,u_horizon_color,pow(1.0-blend/u_sky_horizon_blend,2.0));} else {fragColor=u_sky_color;}}fragColor=mix(fragColor,vec4(vec3(0.0),0.0),u_sky_blend);}", "layout(location=0) in vec2 a_pos;uniform mat4 u_inv_proj_matrix;out vec3 v_view_direction;void main() {v_view_direction=(u_inv_proj_matrix*vec4(a_pos,0.0,1.0)).xyz;gl_Position=vec4(a_pos,1.0,1.0);}")
9102
9525
  };
9103
9526
  /** Expand #pragmas to #ifdefs, extract attributes and uniforms */
9104
9527
  function prepare(fragmentSource, vertexSource) {
@@ -9767,6 +10190,7 @@ var TransformHelper = class {
9767
10190
  const halfFov = this.fovInRadians / 2;
9768
10191
  this._cameraToCenterDistance = .5 / Math.tan(halfFov) * this._height;
9769
10192
  }
10193
+ this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize;
9770
10194
  this._callbacks.calcMatrices();
9771
10195
  }
9772
10196
  calculateCenterFromCameraLngLatAlt(lnglat, alt, bearing, pitch) {
@@ -9836,15 +10260,9 @@ var TransformHelper = class {
9836
10260
  };
9837
10261
  }
9838
10262
  getCameraPoint() {
9839
- const pitch = this.pitchInRadians;
9840
- const offset = Math.tan(pitch) * (this.cameraToCenterDistance || 1);
9841
- return this.centerPoint.add(new Point(offset * Math.sin(this.rollInRadians), offset * Math.cos(this.rollInRadians)));
9842
- }
9843
- getCameraAltitude() {
9844
- return Math.cos(this.pitchInRadians) * this._cameraToCenterDistance / this._pixelPerMeter + this.elevation;
9845
- }
9846
- getCameraLngLat() {
9847
- return cameraMercatorCoordinate(this).toLngLat();
10263
+ const pitch = this.pitchInRadians;
10264
+ const offset = Math.tan(pitch) * (this.cameraToCenterDistance || 1);
10265
+ return this.centerPoint.add(new Point(offset * Math.sin(this.rollInRadians), offset * Math.cos(this.rollInRadians)));
9848
10266
  }
9849
10267
  getMercatorTileCoordinates(overscaledTileID) {
9850
10268
  if (!overscaledTileID) return [
@@ -9863,63 +10281,6 @@ var TransformHelper = class {
9863
10281
  }
9864
10282
  };
9865
10283
  //#endregion
9866
- //#region src/util/primitives/aabb.ts
9867
- var Aabb = class Aabb {
9868
- constructor(min_, max_) {
9869
- this.min = min_;
9870
- this.max = max_;
9871
- this.center = scale$2([], add([], this.min, this.max), .5);
9872
- }
9873
- quadrant(index) {
9874
- const split = [index % 2 === 0, index < 2];
9875
- const qMin = clone(this.min);
9876
- const qMax = clone(this.max);
9877
- for (let axis = 0; axis < split.length; axis++) {
9878
- qMin[axis] = split[axis] ? this.min[axis] : this.center[axis];
9879
- qMax[axis] = split[axis] ? this.center[axis] : this.max[axis];
9880
- }
9881
- qMax[2] = this.max[2];
9882
- return new Aabb(qMin, qMax);
9883
- }
9884
- distanceX(point) {
9885
- return Math.max(Math.min(this.max[0], point[0]), this.min[0]) - point[0];
9886
- }
9887
- distanceY(point) {
9888
- return Math.max(Math.min(this.max[1], point[1]), this.min[1]) - point[1];
9889
- }
9890
- /**
9891
- * Performs a frustum-aabb intersection test.
9892
- */
9893
- intersectsFrustum(frustum) {
9894
- let fullyInside = true;
9895
- for (const plane of frustum.planes) {
9896
- const planeIntersection = this.intersectsPlane(plane);
9897
- if (planeIntersection === 0) return 0;
9898
- if (planeIntersection === 1) fullyInside = false;
9899
- }
9900
- if (fullyInside) return 2;
9901
- if (frustum.aabb.min[0] > this.max[0] || frustum.aabb.min[1] > this.max[1] || frustum.aabb.min[2] > this.max[2] || frustum.aabb.max[0] < this.min[0] || frustum.aabb.max[1] < this.min[1] || frustum.aabb.max[2] < this.min[2]) return 0;
9902
- return 1;
9903
- }
9904
- /**
9905
- * Performs a halfspace-aabb intersection test.
9906
- */
9907
- intersectsPlane(plane) {
9908
- let distMin = plane[3];
9909
- let distMax = plane[3];
9910
- for (let i = 0; i < 3; i++) if (plane[i] > 0) {
9911
- distMin += plane[i] * this.min[i];
9912
- distMax += plane[i] * this.max[i];
9913
- } else {
9914
- distMax += plane[i] * this.min[i];
9915
- distMin += plane[i] * this.max[i];
9916
- }
9917
- if (distMin >= 0) return 2;
9918
- if (distMax < 0) return 0;
9919
- return 1;
9920
- }
9921
- };
9922
- //#endregion
9923
10284
  //#region src/geo/projection/mercator_covering_tiles_details_provider.ts
9924
10285
  var MercatorCoveringTilesDetailsProvider = class {
9925
10286
  distanceToTile2d(pointX, pointY, _tileID, boundingVolume) {
@@ -9958,249 +10319,16 @@ var MercatorCoveringTilesDetailsProvider = class {
9958
10319
  maxElevation
9959
10320
  ]);
9960
10321
  }
9961
- allowVariableZoom(transform, options) {
9962
- const zfov = transform.fov * (Math.abs(Math.cos(transform.rollInRadians)) * transform.height + Math.abs(Math.sin(transform.rollInRadians)) * transform.width) / transform.height;
9963
- const maxConstantZoomPitch = clamp(78.5 - zfov / 2, 0, 60);
9964
- return !!options.terrain || transform.pitch > maxConstantZoomPitch;
9965
- }
9966
- allowWorldCopies() {
9967
- return true;
9968
- }
9969
- prepareNextFrame() {}
9970
- };
9971
- //#endregion
9972
- //#region src/util/primitives/frustum.ts
9973
- var Frustum = class Frustum {
9974
- constructor(points, planes, aabb) {
9975
- this.points = points;
9976
- this.planes = planes;
9977
- this.aabb = aabb;
9978
- }
9979
- static fromInvProjectionMatrix(invProj, worldSize = 1, zoom = 0, horizonPlane, flippedNearFar) {
9980
- const clipSpaceCorners = [
9981
- [
9982
- -1,
9983
- 1,
9984
- -1,
9985
- 1
9986
- ],
9987
- [
9988
- 1,
9989
- 1,
9990
- -1,
9991
- 1
9992
- ],
9993
- [
9994
- 1,
9995
- -1,
9996
- -1,
9997
- 1
9998
- ],
9999
- [
10000
- -1,
10001
- -1,
10002
- -1,
10003
- 1
10004
- ],
10005
- [
10006
- -1,
10007
- 1,
10008
- 1,
10009
- 1
10010
- ],
10011
- [
10012
- 1,
10013
- 1,
10014
- 1,
10015
- 1
10016
- ],
10017
- [
10018
- 1,
10019
- -1,
10020
- 1,
10021
- 1
10022
- ],
10023
- [
10024
- -1,
10025
- -1,
10026
- 1,
10027
- 1
10028
- ]
10029
- ];
10030
- const frustumPlanePointIndices = flippedNearFar ? [
10031
- [
10032
- 6,
10033
- 5,
10034
- 4
10035
- ],
10036
- [
10037
- 0,
10038
- 1,
10039
- 2
10040
- ],
10041
- [
10042
- 0,
10043
- 3,
10044
- 7
10045
- ],
10046
- [
10047
- 2,
10048
- 1,
10049
- 5
10050
- ],
10051
- [
10052
- 3,
10053
- 2,
10054
- 6
10055
- ],
10056
- [
10057
- 0,
10058
- 4,
10059
- 5
10060
- ]
10061
- ] : [
10062
- [
10063
- 0,
10064
- 1,
10065
- 2
10066
- ],
10067
- [
10068
- 6,
10069
- 5,
10070
- 4
10071
- ],
10072
- [
10073
- 0,
10074
- 3,
10075
- 7
10076
- ],
10077
- [
10078
- 2,
10079
- 1,
10080
- 5
10081
- ],
10082
- [
10083
- 3,
10084
- 2,
10085
- 6
10086
- ],
10087
- [
10088
- 0,
10089
- 4,
10090
- 5
10091
- ]
10092
- ];
10093
- const scale = Math.pow(2, zoom);
10094
- const frustumCoords = clipSpaceCorners.map((v) => unprojectClipSpacePoint(v, invProj, worldSize, scale));
10095
- if (horizonPlane) adjustFarPlaneByHorizonPlane(frustumCoords, frustumPlanePointIndices[0], horizonPlane, flippedNearFar);
10096
- const frustumPlanes = frustumPlanePointIndices.map((p) => {
10097
- const a = sub([], frustumCoords[p[0]], frustumCoords[p[1]]);
10098
- const b = sub([], frustumCoords[p[2]], frustumCoords[p[1]]);
10099
- const n = normalize([], cross([], a, b));
10100
- const d = -dot(n, frustumCoords[p[1]]);
10101
- return n.concat(d);
10102
- });
10103
- const min = [
10104
- Number.POSITIVE_INFINITY,
10105
- Number.POSITIVE_INFINITY,
10106
- Number.POSITIVE_INFINITY
10107
- ];
10108
- const max = [
10109
- Number.NEGATIVE_INFINITY,
10110
- Number.NEGATIVE_INFINITY,
10111
- Number.NEGATIVE_INFINITY
10112
- ];
10113
- for (const p of frustumCoords) for (let i = 0; i < 3; i++) {
10114
- min[i] = Math.min(min[i], p[i]);
10115
- max[i] = Math.max(max[i], p[i]);
10116
- }
10117
- return new Frustum(frustumCoords, frustumPlanes, new Aabb(min, max));
10118
- }
10119
- };
10120
- function unprojectClipSpacePoint(point, invProj, worldSize, scale) {
10121
- const v = transformMat4([], point, invProj);
10122
- const s = 1 / v[3] / worldSize * scale;
10123
- return mul(v, v, [
10124
- s,
10125
- s,
10126
- 1 / v[3],
10127
- s
10128
- ]);
10129
- }
10130
- /**
10131
- * Modifies points in the supplied `frustumCoords` array so that the frustum's far plane only lies as far as the horizon,
10132
- * which improves frustum culling effectiveness.
10133
- * @param frustumCoords - Points of the frustum.
10134
- * @param nearPlanePointsIndices - Which indices in the `frustumCoords` form the near plane.
10135
- * @param horizonPlane - The horizon plane.
10136
- */
10137
- function adjustFarPlaneByHorizonPlane(frustumCoords, nearPlanePointsIndices, horizonPlane, flippedNearFar) {
10138
- const nearPlanePointsOffset = flippedNearFar ? 4 : 0;
10139
- const farPlanePointsOffset = flippedNearFar ? 0 : 4;
10140
- let maxDist = 0;
10141
- const cornerRayLengths = [];
10142
- const cornerRayNormalizedDirections = [];
10143
- for (let i = 0; i < 4; i++) {
10144
- const dir = sub([], frustumCoords[i + farPlanePointsOffset], frustumCoords[i + nearPlanePointsOffset]);
10145
- const len = length$1(dir);
10146
- scale$2(dir, dir, 1 / len);
10147
- cornerRayLengths.push(len);
10148
- cornerRayNormalizedDirections.push(dir);
10149
- }
10150
- for (let i = 0; i < 4; i++) {
10151
- const dist = rayPlaneIntersection(frustumCoords[i + nearPlanePointsOffset], cornerRayNormalizedDirections[i], horizonPlane);
10152
- if (dist !== null && dist >= 0) maxDist = Math.max(maxDist, dist);
10153
- else maxDist = Math.max(maxDist, cornerRayLengths[i]);
10154
- }
10155
- const nearPlaneNormalized = getNormalizedNearPlane(frustumCoords, nearPlanePointsIndices);
10156
- const idealFarPlaneDistanceFromNearPlane = getIdealNearFarPlaneDistance(horizonPlane, nearPlaneNormalized);
10157
- if (idealFarPlaneDistanceFromNearPlane !== null) {
10158
- const idealCornerRayLength = idealFarPlaneDistanceFromNearPlane / dot(cornerRayNormalizedDirections[0], nearPlaneNormalized);
10159
- maxDist = Math.min(maxDist, idealCornerRayLength);
10322
+ allowVariableZoom(transform, options) {
10323
+ const zfov = transform.fov * (Math.abs(Math.cos(transform.rollInRadians)) * transform.height + Math.abs(Math.sin(transform.rollInRadians)) * transform.width) / transform.height;
10324
+ const maxConstantZoomPitch = clamp(78.5 - zfov / 2, 0, 60);
10325
+ return !!options.terrain || transform.pitch > maxConstantZoomPitch;
10160
10326
  }
10161
- for (let i = 0; i < 4; i++) {
10162
- const targetLength = Math.min(maxDist, cornerRayLengths[i]);
10163
- frustumCoords[i + farPlanePointsOffset] = [
10164
- frustumCoords[i + nearPlanePointsOffset][0] + cornerRayNormalizedDirections[i][0] * targetLength,
10165
- frustumCoords[i + nearPlanePointsOffset][1] + cornerRayNormalizedDirections[i][1] * targetLength,
10166
- frustumCoords[i + nearPlanePointsOffset][2] + cornerRayNormalizedDirections[i][2] * targetLength,
10167
- 1
10168
- ];
10327
+ allowWorldCopies() {
10328
+ return true;
10169
10329
  }
10170
- }
10171
- /**
10172
- * Returns the near plane equation with unit length direction.
10173
- * @param frustumCoords - Points of the frustum.
10174
- * @param nearPlanePointsIndices - Which indices in the `frustumCoords` form the near plane.
10175
- */
10176
- function getNormalizedNearPlane(frustumCoords, nearPlanePointsIndices) {
10177
- const nearPlaneA = sub([], frustumCoords[nearPlanePointsIndices[0]], frustumCoords[nearPlanePointsIndices[1]]);
10178
- const nearPlaneB = sub([], frustumCoords[nearPlanePointsIndices[2]], frustumCoords[nearPlanePointsIndices[1]]);
10179
- const nearPlaneNormalized = [
10180
- 0,
10181
- 0,
10182
- 0,
10183
- 0
10184
- ];
10185
- normalize(nearPlaneNormalized, cross([], nearPlaneA, nearPlaneB));
10186
- nearPlaneNormalized[3] = -dot(nearPlaneNormalized, frustumCoords[nearPlanePointsIndices[0]]);
10187
- return nearPlaneNormalized;
10188
- }
10189
- /**
10190
- * Returns the ideal distance between the frustum's near and far plane so that the far plane only lies as far as the horizon.
10191
- */
10192
- function getIdealNearFarPlaneDistance(horizonPlane, nearPlaneNormalized) {
10193
- const horizonPlaneLen = len(horizonPlane);
10194
- const normalizedHorizonPlane = scale$3([], horizonPlane, 1 / horizonPlaneLen);
10195
- const projectedViewDirection = sub([], nearPlaneNormalized, scale$2([], normalizedHorizonPlane, dot(nearPlaneNormalized, normalizedHorizonPlane)));
10196
- const projectedViewLength = len(projectedViewDirection);
10197
- if (projectedViewLength > 0) {
10198
- const horizonCircleRadius = Math.sqrt(1 - normalizedHorizonPlane[3] * normalizedHorizonPlane[3]);
10199
- const horizonCircleCenter = scale$2([], normalizedHorizonPlane, -normalizedHorizonPlane[3]);
10200
- const pointFurthestOnHorizonCircle = add([], horizonCircleCenter, scale$2([], projectedViewDirection, horizonCircleRadius / projectedViewLength));
10201
- return pointPlaneSignedDistance(nearPlaneNormalized, pointFurthestOnHorizonCircle);
10202
- } else return null;
10203
- }
10330
+ prepareNextFrame() {}
10331
+ };
10204
10332
  //#endregion
10205
10333
  //#region src/data/pos3d_attributes.ts
10206
10334
  const pos3dAttributes = createLayout([{
@@ -11437,6 +11565,27 @@ var MercatorTransform = class MercatorTransform {
11437
11565
  calculateCenterFromCameraLngLatAlt(lnglat, alt, bearing, pitch) {
11438
11566
  return this._helper.calculateCenterFromCameraLngLatAlt(lnglat, alt, bearing, pitch);
11439
11567
  }
11568
+ calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
11569
+ const fromMercator = MercatorCoordinate.fromLngLat(from, altitudeFrom);
11570
+ const toMercator = MercatorCoordinate.fromLngLat(to, altitudeTo);
11571
+ const dx = toMercator.x - fromMercator.x;
11572
+ const dy = toMercator.y - fromMercator.y;
11573
+ const dz = toMercator.z - fromMercator.z;
11574
+ const distance3D = Math.hypot(dx, dy, dz);
11575
+ if (distance3D === 0) throw new Error("Can't calculate camera options with same From and To");
11576
+ const groundDistance = Math.hypot(dx, dy);
11577
+ const zoom = scaleZoom(this.cameraToCenterDistance / distance3D / this.tileSize);
11578
+ const bearing = radiansToDegrees(Math.atan2(dx, -dy));
11579
+ let pitch = radiansToDegrees(Math.acos(groundDistance / distance3D));
11580
+ pitch = dz < 0 ? 90 - pitch : 90 + pitch;
11581
+ return {
11582
+ center: toMercator.toLngLat(),
11583
+ elevation: altitudeTo,
11584
+ zoom,
11585
+ pitch,
11586
+ bearing
11587
+ };
11588
+ }
11440
11589
  _calculateNearFarZIfNeeded(cameraToSeaLevelDistance, limitedPitchRadians, offset) {
11441
11590
  if (!this._helper.autoCalculateNearFarZ) return;
11442
11591
  const minElevation = Math.min(this.elevation, this.minElevationForCurrentTile, this.getCameraAltitude() - 100);
@@ -11459,7 +11608,6 @@ var MercatorTransform = class MercatorTransform {
11459
11608
  const offset = this.centerOffset;
11460
11609
  const point = projectToWorldCoordinates(this.worldSize, this.center);
11461
11610
  const x = point.x, y = point.y;
11462
- this._helper._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize;
11463
11611
  const limitedPitchRadians = degreesToRadians(Math.min(this.pitch, maxMercatorHorizonAngle));
11464
11612
  const cameraToSeaLevelDistance = Math.max(this._helper.cameraToCenterDistance / 2, this._helper.cameraToCenterDistance + this._helper._elevation * this._helper._pixelPerMeter / Math.cos(limitedPitchRadians));
11465
11613
  this._calculateNearFarZIfNeeded(cameraToSeaLevelDistance, limitedPitchRadians, offset);
@@ -11585,7 +11733,7 @@ var MercatorTransform = class MercatorTransform {
11585
11733
  return this._helper.getCameraPoint();
11586
11734
  }
11587
11735
  getCameraAltitude() {
11588
- return this._helper.getCameraAltitude();
11736
+ return Math.cos(this.pitchInRadians) * this.cameraToCenterDistance / this.pixelsPerMeter + this.elevation;
11589
11737
  }
11590
11738
  getCameraLngLat() {
11591
11739
  const pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize;
@@ -12107,6 +12255,23 @@ function getGlobeRadiusPixels(worldSize, latitudeDegrees) {
12107
12255
  return worldSize / (2 * Math.PI) / Math.cos(latitudeDegrees * Math.PI / 180);
12108
12256
  }
12109
12257
  /**
12258
+ * Returns the globe center in view space, in pixels: the camera is at the origin and looks down the negative Z axis.
12259
+ */
12260
+ function getGlobeCenterInViewSpace(transform) {
12261
+ const position = transformMat4(createVec4f64(), [
12262
+ 0,
12263
+ 0,
12264
+ 0,
12265
+ 1
12266
+ ], transform.modelViewProjectionMatrix);
12267
+ transformMat4(position, position, transform.inverseProjectionMatrix);
12268
+ return [
12269
+ position[0] / position[3],
12270
+ position[1] / position[3],
12271
+ position[2] / position[3]
12272
+ ];
12273
+ }
12274
+ /**
12110
12275
  * Given a 3D point on the surface of a unit sphere, returns its angular coordinates in degrees.
12111
12276
  * The input vector must be normalized.
12112
12277
  */
@@ -12160,7 +12325,7 @@ const PAN_MAX_ANGLE = Math.PI * .98;
12160
12325
  */
12161
12326
  function panSurfaceLocation(tr, point) {
12162
12327
  const origin = tr.cameraPosition;
12163
- const distance = length$1(origin);
12328
+ const distance = length(origin);
12164
12329
  if (distance <= 1) return tr.screenPointToLocation(point);
12165
12330
  const u = createVec3f64();
12166
12331
  normalize(u, origin);
@@ -12168,7 +12333,7 @@ function panSurfaceLocation(tr, point) {
12168
12333
  const c = -dot(direction, u);
12169
12334
  const lateral = createVec3f64();
12170
12335
  scaleAndAdd(lateral, direction, u, c);
12171
- const s = length$1(lateral);
12336
+ const s = length(lateral);
12172
12337
  if (s < 1e-9) return tr.screenPointToLocation(point);
12173
12338
  const angle = Math.atan2(s, c);
12174
12339
  const handoverAngle = Math.asin(1 / distance) * .9;
@@ -12180,9 +12345,9 @@ function panSurfaceLocation(tr, point) {
12180
12345
  const excess = angle - handoverAngle;
12181
12346
  const target = targetAtHandover + room * (slopeAtHandover * excess) / (room + slopeAtHandover * excess);
12182
12347
  const e = createVec3f64();
12183
- scale$2(e, lateral, 1 / s);
12348
+ scale$1(e, lateral, 1 / s);
12184
12349
  const surface = createVec3f64();
12185
- scale$2(surface, u, Math.cos(clamp(target, 0, PAN_MAX_ANGLE)));
12350
+ scale$1(surface, u, Math.cos(clamp(target, 0, PAN_MAX_ANGLE)));
12186
12351
  scaleAndAdd(surface, surface, e, Math.sin(clamp(target, 0, PAN_MAX_ANGLE)));
12187
12352
  normalize(surface, surface);
12188
12353
  return sphereSurfacePointToCoordinates(surface);
@@ -12377,7 +12542,7 @@ function raySphereIntersection(origin, direction, radius = 1) {
12377
12542
  const radiusSquared = radius * radius;
12378
12543
  const inner = createVec3f64();
12379
12544
  const scaledDir = createVec3f64();
12380
- scale$2(scaledDir, direction, originDotDirection);
12545
+ scale$1(scaledDir, direction, originDotDirection);
12381
12546
  sub(inner, origin, scaledDir);
12382
12547
  const discriminant = radiusSquared - dot(inner, inner);
12383
12548
  if (discriminant < 0) return null;
@@ -12537,9 +12702,9 @@ var ConvexVolume = class ConvexVolume {
12537
12702
  const points = [];
12538
12703
  for (let i = 0; i < 8; i++) {
12539
12704
  const p = [...center];
12540
- add(p, p, scale$2([], axisX, (i >> 0 & 1) === 1 ? 1 : -1));
12541
- add(p, p, scale$2([], axisY, (i >> 1 & 1) === 1 ? 1 : -1));
12542
- add(p, p, scale$2([], axisZ, (i >> 2 & 1) === 1 ? 1 : -1));
12705
+ add(p, p, scale$1([], axisX, (i >> 0 & 1) === 1 ? 1 : -1));
12706
+ add(p, p, scale$1([], axisY, (i >> 1 & 1) === 1 ? 1 : -1));
12707
+ add(p, p, scale$1([], axisZ, (i >> 2 & 1) === 1 ? 1 : -1));
12543
12708
  points.push(p);
12544
12709
  }
12545
12710
  return new ConvexVolume(points, [
@@ -12685,6 +12850,11 @@ var GlobeCoveringTilesDetailsProvider = class {
12685
12850
  getTileBoundingVolume(tileID, wrap, elevation, options) {
12686
12851
  return this._boundingVolumeCache.getTileBoundingVolume(tileID, wrap, elevation, options);
12687
12852
  }
12853
+ /**
12854
+ * Computes the bounding volume of a tile for culling. The volume reaches up to `elevation`,
12855
+ * which carries the content elevation allowance (e.g. elevated symbols); terrain elevations
12856
+ * widen the volume but never shrink that allowance.
12857
+ */
12688
12858
  _computeTileBoundingVolume(tileID, wrap, elevation, options) {
12689
12859
  let minElevation = Math.min(0, elevation);
12690
12860
  let maxElevation = Math.max(0, elevation);
@@ -12692,7 +12862,7 @@ var GlobeCoveringTilesDetailsProvider = class {
12692
12862
  const overscaledTileID = new OverscaledTileID(tileID.z, wrap, tileID.z, tileID.x, tileID.y);
12693
12863
  const minMax = options.terrain.getMinMaxElevation(overscaledTileID);
12694
12864
  minElevation = minMax.minElevation ?? minElevation;
12695
- maxElevation = minMax.maxElevation ?? maxElevation;
12865
+ maxElevation = Math.max(minMax.maxElevation ?? maxElevation, maxElevation);
12696
12866
  }
12697
12867
  minElevation /= earthRadius;
12698
12868
  maxElevation /= earthRadius;
@@ -12724,8 +12894,8 @@ var GlobeCoveringTilesDetailsProvider = class {
12724
12894
  projectTileCoordinatesToSphere(0, EXTENT, tileID.x, tileID.y, tileID.z)
12725
12895
  ];
12726
12896
  const extremesPoints = [];
12727
- for (const c of corners) extremesPoints.push(scale$2([], c, maxElevation));
12728
- if (maxElevation !== minElevation) for (const c of corners) extremesPoints.push(scale$2([], c, minElevation));
12897
+ for (const c of corners) extremesPoints.push(scale$1([], c, maxElevation));
12898
+ if (maxElevation !== minElevation) for (const c of corners) extremesPoints.push(scale$1([], c, minElevation));
12729
12899
  if (tileID.y === 0) extremesPoints.push([
12730
12900
  0,
12731
12901
  1,
@@ -12763,9 +12933,9 @@ var GlobeCoveringTilesDetailsProvider = class {
12763
12933
  normalize(axisEast, axisEast);
12764
12934
  const axisWest = cross([], corners[0], corners[3]);
12765
12935
  normalize(axisWest, axisWest);
12766
- extremesPoints.push(scale$2([], center, maxElevation));
12767
- if (tileID.y >= (1 << tileID.z) / 2) extremesPoints.push(scale$2([], projectTileCoordinatesToSphere(EXTENT / 2, 0, tileID.x, tileID.y, tileID.z), maxElevation));
12768
- if (tileID.y < (1 << tileID.z) / 2) extremesPoints.push(scale$2([], projectTileCoordinatesToSphere(EXTENT / 2, EXTENT, tileID.x, tileID.y, tileID.z), maxElevation));
12936
+ extremesPoints.push(scale$1([], center, maxElevation));
12937
+ if (tileID.y >= (1 << tileID.z) / 2) extremesPoints.push(scale$1([], projectTileCoordinatesToSphere(EXTENT / 2, 0, tileID.x, tileID.y, tileID.z), maxElevation));
12938
+ if (tileID.y < (1 << tileID.z) / 2) extremesPoints.push(scale$1([], projectTileCoordinatesToSphere(EXTENT / 2, EXTENT, tileID.x, tileID.y, tileID.z), maxElevation));
12769
12939
  const upDownMinMax = findAxisMinMax(center, extremesPoints);
12770
12940
  const northSouthMinMax = findAxisMinMax(north, extremesPoints);
12771
12941
  const planeUp = [
@@ -12829,6 +12999,10 @@ const GLOBE_SAMPLES = 256;
12829
12999
  const GLOBE_BISECT_EPSILON_T = 1e-12;
12830
13000
  /** Latitudes outside the mercator range project past the world edge; the globe mesh still covers them. */
12831
13001
  const MAX_MERCATOR_Y = 1 - 1e-9;
13002
+ /** Two points on the unit globe closer than this, a micrometre, are the same point. */
13003
+ const SAME_POINT_DISTANCE = 1e-12;
13004
+ /** A camera whose horizontal offset is this small relative to its distance is straight above the center. */
13005
+ const STRAIGHT_ABOVE_RATIO = 1e-9;
12832
13006
  var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
12833
13007
  get pixelsToClipSpaceMatrix() {
12834
13008
  return this._helper.pixelsToClipSpaceMatrix;
@@ -13115,8 +13289,8 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13115
13289
  0,
13116
13290
  0
13117
13291
  ], this.center.lng * Math.PI / 180);
13118
- const scale = 1 / length$1(planeVector);
13119
- scale$2(planeVector, planeVector, scale);
13292
+ const scale = 1 / length(planeVector);
13293
+ scale$1(planeVector, planeVector, scale);
13120
13294
  return [...planeVector, -tangentPlaneDistanceToC * scale];
13121
13295
  }
13122
13296
  isLocationOccluded(location) {
@@ -13172,21 +13346,43 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13172
13346
  const canonical = unwrappedTileID.canonical;
13173
13347
  const spherePos = projectTileCoordinatesToSphere(x, y, canonical.x, canonical.y, canonical.z);
13174
13348
  const vectorMultiplier = 1 + (elevation ?? 0) / earthRadius;
13349
+ const elevatedX = spherePos[0] * vectorMultiplier;
13350
+ const elevatedY = spherePos[1] * vectorMultiplier;
13351
+ const elevatedZ = spherePos[2] * vectorMultiplier;
13175
13352
  const pos = [
13176
- spherePos[0] * vectorMultiplier,
13177
- spherePos[1] * vectorMultiplier,
13178
- spherePos[2] * vectorMultiplier,
13353
+ elevatedX,
13354
+ elevatedY,
13355
+ elevatedZ,
13179
13356
  1
13180
13357
  ];
13181
13358
  transformMat4(pos, pos, this._globeViewProjMatrixF64);
13182
- const plane = this._cachedClippingPlane;
13183
- const isOccluded = plane[0] * spherePos[0] + plane[1] * spherePos[1] + plane[2] * spherePos[2] + plane[3] < 0;
13359
+ let isOccluded;
13360
+ if (vectorMultiplier <= 1) {
13361
+ const plane = this._cachedClippingPlane;
13362
+ isOccluded = plane[0] * spherePos[0] + plane[1] * spherePos[1] + plane[2] * spherePos[2] + plane[3] < 0;
13363
+ } else isOccluded = this._isLineOfSightBlocked(elevatedX, elevatedY, elevatedZ);
13184
13364
  return {
13185
13365
  point: new Point(pos[0] / pos[3], pos[1] / pos[3]),
13186
13366
  signedDistanceFromCamera: pos[3],
13187
13367
  isOccluded
13188
13368
  };
13189
13369
  }
13370
+ /**
13371
+ * True when the segment from the camera to the given point, both in unit-globe coordinates, passes through the planet.
13372
+ */
13373
+ _isLineOfSightBlocked(x, y, z) {
13374
+ const cam = this._cameraPosition;
13375
+ const dx = x - cam[0];
13376
+ const dy = y - cam[1];
13377
+ const dz = z - cam[2];
13378
+ const lengthSq = dx * dx + dy * dy + dz * dz;
13379
+ if (lengthSq === 0) return false;
13380
+ const t = clamp(-(cam[0] * dx + cam[1] * dy + cam[2] * dz) / lengthSq, 0, 1);
13381
+ const cx = cam[0] + t * dx;
13382
+ const cy = cam[1] + t * dy;
13383
+ const cz = cam[2] + t * dz;
13384
+ return cx * cx + cy * cy + cz * cz < 1;
13385
+ }
13190
13386
  _calcMatrices() {
13191
13387
  if (!this._helper._width || !this._helper._height) return;
13192
13388
  const globeRadiusPixels = getGlobeRadiusPixels(this.worldSize, this.center.lat);
@@ -13279,16 +13475,22 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13279
13475
  getCameraPoint() {
13280
13476
  return this._helper.getCameraPoint();
13281
13477
  }
13478
+ /**
13479
+ * The altitude of the rendered camera above sea level. The sphere keeps the center point at sea level whatever its
13480
+ * elevation (`_calcMatrices` does not apply it), so unlike on mercator the center elevation does not lift the camera.
13481
+ * {@link calculateCameraOptionsFromTo} is the inverse.
13482
+ */
13282
13483
  getCameraAltitude() {
13283
- return this._helper.getCameraAltitude();
13484
+ return (length(this._cameraPosition) - 1) * earthRadius;
13284
13485
  }
13285
13486
  getCameraLngLat() {
13286
- return this._helper.getCameraLngLat();
13487
+ const surface = createVec3f64();
13488
+ normalize(surface, this._cameraPosition);
13489
+ return sphereSurfacePointToCoordinates(surface);
13287
13490
  }
13288
13491
  lngLatToCameraDepth(lngLat, elevation) {
13289
- if (!this._globeViewProjMatrixF64) return 1;
13290
13492
  const vec = angularCoordinatesToSurfaceVector(lngLat);
13291
- scale$2(vec, vec, 1 + elevation / earthRadius);
13493
+ scale$1(vec, vec, 1 + elevation / earthRadius);
13292
13494
  const result = createVec4f64();
13293
13495
  transformMat4(result, [
13294
13496
  vec[0],
@@ -13354,6 +13556,34 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13354
13556
  return this._helper.calculateCenterFromCameraLngLatAlt(lngLat, alt, bearing, pitch);
13355
13557
  }
13356
13558
  /**
13559
+ * Inverts the camera placement of `_calcMatrices` in unit-globe coordinates: the camera sits at radius
13560
+ * `1 + altitudeFrom / earthRadius` and looks at the center on the sea-level sphere, the target altitude only becoming
13561
+ * the center elevation (the inverse of {@link getCameraAltitude}). Pitch and bearing are read in the center's local
13562
+ * frame, +z up, +y north, +x east. A camera straight above the center keeps the transform's bearing.
13563
+ */
13564
+ calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
13565
+ const center = LngLat.convert(to);
13566
+ const camera = angularCoordinatesToSurfaceVector(LngLat.convert(from));
13567
+ scale$1(camera, camera, 1 + altitudeFrom / earthRadius);
13568
+ const target = angularCoordinatesToSurfaceVector(center);
13569
+ const targetAtAltitude = scale$1(createVec3f64(), target, 1 + altitudeTo / earthRadius);
13570
+ const toCamera = subtract(createVec3f64(), camera, target);
13571
+ const distance$1 = length(toCamera);
13572
+ if (distance$1 < SAME_POINT_DISTANCE || distance(camera, targetAtAltitude) < SAME_POINT_DISTANCE) throw new Error("Can't calculate camera options with same From and To");
13573
+ const zero = createVec3f64();
13574
+ rotateY(toCamera, toCamera, zero, -degreesToRadians(center.lng));
13575
+ rotateX$1(toCamera, toCamera, zero, degreesToRadians(center.lat));
13576
+ const pitch = radiansToDegrees(Math.acos(clamp(toCamera[2] / distance$1, -1, 1)));
13577
+ const bearing = Math.hypot(toCamera[0], toCamera[1]) < distance$1 * STRAIGHT_ABOVE_RATIO ? this.bearing : radiansToDegrees(Math.atan2(-toCamera[0], -toCamera[1]));
13578
+ return {
13579
+ center,
13580
+ elevation: altitudeTo,
13581
+ zoom: scaleZoom(this.cameraToCenterDistance / distance$1 / getGlobeRadiusPixels(this.tileSize, center.lat)),
13582
+ pitch,
13583
+ bearing
13584
+ };
13585
+ }
13586
+ /**
13357
13587
  * Note: automatically adjusts zoom to keep planet size consistent
13358
13588
  * (same size before and after a {@link setLocationAtPoint} call).
13359
13589
  */
@@ -13414,7 +13644,7 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13414
13644
  const pos = angularCoordinatesToSurfaceVector(lnglat);
13415
13645
  if (terrain) {
13416
13646
  const elevation = terrain.getElevationForLngLatZoom(lnglat, this._helper._tileZoom);
13417
- scale$2(pos, pos, 1 + elevation / earthRadius);
13647
+ scale$1(pos, pos, 1 + elevation / earthRadius);
13418
13648
  }
13419
13649
  return this._projectSurfacePointToScreen(pos);
13420
13650
  }
@@ -13586,9 +13816,9 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13586
13816
  function globeSampleAt(ray, t) {
13587
13817
  const position = createVec3f64();
13588
13818
  scaleAndAdd(position, ray.origin, ray.direction, t);
13589
- const radius = length$1(position);
13819
+ const radius = length(position);
13590
13820
  const surface = createVec3f64();
13591
- scale$2(surface, position, 1 / radius);
13821
+ scale$1(surface, position, 1 / radius);
13592
13822
  const lngLat = sphereSurfacePointToCoordinates(surface);
13593
13823
  const projected = MercatorCoordinate.fromLngLat(lngLat);
13594
13824
  const mercator = new MercatorCoordinate(projected.x, clamp(projected.y, 0, MAX_MERCATOR_Y));
@@ -13925,11 +14155,13 @@ var GlobeTransform = class GlobeTransform {
13925
14155
  getCameraPoint() {
13926
14156
  return this._helper.getCameraPoint();
13927
14157
  }
14158
+ /** The camera of the child that renders the current frame. */
13928
14159
  getCameraAltitude() {
13929
- return this._helper.getCameraAltitude();
14160
+ return this.currentTransform.getCameraAltitude();
13930
14161
  }
14162
+ /** See {@link getCameraAltitude}. */
13931
14163
  getCameraLngLat() {
13932
- return this._helper.getCameraLngLat();
14164
+ return this.currentTransform.getCameraLngLat();
13933
14165
  }
13934
14166
  lngLatToCameraDepth(lngLat, elevation) {
13935
14167
  return this.currentTransform.lngLatToCameraDepth(lngLat, elevation);
@@ -13944,6 +14176,10 @@ var GlobeTransform = class GlobeTransform {
13944
14176
  calculateCenterFromCameraLngLatAlt(lngLat, alt, bearing, pitch) {
13945
14177
  return this._helper.calculateCenterFromCameraLngLatAlt(lngLat, alt, bearing, pitch);
13946
14178
  }
14179
+ /** See {@link getCameraAltitude}. */
14180
+ calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
14181
+ return this.currentTransform.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo);
14182
+ }
13947
14183
  /**
13948
14184
  * Note: automatically adjusts zoom to keep planet size consistent
13949
14185
  * (same size before and after a {@link setLocationAtPoint} call).
@@ -14069,7 +14305,7 @@ var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
14069
14305
  rayDirection[1] * distanceToClosestPoint,
14070
14306
  rayDirection[2] * distanceToClosestPoint
14071
14307
  ]);
14072
- const rayDistanceFromGlobeCenter = length$1(closestPoint);
14308
+ const rayDistanceFromGlobeCenter = length(closestPoint);
14073
14309
  const distanceFromSurface = rayDistanceFromGlobeCenter - 1;
14074
14310
  const distanceFactor = Math.exp(-Math.max(distanceFromSurface - RAY_SURFACE_DISTANCE_FOR_SLOWING_START, 0) * SLOWING_MULTIPLIER);
14075
14311
  const interpolationFactorHorizon = remapSaturate(rayDistanceFromGlobeCenter, INTERPOLATE_TO_HEURISTIC_START_HORIZON, INTERPOLATE_TO_HEURISTIC_END_HORIZON, 0, 1);
@@ -15026,13 +15262,13 @@ var Style = class extends Evented {
15026
15262
  return;
15027
15263
  }
15028
15264
  if (id === before) return;
15029
- const index = this._order.indexOf(id);
15030
- this._order.splice(index, 1);
15031
- const newIndex = before ? this._order.indexOf(before) : this._order.length;
15032
- if (before && newIndex === -1) {
15265
+ if (before && !this._order.includes(before)) {
15033
15266
  this.fire(new ErrorEvent(/* @__PURE__ */ new Error(`Cannot move layer "${id}" before non-existing layer "${before}".`)));
15034
15267
  return;
15035
15268
  }
15269
+ const index = this._order.indexOf(id);
15270
+ this._order.splice(index, 1);
15271
+ const newIndex = before ? this._order.indexOf(before) : this._order.length;
15036
15272
  this._order.splice(newIndex, 0, id);
15037
15273
  this._layerOrderChanged = true;
15038
15274
  }
@@ -15059,6 +15295,7 @@ var Style = class extends Evented {
15059
15295
  if (this._serializedLayers) delete this._serializedLayers[id];
15060
15296
  delete this._updatedLayers[id];
15061
15297
  delete this._updatedPaintProps[id];
15298
+ if (layer.type === "symbol" && layer.source) this.tileManagers[layer.source]?.resetMaxContentElevation();
15062
15299
  if (layer.onRemove) layer.onRemove(this.map);
15063
15300
  }
15064
15301
  /**
@@ -15774,11 +16011,7 @@ var VertexArrayObject = class {
15774
16011
  //#region src/webgl/program/terrain_program.ts
15775
16012
  const terrainPreludeUniforms = (context, locations) => ({
15776
16013
  "u_depth": new Uniform1i(context, locations.u_depth),
15777
- "u_terrain": new Uniform1i(context, locations.u_terrain),
15778
- "u_terrain_dim": new Uniform1f(context, locations.u_terrain_dim),
15779
- "u_terrain_matrix": new UniformMatrix4f(context, locations.u_terrain_matrix),
15780
- "u_terrain_unpack": new Uniform4f(context, locations.u_terrain_unpack),
15781
- "u_terrain_exaggeration": new Uniform1f(context, locations.u_terrain_exaggeration)
16014
+ "u_terrain": new Uniform1i(context, locations.u_terrain)
15782
16015
  });
15783
16016
  const terrainUniforms = (context, locations) => ({
15784
16017
  "u_texture": new Uniform1i(context, locations.u_texture),
@@ -15805,26 +16038,173 @@ const terrainUniformValues = (eleDelta, fogMatrix, sky, pitch, isGlobeMode) => (
15805
16038
  });
15806
16039
  const terrainDepthUniformValues = (eleDelta) => ({ "u_ele_delta": eleDelta });
15807
16040
  //#endregion
15808
- //#region src/webgl/program/projection_program.ts
15809
- const projectionUniforms = (context, locations) => ({
15810
- "u_projection_matrix": new UniformMatrix4f(context, locations.u_projection_matrix),
15811
- "u_projection_tile_mercator_coords": new Uniform4f(context, locations.u_projection_tile_mercator_coords),
15812
- "u_projection_clipping_plane": new Uniform4f(context, locations.u_projection_clipping_plane),
15813
- "u_projection_transition": new Uniform1f(context, locations.u_projection_transition),
15814
- "u_projection_fallback_matrix": new UniformMatrix4f(context, locations.u_projection_fallback_matrix),
15815
- "u_projection_clip_antimeridian": new Uniform1i(context, locations.u_projection_clip_antimeridian)
15816
- });
16041
+ //#region src/webgl/uniform_buffer.ts
16042
+ const UBO_BINDINGS = {
16043
+ ProjectionUBO: 0,
16044
+ TerrainUBO: 1,
16045
+ FrameUBO: 2
16046
+ };
16047
+ function applyUBOBindings(gl, program) {
16048
+ for (const [name, binding] of Object.entries(UBO_BINDINGS)) {
16049
+ const index = gl.getUniformBlockIndex(program, name);
16050
+ if (index !== gl.INVALID_INDEX) gl.uniformBlockBinding(program, index, binding);
16051
+ }
16052
+ }
16053
+ const STD140_SIZE_AND_ALIGNMENT_WORDS = {
16054
+ float: [1, 1],
16055
+ int: [1, 1],
16056
+ vec2: [2, 2],
16057
+ vec4: [4, 4],
16058
+ mat4: [16, 4]
16059
+ };
16060
+ function std140Layout(members) {
16061
+ const offsets = {};
16062
+ let words = 0;
16063
+ for (const { name, type } of members) {
16064
+ const [size, alignment] = STD140_SIZE_AND_ALIGNMENT_WORDS[type];
16065
+ words = Math.ceil(words / alignment) * alignment;
16066
+ offsets[name] = words;
16067
+ words += size;
16068
+ }
16069
+ return {
16070
+ offsets,
16071
+ contentWords: words,
16072
+ sizeWords: Math.ceil(words / 4) * 4
16073
+ };
16074
+ }
15817
16075
  /**
15818
- * Converts a {@link ProjectionData} object into the values expected by the projection prelude's uniforms.
16076
+ * @internal
16077
+ * The buffer behind one std140 uniform block, bound to a fixed binding point. Callers write members into
16078
+ * `pending` at the layout's offsets and call `upload`, which skips the GPU write when nothing changed.
15819
16079
  */
15820
- const projectionUniformValues = (projectionData) => ({
15821
- "u_projection_matrix": projectionData.mainMatrix,
15822
- "u_projection_tile_mercator_coords": projectionData.tileMercatorCoords,
15823
- "u_projection_clipping_plane": projectionData.clippingPlane,
15824
- "u_projection_transition": projectionData.projectionTransition,
15825
- "u_projection_fallback_matrix": projectionData.fallbackMatrix,
15826
- "u_projection_clip_antimeridian": projectionData.clipAntimeridian ? 1 : 0
15827
- });
16080
+ var UniformBuffer = class {
16081
+ constructor(context, binding, layout) {
16082
+ this.context = context;
16083
+ this.binding = binding;
16084
+ this.contentWords = layout.contentWords;
16085
+ const gl = context.gl;
16086
+ this.buffer = gl.createBuffer();
16087
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this.buffer);
16088
+ gl.bufferData(gl.UNIFORM_BUFFER, layout.sizeWords * 4, gl.DYNAMIC_DRAW);
16089
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, this.buffer);
16090
+ this.uploaded = new Float32Array(layout.sizeWords);
16091
+ this.pending = new Float32Array(layout.sizeWords);
16092
+ this.uploadedWords = new Uint32Array(this.uploaded.buffer);
16093
+ this.pendingWords = new Uint32Array(this.pending.buffer);
16094
+ this.hasData = false;
16095
+ this.bindingDirty = false;
16096
+ }
16097
+ upload() {
16098
+ const gl = this.context.gl;
16099
+ let changed = !this.hasData;
16100
+ if (!changed) {
16101
+ const words = this.pendingWords;
16102
+ const uploadedWords = this.uploadedWords;
16103
+ for (let i = 0; i < this.contentWords; i++) if (words[i] !== uploadedWords[i]) {
16104
+ changed = true;
16105
+ break;
16106
+ }
16107
+ }
16108
+ if (this.bindingDirty) {
16109
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, this.binding, this.buffer);
16110
+ this.bindingDirty = false;
16111
+ }
16112
+ if (!changed) return;
16113
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this.buffer);
16114
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, this.pending);
16115
+ this.uploaded.set(this.pending);
16116
+ this.hasData = true;
16117
+ }
16118
+ destroy() {
16119
+ const gl = this.context.gl;
16120
+ if (this.buffer) {
16121
+ gl.deleteBuffer(this.buffer);
16122
+ delete this.buffer;
16123
+ }
16124
+ }
16125
+ };
16126
+ //#endregion
16127
+ //#region src/webgl/projection_uniform_buffer.ts
16128
+ const layout$2 = std140Layout([
16129
+ {
16130
+ name: "u_projection_matrix",
16131
+ type: "mat4"
16132
+ },
16133
+ {
16134
+ name: "u_projection_fallback_matrix",
16135
+ type: "mat4"
16136
+ },
16137
+ {
16138
+ name: "u_projection_tile_mercator_coords",
16139
+ type: "vec4"
16140
+ },
16141
+ {
16142
+ name: "u_projection_clipping_plane",
16143
+ type: "vec4"
16144
+ },
16145
+ {
16146
+ name: "u_projection_transition",
16147
+ type: "float"
16148
+ },
16149
+ {
16150
+ name: "u_projection_clip_antimeridian",
16151
+ type: "int"
16152
+ }
16153
+ ]);
16154
+ const offsets$2 = layout$2.offsets;
16155
+ /**
16156
+ * @internal
16157
+ * The buffer behind the `ProjectionUBO` block in the shader preludes, written by `Program.draw` before each draw.
16158
+ */
16159
+ function createProjectionUniformBuffer(context) {
16160
+ return new UniformBuffer(context, UBO_BINDINGS.ProjectionUBO, layout$2);
16161
+ }
16162
+ function updateProjectionUniformBuffer(buffer, projectionData) {
16163
+ const f32 = buffer.pending;
16164
+ f32.set(projectionData.mainMatrix, offsets$2.u_projection_matrix);
16165
+ f32.set(projectionData.fallbackMatrix, offsets$2.u_projection_fallback_matrix);
16166
+ f32.set(projectionData.tileMercatorCoords, offsets$2.u_projection_tile_mercator_coords);
16167
+ f32.set(projectionData.clippingPlane, offsets$2.u_projection_clipping_plane);
16168
+ f32[offsets$2.u_projection_transition] = projectionData.projectionTransition;
16169
+ buffer.pendingWords[offsets$2.u_projection_clip_antimeridian] = projectionData.clipAntimeridian ? 1 : 0;
16170
+ buffer.upload();
16171
+ }
16172
+ //#endregion
16173
+ //#region src/webgl/terrain_uniform_buffer.ts
16174
+ const layout$1 = std140Layout([
16175
+ {
16176
+ name: "u_terrain_matrix",
16177
+ type: "mat4"
16178
+ },
16179
+ {
16180
+ name: "u_terrain_unpack",
16181
+ type: "vec4"
16182
+ },
16183
+ {
16184
+ name: "u_terrain_dim",
16185
+ type: "float"
16186
+ },
16187
+ {
16188
+ name: "u_terrain_exaggeration",
16189
+ type: "float"
16190
+ }
16191
+ ]);
16192
+ const offsets$1 = layout$1.offsets;
16193
+ /**
16194
+ * @internal
16195
+ * The buffer behind the `TerrainUBO` block in the vertex prelude, written by `Program.draw` for every draw with terrain.
16196
+ */
16197
+ function createTerrainUniformBuffer(context) {
16198
+ return new UniformBuffer(context, UBO_BINDINGS.TerrainUBO, layout$1);
16199
+ }
16200
+ function updateTerrainUniformBuffer(buffer, terrain) {
16201
+ const f32 = buffer.pending;
16202
+ f32.set(terrain.u_terrain_matrix, offsets$1.u_terrain_matrix);
16203
+ f32.set(terrain.u_terrain_unpack, offsets$1.u_terrain_unpack);
16204
+ f32[offsets$1.u_terrain_dim] = terrain.u_terrain_dim;
16205
+ f32[offsets$1.u_terrain_exaggeration] = terrain.u_terrain_exaggeration;
16206
+ buffer.upload();
16207
+ }
15828
16208
  //#endregion
15829
16209
  //#region src/webgl/program.ts
15830
16210
  function getTokenizedAttributesAndUniforms(array) {
@@ -15867,10 +16247,9 @@ var Program = class {
15867
16247
  const dynamicAttrInfo = configuration ? configuration.getBinderAttributes() : [];
15868
16248
  const allAttrInfo = staticAttrInfo.concat(dynamicAttrInfo);
15869
16249
  const preludeUniformsInfo = shaders.prelude.staticUniforms ? getTokenizedAttributesAndUniforms(shaders.prelude.staticUniforms) : [];
15870
- const projectionPreludeUniformsInfo = projectionPrelude.staticUniforms ? getTokenizedAttributesAndUniforms(projectionPrelude.staticUniforms) : [];
15871
16250
  const staticUniformsInfo = source.staticUniforms ? getTokenizedAttributesAndUniforms(source.staticUniforms) : [];
15872
16251
  const dynamicUniformsInfo = configuration ? configuration.getBinderUniforms() : [];
15873
- const uniformList = preludeUniformsInfo.concat(projectionPreludeUniformsInfo).concat(staticUniformsInfo).concat(dynamicUniformsInfo);
16252
+ const uniformList = preludeUniformsInfo.concat(staticUniformsInfo).concat(dynamicUniformsInfo);
15874
16253
  const allUniformsInfo = [];
15875
16254
  for (const uniform of uniformList) if (!allUniformsInfo.includes(uniform)) allUniformsInfo.push(uniform);
15876
16255
  const defines = configuration ? configuration.defines() : [];
@@ -15888,7 +16267,6 @@ var Program = class {
15888
16267
  }
15889
16268
  gl.shaderSource(fragmentShader, fragmentSource);
15890
16269
  gl.compileShader(fragmentShader);
15891
- if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile fragment shader: ${gl.getShaderInfoLog(fragmentShader)}`);
15892
16270
  gl.attachShader(this.program, fragmentShader);
15893
16271
  const vertexShader = gl.createShader(gl.VERTEX_SHADER);
15894
16272
  if (gl.isContextLost()) {
@@ -15897,13 +16275,21 @@ var Program = class {
15897
16275
  }
15898
16276
  gl.shaderSource(vertexShader, vertexSource);
15899
16277
  gl.compileShader(vertexShader);
15900
- if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile vertex shader: ${gl.getShaderInfoLog(vertexShader)}`);
15901
16278
  gl.attachShader(this.program, vertexShader);
15902
16279
  this.attributes = {};
15903
16280
  const uniformLocations = {};
15904
16281
  this.numAttributes = allAttrInfo.length;
15905
16282
  gl.linkProgram(this.program);
15906
- if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) throw new Error(`Program failed to link: ${gl.getProgramInfoLog(this.program)}`);
16283
+ if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
16284
+ if (gl.isContextLost()) {
16285
+ this.failedToCreate = true;
16286
+ return;
16287
+ }
16288
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile fragment shader: ${gl.getShaderInfoLog(fragmentShader)}`);
16289
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile vertex shader: ${gl.getShaderInfoLog(vertexShader)}`);
16290
+ throw new Error(`Program failed to link: ${gl.getProgramInfoLog(this.program)}`);
16291
+ }
16292
+ applyUBOBindings(gl, this.program);
15907
16293
  const integerAttributeNames = getIntegerAttributeNames(gl, this.program);
15908
16294
  for (const name of allAttrInfo) {
15909
16295
  if (!name) continue;
@@ -15921,7 +16307,6 @@ var Program = class {
15921
16307
  }
15922
16308
  this.fixedUniforms = fixedUniforms(context, uniformLocations);
15923
16309
  this.terrainUniforms = terrainPreludeUniforms(context, uniformLocations);
15924
- this.projectionUniforms = projectionUniforms(context, uniformLocations);
15925
16310
  this.binderUniforms = configuration ? configuration.getUniforms(context, uniformLocations) : [];
15926
16311
  }
15927
16312
  draw(context, drawMode, depthMode, stencilMode, colorMode, cullFaceMode, uniformValues, terrain, projectionData, layerID, layoutVertexBuffer, indexBuffer, segments, currentProperties, zoom, configuration, dynamicLayoutBuffer, dynamicLayoutBuffer2, dynamicLayoutBuffer3) {
@@ -15938,11 +16323,9 @@ var Program = class {
15938
16323
  context.activeTexture.set(gl.TEXTURE3);
15939
16324
  gl.bindTexture(gl.TEXTURE_2D, terrain.texture);
15940
16325
  for (const name in this.terrainUniforms) this.terrainUniforms[name].set(terrain[name]);
16326
+ updateTerrainUniformBuffer(context.terrainUniformBuffer, terrain);
15941
16327
  }
15942
- if (projectionData) {
15943
- const values = projectionUniformValues(projectionData);
15944
- for (const name in this.projectionUniforms) this.projectionUniforms[name].set(values[name]);
15945
- }
16328
+ if (projectionData) updateProjectionUniformBuffer(context.projectionUniformBuffer, projectionData);
15946
16329
  if (uniformValues) for (const name in this.fixedUniforms) this.fixedUniforms[name].set(uniformValues[name]);
15947
16330
  if (configuration) configuration.setUniforms(context, this.binderUniforms, currentProperties, { zoom });
15948
16331
  let primitiveSize = 0;
@@ -16071,37 +16454,33 @@ const fillPatternUniforms = (context, locations) => ({
16071
16454
  "u_pixel_coord_lower": new Uniform2f(context, locations.u_pixel_coord_lower),
16072
16455
  "u_scale": new Uniform3f(context, locations.u_scale),
16073
16456
  "u_fade": new Uniform1f(context, locations.u_fade),
16457
+ "u_sdf_pattern": new Uniform1i(context, locations.u_sdf_pattern),
16074
16458
  "u_fill_translate": new Uniform2f(context, locations.u_fill_translate)
16075
16459
  });
16076
- const fillOutlineUniforms = (context, locations) => ({
16077
- "u_world": new Uniform2f(context, locations.u_world),
16078
- "u_fill_translate": new Uniform2f(context, locations.u_fill_translate)
16079
- });
16460
+ const fillOutlineUniforms = (context, locations) => ({ "u_fill_translate": new Uniform2f(context, locations.u_fill_translate) });
16080
16461
  const fillOutlinePatternUniforms = (context, locations) => ({
16081
- "u_world": new Uniform2f(context, locations.u_world),
16082
16462
  "u_image": new Uniform1i(context, locations.u_image),
16083
16463
  "u_texsize": new Uniform2f(context, locations.u_texsize),
16084
16464
  "u_pixel_coord_upper": new Uniform2f(context, locations.u_pixel_coord_upper),
16085
16465
  "u_pixel_coord_lower": new Uniform2f(context, locations.u_pixel_coord_lower),
16086
16466
  "u_scale": new Uniform3f(context, locations.u_scale),
16087
16467
  "u_fade": new Uniform1f(context, locations.u_fade),
16468
+ "u_sdf_pattern": new Uniform1i(context, locations.u_sdf_pattern),
16088
16469
  "u_fill_translate": new Uniform2f(context, locations.u_fill_translate)
16089
16470
  });
16090
- const fillPatternUniformValues = (painter, crossfade, tile, translate) => extend(patternUniformValues(crossfade, painter, tile), { "u_fill_translate": translate });
16091
- const fillUniformValues = (translate) => ({ "u_fill_translate": translate });
16092
- const fillOutlineUniformValues = (drawingBufferSize, translate) => ({
16093
- "u_world": drawingBufferSize,
16094
- "u_fill_translate": translate
16471
+ const fillPatternUniformValues = (painter, crossfade, tile, translate, isSdfPattern) => extend(patternUniformValues(crossfade, painter, tile), {
16472
+ "u_fill_translate": translate,
16473
+ "u_sdf_pattern": isSdfPattern ? 1 : 0
16095
16474
  });
16096
- const fillOutlinePatternUniformValues = (painter, crossfade, tile, drawingBufferSize, translate) => extend(fillPatternUniformValues(painter, crossfade, tile, translate), { "u_world": drawingBufferSize });
16475
+ const fillUniformValues = (translate) => ({ "u_fill_translate": translate });
16476
+ const fillOutlineUniformValues = (translate) => ({ "u_fill_translate": translate });
16477
+ const fillOutlinePatternUniformValues = (painter, crossfade, tile, translate, isSdfPattern) => fillPatternUniformValues(painter, crossfade, tile, translate, isSdfPattern);
16097
16478
  //#endregion
16098
16479
  //#region src/webgl/program/circle_program.ts
16099
16480
  const circleUniforms = (context, locations) => ({
16100
- "u_camera_to_center_distance": new Uniform1f(context, locations.u_camera_to_center_distance),
16101
16481
  "u_scale_with_map": new Uniform1i(context, locations.u_scale_with_map),
16102
16482
  "u_pitch_with_map": new Uniform1i(context, locations.u_pitch_with_map),
16103
16483
  "u_extrude_scale": new Uniform2f(context, locations.u_extrude_scale),
16104
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16105
16484
  "u_globe_extrude_scale": new Uniform1f(context, locations.u_globe_extrude_scale),
16106
16485
  "u_translate": new Uniform2f(context, locations.u_translate)
16107
16486
  });
@@ -16119,26 +16498,14 @@ const circleUniformValues = (painter, tile, layer, translate, radiusCorrectionFa
16119
16498
  extrudeScale = transform.pixelsToGLUnits;
16120
16499
  }
16121
16500
  return {
16122
- "u_camera_to_center_distance": transform.cameraToCenterDistance,
16123
16501
  "u_scale_with_map": +(layer.paint.get("circle-pitch-scale") === "map"),
16124
16502
  "u_pitch_with_map": +pitchWithMap,
16125
- "u_device_pixel_ratio": painter.pixelRatio,
16126
16503
  "u_extrude_scale": extrudeScale,
16127
16504
  "u_globe_extrude_scale": globeExtrudeScale,
16128
16505
  "u_translate": translate
16129
16506
  };
16130
16507
  };
16131
16508
  //#endregion
16132
- //#region src/webgl/program/collision_program.ts
16133
- const collisionUniforms = (context, locations) => ({ "u_pixel_extrude_scale": new Uniform2f(context, locations.u_pixel_extrude_scale) });
16134
- const collisionCircleUniforms = (context, locations) => ({ "u_viewport_size": new Uniform2f(context, locations.u_viewport_size) });
16135
- const collisionUniformValues = (transform) => {
16136
- return { "u_pixel_extrude_scale": [1 / transform.width, 1 / transform.height] };
16137
- };
16138
- const collisionCircleUniformValues = (transform) => {
16139
- return { "u_viewport_size": [transform.width, transform.height] };
16140
- };
16141
- //#endregion
16142
16509
  //#region src/webgl/program/debug_program.ts
16143
16510
  const debugUniforms = (context, locations) => ({
16144
16511
  "u_color": new UniformColor(context, locations.u_color),
@@ -16159,7 +16526,6 @@ const heatmapUniforms = (context, locations) => ({
16159
16526
  });
16160
16527
  const heatmapTextureUniforms = (context, locations) => ({
16161
16528
  "u_matrix": new UniformMatrix4f(context, locations.u_matrix),
16162
- "u_world": new Uniform2f(context, locations.u_world),
16163
16529
  "u_image": new Uniform1i(context, locations.u_image),
16164
16530
  "u_color_ramp": new Uniform1i(context, locations.u_color_ramp),
16165
16531
  "u_opacity": new Uniform1f(context, locations.u_opacity)
@@ -16175,10 +16541,8 @@ const heatmapUniformValues = (tile, zoom, intensity, radiusCorrectionFactor) =>
16175
16541
  const heatmapTextureUniformValues = (painter, layer, textureUnit, colorRampUnit) => {
16176
16542
  const matrix = create$1();
16177
16543
  ortho(matrix, 0, painter.width, painter.height, 0, 0, 1);
16178
- const gl = painter.context.gl;
16179
16544
  return {
16180
16545
  "u_matrix": matrix,
16181
- "u_world": [gl.drawingBufferWidth, gl.drawingBufferHeight],
16182
16546
  "u_image": textureUnit,
16183
16547
  "u_color_ramp": colorRampUnit,
16184
16548
  "u_opacity": layer.paint.get("heatmap-opacity")
@@ -16284,15 +16648,11 @@ const colorReliefUniformValues = (layer, dem, colorRampSize = 0) => {
16284
16648
  //#region src/webgl/program/line_program.ts
16285
16649
  const lineUniforms = (context, locations) => ({
16286
16650
  "u_translation": new Uniform2f(context, locations.u_translation),
16287
- "u_ratio": new Uniform1f(context, locations.u_ratio),
16288
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16289
- "u_units_to_pixels": new Uniform2f(context, locations.u_units_to_pixels)
16651
+ "u_ratio": new Uniform1f(context, locations.u_ratio)
16290
16652
  });
16291
16653
  const lineGradientUniforms = (context, locations) => ({
16292
16654
  "u_translation": new Uniform2f(context, locations.u_translation),
16293
16655
  "u_ratio": new Uniform1f(context, locations.u_ratio),
16294
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16295
- "u_units_to_pixels": new Uniform2f(context, locations.u_units_to_pixels),
16296
16656
  "u_image": new Uniform1i(context, locations.u_image),
16297
16657
  "u_image_height": new Uniform1f(context, locations.u_image_height)
16298
16658
  });
@@ -16300,17 +16660,13 @@ const linePatternUniforms = (context, locations) => ({
16300
16660
  "u_translation": new Uniform2f(context, locations.u_translation),
16301
16661
  "u_texsize": new Uniform2f(context, locations.u_texsize),
16302
16662
  "u_ratio": new Uniform1f(context, locations.u_ratio),
16303
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16304
16663
  "u_image": new Uniform1i(context, locations.u_image),
16305
- "u_units_to_pixels": new Uniform2f(context, locations.u_units_to_pixels),
16306
16664
  "u_scale": new Uniform3f(context, locations.u_scale),
16307
16665
  "u_fade": new Uniform1f(context, locations.u_fade)
16308
16666
  });
16309
16667
  const lineSDFUniforms = (context, locations) => ({
16310
16668
  "u_translation": new Uniform2f(context, locations.u_translation),
16311
16669
  "u_ratio": new Uniform1f(context, locations.u_ratio),
16312
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16313
- "u_units_to_pixels": new Uniform2f(context, locations.u_units_to_pixels),
16314
16670
  "u_image": new Uniform1i(context, locations.u_image),
16315
16671
  "u_mix": new Uniform1f(context, locations.u_mix),
16316
16672
  "u_tileratio": new Uniform1f(context, locations.u_tileratio),
@@ -16322,8 +16678,6 @@ const lineSDFUniforms = (context, locations) => ({
16322
16678
  const lineGradientSDFUniforms = (context, locations) => ({
16323
16679
  "u_translation": new Uniform2f(context, locations.u_translation),
16324
16680
  "u_ratio": new Uniform1f(context, locations.u_ratio),
16325
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16326
- "u_units_to_pixels": new Uniform2f(context, locations.u_units_to_pixels),
16327
16681
  "u_image": new Uniform1i(context, locations.u_image),
16328
16682
  "u_image_height": new Uniform1f(context, locations.u_image_height),
16329
16683
  "u_tileratio": new Uniform1f(context, locations.u_tileratio),
@@ -16338,9 +16692,7 @@ const lineUniformValues = (painter, tile, layer, ratioScale) => {
16338
16692
  const transform = painter.transform;
16339
16693
  return {
16340
16694
  "u_translation": calculateTranslation(painter, tile, layer),
16341
- "u_ratio": ratioScale / pixelsToTileUnits(tile, 1, transform.zoom),
16342
- "u_device_pixel_ratio": painter.pixelRatio,
16343
- "u_units_to_pixels": [1 / transform.pixelsToGLUnits[0], 1 / transform.pixelsToGLUnits[1]]
16695
+ "u_ratio": ratioScale / pixelsToTileUnits(tile, 1, transform.zoom)
16344
16696
  };
16345
16697
  };
16346
16698
  const lineGradientUniformValues = (painter, tile, layer, ratioScale, imageHeight) => {
@@ -16356,15 +16708,13 @@ const linePatternUniformValues = (painter, tile, layer, ratioScale, crossfade) =
16356
16708
  "u_translation": calculateTranslation(painter, tile, layer),
16357
16709
  "u_texsize": tile.imageAtlasTexture.size,
16358
16710
  "u_ratio": ratioScale / pixelsToTileUnits(tile, 1, transform.zoom),
16359
- "u_device_pixel_ratio": painter.pixelRatio,
16360
16711
  "u_image": 0,
16361
16712
  "u_scale": [
16362
16713
  tileZoomRatio,
16363
16714
  crossfade.fromScale,
16364
16715
  crossfade.toScale
16365
16716
  ],
16366
- "u_fade": crossfade.t,
16367
- "u_units_to_pixels": [1 / transform.pixelsToGLUnits[0], 1 / transform.pixelsToGLUnits[1]]
16717
+ "u_fade": crossfade.t
16368
16718
  };
16369
16719
  };
16370
16720
  const lineSDFUniformValues = (painter, tile, layer, ratioScale, crossfade) => {
@@ -16418,11 +16768,7 @@ const symbolIconUniforms = (context, locations) => ({
16418
16768
  "u_is_size_feature_constant": new Uniform1i(context, locations.u_is_size_feature_constant),
16419
16769
  "u_size_t": new Uniform1f(context, locations.u_size_t),
16420
16770
  "u_size": new Uniform1f(context, locations.u_size),
16421
- "u_camera_to_center_distance": new Uniform1f(context, locations.u_camera_to_center_distance),
16422
- "u_pitch": new Uniform1f(context, locations.u_pitch),
16423
16771
  "u_rotate_symbol": new Uniform1i(context, locations.u_rotate_symbol),
16424
- "u_aspect_ratio": new Uniform1f(context, locations.u_aspect_ratio),
16425
- "u_fade_change": new Uniform1f(context, locations.u_fade_change),
16426
16772
  "u_label_plane_matrix": new UniformMatrix4f(context, locations.u_label_plane_matrix),
16427
16773
  "u_coord_matrix": new UniformMatrix4f(context, locations.u_coord_matrix),
16428
16774
  "u_is_text": new Uniform1i(context, locations.u_is_text),
@@ -16441,11 +16787,7 @@ const symbolSDFUniforms = (context, locations) => ({
16441
16787
  "u_is_size_feature_constant": new Uniform1i(context, locations.u_is_size_feature_constant),
16442
16788
  "u_size_t": new Uniform1f(context, locations.u_size_t),
16443
16789
  "u_size": new Uniform1f(context, locations.u_size),
16444
- "u_camera_to_center_distance": new Uniform1f(context, locations.u_camera_to_center_distance),
16445
- "u_pitch": new Uniform1f(context, locations.u_pitch),
16446
16790
  "u_rotate_symbol": new Uniform1i(context, locations.u_rotate_symbol),
16447
- "u_aspect_ratio": new Uniform1f(context, locations.u_aspect_ratio),
16448
- "u_fade_change": new Uniform1f(context, locations.u_fade_change),
16449
16791
  "u_label_plane_matrix": new UniformMatrix4f(context, locations.u_label_plane_matrix),
16450
16792
  "u_coord_matrix": new UniformMatrix4f(context, locations.u_coord_matrix),
16451
16793
  "u_is_text": new Uniform1i(context, locations.u_is_text),
@@ -16455,7 +16797,6 @@ const symbolSDFUniforms = (context, locations) => ({
16455
16797
  "u_texsize": new Uniform2f(context, locations.u_texsize),
16456
16798
  "u_texture": new Uniform1i(context, locations.u_texture),
16457
16799
  "u_gamma_scale": new Uniform1f(context, locations.u_gamma_scale),
16458
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16459
16800
  "u_is_halo": new Uniform1i(context, locations.u_is_halo),
16460
16801
  "u_is_plain": new Uniform1i(context, locations.u_is_plain),
16461
16802
  "u_translation": new Uniform2f(context, locations.u_translation),
@@ -16468,11 +16809,7 @@ const symbolTextAndIconUniforms = (context, locations) => ({
16468
16809
  "u_is_size_feature_constant": new Uniform1i(context, locations.u_is_size_feature_constant),
16469
16810
  "u_size_t": new Uniform1f(context, locations.u_size_t),
16470
16811
  "u_size": new Uniform1f(context, locations.u_size),
16471
- "u_camera_to_center_distance": new Uniform1f(context, locations.u_camera_to_center_distance),
16472
- "u_pitch": new Uniform1f(context, locations.u_pitch),
16473
16812
  "u_rotate_symbol": new Uniform1i(context, locations.u_rotate_symbol),
16474
- "u_aspect_ratio": new Uniform1f(context, locations.u_aspect_ratio),
16475
- "u_fade_change": new Uniform1f(context, locations.u_fade_change),
16476
16813
  "u_label_plane_matrix": new UniformMatrix4f(context, locations.u_label_plane_matrix),
16477
16814
  "u_coord_matrix": new UniformMatrix4f(context, locations.u_coord_matrix),
16478
16815
  "u_is_text": new Uniform1i(context, locations.u_is_text),
@@ -16484,7 +16821,6 @@ const symbolTextAndIconUniforms = (context, locations) => ({
16484
16821
  "u_texture": new Uniform1i(context, locations.u_texture),
16485
16822
  "u_texture_icon": new Uniform1i(context, locations.u_texture_icon),
16486
16823
  "u_gamma_scale": new Uniform1f(context, locations.u_gamma_scale),
16487
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16488
16824
  "u_is_halo": new Uniform1i(context, locations.u_is_halo),
16489
16825
  "u_translation": new Uniform2f(context, locations.u_translation),
16490
16826
  "u_pitched_scale": new Uniform1f(context, locations.u_pitched_scale),
@@ -16492,17 +16828,12 @@ const symbolTextAndIconUniforms = (context, locations) => ({
16492
16828
  "u_height_anchor_ground": new Uniform1i(context, locations.u_height_anchor_ground)
16493
16829
  });
16494
16830
  const symbolIconUniformValues = (functionType, size, rotateInShader, pitchWithMap, isAlongLine, isVariableAnchor, painter, labelPlaneMatrix, glCoordMatrix, translation, isText, texSize, pitchedScale, isOffset, heightAnchorGround) => {
16495
- const transform = painter.transform;
16496
16831
  return {
16497
16832
  "u_is_size_zoom_constant": +(functionType === "constant" || functionType === "source"),
16498
16833
  "u_is_size_feature_constant": +(functionType === "constant" || functionType === "camera"),
16499
16834
  "u_size_t": size ? size.uSizeT : 0,
16500
16835
  "u_size": size ? size.uSize : 0,
16501
- "u_camera_to_center_distance": transform.cameraToCenterDistance,
16502
- "u_pitch": transform.pitch / 360 * 2 * Math.PI,
16503
16836
  "u_rotate_symbol": +rotateInShader,
16504
- "u_aspect_ratio": transform.width / transform.height,
16505
- "u_fade_change": painter.options.fadeDuration ? painter.symbolFadeChange : 1,
16506
16837
  "u_label_plane_matrix": labelPlaneMatrix,
16507
16838
  "u_coord_matrix": glCoordMatrix,
16508
16839
  "u_is_text": +isText,
@@ -16521,7 +16852,6 @@ const symbolSDFUniformValues = (functionType, size, rotateInShader, pitchWithMap
16521
16852
  const transform = painter.transform;
16522
16853
  return extend(symbolIconUniformValues(functionType, size, rotateInShader, pitchWithMap, isAlongLine, isVariableAnchor, painter, labelPlaneMatrix, glCoordMatrix, translation, isText, texSize, pitchedScale, isOffset, heightAnchorGround), {
16523
16854
  "u_gamma_scale": pitchWithMap ? Math.cos(transform.pitch * Math.PI / 180) * transform.cameraToCenterDistance : 1,
16524
- "u_device_pixel_ratio": painter.pixelRatio,
16525
16855
  "u_is_halo": isHalo ? 1 : 0,
16526
16856
  "u_is_plain": 1
16527
16857
  });
@@ -16584,7 +16914,10 @@ const skyUniforms = (context, locations) => ({
16584
16914
  "u_horizon": new Uniform2f(context, locations.u_horizon),
16585
16915
  "u_horizon_normal": new Uniform2f(context, locations.u_horizon_normal),
16586
16916
  "u_sky_horizon_blend": new Uniform1f(context, locations.u_sky_horizon_blend),
16587
- "u_sky_blend": new Uniform1f(context, locations.u_sky_blend)
16917
+ "u_sky_blend": new Uniform1f(context, locations.u_sky_blend),
16918
+ "u_inv_proj_matrix": new UniformMatrix4f(context, locations.u_inv_proj_matrix),
16919
+ "u_globe_position": new Uniform3f(context, locations.u_globe_position),
16920
+ "u_globe_radius": new Uniform1f(context, locations.u_globe_radius)
16588
16921
  });
16589
16922
  const skyUniformValues = (sky, transform, pixelRatio) => {
16590
16923
  const cosRoll = Math.cos(transform.rollInRadians);
@@ -16601,12 +16934,15 @@ const skyUniformValues = (sky, transform, pixelRatio) => {
16601
16934
  "u_horizon": [(transform.width / 2 - mercatorHorizon * sinRoll) * pixelRatio, (transform.height / 2 + mercatorHorizon * cosRoll) * pixelRatio],
16602
16935
  "u_horizon_normal": [-sinRoll, cosRoll],
16603
16936
  "u_sky_horizon_blend": sky.properties.get("sky-horizon-blend") * transform.height / 2 * pixelRatio,
16604
- "u_sky_blend": skyBlend
16937
+ "u_sky_blend": skyBlend,
16938
+ "u_inv_proj_matrix": transform.inverseProjectionMatrix,
16939
+ "u_globe_position": getGlobeCenterInViewSpace(transform),
16940
+ "u_globe_radius": getGlobeRadiusPixels(transform.worldSize, transform.center.lat)
16605
16941
  };
16606
16942
  };
16607
16943
  //#endregion
16608
16944
  //#region src/webgl/program/program_uniforms.ts
16609
- const emptyUniforms = (_, __) => {};
16945
+ const emptyUniforms = (_, __) => ({});
16610
16946
  const programUniforms = {
16611
16947
  fillExtrusion: fillExtrusionUniforms,
16612
16948
  fillExtrusionPattern: fillExtrusionPatternUniforms,
@@ -16615,8 +16951,8 @@ const programUniforms = {
16615
16951
  fillOutline: fillOutlineUniforms,
16616
16952
  fillOutlinePattern: fillOutlinePatternUniforms,
16617
16953
  circle: circleUniforms,
16618
- collisionBox: collisionUniforms,
16619
- collisionCircle: collisionCircleUniforms,
16954
+ collisionBox: emptyUniforms,
16955
+ collisionCircle: emptyUniforms,
16620
16956
  debug: debugUniforms,
16621
16957
  depth: emptyUniforms,
16622
16958
  clippingMask: emptyUniforms,
@@ -17231,6 +17567,73 @@ var Framebuffer = class {
17231
17567
  }
17232
17568
  };
17233
17569
  //#endregion
17570
+ //#region src/webgl/frame_uniform_buffer.ts
17571
+ const layout = std140Layout([
17572
+ {
17573
+ name: "u_units_to_pixels",
17574
+ type: "vec2"
17575
+ },
17576
+ {
17577
+ name: "u_world_size",
17578
+ type: "vec2"
17579
+ },
17580
+ {
17581
+ name: "u_camera_to_center_distance",
17582
+ type: "float"
17583
+ },
17584
+ {
17585
+ name: "u_symbol_fade_change",
17586
+ type: "float"
17587
+ },
17588
+ {
17589
+ name: "u_aspect_ratio",
17590
+ type: "float"
17591
+ },
17592
+ {
17593
+ name: "u_device_pixel_ratio",
17594
+ type: "float"
17595
+ },
17596
+ {
17597
+ name: "u_viewport_size",
17598
+ type: "vec2"
17599
+ },
17600
+ {
17601
+ name: "u_pixel_extrude_scale",
17602
+ type: "vec2"
17603
+ },
17604
+ {
17605
+ name: "u_pitch",
17606
+ type: "float"
17607
+ }
17608
+ ]);
17609
+ const offsets = layout.offsets;
17610
+ /**
17611
+ * @internal
17612
+ * The buffer behind the `FrameUBO` block in the shader preludes, written once per frame by `Painter.render`.
17613
+ */
17614
+ function createFrameUniformBuffer(context) {
17615
+ return new UniformBuffer(context, UBO_BINDINGS.FrameUBO, layout);
17616
+ }
17617
+ function updateFrameUniformBuffer(buffer, painter) {
17618
+ const f32 = buffer.pending;
17619
+ const { transform } = painter;
17620
+ const gl = painter.context.gl;
17621
+ f32[offsets.u_units_to_pixels] = 1 / transform.pixelsToGLUnits[0];
17622
+ f32[offsets.u_units_to_pixels + 1] = 1 / transform.pixelsToGLUnits[1];
17623
+ f32[offsets.u_world_size] = gl.drawingBufferWidth;
17624
+ f32[offsets.u_world_size + 1] = gl.drawingBufferHeight;
17625
+ f32[offsets.u_camera_to_center_distance] = transform.cameraToCenterDistance;
17626
+ f32[offsets.u_symbol_fade_change] = painter.options.fadeDuration ? painter.symbolFadeChange : 1;
17627
+ f32[offsets.u_aspect_ratio] = transform.width / transform.height;
17628
+ f32[offsets.u_device_pixel_ratio] = painter.pixelRatio;
17629
+ f32[offsets.u_viewport_size] = transform.width;
17630
+ f32[offsets.u_viewport_size + 1] = transform.height;
17631
+ f32[offsets.u_pixel_extrude_scale] = 1 / transform.width;
17632
+ f32[offsets.u_pixel_extrude_scale + 1] = 1 / transform.height;
17633
+ f32[offsets.u_pitch] = transform.pitch / 360 * 2 * Math.PI;
17634
+ buffer.upload();
17635
+ }
17636
+ //#endregion
17234
17637
  //#region src/webgl/color_mode.ts
17235
17638
  const ZERO = 0;
17236
17639
  const ONE = 1;
@@ -17306,6 +17709,9 @@ var Context = class {
17306
17709
  this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
17307
17710
  gl.getExtension("EXT_color_buffer_half_float");
17308
17711
  gl.getExtension("EXT_color_buffer_float");
17712
+ this.projectionUniformBuffer = createProjectionUniformBuffer(this);
17713
+ this.terrainUniformBuffer = createTerrainUniformBuffer(this);
17714
+ this.frameUniformBuffer = createFrameUniformBuffer(this);
17309
17715
  }
17310
17716
  setDefault() {
17311
17717
  this.unbindVAO();
@@ -17367,6 +17773,9 @@ var Context = class {
17367
17773
  this.pixelStoreUnpack.dirty = true;
17368
17774
  this.pixelStoreUnpackPremultiplyAlpha.dirty = true;
17369
17775
  this.pixelStoreUnpackFlipY.dirty = true;
17776
+ this.projectionUniformBuffer.bindingDirty = true;
17777
+ this.terrainUniformBuffer.bindingDirty = true;
17778
+ this.frameUniformBuffer.bindingDirty = true;
17370
17779
  }
17371
17780
  /**
17372
17781
  * Reset some GL state to default values before handing users the raw context, as we do for
@@ -17554,7 +17963,7 @@ function drawCollisionDebug(painter, tileManager, layer, coords, isText) {
17554
17963
  circleOffset = circleCount;
17555
17964
  }
17556
17965
  if (!buffers) continue;
17557
- program.draw(context, gl.LINES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, collisionUniformValues(painter.transform), painter.style.map.terrain?.getTerrainData(coord), transform.getProjectionData({
17966
+ program.draw(context, gl.LINES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, null, painter.style.map.terrain?.getTerrainData(coord), transform.getProjectionData({
17558
17967
  overscaledTileID: coord,
17559
17968
  applyGlobeMatrix: true,
17560
17969
  applyTerrainMatrix: true
@@ -17580,10 +17989,7 @@ function drawCollisionDebug(painter, tileManager, layer, coords, isText) {
17580
17989
  if (!quadTriangles || quadTriangles.length < circleCount * 2) quadTriangles = createQuadTriangles(circleCount);
17581
17990
  const indexBuffer = context.createIndexBuffer(quadTriangles, true);
17582
17991
  const vertexBuffer = context.createVertexBuffer(vertexData, collisionCircleLayout.members, true);
17583
- for (const batch of tileBatches) {
17584
- const uniforms = collisionCircleUniformValues(painter.transform);
17585
- circleProgram.draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, uniforms, painter.style.map.terrain?.getTerrainData(batch.coord), null, layer.id, vertexBuffer, indexBuffer, SegmentVector.simpleSegment(0, batch.circleOffset * 2, batch.circleArray.length, batch.circleArray.length / 2), null, painter.transform.zoom, null, null, null);
17586
- }
17992
+ for (const batch of tileBatches) circleProgram.draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, null, painter.style.map.terrain?.getTerrainData(batch.coord), null, layer.id, vertexBuffer, indexBuffer, SegmentVector.simpleSegment(0, batch.circleOffset * 2, batch.circleArray.length, batch.circleArray.length / 2), null, painter.transform.zoom, null, null, null);
17587
17993
  vertexBuffer.destroy();
17588
17994
  indexBuffer.destroy();
17589
17995
  }
@@ -17607,7 +18013,7 @@ function createQuadTriangles(quadCount) {
17607
18013
  //#region src/webgl/draw/draw_symbol.ts
17608
18014
  const identityMat4 = identity(/* @__PURE__ */ new Float32Array(16));
17609
18015
  function drawSymbols(painter, tileManager, layer, coords, variableOffsets, renderOptions) {
17610
- if (painter.renderPass !== "translucent") return;
18016
+ if (renderOptions.currentPass !== "translucent") return;
17611
18017
  const { isRenderingToTexture } = renderOptions;
17612
18018
  const stencilMode = StencilMode.disabled;
17613
18019
  const colorMode = painter.colorModeForRenderPass();
@@ -17863,7 +18269,7 @@ function drawSymbolElements(buffers, segments, layer, painter, program, depthMod
17863
18269
  //#endregion
17864
18270
  //#region src/webgl/draw/draw_circle.ts
17865
18271
  function drawCircles(painter, tileManager, layer, coords, renderOptions) {
17866
- if (painter.renderPass !== "translucent") return;
18272
+ if (renderOptions.currentPass !== "translucent") return;
17867
18273
  const { isRenderingToTexture } = renderOptions;
17868
18274
  const opacity = layer.paint.get("circle-opacity");
17869
18275
  const strokeWidth = layer.paint.get("circle-stroke-width");
@@ -17933,8 +18339,8 @@ function drawHeatmap(painter, tileManager, layer, tileIDs, renderOptions) {
17933
18339
  for (const coord of tileIDs) {
17934
18340
  const tile = tileManager.getTile(coord);
17935
18341
  if (tileManager.hasRenderableParent(coord)) continue;
17936
- if (painter.renderPass === "offscreen") prepareHeatmapTerrain(painter, tile, layer, coord, isRenderingGlobe);
17937
- else if (painter.renderPass === "translucent") renderHeatmapTerrain(painter, layer, coord, isRenderingToTexture, isRenderingGlobe);
18342
+ if (renderOptions.currentPass === "offscreen") prepareHeatmapTerrain(painter, tile, layer, coord, isRenderingGlobe);
18343
+ else if (renderOptions.currentPass === "translucent") renderHeatmapTerrain(painter, layer, coord, isRenderingToTexture, isRenderingGlobe);
17938
18344
  }
17939
18345
  context.viewport.set([
17940
18346
  0,
@@ -17942,8 +18348,8 @@ function drawHeatmap(painter, tileManager, layer, tileIDs, renderOptions) {
17942
18348
  painter.width,
17943
18349
  painter.height
17944
18350
  ]);
17945
- } else if (painter.renderPass === "offscreen") prepareHeatmapFlat(painter, tileManager, layer, tileIDs);
17946
- else if (painter.renderPass === "translucent") renderHeatmapFlat(painter, layer);
18351
+ } else if (renderOptions.currentPass === "offscreen") prepareHeatmapFlat(painter, tileManager, layer, tileIDs);
18352
+ else if (renderOptions.currentPass === "translucent") renderHeatmapFlat(painter, layer);
17947
18353
  }
17948
18354
  function prepareHeatmapFlat(painter, tileManager, layer, coords) {
17949
18355
  const context = painter.context;
@@ -18209,7 +18615,7 @@ function bindGradientAndDashTextures(painter, tileManager, context, gl, layer, b
18209
18615
  programConfiguration.updatePaintBuffers(crossfade);
18210
18616
  }
18211
18617
  function drawLine(painter, tileManager, layer, coords, renderOptions) {
18212
- if (painter.renderPass !== "translucent") return;
18618
+ if (renderOptions.currentPass !== "translucent") return;
18213
18619
  const opacity = layer.paint.get("line-opacity");
18214
18620
  const width = layer.paint.get("line-width");
18215
18621
  const layerOpacity = layer.paint.get("line-layer-opacity");
@@ -18328,7 +18734,7 @@ function drawFill(painter, tileManager, layer, coords, renderOptions) {
18328
18734
  const layerOpacity = layer.paint.get("fill-layer-opacity");
18329
18735
  if (opacity.constantOr(1) === 0 || layerOpacity === 0) return;
18330
18736
  if (layerOpacity < 1) {
18331
- if (painter.renderPass !== "translucent") return;
18737
+ if (renderOptions.currentPass !== "translucent") return;
18332
18738
  const results = prepareDrawLayerOpacity(painter, layer, coords, !!painter.style.map.terrain);
18333
18739
  drawFillAndOutline(painter, tileManager, layer, coords, renderOptions);
18334
18740
  drawLayerOpacity(painter, layerOpacity, results, layer);
@@ -18336,17 +18742,17 @@ function drawFill(painter, tileManager, layer, coords, renderOptions) {
18336
18742
  }
18337
18743
  const pattern = layer.paint.get("fill-pattern");
18338
18744
  const fillEligibleForOpaque = painter.opaquePassEnabledForLayer() && !pattern.constantOr(1) && color.constantOr(Color.transparent).a === 1 && opacity.constantOr(0) === 1;
18339
- if (fillEligibleForOpaque && painter.renderPass === "opaque") {
18745
+ if (fillEligibleForOpaque && renderOptions.currentPass === "opaque") {
18340
18746
  const { isRenderingToTexture } = renderOptions;
18341
18747
  const colorMode = painter.colorModeForRenderPass();
18342
18748
  drawFillTiles(painter, tileManager, layer, coords, painter.getDepthModeForSublayer(1, DepthMode.ReadWrite), colorMode, false, isRenderingToTexture);
18343
18749
  return;
18344
18750
  }
18345
- if (fillEligibleForOpaque && painter.renderPass === "translucent") {
18751
+ if (fillEligibleForOpaque && renderOptions.currentPass === "translucent") {
18346
18752
  drawOutline(painter, tileManager, layer, coords, renderOptions);
18347
18753
  return;
18348
18754
  }
18349
- if (painter.renderPass === "translucent") drawFillAndOutline(painter, tileManager, layer, coords, renderOptions);
18755
+ if (renderOptions.currentPass === "translucent") drawFillAndOutline(painter, tileManager, layer, coords, renderOptions);
18350
18756
  }
18351
18757
  /**
18352
18758
  * Draw fill + outline in a single translucent pass with ReadOnly depth.
@@ -18388,6 +18794,7 @@ function drawFillTiles(painter, tileManager, layer, coords, depthMode, colorMode
18388
18794
  if (image && !tile.patternsLoaded()) continue;
18389
18795
  const bucket = tile.getBucket(layer);
18390
18796
  if (!bucket) continue;
18797
+ const isSdfPattern = bucket.sdfPatterns[layer.id] ?? false;
18391
18798
  const programConfiguration = bucket.programConfigurations.get(layer.id);
18392
18799
  const program = painter.useProgram(programName, programConfiguration);
18393
18800
  const terrainData = painter.getTerrainDataForTile(coord, isRenderingToTexture);
@@ -18406,12 +18813,11 @@ function drawFillTiles(painter, tileManager, layer, coords, depthMode, colorMode
18406
18813
  if (!isOutline) {
18407
18814
  indexBuffer = bucket.indexBuffer;
18408
18815
  segments = bucket.segments;
18409
- uniformValues = image ? fillPatternUniformValues(painter, crossfade, tile, translateForUniforms) : fillUniformValues(translateForUniforms);
18816
+ uniformValues = image ? fillPatternUniformValues(painter, crossfade, tile, translateForUniforms, isSdfPattern) : fillUniformValues(translateForUniforms);
18410
18817
  } else {
18411
18818
  indexBuffer = bucket.indexBuffer2;
18412
18819
  segments = bucket.segments2;
18413
- const drawingBufferSize = [gl.drawingBufferWidth, gl.drawingBufferHeight];
18414
- uniformValues = programName === "fillOutlinePattern" && image ? fillOutlinePatternUniformValues(painter, crossfade, tile, drawingBufferSize, translateForUniforms) : fillOutlineUniformValues(drawingBufferSize, translateForUniforms);
18820
+ uniformValues = programName === "fillOutlinePattern" && image ? fillOutlinePatternUniformValues(painter, crossfade, tile, translateForUniforms, isSdfPattern) : fillOutlineUniformValues(translateForUniforms);
18415
18821
  }
18416
18822
  const stencil = painter.stencilModeForClipping(coord);
18417
18823
  program.draw(painter.context, drawMode, depthMode, stencil, colorMode, CullFaceMode.backCCW, uniformValues, terrainData, projectionData, layer.id, bucket.layoutVertexBuffer, indexBuffer, segments, layer.paint, painter.transform.zoom, programConfiguration);
@@ -18423,8 +18829,8 @@ function drawFillExtrusion(painter, tileManager, layer, coords, renderOptions) {
18423
18829
  const opacity = layer.paint.get("fill-extrusion-opacity");
18424
18830
  if (opacity === 0) return;
18425
18831
  const { isRenderingToTexture } = renderOptions;
18426
- if (painter.renderPass === "translucent") {
18427
- const depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D);
18832
+ if (renderOptions.currentPass === "translucent") {
18833
+ const depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, renderOptions.depthRangeFor3D);
18428
18834
  if (opacity === 1 && !layer.paint.get("fill-extrusion-pattern").constantOr(1)) {
18429
18835
  const colorMode = painter.colorModeForRenderPass();
18430
18836
  drawExtrusionTiles(painter, tileManager, layer, coords, depthMode, StencilMode.disabled, colorMode, isRenderingToTexture);
@@ -18471,13 +18877,13 @@ function drawExtrusionTiles(painter, tileManager, layer, coords, depthMode, sten
18471
18877
  //#endregion
18472
18878
  //#region src/webgl/draw/draw_hillshade.ts
18473
18879
  function drawHillshade(painter, tileManager, layer, tileIDs, renderOptions) {
18474
- if (painter.renderPass !== "offscreen" && painter.renderPass !== "translucent") return;
18880
+ if (renderOptions.currentPass !== "offscreen" && renderOptions.currentPass !== "translucent") return;
18475
18881
  const { isRenderingToTexture } = renderOptions;
18476
18882
  const context = painter.context;
18477
18883
  const useSubdivision = painter.style.projection.useSubdivision;
18478
18884
  const depthMode = painter.getDepthModeForSublayer(0, DepthMode.ReadOnly);
18479
18885
  const colorMode = painter.colorModeForRenderPass();
18480
- if (painter.renderPass === "offscreen") {
18886
+ if (renderOptions.currentPass === "offscreen") {
18481
18887
  prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, StencilMode.disabled, colorMode);
18482
18888
  context.viewport.set([
18483
18889
  0,
@@ -18485,7 +18891,7 @@ function drawHillshade(painter, tileManager, layer, tileIDs, renderOptions) {
18485
18891
  painter.width,
18486
18892
  painter.height
18487
18893
  ]);
18488
- } else if (painter.renderPass === "translucent") {
18894
+ } else if (renderOptions.currentPass === "translucent") {
18489
18895
  if (useSubdivision) {
18490
18896
  const [stencilBorderless, stencilBorders, coords] = painter.stencilConfigForOverlapTwoPass(tileIDs);
18491
18897
  renderHillshade(painter, tileManager, layer, coords, stencilBorderless, depthMode, colorMode, false, isRenderingToTexture);
@@ -18530,7 +18936,7 @@ function prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, stenc
18530
18936
  const dem = tile.dem;
18531
18937
  if (!dem?.data) continue;
18532
18938
  if (!tile.needsHillshadePrepare) continue;
18533
- const tileSize = dem.dim;
18939
+ const hillshadeTextureSize = dem.dim + 2;
18534
18940
  const textureStride = dem.stride;
18535
18941
  const pixelData = dem.getPixels();
18536
18942
  context.activeTexture.set(gl.TEXTURE1);
@@ -18548,20 +18954,20 @@ function prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, stenc
18548
18954
  let fbo = tile.fbo;
18549
18955
  if (!fbo) {
18550
18956
  const renderTexture = new Texture(context, {
18551
- width: tileSize,
18552
- height: tileSize,
18957
+ width: hillshadeTextureSize,
18958
+ height: hillshadeTextureSize,
18553
18959
  data: null
18554
18960
  }, gl.RGBA);
18555
18961
  renderTexture.bind(textureFilter, gl.CLAMP_TO_EDGE);
18556
- fbo = tile.fbo = context.createFramebuffer(tileSize, tileSize, true, false);
18962
+ fbo = tile.fbo = context.createFramebuffer(hillshadeTextureSize, hillshadeTextureSize, true, false);
18557
18963
  fbo.colorAttachment.set(renderTexture.texture);
18558
18964
  }
18559
18965
  context.bindFramebuffer.set(fbo.framebuffer);
18560
18966
  context.viewport.set([
18561
18967
  0,
18562
18968
  0,
18563
- tileSize,
18564
- tileSize
18969
+ hillshadeTextureSize,
18970
+ hillshadeTextureSize
18565
18971
  ]);
18566
18972
  painter.useProgram("hillshadePrepare").draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, hillshadeUniformPrepareValues(tile.tileID, dem), null, null, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments);
18567
18973
  tile.needsHillshadePrepare = false;
@@ -18570,7 +18976,7 @@ function prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, stenc
18570
18976
  //#endregion
18571
18977
  //#region src/webgl/draw/draw_color_relief.ts
18572
18978
  function drawColorRelief(painter, tileManager, layer, tileIDs, renderOptions) {
18573
- if (painter.renderPass !== "translucent") return;
18979
+ if (renderOptions.currentPass !== "translucent") return;
18574
18980
  if (!tileIDs.length) return;
18575
18981
  const { isRenderingToTexture } = renderOptions;
18576
18982
  const useSubdivision = painter.style.projection.useSubdivision;
@@ -18586,6 +18992,12 @@ function drawColorRelief(painter, tileManager, layer, tileIDs, renderOptions) {
18586
18992
  }
18587
18993
  }
18588
18994
  let textureMaxSize = 0;
18995
+ /**
18996
+ * Draws the color-relief tiles of one pass.
18997
+ *
18998
+ * A loaded raster-DEM tile can carry no DEM at all (e.g. an empty 204 response);
18999
+ * such tiles are skipped before the first-tile setup reads from them.
19000
+ */
18589
19001
  function renderColorRelief(painter, tileManager, layer, coords, stencilModes, depthMode, colorMode, useBorder, isRenderingToTexture) {
18590
19002
  const projection = painter.style.projection;
18591
19003
  const context = painter.context;
@@ -18599,6 +19011,7 @@ function renderColorRelief(painter, tileManager, layer, coords, stencilModes, de
18599
19011
  for (const coord of coords) {
18600
19012
  const tile = tileManager.getTile(coord);
18601
19013
  const dem = tile.dem;
19014
+ if (!dem?.data) continue;
18602
19015
  if (firstTile) {
18603
19016
  textureMaxSize ||= gl.getParameter(gl.MAX_TEXTURE_SIZE);
18604
19017
  const maxLength = textureMaxSize;
@@ -18610,7 +19023,6 @@ function renderColorRelief(painter, tileManager, layer, coords, stencilModes, de
18610
19023
  firstTile = false;
18611
19024
  colorRampSize = elevationTexture.size[0];
18612
19025
  }
18613
- if (!dem?.data) continue;
18614
19026
  const textureStride = dem.stride;
18615
19027
  context.activeTexture.set(gl.TEXTURE0);
18616
19028
  if (!tile.demTexture || tile.needsColorReliefPrepare) {
@@ -18644,7 +19056,7 @@ const cornerCoords = [
18644
19056
  new Point(0, EXTENT)
18645
19057
  ];
18646
19058
  function drawRaster(painter, tileManager, layer, tileIDs, renderOptions) {
18647
- if (painter.renderPass !== "translucent") return;
19059
+ if (renderOptions.currentPass !== "translucent") return;
18648
19060
  if (layer.paint.get("raster-opacity") === 0) return;
18649
19061
  if (!tileIDs.length) return;
18650
19062
  const { isRenderingToTexture } = renderOptions;
@@ -18785,7 +19197,7 @@ function drawBackground(painter, tileManager, layer, coords, renderOptions) {
18785
19197
  const image = layer.paint.get("background-pattern");
18786
19198
  if (painter.isPatternMissing(image)) return;
18787
19199
  const pass = !image && color.a === 1 && opacity === 1 && painter.opaquePassEnabledForLayer() ? "opaque" : "translucent";
18788
- if (painter.renderPass !== pass) return;
19200
+ if (renderOptions.currentPass !== pass) return;
18789
19201
  const stencilMode = StencilMode.disabled;
18790
19202
  const depthMode = painter.getDepthModeForSublayer(0, pass === "opaque" ? DepthMode.ReadWrite : DepthMode.ReadOnly);
18791
19203
  const colorMode = painter.colorModeForRenderPass();
@@ -18942,7 +19354,7 @@ function drawCustom(painter, tileManager, layer, renderOptions) {
18942
19354
  }
18943
19355
  };
18944
19356
  const renderingMode = implementation.renderingMode ? implementation.renderingMode : "2d";
18945
- if (painter.renderPass === "offscreen") {
19357
+ if (renderOptions.currentPass === "offscreen") {
18946
19358
  const prerender = implementation.prerender;
18947
19359
  if (prerender) {
18948
19360
  painter.setCustomLayerDefaults();
@@ -18951,7 +19363,7 @@ function drawCustom(painter, tileManager, layer, renderOptions) {
18951
19363
  context.setDirty();
18952
19364
  painter.setBaseState();
18953
19365
  }
18954
- } else if (painter.renderPass === "translucent") {
19366
+ } else if (renderOptions.currentPass === "translucent") {
18955
19367
  painter.setCustomLayerDefaults();
18956
19368
  context.setColorMode(painter.colorModeForRenderPass());
18957
19369
  context.setStencilMode(StencilMode.disabled);
@@ -19028,7 +19440,7 @@ function drawTerrain(painter, terrain, tiles, renderOptions) {
19028
19440
  const texture = painter.renderToTexture.getTexture(tile);
19029
19441
  const terrainData = terrain.getTerrainData(tile.tileID);
19030
19442
  context.activeTexture.set(gl.TEXTURE0);
19031
- gl.bindTexture(gl.TEXTURE_2D, texture.texture);
19443
+ texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_LINEAR);
19032
19444
  const eleDelta = terrain.getSkirtLength(tr.zoom);
19033
19445
  const fogMatrix = tr.calculateFogMatrix(tile.tileID.toUnwrapped());
19034
19446
  const uniformValues = terrainUniformValues(eleDelta, fogMatrix, painter.style.sky, tr.pitch, isRenderingGlobe);
@@ -19096,25 +19508,8 @@ function drawAtmosphere(painter, sky, light) {
19096
19508
  const atmosphereBlend = sky.properties.get("atmosphere-blend") * projectionData.projectionTransition;
19097
19509
  if (atmosphereBlend === 0) return;
19098
19510
  const globeRadius = getGlobeRadiusPixels(transform.worldSize, transform.center.lat);
19099
- const invProjMatrix = transform.inverseProjectionMatrix;
19100
- const vec = /* @__PURE__ */ new Float64Array(4);
19101
- vec[3] = 1;
19102
- transformMat4(vec, vec, transform.modelViewProjectionMatrix);
19103
- vec[0] /= vec[3];
19104
- vec[1] /= vec[3];
19105
- vec[2] /= vec[3];
19106
- vec[3] = 1;
19107
- transformMat4(vec, vec, invProjMatrix);
19108
- vec[0] /= vec[3];
19109
- vec[1] /= vec[3];
19110
- vec[2] /= vec[3];
19111
- vec[3] = 1;
19112
- const globePosition = [
19113
- vec[0],
19114
- vec[1],
19115
- vec[2]
19116
- ];
19117
- const uniformValues = atmosphereUniformValues(sunPos, atmosphereBlend, globePosition, globeRadius, invProjMatrix);
19511
+ const globePosition = getGlobeCenterInViewSpace(transform);
19512
+ const uniformValues = atmosphereUniformValues(sunPos, atmosphereBlend, globePosition, globeRadius, transform.inverseProjectionMatrix);
19118
19513
  const mesh = getMesh(context, sky);
19119
19514
  program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, ColorMode.alphaBlended, CullFaceMode.disabled, uniformValues, null, null, "atmosphere", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments);
19120
19515
  }
@@ -19139,6 +19534,22 @@ const webglDrawFunctions = {
19139
19534
  terrainDepth: drawDepth
19140
19535
  };
19141
19536
  //#endregion
19537
+ //#region src/render/render_options.ts
19538
+ function createRenderOptions(transform, projection, terrain) {
19539
+ const projectionTransition = projection?.transitionState ?? 0;
19540
+ return {
19541
+ currentPass: "offscreen",
19542
+ currentLayer: 0,
19543
+ opaquePassCutoff: Infinity,
19544
+ depthRangeFor3D: [0, 1],
19545
+ isRenderingToTexture: false,
19546
+ transform,
19547
+ terrain,
19548
+ projectionTransition,
19549
+ isRenderingGlobe: projectionTransition > 0
19550
+ };
19551
+ }
19552
+ //#endregion
19142
19553
  //#region src/render/painter.ts
19143
19554
  /**
19144
19555
  * @internal
@@ -19408,38 +19819,36 @@ var Painter = class Painter {
19408
19819
  true,
19409
19820
  true
19410
19821
  ]);
19411
- } else if (this.renderPass === "opaque") return ColorMode.unblended;
19822
+ } else if (this.renderOptions.currentPass === "opaque") return ColorMode.unblended;
19412
19823
  else return ColorMode.alphaBlended;
19413
19824
  }
19414
19825
  getDepthModeForSublayer(n, mask, func) {
19415
19826
  if (!this.opaquePassEnabledForLayer()) return DepthMode.disabled;
19416
- const depth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon;
19827
+ const depth = 1 - ((1 + this.renderOptions.currentLayer) * this.numSublayers + n) * this.depthEpsilon;
19417
19828
  return new DepthMode(func || this.context.gl.LEQUAL, mask, [depth, depth]);
19418
19829
  }
19419
19830
  getDepthModeFor3D() {
19420
- return new DepthMode(this.context.gl.LEQUAL, DepthMode.ReadWrite, this.depthRangeFor3D);
19831
+ return new DepthMode(this.context.gl.LEQUAL, DepthMode.ReadWrite, this.renderOptions.depthRangeFor3D);
19421
19832
  }
19422
19833
  opaquePassEnabledForLayer() {
19423
- return this.currentLayer < this.opaquePassCutoff;
19834
+ return this.renderOptions.currentLayer < this.renderOptions.opaquePassCutoff;
19424
19835
  }
19425
19836
  render(style, options) {
19426
19837
  this.style = style;
19427
19838
  this.options = options;
19839
+ const renderOptions = this.renderOptions = createRenderOptions(this.transform, style.projection, style.map.terrain ?? null);
19428
19840
  this.lineAtlas = style.lineAtlas;
19429
19841
  this.imageManager = style.imageManager;
19430
19842
  this.patternAtlas = style.patternAtlas;
19431
19843
  this.glyphManager = style.glyphManager;
19432
19844
  this.symbolFadeChange = style.placement.symbolFadeChange(now());
19845
+ updateFrameUniformBuffer(this.context.frameUniformBuffer, this);
19433
19846
  this.imageManager.beginFrame();
19434
19847
  const layerIds = this.style._order;
19435
19848
  const tileManagers = this.style.tileManagers;
19436
19849
  const coordsAscending = {};
19437
19850
  const coordsDescending = {};
19438
19851
  const coordsDescendingSymbol = {};
19439
- const renderOptions = {
19440
- isRenderingToTexture: false,
19441
- isRenderingGlobe: style.projection?.transitionState > 0
19442
- };
19443
19852
  for (const id in tileManagers) {
19444
19853
  const tileManager = tileManagers[id];
19445
19854
  if (tileManager.used) tileManager.prepare(this.context);
@@ -19447,20 +19856,20 @@ var Painter = class Painter {
19447
19856
  coordsDescending[id] = coordsAscending[id].slice().reverse();
19448
19857
  coordsDescendingSymbol[id] = tileManager.getVisibleCoordinates(true).reverse();
19449
19858
  }
19450
- this.opaquePassCutoff = Infinity;
19859
+ renderOptions.opaquePassCutoff = Infinity;
19451
19860
  for (let i = 0; i < layerIds.length; i++) {
19452
19861
  const layerId = layerIds[i];
19453
19862
  if (this.style._layers[layerId].is3D()) {
19454
- this.opaquePassCutoff = i;
19863
+ renderOptions.opaquePassCutoff = i;
19455
19864
  break;
19456
19865
  }
19457
19866
  }
19458
19867
  this.maybeDrawDepth();
19459
19868
  if (this.renderToTexture) {
19460
19869
  this.renderToTexture.prepareForRender(this.style, this.transform.zoom);
19461
- this.opaquePassCutoff = 0;
19870
+ renderOptions.opaquePassCutoff = 0;
19462
19871
  }
19463
- this.renderPass = "offscreen";
19872
+ renderOptions.currentPass = "offscreen";
19464
19873
  for (const layerId of layerIds) {
19465
19874
  const layer = this.style._layers[layerId];
19466
19875
  if (!layer.hasOffscreenPass() || layer.isHidden(this.transform.zoom)) continue;
@@ -19482,21 +19891,21 @@ var Painter = class Painter {
19482
19891
  this.clearStencil();
19483
19892
  if (this.style.sky) this.drawFunctions.sky(this, this.style.sky);
19484
19893
  this._showOverdrawInspector = options.showOverdrawInspector;
19485
- this.depthRangeFor3D = [0, 1 - (style._order.length + 2) * this.numSublayers * this.depthEpsilon];
19894
+ renderOptions.depthRangeFor3D = [0, 1 - (style._order.length + 2) * this.numSublayers * this.depthEpsilon];
19486
19895
  if (!this.renderToTexture) {
19487
- this.renderPass = "opaque";
19488
- for (this.currentLayer = layerIds.length - 1; this.currentLayer >= 0; this.currentLayer--) {
19489
- const layer = this.style._layers[layerIds[this.currentLayer]];
19896
+ renderOptions.currentPass = "opaque";
19897
+ for (renderOptions.currentLayer = layerIds.length - 1; renderOptions.currentLayer >= 0; renderOptions.currentLayer--) {
19898
+ const layer = this.style._layers[layerIds[renderOptions.currentLayer]];
19490
19899
  const tileManager = tileManagers[layer.source];
19491
19900
  const coords = coordsAscending[layer.source];
19492
19901
  this.renderTileClippingMasks(layer, coords, false);
19493
19902
  this.renderLayer(this, tileManager, layer, coords, renderOptions);
19494
19903
  }
19495
19904
  }
19496
- this.renderPass = "translucent";
19905
+ renderOptions.currentPass = "translucent";
19497
19906
  let globeDepthRendered = false;
19498
- for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) {
19499
- const layer = this.style._layers[layerIds[this.currentLayer]];
19907
+ for (renderOptions.currentLayer = 0; renderOptions.currentLayer < layerIds.length; renderOptions.currentLayer++) {
19908
+ const layer = this.style._layers[layerIds[renderOptions.currentLayer]];
19500
19909
  const tileManager = tileManagers[layer.source];
19501
19910
  if (this.renderToTexture?.renderLayer(layer, renderOptions)) continue;
19502
19911
  if (!this.opaquePassEnabledForLayer() && !globeDepthRendered) {
@@ -19566,9 +19975,16 @@ var Painter = class Painter {
19566
19975
  const obj = this._rttObjectRecyclePool.pop();
19567
19976
  if (obj) {
19568
19977
  if (obj.size !== size) {
19569
- gl.bindTexture(gl.TEXTURE_2D, obj.texture.texture);
19570
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
19571
- obj.texture.size = [size, size];
19978
+ obj.texture.update({
19979
+ width: size,
19980
+ height: size,
19981
+ data: null
19982
+ }, {
19983
+ premultiply: false,
19984
+ useMipmap: true
19985
+ });
19986
+ obj.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_LINEAR);
19987
+ if (this.context.extTextureFilterAnisotropic) gl.texParameterf(gl.TEXTURE_2D, this.context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, this.context.extTextureFilterAnisotropicMax);
19572
19988
  obj.size = size;
19573
19989
  }
19574
19990
  return obj;
@@ -19577,8 +19993,11 @@ var Painter = class Painter {
19577
19993
  width: size,
19578
19994
  height: size,
19579
19995
  data: null
19580
- }, gl.RGBA);
19581
- texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
19996
+ }, gl.RGBA, {
19997
+ premultiply: false,
19998
+ useMipmap: true
19999
+ });
20000
+ texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_LINEAR);
19582
20001
  if (this.context.extTextureFilterAnisotropic) gl.texParameterf(gl.TEXTURE_2D, this.context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, this.context.extTextureFilterAnisotropicMax);
19583
20002
  return {
19584
20003
  texture,
@@ -19706,6 +20125,9 @@ var Painter = class Painter {
19706
20125
  if (this.tileExtentMesh) this.tileExtentMesh.vertexBuffer?.destroy();
19707
20126
  if (this.tileExtentMesh) this.tileExtentMesh.indexBuffer?.destroy();
19708
20127
  if (this.debugOverlayTexture) this.debugOverlayTexture.destroy();
20128
+ this.context.projectionUniformBuffer.destroy();
20129
+ this.context.terrainUniformBuffer.destroy();
20130
+ this.context.frameUniformBuffer.destroy();
19709
20131
  if (this.cache) {
19710
20132
  for (const key in this.cache) {
19711
20133
  const program = this.cache[key];
@@ -22628,27 +23050,6 @@ var Camera = class extends Evented {
22628
23050
  if (rollChanged) this.fire(new MapMovementEvent("rollstart", eventData)).fire(new MapMovementEvent("roll", eventData)).fire(new MapMovementEvent("rollend", eventData));
22629
23051
  return this.fire(new MapMovementEvent("moveend", eventData));
22630
23052
  }
22631
- calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo = 0) {
22632
- const fromMercator = MercatorCoordinate.fromLngLat(from, altitudeFrom);
22633
- const toMercator = MercatorCoordinate.fromLngLat(to, altitudeTo);
22634
- const dx = toMercator.x - fromMercator.x;
22635
- const dy = toMercator.y - fromMercator.y;
22636
- const dz = toMercator.z - fromMercator.z;
22637
- const distance3D = Math.hypot(dx, dy, dz);
22638
- if (distance3D === 0) throw new Error("Can't calculate camera options with same From and To");
22639
- const groundDistance = Math.hypot(dx, dy);
22640
- const zoom = scaleZoom(this.transform.cameraToCenterDistance / distance3D / this.transform.tileSize);
22641
- const bearing = Math.atan2(dx, -dy) * 180 / Math.PI;
22642
- let pitch = Math.acos(groundDistance / distance3D) * 180 / Math.PI;
22643
- pitch = dz < 0 ? 90 - pitch : 90 + pitch;
22644
- return {
22645
- center: toMercator.toLngLat(),
22646
- elevation: altitudeTo,
22647
- zoom,
22648
- pitch,
22649
- bearing
22650
- };
22651
- }
22652
23053
  calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAlt, bearing, pitch, roll) {
22653
23054
  const centerInfo = this.transform.calculateCenterFromCameraLngLatAlt(cameraLngLat, cameraAlt, bearing, pitch);
22654
23055
  return {
@@ -22776,7 +23177,7 @@ var Camera = class extends Evented {
22776
23177
  const cameraAltitude = tr.getCameraAltitude();
22777
23178
  const minAltitude = this.terrain ? this.terrain.getElevationForLngLatZoom(cameraLngLat, tr.zoom) : 0;
22778
23179
  if (cameraAltitude < minAltitude) {
22779
- const newCamera = this.calculateCameraOptionsFromTo(cameraLngLat, minAltitude, tr.center, tr.elevation);
23180
+ const newCamera = tr.calculateCameraOptionsFromTo(cameraLngLat, minAltitude, tr.center, tr.elevation);
22780
23181
  return {
22781
23182
  pitch: newCamera.pitch,
22782
23183
  zoom: newCamera.zoom
@@ -23219,13 +23620,23 @@ var TaskQueue = class {
23219
23620
  if (this._currentlyRunning) throw new Error("Attempting to run(), but is already running.");
23220
23621
  const queue = this._currentlyRunning = this._queue;
23221
23622
  this._queue = [];
23623
+ let failed = false;
23624
+ let firstError;
23222
23625
  for (const task of queue) {
23223
23626
  if (task.cancelled) continue;
23224
- task.callback(timeStamp);
23627
+ try {
23628
+ task.callback(timeStamp);
23629
+ } catch (error) {
23630
+ if (!failed) {
23631
+ failed = true;
23632
+ firstError = error;
23633
+ }
23634
+ }
23225
23635
  if (this._cleared) break;
23226
23636
  }
23227
23637
  this._cleared = false;
23228
23638
  this._currentlyRunning = false;
23639
+ if (failed) throw firstError;
23229
23640
  }
23230
23641
  clear() {
23231
23642
  if (this._currentlyRunning) this._cleared = true;
@@ -23233,6 +23644,35 @@ var TaskQueue = class {
23233
23644
  }
23234
23645
  };
23235
23646
  //#endregion
23647
+ //#region src/webgl/rtt_fingerprint.ts
23648
+ /**
23649
+ * Immutable value describing the state a render-to-texture tile's textures
23650
+ * were rendered from: the source tiles drawn into them, the source data
23651
+ * revision, and the map zoom at render time (zoom-dependent style properties
23652
+ * are evaluated then).
23653
+ *
23654
+ * @internal
23655
+ */
23656
+ var RTTFingerprint = class {
23657
+ constructor(coords, revision, zoom) {
23658
+ this._tileKeys = coords.map((c) => c.key).sort().join();
23659
+ this._revision = revision;
23660
+ this._zoom = zoom;
23661
+ }
23662
+ equals(other) {
23663
+ return this.equalsIgnoringZoom(other) && this._zoom === other._zoom;
23664
+ }
23665
+ /**
23666
+ * Returns whether the source tiles and revision match, without comparing zoom.
23667
+ * Used to keep a texture on screen while the zoom is still changing and only
23668
+ * re-render it once the zoom has settled.
23669
+ */
23670
+ equalsIgnoringZoom(other) {
23671
+ if (other === void 0) return false;
23672
+ return this._tileKeys === other._tileKeys && this._revision === other._revision;
23673
+ }
23674
+ };
23675
+ //#endregion
23236
23676
  //#region src/webgl/render_to_texture.ts
23237
23677
  /**
23238
23678
  * lookup table which layers should rendered to texture
@@ -23254,6 +23694,7 @@ const LAYERS_TO_TEXTURES = {
23254
23694
  */
23255
23695
  var RenderToTexture = class {
23256
23696
  constructor(painter, terrain) {
23697
+ this.needsFollowUpFrame = false;
23257
23698
  this.painter = painter;
23258
23699
  this.terrain = terrain;
23259
23700
  this.rttSize = terrain.tileManager.tileSize * terrain.qualityFactor;
@@ -23262,6 +23703,8 @@ var RenderToTexture = class {
23262
23703
  return tile.getRTT(this._stacks.length - 1).texture;
23263
23704
  }
23264
23705
  prepareForRender(style, zoom) {
23706
+ const zoomChanged = zoom !== this._lastPrepareZoom;
23707
+ this._lastPrepareZoom = zoom;
23265
23708
  this._stacks = [];
23266
23709
  this._prevType = null;
23267
23710
  this._rttTiles = [];
@@ -23292,11 +23735,15 @@ var RenderToTexture = class {
23292
23735
  this._rttFingerprints[sourceId] = {};
23293
23736
  const fingerprints = this._rttFingerprints[sourceId];
23294
23737
  const revision = tileManager.getState().revision;
23295
- for (const key in coordsAscending) fingerprints[key] = `${coordsAscending[key].map((c) => c.key).sort().join()}#${revision}`;
23738
+ for (const key in coordsAscending) fingerprints[key] = new RTTFingerprint(coordsAscending[key], revision, zoom);
23296
23739
  }
23740
+ this.needsFollowUpFrame = false;
23297
23741
  for (const tile of this._renderableTiles) for (const source in this._rttFingerprints) {
23298
- const fingerprint = this._rttFingerprints[source][tile.tileID.key];
23299
- if (fingerprint && fingerprint !== tile.rttFingerprint[source]) tile.releaseRTT(this.painter);
23742
+ const frameFingerprint = this._rttFingerprints[source][tile.tileID.key];
23743
+ const tileFingerprint = tile.rttFingerprint[source];
23744
+ if (!frameFingerprint || frameFingerprint.equals(tileFingerprint)) continue;
23745
+ if (zoomChanged && frameFingerprint.equalsIgnoringZoom(tileFingerprint)) this.needsFollowUpFrame = true;
23746
+ else tile.releaseRTT(this.painter);
23300
23747
  }
23301
23748
  }
23302
23749
  /**
@@ -23351,6 +23798,7 @@ var RenderToTexture = class {
23351
23798
  painter.renderLayer(painter, painter.style.tileManagers[layer.source], layer, coords, options);
23352
23799
  if (layer.source) tile.rttFingerprint[layer.source] = this._rttFingerprints[layer.source][tile.tileID.key];
23353
23800
  }
23801
+ obj.texture.generateMipmap();
23354
23802
  }
23355
23803
  drawTerrain(this.painter, this.terrain, this._rttTiles, options);
23356
23804
  this._rttTiles = [];
@@ -23504,6 +23952,7 @@ var Map$1 = class extends Evented {
23504
23952
  this._renderTaskQueue = new TaskQueue();
23505
23953
  this._controls = [];
23506
23954
  this._mapId = uniqueId();
23955
+ this._styleUrl = null;
23507
23956
  this._missingStyleImageResolver = null;
23508
23957
  this._lostContextStyle = {
23509
23958
  style: null,
@@ -24396,6 +24845,7 @@ var Map$1 = class extends Evented {
24396
24845
  }
24397
24846
  /**
24398
24847
  * Given a camera 'from' position and a position to look at (`to`), calculates zoom and camera rotation and returns them as {@link CameraOptions}.
24848
+ * Under `globe` and `vertical-perspective` the calculation follows the sphere while the map renders as a globe, keeping the point looked at on the sea-level sphere; `altitudeTo` only becomes the center elevation.
24399
24849
  * @param from - The camera to look from
24400
24850
  * @param altitudeFrom - The altitude of the camera to look from
24401
24851
  * @param to - The center to look at
@@ -24415,7 +24865,7 @@ var Map$1 = class extends Evented {
24415
24865
  */
24416
24866
  calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
24417
24867
  if (altitudeTo == null && this.terrain) altitudeTo = this.terrain.getElevationForLngLat(to, this._camera.transform);
24418
- return this._camera.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo);
24868
+ return this._camera.transform.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo ?? 0);
24419
24869
  }
24420
24870
  /**
24421
24871
  * Resizes the map according to the dimensions of its
@@ -24484,6 +24934,8 @@ var Map$1 = class extends Evented {
24484
24934
  * @internal
24485
24935
  * Return the map's pixel ratio eventually scaled down to respect maxCanvasSize.
24486
24936
  * Internally you should use this and not getPixelRatio().
24937
+ * Warns once when the ratio is scaled down. The message carries no sizes: this runs on every
24938
+ * resize and `warnOnce` de-duplicates by message, so sizes would warn on every drag frame.
24487
24939
  */
24488
24940
  _getClampedPixelRatio(width, height) {
24489
24941
  const { 0: maxCanvasWidth, 1: maxCanvasHeight } = this._maxCanvasSize;
@@ -24492,7 +24944,9 @@ var Map$1 = class extends Evented {
24492
24944
  const canvasHeight = height * pixelRatio;
24493
24945
  const widthScaleFactor = canvasWidth > maxCanvasWidth ? maxCanvasWidth / canvasWidth : 1;
24494
24946
  const heightScaleFactor = canvasHeight > maxCanvasHeight ? maxCanvasHeight / canvasHeight : 1;
24495
- return Math.min(widthScaleFactor, heightScaleFactor) * pixelRatio;
24947
+ const scaleFactor = Math.min(widthScaleFactor, heightScaleFactor);
24948
+ if (scaleFactor < 1) warnOnce("The canvas is larger than maxCanvasSize and is rendered at a lower pixel ratio to fit. Increase maxCanvasSize, within MAX_TEXTURE_SIZE, to render at full resolution.");
24949
+ return scaleFactor * pixelRatio;
24496
24950
  }
24497
24951
  /**
24498
24952
  * Returns the map's pixel ratio.
@@ -25164,6 +25618,7 @@ var Map$1 = class extends Evented {
25164
25618
  localIdeographFontFamily: this._localIdeographFontFamily,
25165
25619
  validate: this._validateStyle
25166
25620
  }, options);
25621
+ this._styleUrl = typeof style === "string" ? style : null;
25167
25622
  if (options.diff !== false && options.localIdeographFontFamily === this._localIdeographFontFamily && this.style && style) {
25168
25623
  this._diffStyle(style, options);
25169
25624
  return this;
@@ -25272,6 +25727,19 @@ var Map$1 = class extends Evented {
25272
25727
  if (this.style) return this.style.serialize();
25273
25728
  }
25274
25729
  /**
25730
+ * Returns the URL the map's style was loaded from.
25731
+ *
25732
+ * @returns The URL given to {@link Map.setStyle} or the `style` map option, or `null` when the style was given as an object or the map has no style.
25733
+ *
25734
+ * @example
25735
+ * ```ts
25736
+ * const styleUrl = map.getStyleUrl();
25737
+ * ```
25738
+ */
25739
+ getStyleUrl() {
25740
+ return this._styleUrl;
25741
+ }
25742
+ /**
25275
25743
  * @internal
25276
25744
  * Returns the map's style and cloned images to restore context.
25277
25745
  * @returns An object containing the style and images.
@@ -25749,7 +26217,7 @@ var Map$1 = class extends Evented {
25749
26217
  * domains must support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).
25750
26218
  *
25751
26219
  * @param url - The URL of the image file. Image file must be in png, webp, or jpg format.
25752
- * @returns a promise that is resolved when the image is loaded
26220
+ * @returns a promise that is resolved when the image is loaded, or rejected when the response has no image data (for example an HTTP 204)
25753
26221
  *
25754
26222
  * @example
25755
26223
  * Load an image from an external URL.
@@ -25761,7 +26229,9 @@ var Map$1 = class extends Evented {
25761
26229
  * @see [Add an icon to the map](https://maplibre.org/maplibre-gl-js/docs/examples/add-an-icon-to-the-map/)
25762
26230
  */
25763
26231
  async loadImage(url) {
25764
- return ImageRequest.getImage(await this._requestManager.transformRequest(url, "Image"), new AbortController());
26232
+ const response = await ImageRequest.getImage(await this._requestManager.transformRequest(url, "Image"), new AbortController());
26233
+ if (!response.data) throw new Error(`Could not load image ${url}: the response is empty`);
26234
+ return response;
25765
26235
  }
25766
26236
  /**
25767
26237
  * Returns an Array of strings containing the IDs of all images currently available in the map.
@@ -26606,7 +27076,7 @@ var Map$1 = class extends Evented {
26606
27076
  }
26607
27077
  if (this.style && (this.style.hasTransitions() || crossFading)) this._styleDirty = true;
26608
27078
  if (this.style && !this._placementDirty) this.style._releaseSymbolFadeTiles();
26609
- const somethingDirty = this._sourcesDirty || this._styleDirty || this._placementDirty;
27079
+ const somethingDirty = this._sourcesDirty || this._styleDirty || this._placementDirty || this.painter.renderToTexture?.needsFollowUpFrame;
26610
27080
  if (somethingDirty || this._repaint) this.triggerRepaint();
26611
27081
  else if (!this.isMoving() && this.loaded()) this.fire(new MapLibreEvent("idle"));
26612
27082
  if (this._loaded && !this._fullyLoaded && !somethingDirty) this._fullyLoaded = true;
@@ -27093,6 +27563,87 @@ const ARROW_KEY_DELTAS = {
27093
27563
  };
27094
27564
  const KEYBOARD_DRAG_SMALL_STEP = 1;
27095
27565
  const KEYBOARD_DRAG_LARGE_STEP = 10;
27566
+ /** Fill color of the default marker when {@link MarkerOptions.color} is not given. */
27567
+ const DEFAULT_MARKER_COLOR = "#3FB1CE";
27568
+ /** Height in CSS pixels of the default marker SVG at scale 1. */
27569
+ const DEFAULT_MARKER_HEIGHT = 41;
27570
+ /** Width in CSS pixels of the default marker SVG at scale 1. */
27571
+ const DEFAULT_MARKER_WIDTH = 27;
27572
+ const SVG_NS = "http://www.w3.org/2000/svg";
27573
+ /** Creates an SVG element with the given attributes, set in the order given, and children. */
27574
+ function svgElement(tag, attributes, children = []) {
27575
+ const element = DOM.createNS(SVG_NS, tag);
27576
+ for (const name in attributes) element.setAttributeNS(null, name, attributes[name]);
27577
+ for (const child of children) element.appendChild(child);
27578
+ return element;
27579
+ }
27580
+ /** The default marker SVG at scale 1 in the default color, built on first use and cloned per marker. */
27581
+ let defaultMarkerTemplate;
27582
+ /**
27583
+ * Returns the shared default marker SVG, building it the first time it is asked for. Assembling
27584
+ * the pin takes about fifty DOM calls, so each default {@link Marker} deep-clones this template
27585
+ * and overrides only its size and its fill, see {@link defaultMarkerFillGroup}.
27586
+ */
27587
+ function getDefaultMarkerTemplate() {
27588
+ if (defaultMarkerTemplate) return defaultMarkerTemplate;
27589
+ const shadow = svgElement("g", {
27590
+ transform: "translate(3.0, 29.0)",
27591
+ fill: "#000000"
27592
+ }, [
27593
+ ["10.5", "5.25002273"],
27594
+ ["10.5", "5.25002273"],
27595
+ ["9.5", "4.77275007"],
27596
+ ["8.5", "4.29549936"],
27597
+ ["7.5", "3.81822308"],
27598
+ ["6.5", "3.34094679"],
27599
+ ["5.5", "2.86367051"],
27600
+ ["4.5", "2.38636864"]
27601
+ ].map(([rx, ry]) => svgElement("ellipse", {
27602
+ opacity: "0.04",
27603
+ cx: "10.5",
27604
+ cy: "5.80029008",
27605
+ rx,
27606
+ ry
27607
+ })));
27608
+ const background = svgElement("g", { fill: DEFAULT_MARKER_COLOR }, [svgElement("path", { d: "M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z" })]);
27609
+ const border = svgElement("g", {
27610
+ opacity: "0.25",
27611
+ fill: "#000000"
27612
+ }, [svgElement("path", { d: "M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z" })]);
27613
+ const maki = svgElement("g", {
27614
+ transform: "translate(6.0, 7.0)",
27615
+ fill: "#FFFFFF"
27616
+ });
27617
+ const circles = svgElement("g", { transform: "translate(8.0, 8.0)" }, [svgElement("circle", {
27618
+ fill: "#000000",
27619
+ opacity: "0.25",
27620
+ cx: "5.5",
27621
+ cy: "5.5",
27622
+ r: "5.4999962"
27623
+ }), svgElement("circle", {
27624
+ fill: "#FFFFFF",
27625
+ cx: "5.5",
27626
+ cy: "5.5",
27627
+ r: "5.4999962"
27628
+ })]);
27629
+ defaultMarkerTemplate = svgElement("svg", {
27630
+ display: "block",
27631
+ height: `${DEFAULT_MARKER_HEIGHT}px`,
27632
+ width: `${DEFAULT_MARKER_WIDTH}px`,
27633
+ viewBox: `0 0 ${DEFAULT_MARKER_WIDTH} ${DEFAULT_MARKER_HEIGHT}`
27634
+ }, [svgElement("g", { "fill-rule": "nonzero" }, [
27635
+ shadow,
27636
+ background,
27637
+ border,
27638
+ maki,
27639
+ circles
27640
+ ])]);
27641
+ return defaultMarkerTemplate;
27642
+ }
27643
+ /** The group of a default marker SVG that carries the pin's fill color: the second child of its single top-level group. */
27644
+ function defaultMarkerFillGroup(svg) {
27645
+ return svg.firstElementChild.children[1];
27646
+ }
27096
27647
  /**
27097
27648
  * The event class for marker drag events (`dragstart`, `drag` and `dragend`).
27098
27649
  *
@@ -27255,7 +27806,7 @@ var Marker = class extends Evented {
27255
27806
  }
27256
27807
  };
27257
27808
  this._anchor = options?.anchor || "center";
27258
- this._color = options?.color || "#3FB1CE";
27809
+ this._color = options?.color || DEFAULT_MARKER_COLOR;
27259
27810
  this._scale = options?.scale || 1;
27260
27811
  this._draggable = options?.draggable || false;
27261
27812
  this._clickTolerance = options?.clickTolerance || 0;
@@ -27272,102 +27823,10 @@ var Marker = class extends Evented {
27272
27823
  if (!options?.element) {
27273
27824
  this._defaultMarker = true;
27274
27825
  this._element = DOM.create("div");
27275
- const svg = DOM.createNS("http://www.w3.org/2000/svg", "svg");
27276
- const defaultHeight = 41;
27277
- const defaultWidth = 27;
27278
- svg.setAttributeNS(null, "display", "block");
27279
- svg.setAttributeNS(null, "height", `${defaultHeight}px`);
27280
- svg.setAttributeNS(null, "width", `${defaultWidth}px`);
27281
- svg.setAttributeNS(null, "viewBox", `0 0 ${defaultWidth} ${defaultHeight}`);
27282
- const markerLarge = DOM.createNS("http://www.w3.org/2000/svg", "g");
27283
- markerLarge.setAttributeNS(null, "stroke", "none");
27284
- markerLarge.setAttributeNS(null, "stroke-width", "1");
27285
- markerLarge.setAttributeNS(null, "fill", "none");
27286
- markerLarge.setAttributeNS(null, "fill-rule", "evenodd");
27287
- const page1 = DOM.createNS("http://www.w3.org/2000/svg", "g");
27288
- page1.setAttributeNS(null, "fill-rule", "nonzero");
27289
- const shadow = DOM.createNS("http://www.w3.org/2000/svg", "g");
27290
- shadow.setAttributeNS(null, "transform", "translate(3.0, 29.0)");
27291
- shadow.setAttributeNS(null, "fill", "#000000");
27292
- for (const data of [
27293
- {
27294
- "rx": "10.5",
27295
- "ry": "5.25002273"
27296
- },
27297
- {
27298
- "rx": "10.5",
27299
- "ry": "5.25002273"
27300
- },
27301
- {
27302
- "rx": "9.5",
27303
- "ry": "4.77275007"
27304
- },
27305
- {
27306
- "rx": "8.5",
27307
- "ry": "4.29549936"
27308
- },
27309
- {
27310
- "rx": "7.5",
27311
- "ry": "3.81822308"
27312
- },
27313
- {
27314
- "rx": "6.5",
27315
- "ry": "3.34094679"
27316
- },
27317
- {
27318
- "rx": "5.5",
27319
- "ry": "2.86367051"
27320
- },
27321
- {
27322
- "rx": "4.5",
27323
- "ry": "2.38636864"
27324
- }
27325
- ]) {
27326
- const ellipse = DOM.createNS("http://www.w3.org/2000/svg", "ellipse");
27327
- ellipse.setAttributeNS(null, "opacity", "0.04");
27328
- ellipse.setAttributeNS(null, "cx", "10.5");
27329
- ellipse.setAttributeNS(null, "cy", "5.80029008");
27330
- ellipse.setAttributeNS(null, "rx", data["rx"]);
27331
- ellipse.setAttributeNS(null, "ry", data["ry"]);
27332
- shadow.appendChild(ellipse);
27333
- }
27334
- const background = DOM.createNS("http://www.w3.org/2000/svg", "g");
27335
- background.setAttributeNS(null, "fill", this._color);
27336
- const bgPath = DOM.createNS("http://www.w3.org/2000/svg", "path");
27337
- bgPath.setAttributeNS(null, "d", "M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z");
27338
- background.appendChild(bgPath);
27339
- const border = DOM.createNS("http://www.w3.org/2000/svg", "g");
27340
- border.setAttributeNS(null, "opacity", "0.25");
27341
- border.setAttributeNS(null, "fill", "#000000");
27342
- const borderPath = DOM.createNS("http://www.w3.org/2000/svg", "path");
27343
- borderPath.setAttributeNS(null, "d", "M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z");
27344
- border.appendChild(borderPath);
27345
- const maki = DOM.createNS("http://www.w3.org/2000/svg", "g");
27346
- maki.setAttributeNS(null, "transform", "translate(6.0, 7.0)");
27347
- maki.setAttributeNS(null, "fill", "#FFFFFF");
27348
- const circleContainer = DOM.createNS("http://www.w3.org/2000/svg", "g");
27349
- circleContainer.setAttributeNS(null, "transform", "translate(8.0, 8.0)");
27350
- const circle1 = DOM.createNS("http://www.w3.org/2000/svg", "circle");
27351
- circle1.setAttributeNS(null, "fill", "#000000");
27352
- circle1.setAttributeNS(null, "opacity", "0.25");
27353
- circle1.setAttributeNS(null, "cx", "5.5");
27354
- circle1.setAttributeNS(null, "cy", "5.5");
27355
- circle1.setAttributeNS(null, "r", "5.4999962");
27356
- const circle2 = DOM.createNS("http://www.w3.org/2000/svg", "circle");
27357
- circle2.setAttributeNS(null, "fill", "#FFFFFF");
27358
- circle2.setAttributeNS(null, "cx", "5.5");
27359
- circle2.setAttributeNS(null, "cy", "5.5");
27360
- circle2.setAttributeNS(null, "r", "5.4999962");
27361
- circleContainer.appendChild(circle1);
27362
- circleContainer.appendChild(circle2);
27363
- page1.appendChild(shadow);
27364
- page1.appendChild(background);
27365
- page1.appendChild(border);
27366
- page1.appendChild(maki);
27367
- page1.appendChild(circleContainer);
27368
- svg.appendChild(page1);
27369
- svg.setAttributeNS(null, "height", `${defaultHeight * this._scale}px`);
27370
- svg.setAttributeNS(null, "width", `${defaultWidth * this._scale}px`);
27826
+ const svg = getDefaultMarkerTemplate().cloneNode(true);
27827
+ svg.setAttributeNS(null, "height", `${DEFAULT_MARKER_HEIGHT * this._scale}px`);
27828
+ svg.setAttributeNS(null, "width", `${DEFAULT_MARKER_WIDTH * this._scale}px`);
27829
+ defaultMarkerFillGroup(svg).setAttributeNS(null, "fill", this._color);
27371
27830
  this._element.appendChild(svg);
27372
27831
  this._offset = Point.convert(options?.offset || [0, -14]);
27373
27832
  } else {
@@ -27484,8 +27943,8 @@ var Marker = class extends Evented {
27484
27943
  setLngLat(lnglat) {
27485
27944
  this._lngLat = LngLat.convert(lnglat);
27486
27945
  this._pos = null;
27487
- if (this._popup) this._popup.setLngLat(this._lngLat);
27488
27946
  this._update();
27947
+ if (this._popup) this._popup.setLngLat(this._lngLat);
27489
27948
  return this;
27490
27949
  }
27491
27950
  /**