maplibre-gl 6.7.0 → 6.9.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 (213) hide show
  1. package/build/generate-unicode-data.ts +321 -110
  2. package/dist/maplibre-gl-dev.mjs +1539 -1009
  3. package/dist/maplibre-gl-dev.mjs.map +1 -1
  4. package/dist/maplibre-gl-shared-dev.mjs +10802 -9186
  5. package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
  6. package/dist/maplibre-gl-shared.mjs +2 -2
  7. package/dist/maplibre-gl-shared.mjs.map +1 -1
  8. package/dist/maplibre-gl-worker-dev.mjs +26 -21
  9. package/dist/maplibre-gl-worker-dev.mjs.map +1 -1
  10. package/dist/maplibre-gl-worker.mjs +2 -2
  11. package/dist/maplibre-gl-worker.mjs.map +1 -1
  12. package/dist/maplibre-gl.d.ts +402 -253
  13. package/dist/maplibre-gl.mjs +60 -47
  14. package/dist/maplibre-gl.mjs.map +1 -1
  15. package/package.json +21 -20
  16. package/src/data/bucket/circle_bucket.ts +3 -0
  17. package/src/data/bucket/fill_bucket.test.ts +106 -13
  18. package/src/data/bucket/fill_bucket.ts +40 -4
  19. package/src/data/bucket/fill_extrusion_bucket.ts +3 -2
  20. package/src/data/bucket/line_bucket.ts +3 -2
  21. package/src/data/bucket/symbol_bucket.test.ts +4 -12
  22. package/src/data/bucket/symbol_bucket.ts +32 -34
  23. package/src/data/bucket.ts +23 -0
  24. package/src/data/dem_data.test.ts +14 -12
  25. package/src/data/dem_data.ts +16 -25
  26. package/src/geo/projection/covering_tiles.ts +71 -10
  27. package/src/geo/projection/globe_covering_tiles.test.ts +49 -0
  28. package/src/geo/projection/globe_covering_tiles_details_provider.ts +6 -1
  29. package/src/geo/projection/globe_transform.test.ts +145 -0
  30. package/src/geo/projection/globe_transform.ts +10 -3
  31. package/src/geo/projection/globe_utils.test.ts +21 -1
  32. package/src/geo/projection/globe_utils.ts +10 -1
  33. package/src/geo/projection/mercator_transform.test.ts +102 -1
  34. package/src/geo/projection/mercator_transform.ts +23 -6
  35. package/src/geo/projection/vertical_perspective_transform.test.ts +162 -1
  36. package/src/geo/projection/vertical_perspective_transform.ts +75 -17
  37. package/src/geo/transform_helper.test.ts +11 -0
  38. package/src/geo/transform_helper.ts +19 -25
  39. package/src/geo/transform_interface.ts +16 -0
  40. package/src/index.ts +5 -1
  41. package/src/render/glyph_manager.test.ts +22 -2
  42. package/src/render/glyph_manager.ts +20 -14
  43. package/src/render/painter.test.ts +35 -1
  44. package/src/render/painter.ts +35 -34
  45. package/src/render/render_options.ts +38 -0
  46. package/src/render/render_to_texture_interface.ts +6 -1
  47. package/src/shaders/glsl/_prelude.fragment.glsl +20 -0
  48. package/src/shaders/glsl/_prelude.fragment.glsl.g.ts +1 -1
  49. package/src/shaders/glsl/_prelude.vertex.glsl +27 -6
  50. package/src/shaders/glsl/_prelude.vertex.glsl.g.ts +1 -1
  51. package/src/shaders/glsl/_projection_globe.fragment.glsl +1 -3
  52. package/src/shaders/glsl/_projection_globe.fragment.glsl.g.ts +1 -1
  53. package/src/shaders/glsl/_projection_globe.vertex.glsl +3 -0
  54. package/src/shaders/glsl/_projection_globe.vertex.glsl.g.ts +1 -1
  55. package/src/shaders/glsl/circle.vertex.glsl +0 -2
  56. package/src/shaders/glsl/circle.vertex.glsl.g.ts +1 -1
  57. package/src/shaders/glsl/collision_box.vertex.glsl +0 -3
  58. package/src/shaders/glsl/collision_box.vertex.glsl.g.ts +1 -1
  59. package/src/shaders/glsl/collision_circle.vertex.glsl +0 -3
  60. package/src/shaders/glsl/collision_circle.vertex.glsl.g.ts +1 -1
  61. package/src/shaders/glsl/color_relief.vertex.glsl +2 -2
  62. package/src/shaders/glsl/color_relief.vertex.glsl.g.ts +1 -1
  63. package/src/shaders/glsl/fill_outline.vertex.glsl +1 -2
  64. package/src/shaders/glsl/fill_outline.vertex.glsl.g.ts +1 -1
  65. package/src/shaders/glsl/fill_outline_pattern.fragment.glsl +13 -1
  66. package/src/shaders/glsl/fill_outline_pattern.fragment.glsl.g.ts +1 -1
  67. package/src/shaders/glsl/fill_outline_pattern.vertex.glsl +3 -2
  68. package/src/shaders/glsl/fill_outline_pattern.vertex.glsl.g.ts +1 -1
  69. package/src/shaders/glsl/fill_pattern.fragment.glsl +13 -1
  70. package/src/shaders/glsl/fill_pattern.fragment.glsl.g.ts +1 -1
  71. package/src/shaders/glsl/fill_pattern.vertex.glsl +2 -0
  72. package/src/shaders/glsl/fill_pattern.vertex.glsl.g.ts +1 -1
  73. package/src/shaders/glsl/heatmap_texture.vertex.glsl +1 -2
  74. package/src/shaders/glsl/heatmap_texture.vertex.glsl.g.ts +1 -1
  75. package/src/shaders/glsl/hillshade.fragment.glsl +3 -1
  76. package/src/shaders/glsl/hillshade.fragment.glsl.g.ts +1 -1
  77. package/src/shaders/glsl/hillshade_prepare.fragment.glsl +1 -1
  78. package/src/shaders/glsl/hillshade_prepare.fragment.glsl.g.ts +1 -1
  79. package/src/shaders/glsl/line.fragment.glsl +0 -2
  80. package/src/shaders/glsl/line.fragment.glsl.g.ts +1 -1
  81. package/src/shaders/glsl/line.vertex.glsl +0 -3
  82. package/src/shaders/glsl/line.vertex.glsl.g.ts +1 -1
  83. package/src/shaders/glsl/line_gradient.fragment.glsl +0 -1
  84. package/src/shaders/glsl/line_gradient.fragment.glsl.g.ts +1 -1
  85. package/src/shaders/glsl/line_gradient.vertex.glsl +0 -2
  86. package/src/shaders/glsl/line_gradient.vertex.glsl.g.ts +1 -1
  87. package/src/shaders/glsl/line_gradient_sdf.fragment.glsl +0 -1
  88. package/src/shaders/glsl/line_gradient_sdf.fragment.glsl.g.ts +1 -1
  89. package/src/shaders/glsl/line_gradient_sdf.vertex.glsl +0 -2
  90. package/src/shaders/glsl/line_gradient_sdf.vertex.glsl.g.ts +1 -1
  91. package/src/shaders/glsl/line_pattern.fragment.glsl +0 -1
  92. package/src/shaders/glsl/line_pattern.fragment.glsl.g.ts +1 -1
  93. package/src/shaders/glsl/line_pattern.vertex.glsl +0 -3
  94. package/src/shaders/glsl/line_pattern.vertex.glsl.g.ts +1 -1
  95. package/src/shaders/glsl/line_sdf.fragment.glsl +0 -2
  96. package/src/shaders/glsl/line_sdf.fragment.glsl.g.ts +1 -1
  97. package/src/shaders/glsl/line_sdf.vertex.glsl +0 -2
  98. package/src/shaders/glsl/line_sdf.vertex.glsl.g.ts +1 -1
  99. package/src/shaders/glsl/sky.fragment.glsl +11 -0
  100. package/src/shaders/glsl/sky.fragment.glsl.g.ts +1 -1
  101. package/src/shaders/glsl/sky.vertex.glsl +5 -0
  102. package/src/shaders/glsl/sky.vertex.glsl.g.ts +1 -1
  103. package/src/shaders/glsl/symbol_icon.vertex.glsl +1 -5
  104. package/src/shaders/glsl/symbol_icon.vertex.glsl.g.ts +1 -1
  105. package/src/shaders/glsl/symbol_sdf.fragment.glsl +0 -1
  106. package/src/shaders/glsl/symbol_sdf.fragment.glsl.g.ts +1 -1
  107. package/src/shaders/glsl/symbol_sdf.vertex.glsl +1 -5
  108. package/src/shaders/glsl/symbol_sdf.vertex.glsl.g.ts +1 -1
  109. package/src/shaders/glsl/symbol_text_and_icon.fragment.glsl +0 -2
  110. package/src/shaders/glsl/symbol_text_and_icon.fragment.glsl.g.ts +1 -1
  111. package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl +1 -5
  112. package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl.g.ts +1 -1
  113. package/src/source/geojson_source_diff.test.ts +59 -0
  114. package/src/source/geojson_source_diff.ts +3 -5
  115. package/src/source/image_source.ts +2 -0
  116. package/src/source/raster_dem_tile_source.test.ts +26 -0
  117. package/src/source/raster_dem_tile_source.ts +13 -6
  118. package/src/source/raster_dem_tile_worker_source.test.ts +2 -0
  119. package/src/source/raster_dem_tile_worker_source.ts +3 -3
  120. package/src/source/raster_tile_source.test.ts +42 -0
  121. package/src/source/raster_tile_source.ts +7 -2
  122. package/src/source/rtl_text_plugin_status.ts +12 -0
  123. package/src/source/rtl_text_plugin_worker.ts +6 -0
  124. package/src/source/vector_tile_source.test.ts +25 -0
  125. package/src/source/vector_tile_source.ts +1 -0
  126. package/src/source/worker.ts +7 -1
  127. package/src/source/worker_tile.test.ts +2 -1
  128. package/src/source/worker_tile.ts +15 -21
  129. package/src/source/worker_tile_mlt.bench.ts +82 -0
  130. package/src/style/evaluation_parameters.ts +0 -12
  131. package/src/style/load_sprite.ts +5 -1
  132. package/src/style/style.test.ts +66 -1
  133. package/src/style/style.ts +9 -7
  134. package/src/style/style_image.ts +1 -1
  135. package/src/symbol/arabic_shaping.test.ts +61 -0
  136. package/src/symbol/arabic_shaping.ts +207 -0
  137. package/src/symbol/bidi.test.ts +88 -0
  138. package/src/symbol/bidi.ts +210 -0
  139. package/src/symbol/shaping.ts +81 -52
  140. package/src/symbol/symbol_layout.ts +13 -15
  141. package/src/symbol/symbol_size.ts +8 -0
  142. package/src/symbol/transform_text.test.ts +46 -0
  143. package/src/symbol/transform_text.ts +2 -5
  144. package/src/tile/tile.ts +2 -1
  145. package/src/tile/tile_manager.test.ts +70 -1
  146. package/src/tile/tile_manager.ts +44 -0
  147. package/src/ui/camera.test.ts +69 -70
  148. package/src/ui/camera.ts +27 -47
  149. package/src/ui/map.ts +58 -11
  150. package/src/ui/map_tests/map_canvas.test.ts +16 -0
  151. package/src/ui/map_tests/map_render.test.ts +45 -0
  152. package/src/ui/map_tests/map_style.test.ts +82 -1
  153. package/src/ui/marker.test.ts +31 -0
  154. package/src/ui/marker.ts +72 -95
  155. package/src/util/browser.test.ts +67 -0
  156. package/src/util/browser.ts +18 -5
  157. package/src/util/dom.test.ts +18 -0
  158. package/src/util/dom.ts +4 -3
  159. package/src/util/graphemes.ts +12 -9
  160. package/src/util/image_request.test.ts +20 -2
  161. package/src/util/image_request.ts +10 -1
  162. package/src/util/offscreen_canvas_supported.test.ts +22 -0
  163. package/src/util/offscreen_canvas_supported.ts +8 -1
  164. package/src/util/script_detection.test.ts +53 -1
  165. package/src/util/script_detection.ts +7 -100
  166. package/src/util/task_queue.test.ts +20 -0
  167. package/src/util/task_queue.ts +11 -1
  168. package/src/util/test/null_gl.ts +5 -0
  169. package/src/util/test/util.ts +2 -2
  170. package/src/util/unicode_properties.g.ts +128 -9
  171. package/src/util/util.ts +1 -4
  172. package/src/webgl/context.ts +14 -0
  173. package/src/webgl/draw/draw_background.ts +3 -2
  174. package/src/webgl/draw/draw_circle.ts +3 -2
  175. package/src/webgl/draw/draw_collision_debug.ts +2 -4
  176. package/src/webgl/draw/draw_color_relief.ts +12 -6
  177. package/src/webgl/draw/draw_custom.test.ts +6 -4
  178. package/src/webgl/draw/draw_custom.ts +4 -3
  179. package/src/webgl/draw/draw_fill.test.ts +6 -5
  180. package/src/webgl/draw/draw_fill.ts +10 -9
  181. package/src/webgl/draw/draw_fill_extrusion.ts +4 -3
  182. package/src/webgl/draw/draw_heatmap.ts +6 -5
  183. package/src/webgl/draw/draw_hillshade.ts +9 -8
  184. package/src/webgl/draw/draw_line.ts +3 -2
  185. package/src/webgl/draw/draw_raster.ts +3 -2
  186. package/src/webgl/draw/draw_sky.ts +5 -18
  187. package/src/webgl/draw/draw_symbol.test.ts +14 -13
  188. package/src/webgl/draw/draw_symbol.ts +3 -2
  189. package/src/webgl/draw/draw_terrain.ts +3 -2
  190. package/src/webgl/frame_uniform_buffer.ts +44 -0
  191. package/src/webgl/index_buffer.ts +2 -2
  192. package/src/webgl/program/circle_program.ts +0 -6
  193. package/src/webgl/program/fill_program.ts +11 -15
  194. package/src/webgl/program/heatmap_program.ts +0 -6
  195. package/src/webgl/program/line_program.ts +0 -30
  196. package/src/webgl/program/program_uniforms.ts +9 -8
  197. package/src/webgl/program/sky_program.ts +11 -1
  198. package/src/webgl/program/symbol_program.ts +0 -35
  199. package/src/webgl/program/terrain_program.ts +1 -10
  200. package/src/webgl/program.ts +20 -19
  201. package/src/webgl/projection_uniform_buffer.ts +33 -0
  202. package/src/webgl/render_to_texture.test.ts +210 -11
  203. package/src/webgl/render_to_texture.ts +57 -11
  204. package/src/webgl/rtt_fingerprint.test.ts +40 -0
  205. package/src/webgl/rtt_fingerprint.ts +44 -0
  206. package/src/webgl/terrain_uniform_buffer.ts +29 -0
  207. package/src/webgl/texture.test.ts +46 -0
  208. package/src/webgl/texture.ts +28 -10
  209. package/src/webgl/uniform_buffer.test.ts +62 -0
  210. package/src/webgl/uniform_buffer.ts +103 -0
  211. package/src/webgl/vertex_array_object.ts +0 -17
  212. package/src/webgl/program/collision_program.ts +0 -34
  213. 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.9.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 projectToWorldCoordinates, $n as degreesToRadians, $r as transformMat4, $t as TRANSITION_SUFFIX, A as evaluateSizeForZoom, Ai as perspective, An as sameOrigin, Ar as rollPitchBearingToQuat, At as toEvaluationFeature, B as isCluster, Bi as invert, Bn as angleToRotateBetweenVectors2D, Br as pixelsToTileUnits, Bt as SegmentVector, C as addDynamicAttributes, Ci as equals, Cn as AJAXError, Cr as pick, Ct as HEATMAP_FULL_RENDER_FBO_KEY, Di as invert$1, Dn as getReferrer, Dr as readImageUsingVideoFrame, Dt as RGBAImage, E as TextAnchorEnum, Ei as identity, En as getJSON, Er as rayPlaneIntersection, Et as AlphaImage, F as potpack, Fi as translate, Fn as AbortError, Fr as translatePosition, Ft as Uniform4f, Gn as clone$2, Gr as sqrLen, Gt as PosArray, Hi as isOffscreenCanvasDistorted, Hn as arrayBufferToImageBitmap, Hr as create$3, Ht as CollisionCircleLayoutArray, I as isStyleImageWebGLData, Ii as create$4, In as isAbortError, Ir as uniqueId, It as UniformColor, J as cameraDirectionFromPitchBearing, Jn as createMat4f64, Jr as fromValues, Jt as TriangleIndexArray, K as isFillExtrusionStyleLayer, Kn as createIdentityMat4f32, Kr as zero, Kt as QuadTriangleArray, L as renderStyleImage, Li as fromRotation, Ln as throwIfAborted, Lr as warnOnce, Lt as UniformColorArray, M as getAnchorAlignment, Mi as rotateY$1, Mn as getProtocol, Mr as sphericalToCartesian, Mt as Uniform1i, Ni as rotateZ, Nn as removeProtocol, Nr as subscribe, Nt as Uniform2f, O as clipLine, Oi as multiply, On as getVideo, Or as remapSaturate, Ot as isCircleStyleLayer, P as ImagePosition, Pi as scale, Pn as config, Pr as threePlaneIntersection, Pt as Uniform3f, Q as maxMercatorHorizonAngle, Qn as defaultEasing, Qr as scale$2, Qt as Properties, R as parseGlyphPbf, Ri as create$2, Rr as wrap, Rt as UniformFloatArray, S as SymbolBucket, Si as create$1, Sn as Evented, Sr as parseCacheControl, St as isHillshadeStyleLayer, T as getAnchorJustification, Ti as fromScaling, Tn as getArrayBuffer, Tr as radiansToDegrees, Tt as renderColorRamp, U as collisionCircleLayout, Ui as offscreenCanvasSupported, Un as bezier, Ur as length$1, Ut as LineStripIndexArray, V as codePointUsesLocalIdeographFontFamily, Vi as rotate, Vn as arrayBufferToImage, Vr as EXTENT, Vt as CollisionBoxArray, W as isLineStyleLayer, Wi as Point, Wn as clamp, Wr as scale$3, Wt as Pos3dArray, X as cameraMercatorCoordinateFromCenterAndRotation, Xn as createVec4f64, Xr as slerp, Xt as isRasterStyleLayer, Y as cameraMercatorCoordinate, Yn as createVec3f64, Yr as multiply$1, Yt as createLayout, Z as getMercatorHorizon, Zn as deepEqual, Zr as mul, Zt as DataConstantProperty, _ as createStyleLayer, _i as transformMat4$1, _n as diff, _r as isWorker, _t as SubdivisionGranularityExpression, a as GeoJSONFeature, ai as len, an as emitValidationErrors, ar as filterObject, at as lngFromMercatorX, b as isBackgroundStyleLayer, bi as clone$1, bn as ErrorEvent, br as mod, ci as normalize, cn as validateStyleAndEmit, cr as getAngleDelta, ct as mercatorZfromAltitude, d as OverscaledTileID, di as rotateZ$1, dn as featureFilter, dr as getRollPitchBearing, ei as add, en as Transitionable, er as differenceOfAnglesDegrees, et as tileCoordinatesToMercatorCoordinates, f as UnwrappedTileID, fi as scale$1, fr as isImageBitmap, ft as EXTENT_BOUNDS, g as Actor, gi as transformMat3, gn as ValidationError, gr as isTouchableOrPointableType, gt as SOUTH_POLE_Y, h as isInBoundsForZoomLngLat, hi as subtract, hn as Color, hr as isTouchableEvent, ht as NORTH_POLE_Y, ii as dot, in as SPEC_SOURCE_TYPES, ir as extend, it as latFromMercatorY, ji as rotateX, jn as addProtocol, jr as scaleZoom, jt as Uniform1f, k as evaluateSizeForFeature, ki as ortho, kn as makeRequest, kr as rollPitchBearingEqual, kt as polygonIntersectsPolygon, li as rotateX$1, ln as emptyStyle, lr as getEdgeTiles, lt as LngLat, m as compareTileId, mi as sub, mn as ProjectionDefinition, mr as isSafari, mt as isFillStyleLayer, n as TileCache, ni as cross, nn as ZoomHistory, nr as ensureError, nt as MercatorCoordinate, oi as length, on as validateAndEmit, or as findLineIntersection, ot as mercatorXfromLng, p as calculateTileKey, pi as scaleAndAdd, pn as interpolateFactory, pr as isPointableEvent, pt as Bounds, q as calculateTileMatrix, qn as createIdentityMat4f64, qr as fromEuler, qt as RasterBoundsArray, ri as distance, rr as evaluateZoomSnap, rt as altitudeFromMercatorZ, s as GEOJSON_TILE_LAYER_NAME, si as negate, sn as validateStyle, sr as getAABB, st as mercatorYfromLat, ti as clone, tn as EvaluationParameters, tr as distanceOfAnglesRadians, tt as unprojectFromWorldCoordinates, u as CanonicalTileID, ui as rotateY, ut as earthRadius, v as isCustomStyleLayer, vi as transformQuat, vn as derefLayers, vr as lerp, vt as SubdivisionGranularitySetting, w as getOverlapMode, wi as exactEquals, wn as GLOBAL_DISPATCHER_ID, wr as pointPlaneSignedDistance, wt as isHeatmapStyleLayer, x as isSymbolStyleLayer, xi as copy, xn as Event, xr as nextPowerOfTwo, xt as Texture, y as validateCustomStyleLayer, yi as zero$1, yn as latest, yr as mapObject, yt as isColorReliefStyleLayer, zi as determinant, zn as MAX_VALID_LATITUDE, zr as zoomScale, zt as UniformMatrix4f } from "./maplibre-gl-shared-dev.mjs";
6
6
  //#region package.json
7
- var version$2 = "6.7.0";
7
+ var version$2 = "6.9.0";
8
8
  //#endregion
9
9
  //#region src/util/browser.ts
10
10
  let linkEl;
@@ -48,12 +48,22 @@ const browser = {
48
48
  getImageData(img, padding = 0) {
49
49
  return this.getImageCanvasContext(img).getImageData(-padding, -padding, img.width + 2 * padding, img.height + 2 * padding);
50
50
  },
51
+ /**
52
+ * Draws an image into a 2D canvas whose pixels can be read back cheaply. An `OffscreenCanvas`
53
+ * is used where the browser has one that reads back faithfully: drawing a GPU-backed
54
+ * `ImageBitmap` into a document canvas opened with `willReadFrequently` stalls the main thread
55
+ * for tens of milliseconds on GPU-accelerated browsers, an `OffscreenCanvas` does not.
56
+ */
51
57
  getImageCanvasContext(img) {
52
- const canvas = window.document.createElement("canvas");
53
- const context = canvas.getContext("2d", { willReadFrequently: true });
58
+ let context;
59
+ if (offscreenCanvasSupported() && !isOffscreenCanvasDistorted()) context = new OffscreenCanvas(img.width, img.height).getContext("2d", { willReadFrequently: true });
60
+ else {
61
+ const canvas = window.document.createElement("canvas");
62
+ canvas.width = img.width;
63
+ canvas.height = img.height;
64
+ context = canvas.getContext("2d", { willReadFrequently: true });
65
+ }
54
66
  if (!context) throw new Error("failed to create canvas 2d context");
55
- canvas.width = img.width;
56
- canvas.height = img.height;
57
67
  context.drawImage(img, 0, 0, img.width, img.height);
58
68
  return context;
59
69
  },
@@ -253,8 +263,8 @@ var DOM = class DOM {
253
263
  */
254
264
  static sanitize(str) {
255
265
  const html = new DOMParser().parseFromString(str, "text/html").body || document.createElement("body");
256
- const scripts = html.querySelectorAll("script");
257
- for (const script of scripts) script.remove();
266
+ const dangerousElements = html.querySelectorAll("script, iframe");
267
+ for (const element of dangerousElements) element.remove();
258
268
  DOM.clean(html);
259
269
  return html.innerHTML;
260
270
  }
@@ -270,6 +280,7 @@ var DOM = class DOM {
270
280
  ].includes(name)) {
271
281
  if (val.includes("javascript:") || val.includes("data:")) return true;
272
282
  }
283
+ if (name === "srcdoc") return true;
273
284
  if (name.startsWith("on")) return true;
274
285
  }
275
286
  /**
@@ -358,6 +369,13 @@ let ImageRequest;
358
369
  if (typeof createImageBitmap === "function") return arrayBufferToImageBitmap(data, imageBitmapOptions);
359
370
  else return arrayBufferToImage(data);
360
371
  };
372
+ /**
373
+ * Runs one queued image request.
374
+ *
375
+ * An empty response body (e.g. HTTP 204 for a tile without content) resolves with
376
+ * `data: null`, keeping the expiry headers, so callers can handle the absence
377
+ * explicitly and re-request when the headers say so.
378
+ */
361
379
  const doImageRequest = async (itemInQueue) => {
362
380
  itemInQueue.state = "running";
363
381
  const { requestParameters, supportImageRefresh, imageBitmapOptions, onError, onSuccess, abortController } = itemInQueue;
@@ -369,7 +387,12 @@ let ImageRequest;
369
387
  delete itemInQueue.abortController;
370
388
  itemInQueue.state = "completed";
371
389
  if (response.data instanceof HTMLImageElement || isImageBitmap(response.data)) onSuccess(response);
372
- else if (response.data) onSuccess({
390
+ else if (!response.data || response.data.byteLength === 0) onSuccess({
391
+ data: null,
392
+ cacheControl: response.cacheControl,
393
+ expires: response.expires
394
+ });
395
+ else onSuccess({
373
396
  data: await arrayBufferToCanvasImageSource(response.data, imageBitmapOptions),
374
397
  cacheControl: response.cacheControl,
375
398
  expires: response.expires
@@ -731,7 +754,9 @@ async function doOnceCompleted(jsonsMap, imagesMap) {
731
754
  const result = {};
732
755
  for (const spriteName in jsonsMap) {
733
756
  result[spriteName] = {};
734
- const context = browser.getImageCanvasContext((await imagesMap[spriteName]).data);
757
+ const image = (await imagesMap[spriteName]).data;
758
+ if (!image) throw new Error(`Could not load sprite image for ${spriteName}: the response is empty`);
759
+ const context = browser.getImageCanvasContext(image);
735
760
  const json = (await jsonsMap[spriteName]).data;
736
761
  for (const id in json) {
737
762
  const { width, height, x, y, sdf, pixelRatio, stretchX, stretchY, content, textFitWidth, textFitHeight } = json[id];
@@ -1522,9 +1547,10 @@ var GlyphManager = class {
1522
1547
  * Gets one glyph, asked for by grapheme cluster so that a letter and its marks are drawn as the
1523
1548
  * one shape they are written as.
1524
1549
  *
1525
- * Only a file the style pinned with `font-faces` can draw a cluster -- a glyphs URL serves
1526
- * codepoints -- so where none covers it this returns nothing and layout falls back to codepoints.
1527
- * For a single codepoint a declared file still wins over the glyphs URL and the local fallbacks.
1550
+ * A cluster is drawn from a font rather than fetched, because a glyphs URL serves codepoints and
1551
+ * has no way to serve the one shape they are written as. A file the style pinned with
1552
+ * `font-faces` draws it where one covers it, and the local fonts otherwise. For a single
1553
+ * codepoint a declared file still wins over the glyphs URL and the local fallbacks.
1528
1554
  */
1529
1555
  async _getAndCacheGlyphsPromise(stack, id) {
1530
1556
  this.entries[stack] ??= {
@@ -1549,15 +1575,7 @@ var GlyphManager = class {
1549
1575
  glyph
1550
1576
  };
1551
1577
  }
1552
- if (isCluster(id)) {
1553
- glyph = entry.glyphs[id] = null;
1554
- return {
1555
- stack,
1556
- id,
1557
- glyph
1558
- };
1559
- }
1560
- if (!this.url || this._charUsesLocalIdeographFontFamily(codePoint)) {
1578
+ if (!this.url || isCluster(id) || this._charUsesLocalIdeographFontFamily(codePoint)) {
1561
1579
  glyph = entry.glyphs[id] = await this._drawGlyph(entry, stack, id);
1562
1580
  return {
1563
1581
  stack,
@@ -1676,16 +1694,22 @@ var GlyphManager = class {
1676
1694
  * Where no file covers the grapheme, `localIdeographFontFamily` beats the last resort fontstack.
1677
1695
  */
1678
1696
  _getTinySDF(entry, stack, id, fontFaceFamily) {
1697
+ const cluster = isCluster(id);
1679
1698
  if (fontFaceFamily) {
1680
- const cluster = isCluster(id);
1681
1699
  const cache = cluster ? "clusterTinySDFs" : "fontFaceTinySDFs";
1682
1700
  entry[cache] ??= {};
1683
1701
  entry[cache][fontFaceFamily] ||= this._createTinySDF(fontFaceFamily, false, cluster ? clusterEmsWide : 1);
1684
1702
  return entry[cache][fontFaceFamily];
1685
1703
  }
1686
1704
  const usesLocalIdeographFontFamily = stack === defaultStack && this.localIdeographFontFamily !== "" && this._charUsesLocalIdeographFontFamily(id.codePointAt(0));
1705
+ const family = usesLocalIdeographFontFamily ? this.localIdeographFontFamily : stack;
1706
+ if (cluster) {
1707
+ entry.clusterTinySDFs ??= {};
1708
+ entry.clusterTinySDFs[family] ||= this._createTinySDF(family, true, clusterEmsWide);
1709
+ return entry.clusterTinySDFs[family];
1710
+ }
1687
1711
  const cache = usesLocalIdeographFontFamily ? "ideographTinySDF" : "tinySDF";
1688
- entry[cache] ||= this._createTinySDF(usesLocalIdeographFontFamily ? this.localIdeographFontFamily : stack);
1712
+ entry[cache] ||= this._createTinySDF(family);
1689
1713
  return entry[cache];
1690
1714
  }
1691
1715
  /**
@@ -2878,6 +2902,7 @@ var VectorTileSource = class extends Evented {
2878
2902
  */
2879
2903
  setTiles(tiles) {
2880
2904
  this.setSourceProperty(() => {
2905
+ this.tiles = tiles;
2881
2906
  this._options.tiles = tiles;
2882
2907
  });
2883
2908
  return this;
@@ -3111,6 +3136,7 @@ var RasterTileSource = class extends Evented {
3111
3136
  */
3112
3137
  setTiles(tiles) {
3113
3138
  this.setSourceProperty(() => {
3139
+ this.tiles = tiles;
3114
3140
  this._options.tiles = tiles;
3115
3141
  });
3116
3142
  return this;
@@ -3162,14 +3188,17 @@ var RasterTileSource = class extends Evented {
3162
3188
  tile.state = "unloaded";
3163
3189
  return;
3164
3190
  }
3165
- if (response?.data) {
3191
+ if (response) {
3166
3192
  if (this.map._refreshExpiredTiles && (response.cacheControl || response.expires)) tile.setExpiryData({
3167
3193
  cacheControl: response.cacheControl,
3168
3194
  expires: response.expires
3169
3195
  });
3170
3196
  const context = this.map.painter.context;
3171
3197
  const gl = context.gl;
3172
- const img = response.data;
3198
+ const img = response.data ?? new RGBAImage({
3199
+ width: 1,
3200
+ height: 1
3201
+ }, /* @__PURE__ */ new Uint8Array(4));
3173
3202
  tile.texture = this.map.painter.getTileTexture(img.width);
3174
3203
  if (tile.texture) tile.texture.update(img, {
3175
3204
  useMipmap: true,
@@ -3247,12 +3276,16 @@ var RasterDEMTileSource = class extends RasterTileSource {
3247
3276
  tile.state = "unloaded";
3248
3277
  return;
3249
3278
  }
3250
- if (response?.data) {
3251
- const img = response.data;
3279
+ if (response) {
3252
3280
  if (this.map._refreshExpiredTiles && (response.cacheControl || response.expires)) tile.setExpiryData({
3253
3281
  cacheControl: response.cacheControl,
3254
3282
  expires: response.expires
3255
3283
  });
3284
+ if (!response.data) {
3285
+ tile.state = "loaded";
3286
+ return;
3287
+ }
3288
+ const img = response.data;
3256
3289
  const rawImageData = isImageBitmap(img) && offscreenCanvasSupported() ? img : await this.readImageNow(img);
3257
3290
  const params = {
3258
3291
  type: this.type,
@@ -3288,16 +3321,16 @@ var RasterDEMTileSource = class extends RasterTileSource {
3288
3321
  }
3289
3322
  async readImageNow(img) {
3290
3323
  if (typeof VideoFrame !== "undefined" && isOffscreenCanvasDistorted()) {
3291
- const width = img.width + 2;
3292
- const height = img.height + 2;
3324
+ const width = img.width + 4;
3325
+ const height = img.height + 4;
3293
3326
  try {
3294
3327
  return new RGBAImage({
3295
3328
  width,
3296
3329
  height
3297
- }, await readImageUsingVideoFrame(img, -1, -1, width, height));
3330
+ }, await readImageUsingVideoFrame(img, -2, -2, width, height));
3298
3331
  } catch {}
3299
3332
  }
3300
- return browser.getImageData(img, 1);
3333
+ return browser.getImageData(img, 2);
3301
3334
  }
3302
3335
  _getNeighboringTiles(tileID) {
3303
3336
  const canonical = tileID.canonical;
@@ -3483,9 +3516,9 @@ function mergeFeatureDiffs(prev, next) {
3483
3516
  delete prev.addOrUpdateProperties;
3484
3517
  delete next.removeProperties;
3485
3518
  }
3486
- if (next.removeProperties) for (const key of next.removeProperties) {
3487
- const index = prev.addOrUpdateProperties.findIndex((prop) => prop.key === key);
3488
- if (index > -1) prev.addOrUpdateProperties.splice(index, 1);
3519
+ if (next.removeProperties && prev.addOrUpdateProperties) {
3520
+ const removedProperties = new Set(next.removeProperties);
3521
+ prev.addOrUpdateProperties = prev.addOrUpdateProperties.filter((prop) => !removedProperties.has(prop.key));
3489
3522
  }
3490
3523
  if (prev.removeAllProperties || next.removeAllProperties) merged.removeAllProperties = true;
3491
3524
  if (prev.removeProperties || next.removeProperties) merged.removeProperties = [...prev.removeProperties || [], ...next.removeProperties || []];
@@ -4379,7 +4412,7 @@ var ImageSource = class extends Evented {
4379
4412
  this._setImage(image.data);
4380
4413
  if (newCoordinates) this.coordinates = newCoordinates;
4381
4414
  this._finishLoading();
4382
- }
4415
+ } else this.fire(new ErrorEvent(/* @__PURE__ */ new Error(`Could not load image ${this.url}: the response is empty`)));
4383
4416
  } catch (err) {
4384
4417
  if (isAbortError(err)) return;
4385
4418
  this._abortController = null;
@@ -5016,6 +5049,12 @@ function deserialize(input, style) {
5016
5049
  }
5017
5050
  //#endregion
5018
5051
  //#region src/source/rtl_text_plugin_status.ts
5052
+ /**
5053
+ * Fired once a plugin set through {@link setRTLTextPlugin} has loaded, so that tiles drawn before it
5054
+ * arrived can be drawn again.
5055
+ *
5056
+ * @deprecated Right-to-left text is drawn without a plugin, so nothing has to be waited for.
5057
+ */
5019
5058
  const RTLPluginLoadedEventName = "RTLPluginLoaded";
5020
5059
  //#endregion
5021
5060
  //#region src/source/rtl_text_plugin_main_thread.ts
@@ -5494,214 +5533,576 @@ var SourceFeatureState = class {
5494
5533
  }
5495
5534
  };
5496
5535
  //#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));
5536
+ //#region src/util/primitives/aabb.ts
5537
+ var Aabb = class Aabb {
5538
+ constructor(min_, max_) {
5539
+ this.min = min_;
5540
+ this.max = max_;
5541
+ this.center = scale$1([], add([], this.min, this.max), .5);
5642
5542
  }
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;
5659
- }
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;
5543
+ quadrant(index) {
5544
+ const split = [index % 2 === 0, index < 2];
5545
+ const qMin = clone(this.min);
5546
+ const qMax = clone(this.max);
5547
+ for (let axis = 0; axis < split.length; axis++) {
5548
+ qMin[axis] = split[axis] ? this.min[axis] : this.center[axis];
5549
+ qMax[axis] = split[axis] ? this.center[axis] : this.max[axis];
5679
5550
  }
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
- });
5551
+ qMax[2] = this.max[2];
5552
+ return new Aabb(qMin, qMax);
5553
+ }
5554
+ distanceX(point) {
5555
+ return Math.max(Math.min(this.max[0], point[0]), this.min[0]) - point[0];
5556
+ }
5557
+ distanceY(point) {
5558
+ return Math.max(Math.min(this.max[1], point[1]), this.min[1]) - point[1];
5559
+ }
5560
+ /**
5561
+ * Performs a frustum-aabb intersection test.
5562
+ */
5563
+ intersectsFrustum(frustum) {
5564
+ let fullyInside = true;
5565
+ for (const plane of frustum.planes) {
5566
+ const planeIntersection = this.intersectsPlane(plane);
5567
+ if (planeIntersection === 0) return 0;
5568
+ if (planeIntersection === 1) fullyInside = false;
5691
5569
  }
5570
+ if (fullyInside) return 2;
5571
+ 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;
5572
+ return 1;
5692
5573
  }
5693
- return result.sort((a, b) => a.distanceSq - b.distanceSq).map((a) => a.tileID);
5694
- }
5695
- //#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
- *
5704
- * Tiles that are candidates for fading out must be loaded and rendered tiles, as loading a tile to then
5574
+ /**
5575
+ * Performs a halfspace-aabb intersection test.
5576
+ */
5577
+ intersectsPlane(plane) {
5578
+ let distMin = plane[3];
5579
+ let distMax = plane[3];
5580
+ for (let i = 0; i < 3; i++) if (plane[i] > 0) {
5581
+ distMin += plane[i] * this.min[i];
5582
+ distMax += plane[i] * this.max[i];
5583
+ } else {
5584
+ distMax += plane[i] * this.min[i];
5585
+ distMin += plane[i] * this.max[i];
5586
+ }
5587
+ if (distMin >= 0) return 2;
5588
+ if (distMax < 0) return 0;
5589
+ return 1;
5590
+ }
5591
+ };
5592
+ //#endregion
5593
+ //#region src/util/primitives/frustum.ts
5594
+ var Frustum = class Frustum {
5595
+ constructor(points, planes, aabb) {
5596
+ this.points = points;
5597
+ this.planes = planes;
5598
+ this.aabb = aabb;
5599
+ }
5600
+ static fromInvProjectionMatrix(invProj, worldSize = 1, zoom = 0, horizonPlane, flippedNearFar) {
5601
+ const clipSpaceCorners = [
5602
+ [
5603
+ -1,
5604
+ 1,
5605
+ -1,
5606
+ 1
5607
+ ],
5608
+ [
5609
+ 1,
5610
+ 1,
5611
+ -1,
5612
+ 1
5613
+ ],
5614
+ [
5615
+ 1,
5616
+ -1,
5617
+ -1,
5618
+ 1
5619
+ ],
5620
+ [
5621
+ -1,
5622
+ -1,
5623
+ -1,
5624
+ 1
5625
+ ],
5626
+ [
5627
+ -1,
5628
+ 1,
5629
+ 1,
5630
+ 1
5631
+ ],
5632
+ [
5633
+ 1,
5634
+ 1,
5635
+ 1,
5636
+ 1
5637
+ ],
5638
+ [
5639
+ 1,
5640
+ -1,
5641
+ 1,
5642
+ 1
5643
+ ],
5644
+ [
5645
+ -1,
5646
+ -1,
5647
+ 1,
5648
+ 1
5649
+ ]
5650
+ ];
5651
+ const frustumPlanePointIndices = flippedNearFar ? [
5652
+ [
5653
+ 6,
5654
+ 5,
5655
+ 4
5656
+ ],
5657
+ [
5658
+ 0,
5659
+ 1,
5660
+ 2
5661
+ ],
5662
+ [
5663
+ 0,
5664
+ 3,
5665
+ 7
5666
+ ],
5667
+ [
5668
+ 2,
5669
+ 1,
5670
+ 5
5671
+ ],
5672
+ [
5673
+ 3,
5674
+ 2,
5675
+ 6
5676
+ ],
5677
+ [
5678
+ 0,
5679
+ 4,
5680
+ 5
5681
+ ]
5682
+ ] : [
5683
+ [
5684
+ 0,
5685
+ 1,
5686
+ 2
5687
+ ],
5688
+ [
5689
+ 6,
5690
+ 5,
5691
+ 4
5692
+ ],
5693
+ [
5694
+ 0,
5695
+ 3,
5696
+ 7
5697
+ ],
5698
+ [
5699
+ 2,
5700
+ 1,
5701
+ 5
5702
+ ],
5703
+ [
5704
+ 3,
5705
+ 2,
5706
+ 6
5707
+ ],
5708
+ [
5709
+ 0,
5710
+ 4,
5711
+ 5
5712
+ ]
5713
+ ];
5714
+ const scale = Math.pow(2, zoom);
5715
+ const frustumCoords = clipSpaceCorners.map((v) => unprojectClipSpacePoint(v, invProj, worldSize, scale));
5716
+ if (horizonPlane) adjustFarPlaneByHorizonPlane(frustumCoords, frustumPlanePointIndices[0], horizonPlane, flippedNearFar);
5717
+ const frustumPlanes = frustumPlanePointIndices.map((p) => {
5718
+ const a = sub([], frustumCoords[p[0]], frustumCoords[p[1]]);
5719
+ const b = sub([], frustumCoords[p[2]], frustumCoords[p[1]]);
5720
+ const n = normalize([], cross([], a, b));
5721
+ const d = -dot(n, frustumCoords[p[1]]);
5722
+ return n.concat(d);
5723
+ });
5724
+ const min = [
5725
+ Number.POSITIVE_INFINITY,
5726
+ Number.POSITIVE_INFINITY,
5727
+ Number.POSITIVE_INFINITY
5728
+ ];
5729
+ const max = [
5730
+ Number.NEGATIVE_INFINITY,
5731
+ Number.NEGATIVE_INFINITY,
5732
+ Number.NEGATIVE_INFINITY
5733
+ ];
5734
+ for (const p of frustumCoords) for (let i = 0; i < 3; i++) {
5735
+ min[i] = Math.min(min[i], p[i]);
5736
+ max[i] = Math.max(max[i], p[i]);
5737
+ }
5738
+ return new Frustum(frustumCoords, frustumPlanes, new Aabb(min, max));
5739
+ }
5740
+ };
5741
+ function unprojectClipSpacePoint(point, invProj, worldSize, scale) {
5742
+ const v = transformMat4([], point, invProj);
5743
+ const s = 1 / v[3] / worldSize * scale;
5744
+ return mul(v, v, [
5745
+ s,
5746
+ s,
5747
+ 1 / v[3],
5748
+ s
5749
+ ]);
5750
+ }
5751
+ /**
5752
+ * Modifies points in the supplied `frustumCoords` array so that the frustum's far plane only lies as far as the horizon,
5753
+ * which improves frustum culling effectiveness.
5754
+ * @param frustumCoords - Points of the frustum.
5755
+ * @param nearPlanePointsIndices - Which indices in the `frustumCoords` form the near plane.
5756
+ * @param horizonPlane - The horizon plane.
5757
+ */
5758
+ function adjustFarPlaneByHorizonPlane(frustumCoords, nearPlanePointsIndices, horizonPlane, flippedNearFar) {
5759
+ const nearPlanePointsOffset = flippedNearFar ? 4 : 0;
5760
+ const farPlanePointsOffset = flippedNearFar ? 0 : 4;
5761
+ let maxDist = 0;
5762
+ const cornerRayLengths = [];
5763
+ const cornerRayNormalizedDirections = [];
5764
+ for (let i = 0; i < 4; i++) {
5765
+ const dir = sub([], frustumCoords[i + farPlanePointsOffset], frustumCoords[i + nearPlanePointsOffset]);
5766
+ const len = length(dir);
5767
+ scale$1(dir, dir, 1 / len);
5768
+ cornerRayLengths.push(len);
5769
+ cornerRayNormalizedDirections.push(dir);
5770
+ }
5771
+ for (let i = 0; i < 4; i++) {
5772
+ const dist = rayPlaneIntersection(frustumCoords[i + nearPlanePointsOffset], cornerRayNormalizedDirections[i], horizonPlane);
5773
+ if (dist !== null && dist >= 0) maxDist = Math.max(maxDist, dist);
5774
+ else maxDist = Math.max(maxDist, cornerRayLengths[i]);
5775
+ }
5776
+ const nearPlaneNormalized = getNormalizedNearPlane(frustumCoords, nearPlanePointsIndices);
5777
+ const idealFarPlaneDistanceFromNearPlane = getIdealNearFarPlaneDistance(horizonPlane, nearPlaneNormalized);
5778
+ if (idealFarPlaneDistanceFromNearPlane !== null) {
5779
+ const idealCornerRayLength = idealFarPlaneDistanceFromNearPlane / dot(cornerRayNormalizedDirections[0], nearPlaneNormalized);
5780
+ maxDist = Math.min(maxDist, idealCornerRayLength);
5781
+ }
5782
+ for (let i = 0; i < 4; i++) {
5783
+ const targetLength = Math.min(maxDist, cornerRayLengths[i]);
5784
+ frustumCoords[i + farPlanePointsOffset] = [
5785
+ frustumCoords[i + nearPlanePointsOffset][0] + cornerRayNormalizedDirections[i][0] * targetLength,
5786
+ frustumCoords[i + nearPlanePointsOffset][1] + cornerRayNormalizedDirections[i][1] * targetLength,
5787
+ frustumCoords[i + nearPlanePointsOffset][2] + cornerRayNormalizedDirections[i][2] * targetLength,
5788
+ 1
5789
+ ];
5790
+ }
5791
+ }
5792
+ /**
5793
+ * Returns the near plane equation with unit length direction.
5794
+ * @param frustumCoords - Points of the frustum.
5795
+ * @param nearPlanePointsIndices - Which indices in the `frustumCoords` form the near plane.
5796
+ */
5797
+ function getNormalizedNearPlane(frustumCoords, nearPlanePointsIndices) {
5798
+ const nearPlaneA = sub([], frustumCoords[nearPlanePointsIndices[0]], frustumCoords[nearPlanePointsIndices[1]]);
5799
+ const nearPlaneB = sub([], frustumCoords[nearPlanePointsIndices[2]], frustumCoords[nearPlanePointsIndices[1]]);
5800
+ const nearPlaneNormalized = [
5801
+ 0,
5802
+ 0,
5803
+ 0,
5804
+ 0
5805
+ ];
5806
+ normalize(nearPlaneNormalized, cross([], nearPlaneA, nearPlaneB));
5807
+ nearPlaneNormalized[3] = -dot(nearPlaneNormalized, frustumCoords[nearPlanePointsIndices[0]]);
5808
+ return nearPlaneNormalized;
5809
+ }
5810
+ /**
5811
+ * Returns the ideal distance between the frustum's near and far plane so that the far plane only lies as far as the horizon.
5812
+ */
5813
+ function getIdealNearFarPlaneDistance(horizonPlane, nearPlaneNormalized) {
5814
+ const horizonPlaneLen = len(horizonPlane);
5815
+ const normalizedHorizonPlane = scale$2([], horizonPlane, 1 / horizonPlaneLen);
5816
+ const projectedViewDirection = sub([], nearPlaneNormalized, scale$1([], normalizedHorizonPlane, dot(nearPlaneNormalized, normalizedHorizonPlane)));
5817
+ const projectedViewLength = len(projectedViewDirection);
5818
+ if (projectedViewLength > 0) {
5819
+ const horizonCircleRadius = Math.sqrt(1 - normalizedHorizonPlane[3] * normalizedHorizonPlane[3]);
5820
+ const horizonCircleCenter = scale$1([], normalizedHorizonPlane, -normalizedHorizonPlane[3]);
5821
+ const pointFurthestOnHorizonCircle = add([], horizonCircleCenter, scale$1([], projectedViewDirection, horizonCircleRadius / projectedViewLength));
5822
+ return pointPlaneSignedDistance(nearPlaneNormalized, pointFurthestOnHorizonCircle);
5823
+ } else return null;
5824
+ }
5825
+ //#endregion
5826
+ //#region src/geo/projection/covering_tiles.ts
5827
+ /**
5828
+ * A simple/heuristic function that returns whether the tile is visible under the current transform.
5829
+ * @returns an {@link IntersectionResult}.
5830
+ */
5831
+ function isTileVisible(frustum, tileBoundingVolume, plane) {
5832
+ const frustumTest = tileBoundingVolume.intersectsFrustum(frustum);
5833
+ if (!plane || frustumTest === 0) return frustumTest;
5834
+ const planeTest = tileBoundingVolume.intersectsPlane(plane);
5835
+ if (planeTest === 0) return 0;
5836
+ if (frustumTest === 2 && planeTest === 2) return 2;
5837
+ return 1;
5838
+ }
5839
+ /**
5840
+ * Definite integral of cos(x)^p. The analytical solution is described in `developer-guides/covering-tiles.md`,
5841
+ * but here the integral is evaluated numerically.
5842
+ * @param p - the power to raise cos(x) to inside the integral
5843
+ * @param x1 - the starting point of the integral.
5844
+ * @param x2 - the ending point of the integral.
5845
+ * @return the integral of cos(x)^p from x=x1 to x=x2
5846
+ */
5847
+ function integralOfCosXByP(p, x1, x2) {
5848
+ const numPoints = 10;
5849
+ let sum = 0;
5850
+ const dx = (x2 - x1) / numPoints;
5851
+ for (let i = 0; i < numPoints; i++) {
5852
+ const x = x1 + (i + .5) / numPoints * (x2 - x1);
5853
+ sum += dx * Math.pow(Math.cos(x), p);
5854
+ }
5855
+ return sum;
5856
+ }
5857
+ function createCalculateTileZoomFunction(maxZoomLevelsOnScreen, tileCountMaxMinRatio) {
5858
+ return function(requestedCenterZoom, distanceToTile2D, distanceToTileZ, distanceToCenter3D, cameraVerticalFOV) {
5859
+ /**
5860
+ * Controls how tiles are loaded at high pitch angles. Higher numbers cause fewer, lower resolution
5861
+ * tiles to be loaded. Calculate the value that will result in the selected number of zoom levels in
5862
+ * the worst-case condition (when the horizon is at the top of the screen). For more information, see
5863
+ * `developer-guides/covering-tiles.md`
5864
+ */
5865
+ const pitchTileLoadingBehavior = 2 * ((maxZoomLevelsOnScreen - 1) / scaleZoom(Math.cos(degreesToRadians(maxMercatorHorizonAngle - cameraVerticalFOV)) / Math.cos(degreesToRadians(maxMercatorHorizonAngle))) - 1);
5866
+ const centerPitch = Math.acos(distanceToTileZ / distanceToCenter3D);
5867
+ const tileCountPitch0 = 2 * integralOfCosXByP(pitchTileLoadingBehavior - 1, 0, degreesToRadians(cameraVerticalFOV / 2));
5868
+ const highestPitch = Math.min(degreesToRadians(maxMercatorHorizonAngle), centerPitch + degreesToRadians(cameraVerticalFOV / 2));
5869
+ const lowestPitch = Math.min(highestPitch, centerPitch - degreesToRadians(cameraVerticalFOV / 2));
5870
+ const tileCount = integralOfCosXByP(pitchTileLoadingBehavior - 1, lowestPitch, highestPitch);
5871
+ const thisTilePitch = Math.atan(distanceToTile2D / distanceToTileZ);
5872
+ const distanceToTile3D = Math.hypot(distanceToTile2D, distanceToTileZ);
5873
+ let thisTileDesiredZ = requestedCenterZoom;
5874
+ thisTileDesiredZ = thisTileDesiredZ + scaleZoom(distanceToCenter3D / distanceToTile3D / Math.max(.5, Math.cos(degreesToRadians(cameraVerticalFOV / 2))));
5875
+ thisTileDesiredZ += pitchTileLoadingBehavior * scaleZoom(Math.cos(thisTilePitch)) / 2;
5876
+ thisTileDesiredZ -= scaleZoom(Math.max(1, tileCount / tileCountPitch0 / tileCountMaxMinRatio)) / 2;
5877
+ return thisTileDesiredZ;
5878
+ };
5879
+ }
5880
+ const defaultCalculateTileZoom = createCalculateTileZoomFunction(9.314, 3);
5881
+ /**
5882
+ * Return what zoom level of a tile source would most closely cover the tiles displayed by this transform.
5883
+ * @param options - The options, most importantly the source's tile size.
5884
+ * @returns An integer zoom level at which all tiles will be visible.
5885
+ */
5886
+ function coveringZoomLevel(transform, options) {
5887
+ const z = (options.roundZoom ? Math.round : Math.floor)(transform.zoom + scaleZoom(transform.tileSize / options.tileSize));
5888
+ return Math.max(0, z);
5889
+ }
5890
+ /**
5891
+ * Without terrain, `getTileBoundingVolume` has no knowledge of extruded features
5892
+ * (eg. 3D buildings): every tile's bounding box is flat at the camera's `elevation`.
5893
+ * That's a fine approximation of what's visible for most views, but it breaks down
5894
+ * as the frustum's bottom edge approaches horizontal (which depends on both `pitch`
5895
+ * and `fov`, not pitch alone) - a tall building can still be poking up into view
5896
+ * long after its tile's ground point has dropped out of the frustum.
5897
+ *
5898
+ * This is an assumed upper bound on real-world feature height (in metres), used to
5899
+ * grow the elevation used for tile culling as that bottom edge nears horizontal, so
5900
+ * such tiles are not dropped too early. It has no effect away from that edge case.
5901
+ */
5902
+ const ASSUMED_MAX_FEATURE_HEIGHT_METERS = 500;
5903
+ /**
5904
+ * Angle between the frustum's bottom edge and the mercator horizon below which
5905
+ * the culling elevation starts to grow.
5906
+ */
5907
+ const TILE_CULLING_HORIZON_ONSET_DEGREES = 15;
5908
+ /**
5909
+ * Returns the elevation to use when computing tile bounding volumes for culling:
5910
+ * `transform.elevation`, growing by up to the greater of
5911
+ * `ASSUMED_MAX_FEATURE_HEIGHT_METERS` and `maxContentElevation` (when provided)
5912
+ * as the frustum's bottom edge approaches the horizon, where a ground-level
5913
+ * bounding box would cull tiles whose extruded features are still visible.
5914
+ */
5915
+ function getElevationForTileCulling(transform, maxContentElevation) {
5916
+ const bottomEdgeDegreesAboveHorizontal = maxMercatorHorizonAngle - transform.pitch - transform.fov / 2;
5917
+ const proximityToHorizon = clamp((TILE_CULLING_HORIZON_ONSET_DEGREES - bottomEdgeDegreesAboveHorizontal) / TILE_CULLING_HORIZON_ONSET_DEGREES, 0, 1);
5918
+ const maxFeatureHeight = Math.max(ASSUMED_MAX_FEATURE_HEIGHT_METERS, maxContentElevation ?? 0);
5919
+ return transform.elevation + proximityToHorizon * maxFeatureHeight;
5920
+ }
5921
+ /**
5922
+ * Returns a copy of the frustum with its far plane moved away from the camera by `distance`.
5923
+ * Each far corner travels along its own camera ray until it reaches the pushed plane, so the
5924
+ * result stays a pyramid and the corners stay consistent with the side planes. The globe
5925
+ * frustum's far plane is fitted to the surface horizon, so elevated content beyond it would
5926
+ * otherwise be culled while still visible.
5927
+ */
5928
+ function pushFrustumFarPlane(frustum, distance, cameraPos) {
5929
+ const far = frustum.planes[1];
5930
+ const points = frustum.points.map((p) => {
5931
+ const distanceToFar = far[0] * p[0] + far[1] * p[1] + far[2] * p[2] + far[3];
5932
+ if (Math.abs(distanceToFar) > 1e-6) return p;
5933
+ const ray = [
5934
+ p[0] - cameraPos[0],
5935
+ p[1] - cameraPos[1],
5936
+ p[2] - cameraPos[2]
5937
+ ];
5938
+ const rayDotNormal = far[0] * ray[0] + far[1] * ray[1] + far[2] * ray[2];
5939
+ if (rayDotNormal >= -1e-9) return p;
5940
+ const scale = distance / -rayDotNormal;
5941
+ return [
5942
+ p[0] + ray[0] * scale,
5943
+ p[1] + ray[1] * scale,
5944
+ p[2] + ray[2] * scale,
5945
+ p[3]
5946
+ ];
5947
+ });
5948
+ const planes = frustum.planes.map((p, i) => i === 1 ? [
5949
+ p[0],
5950
+ p[1],
5951
+ p[2],
5952
+ p[3] + distance
5953
+ ] : p);
5954
+ const min = [
5955
+ Number.POSITIVE_INFINITY,
5956
+ Number.POSITIVE_INFINITY,
5957
+ Number.POSITIVE_INFINITY
5958
+ ];
5959
+ const max = [
5960
+ Number.NEGATIVE_INFINITY,
5961
+ Number.NEGATIVE_INFINITY,
5962
+ Number.NEGATIVE_INFINITY
5963
+ ];
5964
+ for (const p of points) for (let i = 0; i < 3; i++) {
5965
+ min[i] = Math.min(min[i], p[i]);
5966
+ max[i] = Math.max(max[i], p[i]);
5967
+ }
5968
+ return new Frustum(points, planes, new Aabb(min, max));
5969
+ }
5970
+ /**
5971
+ * Returns a list of tiles that optimally covers the screen. Adapted for globe projection.
5972
+ * Correctly handles LOD when moving over the antimeridian.
5973
+ *
5974
+ * The horizon culling plane and the frustum's far plane both assume content sits on the
5975
+ * surface. When `options.maxContentElevation` is set, a point elevated to radius r (in planet
5976
+ * radii) stays visible up to acos(1/r) beyond the surface horizon and up to sqrt(r^2-1)
5977
+ * farther away, so both are pushed back accordingly; without this, tiles under highly
5978
+ * elevated symbols would be dropped while the symbols are still in view.
5979
+ * @param transform - The transform instance.
5980
+ * @param frustum - The covering frustum.
5981
+ * @param plane - The clipping plane used by globe transform, or null.
5982
+ * @param cameraCoord - The x, y, z position of the camera in MercatorCoordinates.
5983
+ * @param centerCoord - The x, y, z position of the center point in MercatorCoordinates.
5984
+ * @param options - Additional coveringTiles options.
5985
+ * @param details - Interface to define required helper functions.
5986
+ * @returns A list of tile coordinates, ordered by ascending distance from camera.
5987
+ */
5988
+ function coveringTiles(transform, options) {
5989
+ let frustum = transform.getCameraFrustum();
5990
+ let plane = transform.getClippingPlane();
5991
+ if (plane && options.maxContentElevation > 0) {
5992
+ const len = Math.hypot(plane[0], plane[1], plane[2]);
5993
+ if (len > 0) {
5994
+ const shellRadius = 1 + options.maxContentElevation / earthRadius;
5995
+ const horizonCos = clamp(-plane[3] / len, -1, 1);
5996
+ const shellCos = Math.cos(Math.acos(horizonCos) + Math.acos(1 / shellRadius));
5997
+ plane = [
5998
+ plane[0],
5999
+ plane[1],
6000
+ plane[2],
6001
+ -shellCos * len
6002
+ ];
6003
+ frustum = pushFrustumFarPlane(frustum, Math.sqrt(shellRadius * shellRadius - 1), transform.cameraPosition);
6004
+ }
6005
+ }
6006
+ const cameraCoord = cameraMercatorCoordinate(transform);
6007
+ const centerCoord = MercatorCoordinate.fromLngLat(transform.center, transform.elevation);
6008
+ const elevationForTileCulling = getElevationForTileCulling(transform, options.maxContentElevation);
6009
+ const detailsProvider = transform.getCoveringTilesDetailsProvider();
6010
+ const allowVariableZoom = detailsProvider.allowVariableZoom(transform, options);
6011
+ const desiredZ = coveringZoomLevel(transform, options);
6012
+ const minZoom = options.minzoom || 0;
6013
+ const maxZoom = options.maxzoom !== void 0 ? options.maxzoom : transform.maxZoom;
6014
+ const nominalZ = Math.min(Math.max(0, desiredZ), maxZoom);
6015
+ const numTiles = Math.pow(2, nominalZ);
6016
+ const cameraPoint = [
6017
+ numTiles * cameraCoord.x,
6018
+ numTiles * cameraCoord.y,
6019
+ 0
6020
+ ];
6021
+ const centerPoint = [
6022
+ numTiles * centerCoord.x,
6023
+ numTiles * centerCoord.y,
6024
+ 0
6025
+ ];
6026
+ const distanceToCenter2d = Math.hypot(centerCoord.x - cameraCoord.x, centerCoord.y - cameraCoord.y);
6027
+ const distanceZ = Math.abs(centerCoord.z - cameraCoord.z);
6028
+ const distanceToCenter3d = Math.hypot(distanceToCenter2d, distanceZ);
6029
+ const newRootTile = (wrap) => {
6030
+ return {
6031
+ zoom: 0,
6032
+ x: 0,
6033
+ y: 0,
6034
+ wrap,
6035
+ fullyVisible: false
6036
+ };
6037
+ };
6038
+ const stack = [];
6039
+ const result = [];
6040
+ if (transform.renderWorldCopies && detailsProvider.allowWorldCopies()) for (let i = 1; i <= 3; i++) {
6041
+ stack.push(newRootTile(-i));
6042
+ stack.push(newRootTile(i));
6043
+ }
6044
+ stack.push(newRootTile(0));
6045
+ while (stack.length > 0) {
6046
+ const it = stack.pop();
6047
+ const x = it.x;
6048
+ const y = it.y;
6049
+ let fullyVisible = it.fullyVisible;
6050
+ const tileID = {
6051
+ x,
6052
+ y,
6053
+ z: it.zoom
6054
+ };
6055
+ const boundingVolume = detailsProvider.getTileBoundingVolume(tileID, it.wrap, elevationForTileCulling, options);
6056
+ if (!fullyVisible) {
6057
+ const intersectResult = isTileVisible(frustum, boundingVolume, plane);
6058
+ if (intersectResult === 0) continue;
6059
+ fullyVisible = intersectResult === 2;
6060
+ }
6061
+ const distToTile2d = detailsProvider.distanceToTile2d(cameraCoord.x, cameraCoord.y, tileID, boundingVolume);
6062
+ let thisTileDesiredZ = desiredZ;
6063
+ if (allowVariableZoom) thisTileDesiredZ = (options.calculateTileZoom || defaultCalculateTileZoom)(transform.zoom + scaleZoom(transform.tileSize / options.tileSize), distToTile2d, distanceZ, distanceToCenter3d, transform.fov);
6064
+ thisTileDesiredZ = (options.roundZoom ? Math.round : Math.floor)(thisTileDesiredZ);
6065
+ thisTileDesiredZ = Math.max(0, thisTileDesiredZ);
6066
+ const z = Math.min(thisTileDesiredZ, maxZoom);
6067
+ it.wrap = detailsProvider.getWrap(centerCoord, tileID, it.wrap);
6068
+ if (it.zoom >= z) {
6069
+ if (it.zoom < minZoom) continue;
6070
+ const dz = nominalZ - it.zoom;
6071
+ const dx = cameraPoint[0] - .5 - (x << dz);
6072
+ const dy = cameraPoint[1] - .5 - (y << dz);
6073
+ const overscaledZ = options.reparseOverscaled ? Math.max(it.zoom, thisTileDesiredZ) : it.zoom;
6074
+ result.push({
6075
+ tileID: new OverscaledTileID(it.zoom === maxZoom ? overscaledZ : it.zoom, it.wrap, it.zoom, x, y),
6076
+ distanceSq: sqrLen([centerPoint[0] - .5 - x, centerPoint[1] - .5 - y]),
6077
+ tileDistanceToCamera: Math.sqrt(dx * dx + dy * dy)
6078
+ });
6079
+ continue;
6080
+ }
6081
+ for (let i = 0; i < 4; i++) {
6082
+ const childX = (x << 1) + i % 2;
6083
+ const childY = (y << 1) + (i >> 1);
6084
+ const childZ = it.zoom + 1;
6085
+ stack.push({
6086
+ zoom: childZ,
6087
+ x: childX,
6088
+ y: childY,
6089
+ wrap: it.wrap,
6090
+ fullyVisible
6091
+ });
6092
+ }
6093
+ }
6094
+ return result.sort((a, b) => a.distanceSq - b.distanceSq).map((a) => a.tileID);
6095
+ }
6096
+ //#endregion
6097
+ //#region src/tile/tile_manager_raster.ts
6098
+ function isRasterType(type) {
6099
+ return type === "raster" || type === "image" || type === "video";
6100
+ }
6101
+ /**
6102
+ * Designate fading bases and parents using a many-to-one relationship where the lower children fade in/out
6103
+ * with their parents. Raster shaders are not currently designed for a one-to-many fade relationship.
6104
+ *
6105
+ * Tiles that are candidates for fading out must be loaded and rendered tiles, as loading a tile to then
5705
6106
  * fade it out would not appear smoothly. The first source of truth for tile fading always starts at the
5706
6107
  * ideal tile, which continually changes on map adjustment. The state of the previously rendered ideal
5707
6108
  * tile plane indicates which direction to fade each part of the newer ideal plane (with varying z).
@@ -5946,6 +6347,7 @@ var TileManager = class TileManager extends Evented {
5946
6347
  }
5947
6348
  constructor(id, options, dispatcher) {
5948
6349
  super();
6350
+ this._maxContentElevationSeen = 0;
5949
6351
  this.id = id;
5950
6352
  this.dispatcher = dispatcher;
5951
6353
  this.on("data", (e) => {
@@ -6211,6 +6613,33 @@ var TileManager = class TileManager extends Evented {
6211
6613
  }
6212
6614
  }
6213
6615
  /**
6616
+ * The highest elevation this source's symbols may reach, in meters: `symbol-height-offset`
6617
+ * constants read from the visible symbol layers, data-driven maxima tracked by the loaded
6618
+ * buckets at layout time. The value is a high-water mark: a maximum seen once is kept even
6619
+ * after its tile unloads, otherwise dropping the tile would also drop the reason to keep it,
6620
+ * and the tile could not come back while its content is still visible. The mark resets with
6621
+ * the tiles in `clearTiles`.
6622
+ */
6623
+ _updateMaxContentElevation() {
6624
+ let maxElevation = this._maxContentElevationSeen;
6625
+ const layers = this.map?.style?._layers;
6626
+ if (!layers) return maxElevation;
6627
+ const tiles = this._inViewTiles.getAllTiles();
6628
+ for (const layerId in layers) {
6629
+ const layer = layers[layerId];
6630
+ if (layer.type !== "symbol" || layer.source !== this.id || layer.isHidden(this.transform.zoom)) continue;
6631
+ const symbolLayer = layer;
6632
+ if (!symbolLayer.layout) continue;
6633
+ maxElevation = Math.max(maxElevation, symbolLayer.layout.get("symbol-height-offset").constantOr(0));
6634
+ for (const tile of tiles) {
6635
+ const bucket = tile.getBucket(layer);
6636
+ if (bucket && bucket.maxHeightOffset > maxElevation) maxElevation = bucket.maxHeightOffset;
6637
+ }
6638
+ }
6639
+ this._maxContentElevationSeen = maxElevation;
6640
+ return maxElevation;
6641
+ }
6642
+ /**
6214
6643
  * Removes tiles that are outside the viewport and adds new tiles that
6215
6644
  * are inside the viewport.
6216
6645
  */
@@ -6231,7 +6660,8 @@ var TileManager = class TileManager extends Evented {
6231
6660
  roundZoom: this.usedForTerrain ? false : this._source.roundZoom,
6232
6661
  reparseOverscaled: this._source.reparseOverscaled,
6233
6662
  terrain,
6234
- calculateTileZoom: this._source.calculateTileZoom
6663
+ calculateTileZoom: this._source.calculateTileZoom,
6664
+ maxContentElevation: this._updateMaxContentElevation()
6235
6665
  });
6236
6666
  if (this._source.hasTile) idealTileIDs = idealTileIDs.filter((coord) => this._source.hasTile(coord));
6237
6667
  }
@@ -6424,11 +6854,20 @@ var TileManager = class TileManager extends Evented {
6424
6854
  this._didEmitContent = true;
6425
6855
  }
6426
6856
  /**
6857
+ * Forgets the recorded maximum content elevation, so the next update recomputes it from the
6858
+ * current layers and loaded tiles. Called when a symbol layer is removed, since the removed
6859
+ * layer's heights would otherwise keep expanding tile coverage.
6860
+ */
6861
+ resetMaxContentElevation() {
6862
+ this._maxContentElevationSeen = 0;
6863
+ }
6864
+ /**
6427
6865
  * Remove all tiles from this pyramid
6428
6866
  */
6429
6867
  clearTiles() {
6430
6868
  this._shouldReloadOnResume = false;
6431
6869
  this._paused = false;
6870
+ this.resetMaxContentElevation();
6432
6871
  for (const id of this._inViewTiles.getAllIds()) this._removeTile(id);
6433
6872
  this._outOfViewCache.reset();
6434
6873
  }
@@ -6967,15 +7406,15 @@ function getTileSkewVectors(transform) {
6967
7406
  const vecSouth = create$3();
6968
7407
  vecSouth[0] = -cosBearing * cosPitch * sinRoll - sinBearing * cosRoll;
6969
7408
  vecSouth[1] = -sinBearing * cosPitch * sinRoll + cosBearing * cosRoll;
6970
- const vecSouthLen = length(vecSouth);
7409
+ const vecSouthLen = length$1(vecSouth);
6971
7410
  if (vecSouthLen < 1e-9) zero(vecSouth);
6972
- else scale$1(vecSouth, vecSouth, 1 / vecSouthLen);
7411
+ else scale$3(vecSouth, vecSouth, 1 / vecSouthLen);
6973
7412
  const vecEast = create$3();
6974
7413
  vecEast[0] = cosBearing * cosPitch * cosRoll - sinBearing * sinRoll;
6975
7414
  vecEast[1] = sinBearing * cosPitch * cosRoll + cosBearing * sinRoll;
6976
- const vecEastLen = length(vecEast);
7415
+ const vecEastLen = length$1(vecEast);
6977
7416
  if (vecEastLen < 1e-9) zero(vecEast);
6978
- else scale$1(vecEast, vecEast, 1 / vecEastLen);
7417
+ else scale$3(vecEast, vecEast, 1 / vecEastLen);
6979
7418
  return {
6980
7419
  vecEast,
6981
7420
  vecSouth
@@ -9035,10 +9474,10 @@ var CrossTileSymbolIndex = class {
9035
9474
  };
9036
9475
  //#endregion
9037
9476
  //#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;";
9477
+ 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
9478
  //#endregion
9040
9479
  //#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;";
9480
+ 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
9481
  //#endregion
9043
9482
  //#region src/shaders/glsl/background.fragment.glsl.g.ts
9044
9483
  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 +9495,7 @@ var background_pattern_vertex_glsl_g_default = "uniform vec2 u_pattern_size_a;un
9056
9495
  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
9496
  //#endregion
9058
9497
  //#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);}";
9498
+ 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
9499
  //#endregion
9061
9500
  //#region src/shaders/glsl/clipping_mask.fragment.glsl.g.ts
9062
9501
  var clipping_mask_fragment_glsl_g_default = "void main() {fragColor=vec4(1.0);}";
@@ -9065,40 +9504,40 @@ var clipping_mask_fragment_glsl_g_default = "void main() {fragColor=vec4(1.0);}"
9065
9504
  const shaders = {
9066
9505
  prelude: prepare(_prelude_fragment_glsl_g_default, _prelude_vertex_glsl_g_default),
9067
9506
  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);}"),
9507
+ 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
9508
  background: prepare(background_fragment_glsl_g_default, background_vertex_glsl_g_default),
9070
9509
  backgroundPattern: prepare(background_pattern_fragment_glsl_g_default, background_pattern_vertex_glsl_g_default),
9071
9510
  circle: prepare(circle_fragment_glsl_g_default, circle_vertex_glsl_g_default),
9072
9511
  clippingMask: prepare(clipping_mask_fragment_glsl_g_default, "layout(location=0) in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}"),
9073
9512
  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;}}"),
9513
+ 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;}"),
9514
+ 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;}"),
9515
+ 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);}"),
9516
+ 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
9517
  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
9518
  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
9519
  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);}"),
9520
+ 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}"),
9521
+ 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}"),
9522
+ 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
9523
  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
9524
  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);}"),
9525
+ 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;}"),
9526
+ 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;}}"),
9527
+ 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);}"),
9528
+ 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);}"),
9529
+ 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;}"),
9530
+ 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);}"),
9531
+ 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
9532
  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
9533
  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;}"),
9534
+ 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;}"),
9535
+ 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);}"),
9536
+ 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
9537
  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
9538
  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
9539
  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);}")
9540
+ 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
9541
  };
9103
9542
  /** Expand #pragmas to #ifdefs, extract attributes and uniforms */
9104
9543
  function prepare(fragmentSource, vertexSource) {
@@ -9731,42 +10170,43 @@ var TransformHelper = class {
9731
10170
  * This function is called every time one of the transform's defining properties (center, pitch, etc.) changes.
9732
10171
  * This function should update the transform's internal data, such as matrices.
9733
10172
  * Any derived `_calcMatrices` function should also call the base function first. The base function only depends on the `_width` and `_height` fields.
10173
+ * While either dimension is zero there is no view to build, so the derived function is not called at all.
9734
10174
  */
9735
10175
  _calcMatrices() {
9736
- if (this._width && this._height) {
9737
- this._pixelsToGLUnits = [2 / this._width, -2 / this._height];
9738
- let m = identity(/* @__PURE__ */ new Float64Array(16));
9739
- scale(m, m, [
9740
- this._width / 2,
9741
- -this._height / 2,
9742
- 1
9743
- ]);
9744
- translate(m, m, [
9745
- 1,
9746
- -1,
9747
- 0
9748
- ]);
9749
- this._clipSpaceToPixelsMatrix = m;
9750
- m = identity(/* @__PURE__ */ new Float64Array(16));
9751
- scale(m, m, [
9752
- 1,
9753
- -1,
9754
- 1
9755
- ]);
9756
- translate(m, m, [
9757
- -1,
9758
- -1,
9759
- 0
9760
- ]);
9761
- scale(m, m, [
9762
- 2 / this._width,
9763
- 2 / this._height,
9764
- 1
9765
- ]);
9766
- this._pixelsToClipSpaceMatrix = m;
9767
- const halfFov = this.fovInRadians / 2;
9768
- this._cameraToCenterDistance = .5 / Math.tan(halfFov) * this._height;
9769
- }
10176
+ this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize;
10177
+ if (!this._width || !this._height) return;
10178
+ this._pixelsToGLUnits = [2 / this._width, -2 / this._height];
10179
+ let m = identity(/* @__PURE__ */ new Float64Array(16));
10180
+ scale(m, m, [
10181
+ this._width / 2,
10182
+ -this._height / 2,
10183
+ 1
10184
+ ]);
10185
+ translate(m, m, [
10186
+ 1,
10187
+ -1,
10188
+ 0
10189
+ ]);
10190
+ this._clipSpaceToPixelsMatrix = m;
10191
+ m = identity(/* @__PURE__ */ new Float64Array(16));
10192
+ scale(m, m, [
10193
+ 1,
10194
+ -1,
10195
+ 1
10196
+ ]);
10197
+ translate(m, m, [
10198
+ -1,
10199
+ -1,
10200
+ 0
10201
+ ]);
10202
+ scale(m, m, [
10203
+ 2 / this._width,
10204
+ 2 / this._height,
10205
+ 1
10206
+ ]);
10207
+ this._pixelsToClipSpaceMatrix = m;
10208
+ const halfFov = this.fovInRadians / 2;
10209
+ this._cameraToCenterDistance = .5 / Math.tan(halfFov) * this._height;
9770
10210
  this._callbacks.calcMatrices();
9771
10211
  }
9772
10212
  calculateCenterFromCameraLngLatAlt(lnglat, alt, bearing, pitch) {
@@ -9840,12 +10280,6 @@ var TransformHelper = class {
9840
10280
  const offset = Math.tan(pitch) * (this.cameraToCenterDistance || 1);
9841
10281
  return this.centerPoint.add(new Point(offset * Math.sin(this.rollInRadians), offset * Math.cos(this.rollInRadians)));
9842
10282
  }
9843
- getCameraAltitude() {
9844
- return Math.cos(this.pitchInRadians) * this._cameraToCenterDistance / this._pixelPerMeter + this.elevation;
9845
- }
9846
- getCameraLngLat() {
9847
- return cameraMercatorCoordinate(this).toLngLat();
9848
- }
9849
10283
  getMercatorTileCoordinates(overscaledTileID) {
9850
10284
  if (!overscaledTileID) return [
9851
10285
  0,
@@ -9858,65 +10292,8 @@ var TransformHelper = class {
9858
10292
  overscaledTileID.canonical.x / scale,
9859
10293
  overscaledTileID.canonical.y / scale,
9860
10294
  1 / scale / EXTENT,
9861
- 1 / scale / EXTENT
9862
- ];
9863
- }
9864
- };
9865
- //#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;
10295
+ 1 / scale / EXTENT
10296
+ ];
9920
10297
  }
9921
10298
  };
9922
10299
  //#endregion
@@ -9941,266 +10318,33 @@ var MercatorCoveringTilesDetailsProvider = class {
9941
10318
  getTileBoundingVolume(tileID, wrap, elevation, options) {
9942
10319
  let minElevation = Math.min(0, elevation);
9943
10320
  let maxElevation = Math.max(0, elevation);
9944
- if (options?.terrain) {
9945
- const overscaledTileID = new OverscaledTileID(tileID.z, wrap, tileID.z, tileID.x, tileID.y);
9946
- const minMax = options.terrain.getMinMaxElevation(overscaledTileID);
9947
- minElevation = minMax.minElevation ?? minElevation;
9948
- maxElevation = minMax.maxElevation ?? maxElevation;
9949
- }
9950
- const numTiles = 1 << tileID.z;
9951
- return new Aabb([
9952
- wrap + tileID.x / numTiles,
9953
- tileID.y / numTiles,
9954
- minElevation
9955
- ], [
9956
- wrap + (tileID.x + 1) / numTiles,
9957
- (tileID.y + 1) / numTiles,
9958
- maxElevation
9959
- ]);
9960
- }
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);
10160
- }
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
- ];
10169
- }
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
- }
10321
+ if (options?.terrain) {
10322
+ const overscaledTileID = new OverscaledTileID(tileID.z, wrap, tileID.z, tileID.x, tileID.y);
10323
+ const minMax = options.terrain.getMinMaxElevation(overscaledTileID);
10324
+ minElevation = minMax.minElevation ?? minElevation;
10325
+ maxElevation = minMax.maxElevation ?? maxElevation;
10326
+ }
10327
+ const numTiles = 1 << tileID.z;
10328
+ return new Aabb([
10329
+ wrap + tileID.x / numTiles,
10330
+ tileID.y / numTiles,
10331
+ minElevation
10332
+ ], [
10333
+ wrap + (tileID.x + 1) / numTiles,
10334
+ (tileID.y + 1) / numTiles,
10335
+ maxElevation
10336
+ ]);
10337
+ }
10338
+ allowVariableZoom(transform, options) {
10339
+ const zfov = transform.fov * (Math.abs(Math.cos(transform.rollInRadians)) * transform.height + Math.abs(Math.sin(transform.rollInRadians)) * transform.width) / transform.height;
10340
+ const maxConstantZoomPitch = clamp(78.5 - zfov / 2, 0, 60);
10341
+ return !!options.terrain || transform.pitch > maxConstantZoomPitch;
10342
+ }
10343
+ allowWorldCopies() {
10344
+ return true;
10345
+ }
10346
+ prepareNextFrame() {}
10347
+ };
10204
10348
  //#endregion
10205
10349
  //#region src/data/pos3d_attributes.ts
10206
10350
  const pos3dAttributes = createLayout([{
@@ -11437,6 +11581,27 @@ var MercatorTransform = class MercatorTransform {
11437
11581
  calculateCenterFromCameraLngLatAlt(lnglat, alt, bearing, pitch) {
11438
11582
  return this._helper.calculateCenterFromCameraLngLatAlt(lnglat, alt, bearing, pitch);
11439
11583
  }
11584
+ calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
11585
+ const fromMercator = MercatorCoordinate.fromLngLat(from, altitudeFrom);
11586
+ const toMercator = MercatorCoordinate.fromLngLat(to, altitudeTo);
11587
+ const dx = toMercator.x - fromMercator.x;
11588
+ const dy = toMercator.y - fromMercator.y;
11589
+ const dz = toMercator.z - fromMercator.z;
11590
+ const distance3D = Math.hypot(dx, dy, dz);
11591
+ if (distance3D === 0) throw new Error("Can't calculate camera options with same From and To");
11592
+ const groundDistance = Math.hypot(dx, dy);
11593
+ const zoom = scaleZoom(this.cameraToCenterDistance / distance3D / this.tileSize);
11594
+ const bearing = radiansToDegrees(Math.atan2(dx, -dy));
11595
+ let pitch = radiansToDegrees(Math.acos(groundDistance / distance3D));
11596
+ pitch = dz < 0 ? 90 - pitch : 90 + pitch;
11597
+ return {
11598
+ center: toMercator.toLngLat(),
11599
+ elevation: altitudeTo,
11600
+ zoom,
11601
+ pitch,
11602
+ bearing
11603
+ };
11604
+ }
11440
11605
  _calculateNearFarZIfNeeded(cameraToSeaLevelDistance, limitedPitchRadians, offset) {
11441
11606
  if (!this._helper.autoCalculateNearFarZ) return;
11442
11607
  const minElevation = Math.min(this.elevation, this.minElevationForCurrentTile, this.getCameraAltitude() - 100);
@@ -11455,11 +11620,9 @@ var MercatorTransform = class MercatorTransform {
11455
11620
  this._helper._nearZ = this._helper._height / 50;
11456
11621
  }
11457
11622
  _calcMatrices() {
11458
- if (!this._helper._height) return;
11459
11623
  const offset = this.centerOffset;
11460
11624
  const point = projectToWorldCoordinates(this.worldSize, this.center);
11461
11625
  const x = point.x, y = point.y;
11462
- this._helper._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize;
11463
11626
  const limitedPitchRadians = degreesToRadians(Math.min(this.pitch, maxMercatorHorizonAngle));
11464
11627
  const cameraToSeaLevelDistance = Math.max(this._helper.cameraToCenterDistance / 2, this._helper.cameraToCenterDistance + this._helper._elevation * this._helper._pixelPerMeter / Math.cos(limitedPitchRadians));
11465
11628
  this._calculateNearFarZIfNeeded(cameraToSeaLevelDistance, limitedPitchRadians, offset);
@@ -11585,7 +11748,7 @@ var MercatorTransform = class MercatorTransform {
11585
11748
  return this._helper.getCameraPoint();
11586
11749
  }
11587
11750
  getCameraAltitude() {
11588
- return this._helper.getCameraAltitude();
11751
+ return Math.cos(this.pitchInRadians) * this.cameraToCenterDistance / this.pixelsPerMeter + this.elevation;
11589
11752
  }
11590
11753
  getCameraLngLat() {
11591
11754
  const pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize;
@@ -12107,6 +12270,23 @@ function getGlobeRadiusPixels(worldSize, latitudeDegrees) {
12107
12270
  return worldSize / (2 * Math.PI) / Math.cos(latitudeDegrees * Math.PI / 180);
12108
12271
  }
12109
12272
  /**
12273
+ * Returns the globe center in view space, in pixels: the camera is at the origin and looks down the negative Z axis.
12274
+ */
12275
+ function getGlobeCenterInViewSpace(transform) {
12276
+ const position = transformMat4(createVec4f64(), [
12277
+ 0,
12278
+ 0,
12279
+ 0,
12280
+ 1
12281
+ ], transform.modelViewProjectionMatrix);
12282
+ transformMat4(position, position, transform.inverseProjectionMatrix);
12283
+ return [
12284
+ position[0] / position[3],
12285
+ position[1] / position[3],
12286
+ position[2] / position[3]
12287
+ ];
12288
+ }
12289
+ /**
12110
12290
  * Given a 3D point on the surface of a unit sphere, returns its angular coordinates in degrees.
12111
12291
  * The input vector must be normalized.
12112
12292
  */
@@ -12160,7 +12340,7 @@ const PAN_MAX_ANGLE = Math.PI * .98;
12160
12340
  */
12161
12341
  function panSurfaceLocation(tr, point) {
12162
12342
  const origin = tr.cameraPosition;
12163
- const distance = length$1(origin);
12343
+ const distance = length(origin);
12164
12344
  if (distance <= 1) return tr.screenPointToLocation(point);
12165
12345
  const u = createVec3f64();
12166
12346
  normalize(u, origin);
@@ -12168,7 +12348,7 @@ function panSurfaceLocation(tr, point) {
12168
12348
  const c = -dot(direction, u);
12169
12349
  const lateral = createVec3f64();
12170
12350
  scaleAndAdd(lateral, direction, u, c);
12171
- const s = length$1(lateral);
12351
+ const s = length(lateral);
12172
12352
  if (s < 1e-9) return tr.screenPointToLocation(point);
12173
12353
  const angle = Math.atan2(s, c);
12174
12354
  const handoverAngle = Math.asin(1 / distance) * .9;
@@ -12180,9 +12360,9 @@ function panSurfaceLocation(tr, point) {
12180
12360
  const excess = angle - handoverAngle;
12181
12361
  const target = targetAtHandover + room * (slopeAtHandover * excess) / (room + slopeAtHandover * excess);
12182
12362
  const e = createVec3f64();
12183
- scale$2(e, lateral, 1 / s);
12363
+ scale$1(e, lateral, 1 / s);
12184
12364
  const surface = createVec3f64();
12185
- scale$2(surface, u, Math.cos(clamp(target, 0, PAN_MAX_ANGLE)));
12365
+ scale$1(surface, u, Math.cos(clamp(target, 0, PAN_MAX_ANGLE)));
12186
12366
  scaleAndAdd(surface, surface, e, Math.sin(clamp(target, 0, PAN_MAX_ANGLE)));
12187
12367
  normalize(surface, surface);
12188
12368
  return sphereSurfacePointToCoordinates(surface);
@@ -12377,7 +12557,7 @@ function raySphereIntersection(origin, direction, radius = 1) {
12377
12557
  const radiusSquared = radius * radius;
12378
12558
  const inner = createVec3f64();
12379
12559
  const scaledDir = createVec3f64();
12380
- scale$2(scaledDir, direction, originDotDirection);
12560
+ scale$1(scaledDir, direction, originDotDirection);
12381
12561
  sub(inner, origin, scaledDir);
12382
12562
  const discriminant = radiusSquared - dot(inner, inner);
12383
12563
  if (discriminant < 0) return null;
@@ -12537,9 +12717,9 @@ var ConvexVolume = class ConvexVolume {
12537
12717
  const points = [];
12538
12718
  for (let i = 0; i < 8; i++) {
12539
12719
  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));
12720
+ add(p, p, scale$1([], axisX, (i >> 0 & 1) === 1 ? 1 : -1));
12721
+ add(p, p, scale$1([], axisY, (i >> 1 & 1) === 1 ? 1 : -1));
12722
+ add(p, p, scale$1([], axisZ, (i >> 2 & 1) === 1 ? 1 : -1));
12543
12723
  points.push(p);
12544
12724
  }
12545
12725
  return new ConvexVolume(points, [
@@ -12685,6 +12865,11 @@ var GlobeCoveringTilesDetailsProvider = class {
12685
12865
  getTileBoundingVolume(tileID, wrap, elevation, options) {
12686
12866
  return this._boundingVolumeCache.getTileBoundingVolume(tileID, wrap, elevation, options);
12687
12867
  }
12868
+ /**
12869
+ * Computes the bounding volume of a tile for culling. The volume reaches up to `elevation`,
12870
+ * which carries the content elevation allowance (e.g. elevated symbols); terrain elevations
12871
+ * widen the volume but never shrink that allowance.
12872
+ */
12688
12873
  _computeTileBoundingVolume(tileID, wrap, elevation, options) {
12689
12874
  let minElevation = Math.min(0, elevation);
12690
12875
  let maxElevation = Math.max(0, elevation);
@@ -12692,7 +12877,7 @@ var GlobeCoveringTilesDetailsProvider = class {
12692
12877
  const overscaledTileID = new OverscaledTileID(tileID.z, wrap, tileID.z, tileID.x, tileID.y);
12693
12878
  const minMax = options.terrain.getMinMaxElevation(overscaledTileID);
12694
12879
  minElevation = minMax.minElevation ?? minElevation;
12695
- maxElevation = minMax.maxElevation ?? maxElevation;
12880
+ maxElevation = Math.max(minMax.maxElevation ?? maxElevation, maxElevation);
12696
12881
  }
12697
12882
  minElevation /= earthRadius;
12698
12883
  maxElevation /= earthRadius;
@@ -12724,8 +12909,8 @@ var GlobeCoveringTilesDetailsProvider = class {
12724
12909
  projectTileCoordinatesToSphere(0, EXTENT, tileID.x, tileID.y, tileID.z)
12725
12910
  ];
12726
12911
  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));
12912
+ for (const c of corners) extremesPoints.push(scale$1([], c, maxElevation));
12913
+ if (maxElevation !== minElevation) for (const c of corners) extremesPoints.push(scale$1([], c, minElevation));
12729
12914
  if (tileID.y === 0) extremesPoints.push([
12730
12915
  0,
12731
12916
  1,
@@ -12763,9 +12948,9 @@ var GlobeCoveringTilesDetailsProvider = class {
12763
12948
  normalize(axisEast, axisEast);
12764
12949
  const axisWest = cross([], corners[0], corners[3]);
12765
12950
  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));
12951
+ extremesPoints.push(scale$1([], center, maxElevation));
12952
+ if (tileID.y >= (1 << tileID.z) / 2) extremesPoints.push(scale$1([], projectTileCoordinatesToSphere(EXTENT / 2, 0, tileID.x, tileID.y, tileID.z), maxElevation));
12953
+ if (tileID.y < (1 << tileID.z) / 2) extremesPoints.push(scale$1([], projectTileCoordinatesToSphere(EXTENT / 2, EXTENT, tileID.x, tileID.y, tileID.z), maxElevation));
12769
12954
  const upDownMinMax = findAxisMinMax(center, extremesPoints);
12770
12955
  const northSouthMinMax = findAxisMinMax(north, extremesPoints);
12771
12956
  const planeUp = [
@@ -12829,6 +13014,10 @@ const GLOBE_SAMPLES = 256;
12829
13014
  const GLOBE_BISECT_EPSILON_T = 1e-12;
12830
13015
  /** Latitudes outside the mercator range project past the world edge; the globe mesh still covers them. */
12831
13016
  const MAX_MERCATOR_Y = 1 - 1e-9;
13017
+ /** Two points on the unit globe closer than this, a micrometre, are the same point. */
13018
+ const SAME_POINT_DISTANCE = 1e-12;
13019
+ /** A camera whose horizontal offset is this small relative to its distance is straight above the center. */
13020
+ const STRAIGHT_ABOVE_RATIO = 1e-9;
12832
13021
  var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
12833
13022
  get pixelsToClipSpaceMatrix() {
12834
13023
  return this._helper.pixelsToClipSpaceMatrix;
@@ -13115,8 +13304,8 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13115
13304
  0,
13116
13305
  0
13117
13306
  ], this.center.lng * Math.PI / 180);
13118
- const scale = 1 / length$1(planeVector);
13119
- scale$2(planeVector, planeVector, scale);
13307
+ const scale = 1 / length(planeVector);
13308
+ scale$1(planeVector, planeVector, scale);
13120
13309
  return [...planeVector, -tangentPlaneDistanceToC * scale];
13121
13310
  }
13122
13311
  isLocationOccluded(location) {
@@ -13172,23 +13361,44 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13172
13361
  const canonical = unwrappedTileID.canonical;
13173
13362
  const spherePos = projectTileCoordinatesToSphere(x, y, canonical.x, canonical.y, canonical.z);
13174
13363
  const vectorMultiplier = 1 + (elevation ?? 0) / earthRadius;
13364
+ const elevatedX = spherePos[0] * vectorMultiplier;
13365
+ const elevatedY = spherePos[1] * vectorMultiplier;
13366
+ const elevatedZ = spherePos[2] * vectorMultiplier;
13175
13367
  const pos = [
13176
- spherePos[0] * vectorMultiplier,
13177
- spherePos[1] * vectorMultiplier,
13178
- spherePos[2] * vectorMultiplier,
13368
+ elevatedX,
13369
+ elevatedY,
13370
+ elevatedZ,
13179
13371
  1
13180
13372
  ];
13181
13373
  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;
13374
+ let isOccluded;
13375
+ if (vectorMultiplier <= 1) {
13376
+ const plane = this._cachedClippingPlane;
13377
+ isOccluded = plane[0] * spherePos[0] + plane[1] * spherePos[1] + plane[2] * spherePos[2] + plane[3] < 0;
13378
+ } else isOccluded = this._isLineOfSightBlocked(elevatedX, elevatedY, elevatedZ);
13184
13379
  return {
13185
13380
  point: new Point(pos[0] / pos[3], pos[1] / pos[3]),
13186
13381
  signedDistanceFromCamera: pos[3],
13187
13382
  isOccluded
13188
13383
  };
13189
13384
  }
13385
+ /**
13386
+ * True when the segment from the camera to the given point, both in unit-globe coordinates, passes through the planet.
13387
+ */
13388
+ _isLineOfSightBlocked(x, y, z) {
13389
+ const cam = this._cameraPosition;
13390
+ const dx = x - cam[0];
13391
+ const dy = y - cam[1];
13392
+ const dz = z - cam[2];
13393
+ const lengthSq = dx * dx + dy * dy + dz * dz;
13394
+ if (lengthSq === 0) return false;
13395
+ const t = clamp(-(cam[0] * dx + cam[1] * dy + cam[2] * dz) / lengthSq, 0, 1);
13396
+ const cx = cam[0] + t * dx;
13397
+ const cy = cam[1] + t * dy;
13398
+ const cz = cam[2] + t * dz;
13399
+ return cx * cx + cy * cy + cz * cz < 1;
13400
+ }
13190
13401
  _calcMatrices() {
13191
- if (!this._helper._width || !this._helper._height) return;
13192
13402
  const globeRadiusPixels = getGlobeRadiusPixels(this.worldSize, this.center.lat);
13193
13403
  const globeMatrix = createMat4f64();
13194
13404
  if (this._helper.autoCalculateNearFarZ) {
@@ -13279,16 +13489,22 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13279
13489
  getCameraPoint() {
13280
13490
  return this._helper.getCameraPoint();
13281
13491
  }
13492
+ /**
13493
+ * The altitude of the rendered camera above sea level. The sphere keeps the center point at sea level whatever its
13494
+ * elevation (`_calcMatrices` does not apply it), so unlike on mercator the center elevation does not lift the camera.
13495
+ * {@link calculateCameraOptionsFromTo} is the inverse.
13496
+ */
13282
13497
  getCameraAltitude() {
13283
- return this._helper.getCameraAltitude();
13498
+ return (length(this._cameraPosition) - 1) * earthRadius;
13284
13499
  }
13285
13500
  getCameraLngLat() {
13286
- return this._helper.getCameraLngLat();
13501
+ const surface = createVec3f64();
13502
+ normalize(surface, this._cameraPosition);
13503
+ return sphereSurfacePointToCoordinates(surface);
13287
13504
  }
13288
13505
  lngLatToCameraDepth(lngLat, elevation) {
13289
- if (!this._globeViewProjMatrixF64) return 1;
13290
13506
  const vec = angularCoordinatesToSurfaceVector(lngLat);
13291
- scale$2(vec, vec, 1 + elevation / earthRadius);
13507
+ scale$1(vec, vec, 1 + elevation / earthRadius);
13292
13508
  const result = createVec4f64();
13293
13509
  transformMat4(result, [
13294
13510
  vec[0],
@@ -13354,6 +13570,34 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13354
13570
  return this._helper.calculateCenterFromCameraLngLatAlt(lngLat, alt, bearing, pitch);
13355
13571
  }
13356
13572
  /**
13573
+ * Inverts the camera placement of `_calcMatrices` in unit-globe coordinates: the camera sits at radius
13574
+ * `1 + altitudeFrom / earthRadius` and looks at the center on the sea-level sphere, the target altitude only becoming
13575
+ * the center elevation (the inverse of {@link getCameraAltitude}). Pitch and bearing are read in the center's local
13576
+ * frame, +z up, +y north, +x east. A camera straight above the center keeps the transform's bearing.
13577
+ */
13578
+ calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
13579
+ const center = LngLat.convert(to);
13580
+ const camera = angularCoordinatesToSurfaceVector(LngLat.convert(from));
13581
+ scale$1(camera, camera, 1 + altitudeFrom / earthRadius);
13582
+ const target = angularCoordinatesToSurfaceVector(center);
13583
+ const targetAtAltitude = scale$1(createVec3f64(), target, 1 + altitudeTo / earthRadius);
13584
+ const toCamera = subtract(createVec3f64(), camera, target);
13585
+ const distance$1 = length(toCamera);
13586
+ 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");
13587
+ const zero = createVec3f64();
13588
+ rotateY(toCamera, toCamera, zero, -degreesToRadians(center.lng));
13589
+ rotateX$1(toCamera, toCamera, zero, degreesToRadians(center.lat));
13590
+ const pitch = radiansToDegrees(Math.acos(clamp(toCamera[2] / distance$1, -1, 1)));
13591
+ const bearing = Math.hypot(toCamera[0], toCamera[1]) < distance$1 * STRAIGHT_ABOVE_RATIO ? this.bearing : radiansToDegrees(Math.atan2(-toCamera[0], -toCamera[1]));
13592
+ return {
13593
+ center,
13594
+ elevation: altitudeTo,
13595
+ zoom: scaleZoom(this.cameraToCenterDistance / distance$1 / getGlobeRadiusPixels(this.tileSize, center.lat)),
13596
+ pitch,
13597
+ bearing
13598
+ };
13599
+ }
13600
+ /**
13357
13601
  * Note: automatically adjusts zoom to keep planet size consistent
13358
13602
  * (same size before and after a {@link setLocationAtPoint} call).
13359
13603
  */
@@ -13414,7 +13658,7 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13414
13658
  const pos = angularCoordinatesToSurfaceVector(lnglat);
13415
13659
  if (terrain) {
13416
13660
  const elevation = terrain.getElevationForLngLatZoom(lnglat, this._helper._tileZoom);
13417
- scale$2(pos, pos, 1 + elevation / earthRadius);
13661
+ scale$1(pos, pos, 1 + elevation / earthRadius);
13418
13662
  }
13419
13663
  return this._projectSurfacePointToScreen(pos);
13420
13664
  }
@@ -13586,9 +13830,9 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
13586
13830
  function globeSampleAt(ray, t) {
13587
13831
  const position = createVec3f64();
13588
13832
  scaleAndAdd(position, ray.origin, ray.direction, t);
13589
- const radius = length$1(position);
13833
+ const radius = length(position);
13590
13834
  const surface = createVec3f64();
13591
- scale$2(surface, position, 1 / radius);
13835
+ scale$1(surface, position, 1 / radius);
13592
13836
  const lngLat = sphereSurfacePointToCoordinates(surface);
13593
13837
  const projected = MercatorCoordinate.fromLngLat(lngLat);
13594
13838
  const mercator = new MercatorCoordinate(projected.x, clamp(projected.y, 0, MAX_MERCATOR_Y));
@@ -13925,11 +14169,13 @@ var GlobeTransform = class GlobeTransform {
13925
14169
  getCameraPoint() {
13926
14170
  return this._helper.getCameraPoint();
13927
14171
  }
14172
+ /** The camera of the child that renders the current frame. */
13928
14173
  getCameraAltitude() {
13929
- return this._helper.getCameraAltitude();
14174
+ return this.currentTransform.getCameraAltitude();
13930
14175
  }
14176
+ /** See {@link getCameraAltitude}. */
13931
14177
  getCameraLngLat() {
13932
- return this._helper.getCameraLngLat();
14178
+ return this.currentTransform.getCameraLngLat();
13933
14179
  }
13934
14180
  lngLatToCameraDepth(lngLat, elevation) {
13935
14181
  return this.currentTransform.lngLatToCameraDepth(lngLat, elevation);
@@ -13944,6 +14190,10 @@ var GlobeTransform = class GlobeTransform {
13944
14190
  calculateCenterFromCameraLngLatAlt(lngLat, alt, bearing, pitch) {
13945
14191
  return this._helper.calculateCenterFromCameraLngLatAlt(lngLat, alt, bearing, pitch);
13946
14192
  }
14193
+ /** See {@link getCameraAltitude}. */
14194
+ calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
14195
+ return this.currentTransform.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo);
14196
+ }
13947
14197
  /**
13948
14198
  * Note: automatically adjusts zoom to keep planet size consistent
13949
14199
  * (same size before and after a {@link setLocationAtPoint} call).
@@ -14069,7 +14319,7 @@ var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
14069
14319
  rayDirection[1] * distanceToClosestPoint,
14070
14320
  rayDirection[2] * distanceToClosestPoint
14071
14321
  ]);
14072
- const rayDistanceFromGlobeCenter = length$1(closestPoint);
14322
+ const rayDistanceFromGlobeCenter = length(closestPoint);
14073
14323
  const distanceFromSurface = rayDistanceFromGlobeCenter - 1;
14074
14324
  const distanceFactor = Math.exp(-Math.max(distanceFromSurface - RAY_SURFACE_DISTANCE_FOR_SLOWING_START, 0) * SLOWING_MULTIPLIER);
14075
14325
  const interpolationFactorHorizon = remapSaturate(rayDistanceFromGlobeCenter, INTERPOLATE_TO_HEURISTIC_START_HORIZON, INTERPOLATE_TO_HEURISTIC_END_HORIZON, 0, 1);
@@ -14711,8 +14961,6 @@ var Style = class extends Evented {
14711
14961
  this._updateTilesForChangedImages();
14712
14962
  this._updateTilesForChangedGlyphs();
14713
14963
  for (const id in this._updatedPaintProps) this._layers[id].updateTransitions(parameters);
14714
- this.light.updateTransitions(parameters);
14715
- this.sky.updateTransitions(parameters);
14716
14964
  this._resetUpdates();
14717
14965
  }
14718
14966
  const managersUsedBefore = {};
@@ -15026,13 +15274,13 @@ var Style = class extends Evented {
15026
15274
  return;
15027
15275
  }
15028
15276
  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) {
15277
+ if (before && !this._order.includes(before)) {
15033
15278
  this.fire(new ErrorEvent(/* @__PURE__ */ new Error(`Cannot move layer "${id}" before non-existing layer "${before}".`)));
15034
15279
  return;
15035
15280
  }
15281
+ const index = this._order.indexOf(id);
15282
+ this._order.splice(index, 1);
15283
+ const newIndex = before ? this._order.indexOf(before) : this._order.length;
15036
15284
  this._order.splice(newIndex, 0, id);
15037
15285
  this._layerOrderChanged = true;
15038
15286
  }
@@ -15059,6 +15307,7 @@ var Style = class extends Evented {
15059
15307
  if (this._serializedLayers) delete this._serializedLayers[id];
15060
15308
  delete this._updatedLayers[id];
15061
15309
  delete this._updatedPaintProps[id];
15310
+ if (layer.type === "symbol" && layer.source) this.tileManagers[layer.source]?.resetMaxContentElevation();
15062
15311
  if (layer.onRemove) layer.onRemove(this.map);
15063
15312
  }
15064
15313
  /**
@@ -15714,13 +15963,7 @@ var VertexArrayObject = class {
15714
15963
  let paintBuffersDiffer = this.boundPaintVertexBuffers.length !== paintVertexBuffers.length;
15715
15964
  for (let i = 0; !paintBuffersDiffer && i < paintVertexBuffers.length; i++) if (this.boundPaintVertexBuffers[i] !== paintVertexBuffers[i]) paintBuffersDiffer = true;
15716
15965
  if (!this.vao || this.boundProgram !== program || this.boundLayoutVertexBuffer !== layoutVertexBuffer || paintBuffersDiffer || this.boundIndexBuffer !== indexBuffer || this.boundVertexOffset !== vertexOffset || this.boundDynamicVertexBuffer !== dynamicVertexBuffer || this.boundDynamicVertexBuffer2 !== dynamicVertexBuffer2 || this.boundDynamicVertexBuffer3 !== dynamicVertexBuffer3) this.freshBind(program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2, dynamicVertexBuffer3);
15717
- else {
15718
- context.bindVertexArray.set(this.vao);
15719
- if (dynamicVertexBuffer) dynamicVertexBuffer.bind();
15720
- if (indexBuffer?.dynamicDraw) indexBuffer.bind();
15721
- if (dynamicVertexBuffer2) dynamicVertexBuffer2.bind();
15722
- if (dynamicVertexBuffer3) dynamicVertexBuffer3.bind();
15723
- }
15966
+ else context.bindVertexArray.set(this.vao);
15724
15967
  }
15725
15968
  freshBind(program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2, dynamicVertexBuffer3) {
15726
15969
  const numNextAttributes = program.numAttributes;
@@ -15774,11 +16017,7 @@ var VertexArrayObject = class {
15774
16017
  //#region src/webgl/program/terrain_program.ts
15775
16018
  const terrainPreludeUniforms = (context, locations) => ({
15776
16019
  "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)
16020
+ "u_terrain": new Uniform1i(context, locations.u_terrain)
15782
16021
  });
15783
16022
  const terrainUniforms = (context, locations) => ({
15784
16023
  "u_texture": new Uniform1i(context, locations.u_texture),
@@ -15805,26 +16044,173 @@ const terrainUniformValues = (eleDelta, fogMatrix, sky, pitch, isGlobeMode) => (
15805
16044
  });
15806
16045
  const terrainDepthUniformValues = (eleDelta) => ({ "u_ele_delta": eleDelta });
15807
16046
  //#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
- });
16047
+ //#region src/webgl/uniform_buffer.ts
16048
+ const UBO_BINDINGS = {
16049
+ ProjectionUBO: 0,
16050
+ TerrainUBO: 1,
16051
+ FrameUBO: 2
16052
+ };
16053
+ function applyUBOBindings(gl, program) {
16054
+ for (const [name, binding] of Object.entries(UBO_BINDINGS)) {
16055
+ const index = gl.getUniformBlockIndex(program, name);
16056
+ if (index !== gl.INVALID_INDEX) gl.uniformBlockBinding(program, index, binding);
16057
+ }
16058
+ }
16059
+ const STD140_SIZE_AND_ALIGNMENT_WORDS = {
16060
+ float: [1, 1],
16061
+ int: [1, 1],
16062
+ vec2: [2, 2],
16063
+ vec4: [4, 4],
16064
+ mat4: [16, 4]
16065
+ };
16066
+ function std140Layout(members) {
16067
+ const offsets = {};
16068
+ let words = 0;
16069
+ for (const { name, type } of members) {
16070
+ const [size, alignment] = STD140_SIZE_AND_ALIGNMENT_WORDS[type];
16071
+ words = Math.ceil(words / alignment) * alignment;
16072
+ offsets[name] = words;
16073
+ words += size;
16074
+ }
16075
+ return {
16076
+ offsets,
16077
+ contentWords: words,
16078
+ sizeWords: Math.ceil(words / 4) * 4
16079
+ };
16080
+ }
15817
16081
  /**
15818
- * Converts a {@link ProjectionData} object into the values expected by the projection prelude's uniforms.
16082
+ * @internal
16083
+ * The buffer behind one std140 uniform block, bound to a fixed binding point. Callers write members into
16084
+ * `pending` at the layout's offsets and call `upload`, which skips the GPU write when nothing changed.
15819
16085
  */
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
- });
16086
+ var UniformBuffer = class {
16087
+ constructor(context, binding, layout) {
16088
+ this.context = context;
16089
+ this.binding = binding;
16090
+ this.contentWords = layout.contentWords;
16091
+ const gl = context.gl;
16092
+ this.buffer = gl.createBuffer();
16093
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this.buffer);
16094
+ gl.bufferData(gl.UNIFORM_BUFFER, layout.sizeWords * 4, gl.DYNAMIC_DRAW);
16095
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, this.buffer);
16096
+ this.uploaded = new Float32Array(layout.sizeWords);
16097
+ this.pending = new Float32Array(layout.sizeWords);
16098
+ this.uploadedWords = new Uint32Array(this.uploaded.buffer);
16099
+ this.pendingWords = new Uint32Array(this.pending.buffer);
16100
+ this.hasData = false;
16101
+ this.bindingDirty = false;
16102
+ }
16103
+ upload() {
16104
+ const gl = this.context.gl;
16105
+ let changed = !this.hasData;
16106
+ if (!changed) {
16107
+ const words = this.pendingWords;
16108
+ const uploadedWords = this.uploadedWords;
16109
+ for (let i = 0; i < this.contentWords; i++) if (words[i] !== uploadedWords[i]) {
16110
+ changed = true;
16111
+ break;
16112
+ }
16113
+ }
16114
+ if (this.bindingDirty) {
16115
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, this.binding, this.buffer);
16116
+ this.bindingDirty = false;
16117
+ }
16118
+ if (!changed) return;
16119
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this.buffer);
16120
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, this.pending);
16121
+ this.uploaded.set(this.pending);
16122
+ this.hasData = true;
16123
+ }
16124
+ destroy() {
16125
+ const gl = this.context.gl;
16126
+ if (this.buffer) {
16127
+ gl.deleteBuffer(this.buffer);
16128
+ delete this.buffer;
16129
+ }
16130
+ }
16131
+ };
16132
+ //#endregion
16133
+ //#region src/webgl/projection_uniform_buffer.ts
16134
+ const layout$2 = std140Layout([
16135
+ {
16136
+ name: "u_projection_matrix",
16137
+ type: "mat4"
16138
+ },
16139
+ {
16140
+ name: "u_projection_fallback_matrix",
16141
+ type: "mat4"
16142
+ },
16143
+ {
16144
+ name: "u_projection_tile_mercator_coords",
16145
+ type: "vec4"
16146
+ },
16147
+ {
16148
+ name: "u_projection_clipping_plane",
16149
+ type: "vec4"
16150
+ },
16151
+ {
16152
+ name: "u_projection_transition",
16153
+ type: "float"
16154
+ },
16155
+ {
16156
+ name: "u_projection_clip_antimeridian",
16157
+ type: "int"
16158
+ }
16159
+ ]);
16160
+ const offsets$2 = layout$2.offsets;
16161
+ /**
16162
+ * @internal
16163
+ * The buffer behind the `ProjectionUBO` block in the shader preludes, written by `Program.draw` before each draw.
16164
+ */
16165
+ function createProjectionUniformBuffer(context) {
16166
+ return new UniformBuffer(context, UBO_BINDINGS.ProjectionUBO, layout$2);
16167
+ }
16168
+ function updateProjectionUniformBuffer(buffer, projectionData) {
16169
+ const f32 = buffer.pending;
16170
+ f32.set(projectionData.mainMatrix, offsets$2.u_projection_matrix);
16171
+ f32.set(projectionData.fallbackMatrix, offsets$2.u_projection_fallback_matrix);
16172
+ f32.set(projectionData.tileMercatorCoords, offsets$2.u_projection_tile_mercator_coords);
16173
+ f32.set(projectionData.clippingPlane, offsets$2.u_projection_clipping_plane);
16174
+ f32[offsets$2.u_projection_transition] = projectionData.projectionTransition;
16175
+ buffer.pendingWords[offsets$2.u_projection_clip_antimeridian] = projectionData.clipAntimeridian ? 1 : 0;
16176
+ buffer.upload();
16177
+ }
16178
+ //#endregion
16179
+ //#region src/webgl/terrain_uniform_buffer.ts
16180
+ const layout$1 = std140Layout([
16181
+ {
16182
+ name: "u_terrain_matrix",
16183
+ type: "mat4"
16184
+ },
16185
+ {
16186
+ name: "u_terrain_unpack",
16187
+ type: "vec4"
16188
+ },
16189
+ {
16190
+ name: "u_terrain_dim",
16191
+ type: "float"
16192
+ },
16193
+ {
16194
+ name: "u_terrain_exaggeration",
16195
+ type: "float"
16196
+ }
16197
+ ]);
16198
+ const offsets$1 = layout$1.offsets;
16199
+ /**
16200
+ * @internal
16201
+ * The buffer behind the `TerrainUBO` block in the vertex prelude, written by `Program.draw` for every draw with terrain.
16202
+ */
16203
+ function createTerrainUniformBuffer(context) {
16204
+ return new UniformBuffer(context, UBO_BINDINGS.TerrainUBO, layout$1);
16205
+ }
16206
+ function updateTerrainUniformBuffer(buffer, terrain) {
16207
+ const f32 = buffer.pending;
16208
+ f32.set(terrain.u_terrain_matrix, offsets$1.u_terrain_matrix);
16209
+ f32.set(terrain.u_terrain_unpack, offsets$1.u_terrain_unpack);
16210
+ f32[offsets$1.u_terrain_dim] = terrain.u_terrain_dim;
16211
+ f32[offsets$1.u_terrain_exaggeration] = terrain.u_terrain_exaggeration;
16212
+ buffer.upload();
16213
+ }
15828
16214
  //#endregion
15829
16215
  //#region src/webgl/program.ts
15830
16216
  function getTokenizedAttributesAndUniforms(array) {
@@ -15867,10 +16253,9 @@ var Program = class {
15867
16253
  const dynamicAttrInfo = configuration ? configuration.getBinderAttributes() : [];
15868
16254
  const allAttrInfo = staticAttrInfo.concat(dynamicAttrInfo);
15869
16255
  const preludeUniformsInfo = shaders.prelude.staticUniforms ? getTokenizedAttributesAndUniforms(shaders.prelude.staticUniforms) : [];
15870
- const projectionPreludeUniformsInfo = projectionPrelude.staticUniforms ? getTokenizedAttributesAndUniforms(projectionPrelude.staticUniforms) : [];
15871
16256
  const staticUniformsInfo = source.staticUniforms ? getTokenizedAttributesAndUniforms(source.staticUniforms) : [];
15872
16257
  const dynamicUniformsInfo = configuration ? configuration.getBinderUniforms() : [];
15873
- const uniformList = preludeUniformsInfo.concat(projectionPreludeUniformsInfo).concat(staticUniformsInfo).concat(dynamicUniformsInfo);
16258
+ const uniformList = preludeUniformsInfo.concat(staticUniformsInfo).concat(dynamicUniformsInfo);
15874
16259
  const allUniformsInfo = [];
15875
16260
  for (const uniform of uniformList) if (!allUniformsInfo.includes(uniform)) allUniformsInfo.push(uniform);
15876
16261
  const defines = configuration ? configuration.defines() : [];
@@ -15888,7 +16273,6 @@ var Program = class {
15888
16273
  }
15889
16274
  gl.shaderSource(fragmentShader, fragmentSource);
15890
16275
  gl.compileShader(fragmentShader);
15891
- if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile fragment shader: ${gl.getShaderInfoLog(fragmentShader)}`);
15892
16276
  gl.attachShader(this.program, fragmentShader);
15893
16277
  const vertexShader = gl.createShader(gl.VERTEX_SHADER);
15894
16278
  if (gl.isContextLost()) {
@@ -15897,13 +16281,21 @@ var Program = class {
15897
16281
  }
15898
16282
  gl.shaderSource(vertexShader, vertexSource);
15899
16283
  gl.compileShader(vertexShader);
15900
- if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile vertex shader: ${gl.getShaderInfoLog(vertexShader)}`);
15901
16284
  gl.attachShader(this.program, vertexShader);
15902
16285
  this.attributes = {};
15903
16286
  const uniformLocations = {};
15904
16287
  this.numAttributes = allAttrInfo.length;
15905
16288
  gl.linkProgram(this.program);
15906
- if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) throw new Error(`Program failed to link: ${gl.getProgramInfoLog(this.program)}`);
16289
+ if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
16290
+ if (gl.isContextLost()) {
16291
+ this.failedToCreate = true;
16292
+ return;
16293
+ }
16294
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile fragment shader: ${gl.getShaderInfoLog(fragmentShader)}`);
16295
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) throw new Error(`Could not compile vertex shader: ${gl.getShaderInfoLog(vertexShader)}`);
16296
+ throw new Error(`Program failed to link: ${gl.getProgramInfoLog(this.program)}`);
16297
+ }
16298
+ applyUBOBindings(gl, this.program);
15907
16299
  const integerAttributeNames = getIntegerAttributeNames(gl, this.program);
15908
16300
  for (const name of allAttrInfo) {
15909
16301
  if (!name) continue;
@@ -15921,7 +16313,6 @@ var Program = class {
15921
16313
  }
15922
16314
  this.fixedUniforms = fixedUniforms(context, uniformLocations);
15923
16315
  this.terrainUniforms = terrainPreludeUniforms(context, uniformLocations);
15924
- this.projectionUniforms = projectionUniforms(context, uniformLocations);
15925
16316
  this.binderUniforms = configuration ? configuration.getUniforms(context, uniformLocations) : [];
15926
16317
  }
15927
16318
  draw(context, drawMode, depthMode, stencilMode, colorMode, cullFaceMode, uniformValues, terrain, projectionData, layerID, layoutVertexBuffer, indexBuffer, segments, currentProperties, zoom, configuration, dynamicLayoutBuffer, dynamicLayoutBuffer2, dynamicLayoutBuffer3) {
@@ -15938,11 +16329,9 @@ var Program = class {
15938
16329
  context.activeTexture.set(gl.TEXTURE3);
15939
16330
  gl.bindTexture(gl.TEXTURE_2D, terrain.texture);
15940
16331
  for (const name in this.terrainUniforms) this.terrainUniforms[name].set(terrain[name]);
16332
+ updateTerrainUniformBuffer(context.terrainUniformBuffer, terrain);
15941
16333
  }
15942
- if (projectionData) {
15943
- const values = projectionUniformValues(projectionData);
15944
- for (const name in this.projectionUniforms) this.projectionUniforms[name].set(values[name]);
15945
- }
16334
+ if (projectionData) updateProjectionUniformBuffer(context.projectionUniformBuffer, projectionData);
15946
16335
  if (uniformValues) for (const name in this.fixedUniforms) this.fixedUniforms[name].set(uniformValues[name]);
15947
16336
  if (configuration) configuration.setUniforms(context, this.binderUniforms, currentProperties, { zoom });
15948
16337
  let primitiveSize = 0;
@@ -16071,37 +16460,33 @@ const fillPatternUniforms = (context, locations) => ({
16071
16460
  "u_pixel_coord_lower": new Uniform2f(context, locations.u_pixel_coord_lower),
16072
16461
  "u_scale": new Uniform3f(context, locations.u_scale),
16073
16462
  "u_fade": new Uniform1f(context, locations.u_fade),
16463
+ "u_sdf_pattern": new Uniform1i(context, locations.u_sdf_pattern),
16074
16464
  "u_fill_translate": new Uniform2f(context, locations.u_fill_translate)
16075
16465
  });
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
- });
16466
+ const fillOutlineUniforms = (context, locations) => ({ "u_fill_translate": new Uniform2f(context, locations.u_fill_translate) });
16080
16467
  const fillOutlinePatternUniforms = (context, locations) => ({
16081
- "u_world": new Uniform2f(context, locations.u_world),
16082
16468
  "u_image": new Uniform1i(context, locations.u_image),
16083
16469
  "u_texsize": new Uniform2f(context, locations.u_texsize),
16084
16470
  "u_pixel_coord_upper": new Uniform2f(context, locations.u_pixel_coord_upper),
16085
16471
  "u_pixel_coord_lower": new Uniform2f(context, locations.u_pixel_coord_lower),
16086
16472
  "u_scale": new Uniform3f(context, locations.u_scale),
16087
16473
  "u_fade": new Uniform1f(context, locations.u_fade),
16474
+ "u_sdf_pattern": new Uniform1i(context, locations.u_sdf_pattern),
16088
16475
  "u_fill_translate": new Uniform2f(context, locations.u_fill_translate)
16089
16476
  });
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
16477
+ const fillPatternUniformValues = (painter, crossfade, tile, translate, isSdfPattern) => extend(patternUniformValues(crossfade, painter, tile), {
16478
+ "u_fill_translate": translate,
16479
+ "u_sdf_pattern": isSdfPattern ? 1 : 0
16095
16480
  });
16096
- const fillOutlinePatternUniformValues = (painter, crossfade, tile, drawingBufferSize, translate) => extend(fillPatternUniformValues(painter, crossfade, tile, translate), { "u_world": drawingBufferSize });
16481
+ const fillUniformValues = (translate) => ({ "u_fill_translate": translate });
16482
+ const fillOutlineUniformValues = (translate) => ({ "u_fill_translate": translate });
16483
+ const fillOutlinePatternUniformValues = (painter, crossfade, tile, translate, isSdfPattern) => fillPatternUniformValues(painter, crossfade, tile, translate, isSdfPattern);
16097
16484
  //#endregion
16098
16485
  //#region src/webgl/program/circle_program.ts
16099
16486
  const circleUniforms = (context, locations) => ({
16100
- "u_camera_to_center_distance": new Uniform1f(context, locations.u_camera_to_center_distance),
16101
16487
  "u_scale_with_map": new Uniform1i(context, locations.u_scale_with_map),
16102
16488
  "u_pitch_with_map": new Uniform1i(context, locations.u_pitch_with_map),
16103
16489
  "u_extrude_scale": new Uniform2f(context, locations.u_extrude_scale),
16104
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16105
16490
  "u_globe_extrude_scale": new Uniform1f(context, locations.u_globe_extrude_scale),
16106
16491
  "u_translate": new Uniform2f(context, locations.u_translate)
16107
16492
  });
@@ -16119,26 +16504,14 @@ const circleUniformValues = (painter, tile, layer, translate, radiusCorrectionFa
16119
16504
  extrudeScale = transform.pixelsToGLUnits;
16120
16505
  }
16121
16506
  return {
16122
- "u_camera_to_center_distance": transform.cameraToCenterDistance,
16123
16507
  "u_scale_with_map": +(layer.paint.get("circle-pitch-scale") === "map"),
16124
16508
  "u_pitch_with_map": +pitchWithMap,
16125
- "u_device_pixel_ratio": painter.pixelRatio,
16126
16509
  "u_extrude_scale": extrudeScale,
16127
16510
  "u_globe_extrude_scale": globeExtrudeScale,
16128
16511
  "u_translate": translate
16129
16512
  };
16130
16513
  };
16131
16514
  //#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
16515
  //#region src/webgl/program/debug_program.ts
16143
16516
  const debugUniforms = (context, locations) => ({
16144
16517
  "u_color": new UniformColor(context, locations.u_color),
@@ -16159,7 +16532,6 @@ const heatmapUniforms = (context, locations) => ({
16159
16532
  });
16160
16533
  const heatmapTextureUniforms = (context, locations) => ({
16161
16534
  "u_matrix": new UniformMatrix4f(context, locations.u_matrix),
16162
- "u_world": new Uniform2f(context, locations.u_world),
16163
16535
  "u_image": new Uniform1i(context, locations.u_image),
16164
16536
  "u_color_ramp": new Uniform1i(context, locations.u_color_ramp),
16165
16537
  "u_opacity": new Uniform1f(context, locations.u_opacity)
@@ -16175,10 +16547,8 @@ const heatmapUniformValues = (tile, zoom, intensity, radiusCorrectionFactor) =>
16175
16547
  const heatmapTextureUniformValues = (painter, layer, textureUnit, colorRampUnit) => {
16176
16548
  const matrix = create$1();
16177
16549
  ortho(matrix, 0, painter.width, painter.height, 0, 0, 1);
16178
- const gl = painter.context.gl;
16179
16550
  return {
16180
16551
  "u_matrix": matrix,
16181
- "u_world": [gl.drawingBufferWidth, gl.drawingBufferHeight],
16182
16552
  "u_image": textureUnit,
16183
16553
  "u_color_ramp": colorRampUnit,
16184
16554
  "u_opacity": layer.paint.get("heatmap-opacity")
@@ -16284,15 +16654,11 @@ const colorReliefUniformValues = (layer, dem, colorRampSize = 0) => {
16284
16654
  //#region src/webgl/program/line_program.ts
16285
16655
  const lineUniforms = (context, locations) => ({
16286
16656
  "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)
16657
+ "u_ratio": new Uniform1f(context, locations.u_ratio)
16290
16658
  });
16291
16659
  const lineGradientUniforms = (context, locations) => ({
16292
16660
  "u_translation": new Uniform2f(context, locations.u_translation),
16293
16661
  "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
16662
  "u_image": new Uniform1i(context, locations.u_image),
16297
16663
  "u_image_height": new Uniform1f(context, locations.u_image_height)
16298
16664
  });
@@ -16300,17 +16666,13 @@ const linePatternUniforms = (context, locations) => ({
16300
16666
  "u_translation": new Uniform2f(context, locations.u_translation),
16301
16667
  "u_texsize": new Uniform2f(context, locations.u_texsize),
16302
16668
  "u_ratio": new Uniform1f(context, locations.u_ratio),
16303
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16304
16669
  "u_image": new Uniform1i(context, locations.u_image),
16305
- "u_units_to_pixels": new Uniform2f(context, locations.u_units_to_pixels),
16306
16670
  "u_scale": new Uniform3f(context, locations.u_scale),
16307
16671
  "u_fade": new Uniform1f(context, locations.u_fade)
16308
16672
  });
16309
16673
  const lineSDFUniforms = (context, locations) => ({
16310
16674
  "u_translation": new Uniform2f(context, locations.u_translation),
16311
16675
  "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
16676
  "u_image": new Uniform1i(context, locations.u_image),
16315
16677
  "u_mix": new Uniform1f(context, locations.u_mix),
16316
16678
  "u_tileratio": new Uniform1f(context, locations.u_tileratio),
@@ -16322,8 +16684,6 @@ const lineSDFUniforms = (context, locations) => ({
16322
16684
  const lineGradientSDFUniforms = (context, locations) => ({
16323
16685
  "u_translation": new Uniform2f(context, locations.u_translation),
16324
16686
  "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
16687
  "u_image": new Uniform1i(context, locations.u_image),
16328
16688
  "u_image_height": new Uniform1f(context, locations.u_image_height),
16329
16689
  "u_tileratio": new Uniform1f(context, locations.u_tileratio),
@@ -16338,9 +16698,7 @@ const lineUniformValues = (painter, tile, layer, ratioScale) => {
16338
16698
  const transform = painter.transform;
16339
16699
  return {
16340
16700
  "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]]
16701
+ "u_ratio": ratioScale / pixelsToTileUnits(tile, 1, transform.zoom)
16344
16702
  };
16345
16703
  };
16346
16704
  const lineGradientUniformValues = (painter, tile, layer, ratioScale, imageHeight) => {
@@ -16356,15 +16714,13 @@ const linePatternUniformValues = (painter, tile, layer, ratioScale, crossfade) =
16356
16714
  "u_translation": calculateTranslation(painter, tile, layer),
16357
16715
  "u_texsize": tile.imageAtlasTexture.size,
16358
16716
  "u_ratio": ratioScale / pixelsToTileUnits(tile, 1, transform.zoom),
16359
- "u_device_pixel_ratio": painter.pixelRatio,
16360
16717
  "u_image": 0,
16361
16718
  "u_scale": [
16362
16719
  tileZoomRatio,
16363
16720
  crossfade.fromScale,
16364
16721
  crossfade.toScale
16365
16722
  ],
16366
- "u_fade": crossfade.t,
16367
- "u_units_to_pixels": [1 / transform.pixelsToGLUnits[0], 1 / transform.pixelsToGLUnits[1]]
16723
+ "u_fade": crossfade.t
16368
16724
  };
16369
16725
  };
16370
16726
  const lineSDFUniformValues = (painter, tile, layer, ratioScale, crossfade) => {
@@ -16418,11 +16774,7 @@ const symbolIconUniforms = (context, locations) => ({
16418
16774
  "u_is_size_feature_constant": new Uniform1i(context, locations.u_is_size_feature_constant),
16419
16775
  "u_size_t": new Uniform1f(context, locations.u_size_t),
16420
16776
  "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
16777
  "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
16778
  "u_label_plane_matrix": new UniformMatrix4f(context, locations.u_label_plane_matrix),
16427
16779
  "u_coord_matrix": new UniformMatrix4f(context, locations.u_coord_matrix),
16428
16780
  "u_is_text": new Uniform1i(context, locations.u_is_text),
@@ -16441,11 +16793,7 @@ const symbolSDFUniforms = (context, locations) => ({
16441
16793
  "u_is_size_feature_constant": new Uniform1i(context, locations.u_is_size_feature_constant),
16442
16794
  "u_size_t": new Uniform1f(context, locations.u_size_t),
16443
16795
  "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
16796
  "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
16797
  "u_label_plane_matrix": new UniformMatrix4f(context, locations.u_label_plane_matrix),
16450
16798
  "u_coord_matrix": new UniformMatrix4f(context, locations.u_coord_matrix),
16451
16799
  "u_is_text": new Uniform1i(context, locations.u_is_text),
@@ -16455,7 +16803,6 @@ const symbolSDFUniforms = (context, locations) => ({
16455
16803
  "u_texsize": new Uniform2f(context, locations.u_texsize),
16456
16804
  "u_texture": new Uniform1i(context, locations.u_texture),
16457
16805
  "u_gamma_scale": new Uniform1f(context, locations.u_gamma_scale),
16458
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16459
16806
  "u_is_halo": new Uniform1i(context, locations.u_is_halo),
16460
16807
  "u_is_plain": new Uniform1i(context, locations.u_is_plain),
16461
16808
  "u_translation": new Uniform2f(context, locations.u_translation),
@@ -16468,11 +16815,7 @@ const symbolTextAndIconUniforms = (context, locations) => ({
16468
16815
  "u_is_size_feature_constant": new Uniform1i(context, locations.u_is_size_feature_constant),
16469
16816
  "u_size_t": new Uniform1f(context, locations.u_size_t),
16470
16817
  "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
16818
  "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
16819
  "u_label_plane_matrix": new UniformMatrix4f(context, locations.u_label_plane_matrix),
16477
16820
  "u_coord_matrix": new UniformMatrix4f(context, locations.u_coord_matrix),
16478
16821
  "u_is_text": new Uniform1i(context, locations.u_is_text),
@@ -16484,7 +16827,6 @@ const symbolTextAndIconUniforms = (context, locations) => ({
16484
16827
  "u_texture": new Uniform1i(context, locations.u_texture),
16485
16828
  "u_texture_icon": new Uniform1i(context, locations.u_texture_icon),
16486
16829
  "u_gamma_scale": new Uniform1f(context, locations.u_gamma_scale),
16487
- "u_device_pixel_ratio": new Uniform1f(context, locations.u_device_pixel_ratio),
16488
16830
  "u_is_halo": new Uniform1i(context, locations.u_is_halo),
16489
16831
  "u_translation": new Uniform2f(context, locations.u_translation),
16490
16832
  "u_pitched_scale": new Uniform1f(context, locations.u_pitched_scale),
@@ -16492,17 +16834,12 @@ const symbolTextAndIconUniforms = (context, locations) => ({
16492
16834
  "u_height_anchor_ground": new Uniform1i(context, locations.u_height_anchor_ground)
16493
16835
  });
16494
16836
  const symbolIconUniformValues = (functionType, size, rotateInShader, pitchWithMap, isAlongLine, isVariableAnchor, painter, labelPlaneMatrix, glCoordMatrix, translation, isText, texSize, pitchedScale, isOffset, heightAnchorGround) => {
16495
- const transform = painter.transform;
16496
16837
  return {
16497
16838
  "u_is_size_zoom_constant": +(functionType === "constant" || functionType === "source"),
16498
16839
  "u_is_size_feature_constant": +(functionType === "constant" || functionType === "camera"),
16499
16840
  "u_size_t": size ? size.uSizeT : 0,
16500
16841
  "u_size": size ? size.uSize : 0,
16501
- "u_camera_to_center_distance": transform.cameraToCenterDistance,
16502
- "u_pitch": transform.pitch / 360 * 2 * Math.PI,
16503
16842
  "u_rotate_symbol": +rotateInShader,
16504
- "u_aspect_ratio": transform.width / transform.height,
16505
- "u_fade_change": painter.options.fadeDuration ? painter.symbolFadeChange : 1,
16506
16843
  "u_label_plane_matrix": labelPlaneMatrix,
16507
16844
  "u_coord_matrix": glCoordMatrix,
16508
16845
  "u_is_text": +isText,
@@ -16521,7 +16858,6 @@ const symbolSDFUniformValues = (functionType, size, rotateInShader, pitchWithMap
16521
16858
  const transform = painter.transform;
16522
16859
  return extend(symbolIconUniformValues(functionType, size, rotateInShader, pitchWithMap, isAlongLine, isVariableAnchor, painter, labelPlaneMatrix, glCoordMatrix, translation, isText, texSize, pitchedScale, isOffset, heightAnchorGround), {
16523
16860
  "u_gamma_scale": pitchWithMap ? Math.cos(transform.pitch * Math.PI / 180) * transform.cameraToCenterDistance : 1,
16524
- "u_device_pixel_ratio": painter.pixelRatio,
16525
16861
  "u_is_halo": isHalo ? 1 : 0,
16526
16862
  "u_is_plain": 1
16527
16863
  });
@@ -16584,7 +16920,10 @@ const skyUniforms = (context, locations) => ({
16584
16920
  "u_horizon": new Uniform2f(context, locations.u_horizon),
16585
16921
  "u_horizon_normal": new Uniform2f(context, locations.u_horizon_normal),
16586
16922
  "u_sky_horizon_blend": new Uniform1f(context, locations.u_sky_horizon_blend),
16587
- "u_sky_blend": new Uniform1f(context, locations.u_sky_blend)
16923
+ "u_sky_blend": new Uniform1f(context, locations.u_sky_blend),
16924
+ "u_inv_proj_matrix": new UniformMatrix4f(context, locations.u_inv_proj_matrix),
16925
+ "u_globe_position": new Uniform3f(context, locations.u_globe_position),
16926
+ "u_globe_radius": new Uniform1f(context, locations.u_globe_radius)
16588
16927
  });
16589
16928
  const skyUniformValues = (sky, transform, pixelRatio) => {
16590
16929
  const cosRoll = Math.cos(transform.rollInRadians);
@@ -16601,12 +16940,15 @@ const skyUniformValues = (sky, transform, pixelRatio) => {
16601
16940
  "u_horizon": [(transform.width / 2 - mercatorHorizon * sinRoll) * pixelRatio, (transform.height / 2 + mercatorHorizon * cosRoll) * pixelRatio],
16602
16941
  "u_horizon_normal": [-sinRoll, cosRoll],
16603
16942
  "u_sky_horizon_blend": sky.properties.get("sky-horizon-blend") * transform.height / 2 * pixelRatio,
16604
- "u_sky_blend": skyBlend
16943
+ "u_sky_blend": skyBlend,
16944
+ "u_inv_proj_matrix": transform.inverseProjectionMatrix,
16945
+ "u_globe_position": getGlobeCenterInViewSpace(transform),
16946
+ "u_globe_radius": getGlobeRadiusPixels(transform.worldSize, transform.center.lat)
16605
16947
  };
16606
16948
  };
16607
16949
  //#endregion
16608
16950
  //#region src/webgl/program/program_uniforms.ts
16609
- const emptyUniforms = (_, __) => {};
16951
+ const emptyUniforms = (_, __) => ({});
16610
16952
  const programUniforms = {
16611
16953
  fillExtrusion: fillExtrusionUniforms,
16612
16954
  fillExtrusionPattern: fillExtrusionPatternUniforms,
@@ -16615,8 +16957,8 @@ const programUniforms = {
16615
16957
  fillOutline: fillOutlineUniforms,
16616
16958
  fillOutlinePattern: fillOutlinePatternUniforms,
16617
16959
  circle: circleUniforms,
16618
- collisionBox: collisionUniforms,
16619
- collisionCircle: collisionCircleUniforms,
16960
+ collisionBox: emptyUniforms,
16961
+ collisionCircle: emptyUniforms,
16620
16962
  debug: debugUniforms,
16621
16963
  depth: emptyUniforms,
16622
16964
  clippingMask: emptyUniforms,
@@ -17231,6 +17573,73 @@ var Framebuffer = class {
17231
17573
  }
17232
17574
  };
17233
17575
  //#endregion
17576
+ //#region src/webgl/frame_uniform_buffer.ts
17577
+ const layout = std140Layout([
17578
+ {
17579
+ name: "u_units_to_pixels",
17580
+ type: "vec2"
17581
+ },
17582
+ {
17583
+ name: "u_world_size",
17584
+ type: "vec2"
17585
+ },
17586
+ {
17587
+ name: "u_camera_to_center_distance",
17588
+ type: "float"
17589
+ },
17590
+ {
17591
+ name: "u_symbol_fade_change",
17592
+ type: "float"
17593
+ },
17594
+ {
17595
+ name: "u_aspect_ratio",
17596
+ type: "float"
17597
+ },
17598
+ {
17599
+ name: "u_device_pixel_ratio",
17600
+ type: "float"
17601
+ },
17602
+ {
17603
+ name: "u_viewport_size",
17604
+ type: "vec2"
17605
+ },
17606
+ {
17607
+ name: "u_pixel_extrude_scale",
17608
+ type: "vec2"
17609
+ },
17610
+ {
17611
+ name: "u_pitch",
17612
+ type: "float"
17613
+ }
17614
+ ]);
17615
+ const offsets = layout.offsets;
17616
+ /**
17617
+ * @internal
17618
+ * The buffer behind the `FrameUBO` block in the shader preludes, written once per frame by `Painter.render`.
17619
+ */
17620
+ function createFrameUniformBuffer(context) {
17621
+ return new UniformBuffer(context, UBO_BINDINGS.FrameUBO, layout);
17622
+ }
17623
+ function updateFrameUniformBuffer(buffer, painter) {
17624
+ const f32 = buffer.pending;
17625
+ const { transform } = painter;
17626
+ const gl = painter.context.gl;
17627
+ f32[offsets.u_units_to_pixels] = 1 / transform.pixelsToGLUnits[0];
17628
+ f32[offsets.u_units_to_pixels + 1] = 1 / transform.pixelsToGLUnits[1];
17629
+ f32[offsets.u_world_size] = gl.drawingBufferWidth;
17630
+ f32[offsets.u_world_size + 1] = gl.drawingBufferHeight;
17631
+ f32[offsets.u_camera_to_center_distance] = transform.cameraToCenterDistance;
17632
+ f32[offsets.u_symbol_fade_change] = painter.options.fadeDuration ? painter.symbolFadeChange : 1;
17633
+ f32[offsets.u_aspect_ratio] = transform.width / transform.height;
17634
+ f32[offsets.u_device_pixel_ratio] = painter.pixelRatio;
17635
+ f32[offsets.u_viewport_size] = transform.width;
17636
+ f32[offsets.u_viewport_size + 1] = transform.height;
17637
+ f32[offsets.u_pixel_extrude_scale] = 1 / transform.width;
17638
+ f32[offsets.u_pixel_extrude_scale + 1] = 1 / transform.height;
17639
+ f32[offsets.u_pitch] = transform.pitch / 360 * 2 * Math.PI;
17640
+ buffer.upload();
17641
+ }
17642
+ //#endregion
17234
17643
  //#region src/webgl/color_mode.ts
17235
17644
  const ZERO = 0;
17236
17645
  const ONE = 1;
@@ -17306,6 +17715,9 @@ var Context = class {
17306
17715
  this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
17307
17716
  gl.getExtension("EXT_color_buffer_half_float");
17308
17717
  gl.getExtension("EXT_color_buffer_float");
17718
+ this.projectionUniformBuffer = createProjectionUniformBuffer(this);
17719
+ this.terrainUniformBuffer = createTerrainUniformBuffer(this);
17720
+ this.frameUniformBuffer = createFrameUniformBuffer(this);
17309
17721
  }
17310
17722
  setDefault() {
17311
17723
  this.unbindVAO();
@@ -17367,6 +17779,9 @@ var Context = class {
17367
17779
  this.pixelStoreUnpack.dirty = true;
17368
17780
  this.pixelStoreUnpackPremultiplyAlpha.dirty = true;
17369
17781
  this.pixelStoreUnpackFlipY.dirty = true;
17782
+ this.projectionUniformBuffer.bindingDirty = true;
17783
+ this.terrainUniformBuffer.bindingDirty = true;
17784
+ this.frameUniformBuffer.bindingDirty = true;
17370
17785
  }
17371
17786
  /**
17372
17787
  * Reset some GL state to default values before handing users the raw context, as we do for
@@ -17554,7 +17969,7 @@ function drawCollisionDebug(painter, tileManager, layer, coords, isText) {
17554
17969
  circleOffset = circleCount;
17555
17970
  }
17556
17971
  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({
17972
+ program.draw(context, gl.LINES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, null, painter.style.map.terrain?.getTerrainData(coord), transform.getProjectionData({
17558
17973
  overscaledTileID: coord,
17559
17974
  applyGlobeMatrix: true,
17560
17975
  applyTerrainMatrix: true
@@ -17580,10 +17995,7 @@ function drawCollisionDebug(painter, tileManager, layer, coords, isText) {
17580
17995
  if (!quadTriangles || quadTriangles.length < circleCount * 2) quadTriangles = createQuadTriangles(circleCount);
17581
17996
  const indexBuffer = context.createIndexBuffer(quadTriangles, true);
17582
17997
  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
- }
17998
+ 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
17999
  vertexBuffer.destroy();
17588
18000
  indexBuffer.destroy();
17589
18001
  }
@@ -17607,7 +18019,7 @@ function createQuadTriangles(quadCount) {
17607
18019
  //#region src/webgl/draw/draw_symbol.ts
17608
18020
  const identityMat4 = identity(/* @__PURE__ */ new Float32Array(16));
17609
18021
  function drawSymbols(painter, tileManager, layer, coords, variableOffsets, renderOptions) {
17610
- if (painter.renderPass !== "translucent") return;
18022
+ if (renderOptions.currentPass !== "translucent") return;
17611
18023
  const { isRenderingToTexture } = renderOptions;
17612
18024
  const stencilMode = StencilMode.disabled;
17613
18025
  const colorMode = painter.colorModeForRenderPass();
@@ -17863,7 +18275,7 @@ function drawSymbolElements(buffers, segments, layer, painter, program, depthMod
17863
18275
  //#endregion
17864
18276
  //#region src/webgl/draw/draw_circle.ts
17865
18277
  function drawCircles(painter, tileManager, layer, coords, renderOptions) {
17866
- if (painter.renderPass !== "translucent") return;
18278
+ if (renderOptions.currentPass !== "translucent") return;
17867
18279
  const { isRenderingToTexture } = renderOptions;
17868
18280
  const opacity = layer.paint.get("circle-opacity");
17869
18281
  const strokeWidth = layer.paint.get("circle-stroke-width");
@@ -17933,8 +18345,8 @@ function drawHeatmap(painter, tileManager, layer, tileIDs, renderOptions) {
17933
18345
  for (const coord of tileIDs) {
17934
18346
  const tile = tileManager.getTile(coord);
17935
18347
  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);
18348
+ if (renderOptions.currentPass === "offscreen") prepareHeatmapTerrain(painter, tile, layer, coord, isRenderingGlobe);
18349
+ else if (renderOptions.currentPass === "translucent") renderHeatmapTerrain(painter, layer, coord, isRenderingToTexture, isRenderingGlobe);
17938
18350
  }
17939
18351
  context.viewport.set([
17940
18352
  0,
@@ -17942,8 +18354,8 @@ function drawHeatmap(painter, tileManager, layer, tileIDs, renderOptions) {
17942
18354
  painter.width,
17943
18355
  painter.height
17944
18356
  ]);
17945
- } else if (painter.renderPass === "offscreen") prepareHeatmapFlat(painter, tileManager, layer, tileIDs);
17946
- else if (painter.renderPass === "translucent") renderHeatmapFlat(painter, layer);
18357
+ } else if (renderOptions.currentPass === "offscreen") prepareHeatmapFlat(painter, tileManager, layer, tileIDs);
18358
+ else if (renderOptions.currentPass === "translucent") renderHeatmapFlat(painter, layer);
17947
18359
  }
17948
18360
  function prepareHeatmapFlat(painter, tileManager, layer, coords) {
17949
18361
  const context = painter.context;
@@ -18209,7 +18621,7 @@ function bindGradientAndDashTextures(painter, tileManager, context, gl, layer, b
18209
18621
  programConfiguration.updatePaintBuffers(crossfade);
18210
18622
  }
18211
18623
  function drawLine(painter, tileManager, layer, coords, renderOptions) {
18212
- if (painter.renderPass !== "translucent") return;
18624
+ if (renderOptions.currentPass !== "translucent") return;
18213
18625
  const opacity = layer.paint.get("line-opacity");
18214
18626
  const width = layer.paint.get("line-width");
18215
18627
  const layerOpacity = layer.paint.get("line-layer-opacity");
@@ -18328,7 +18740,7 @@ function drawFill(painter, tileManager, layer, coords, renderOptions) {
18328
18740
  const layerOpacity = layer.paint.get("fill-layer-opacity");
18329
18741
  if (opacity.constantOr(1) === 0 || layerOpacity === 0) return;
18330
18742
  if (layerOpacity < 1) {
18331
- if (painter.renderPass !== "translucent") return;
18743
+ if (renderOptions.currentPass !== "translucent") return;
18332
18744
  const results = prepareDrawLayerOpacity(painter, layer, coords, !!painter.style.map.terrain);
18333
18745
  drawFillAndOutline(painter, tileManager, layer, coords, renderOptions);
18334
18746
  drawLayerOpacity(painter, layerOpacity, results, layer);
@@ -18336,17 +18748,17 @@ function drawFill(painter, tileManager, layer, coords, renderOptions) {
18336
18748
  }
18337
18749
  const pattern = layer.paint.get("fill-pattern");
18338
18750
  const fillEligibleForOpaque = painter.opaquePassEnabledForLayer() && !pattern.constantOr(1) && color.constantOr(Color.transparent).a === 1 && opacity.constantOr(0) === 1;
18339
- if (fillEligibleForOpaque && painter.renderPass === "opaque") {
18751
+ if (fillEligibleForOpaque && renderOptions.currentPass === "opaque") {
18340
18752
  const { isRenderingToTexture } = renderOptions;
18341
18753
  const colorMode = painter.colorModeForRenderPass();
18342
18754
  drawFillTiles(painter, tileManager, layer, coords, painter.getDepthModeForSublayer(1, DepthMode.ReadWrite), colorMode, false, isRenderingToTexture);
18343
18755
  return;
18344
18756
  }
18345
- if (fillEligibleForOpaque && painter.renderPass === "translucent") {
18757
+ if (fillEligibleForOpaque && renderOptions.currentPass === "translucent") {
18346
18758
  drawOutline(painter, tileManager, layer, coords, renderOptions);
18347
18759
  return;
18348
18760
  }
18349
- if (painter.renderPass === "translucent") drawFillAndOutline(painter, tileManager, layer, coords, renderOptions);
18761
+ if (renderOptions.currentPass === "translucent") drawFillAndOutline(painter, tileManager, layer, coords, renderOptions);
18350
18762
  }
18351
18763
  /**
18352
18764
  * Draw fill + outline in a single translucent pass with ReadOnly depth.
@@ -18388,6 +18800,7 @@ function drawFillTiles(painter, tileManager, layer, coords, depthMode, colorMode
18388
18800
  if (image && !tile.patternsLoaded()) continue;
18389
18801
  const bucket = tile.getBucket(layer);
18390
18802
  if (!bucket) continue;
18803
+ const isSdfPattern = bucket.sdfPatterns[layer.id] ?? false;
18391
18804
  const programConfiguration = bucket.programConfigurations.get(layer.id);
18392
18805
  const program = painter.useProgram(programName, programConfiguration);
18393
18806
  const terrainData = painter.getTerrainDataForTile(coord, isRenderingToTexture);
@@ -18406,12 +18819,11 @@ function drawFillTiles(painter, tileManager, layer, coords, depthMode, colorMode
18406
18819
  if (!isOutline) {
18407
18820
  indexBuffer = bucket.indexBuffer;
18408
18821
  segments = bucket.segments;
18409
- uniformValues = image ? fillPatternUniformValues(painter, crossfade, tile, translateForUniforms) : fillUniformValues(translateForUniforms);
18822
+ uniformValues = image ? fillPatternUniformValues(painter, crossfade, tile, translateForUniforms, isSdfPattern) : fillUniformValues(translateForUniforms);
18410
18823
  } else {
18411
18824
  indexBuffer = bucket.indexBuffer2;
18412
18825
  segments = bucket.segments2;
18413
- const drawingBufferSize = [gl.drawingBufferWidth, gl.drawingBufferHeight];
18414
- uniformValues = programName === "fillOutlinePattern" && image ? fillOutlinePatternUniformValues(painter, crossfade, tile, drawingBufferSize, translateForUniforms) : fillOutlineUniformValues(drawingBufferSize, translateForUniforms);
18826
+ uniformValues = programName === "fillOutlinePattern" && image ? fillOutlinePatternUniformValues(painter, crossfade, tile, translateForUniforms, isSdfPattern) : fillOutlineUniformValues(translateForUniforms);
18415
18827
  }
18416
18828
  const stencil = painter.stencilModeForClipping(coord);
18417
18829
  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 +18835,8 @@ function drawFillExtrusion(painter, tileManager, layer, coords, renderOptions) {
18423
18835
  const opacity = layer.paint.get("fill-extrusion-opacity");
18424
18836
  if (opacity === 0) return;
18425
18837
  const { isRenderingToTexture } = renderOptions;
18426
- if (painter.renderPass === "translucent") {
18427
- const depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D);
18838
+ if (renderOptions.currentPass === "translucent") {
18839
+ const depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, renderOptions.depthRangeFor3D);
18428
18840
  if (opacity === 1 && !layer.paint.get("fill-extrusion-pattern").constantOr(1)) {
18429
18841
  const colorMode = painter.colorModeForRenderPass();
18430
18842
  drawExtrusionTiles(painter, tileManager, layer, coords, depthMode, StencilMode.disabled, colorMode, isRenderingToTexture);
@@ -18471,13 +18883,13 @@ function drawExtrusionTiles(painter, tileManager, layer, coords, depthMode, sten
18471
18883
  //#endregion
18472
18884
  //#region src/webgl/draw/draw_hillshade.ts
18473
18885
  function drawHillshade(painter, tileManager, layer, tileIDs, renderOptions) {
18474
- if (painter.renderPass !== "offscreen" && painter.renderPass !== "translucent") return;
18886
+ if (renderOptions.currentPass !== "offscreen" && renderOptions.currentPass !== "translucent") return;
18475
18887
  const { isRenderingToTexture } = renderOptions;
18476
18888
  const context = painter.context;
18477
18889
  const useSubdivision = painter.style.projection.useSubdivision;
18478
18890
  const depthMode = painter.getDepthModeForSublayer(0, DepthMode.ReadOnly);
18479
18891
  const colorMode = painter.colorModeForRenderPass();
18480
- if (painter.renderPass === "offscreen") {
18892
+ if (renderOptions.currentPass === "offscreen") {
18481
18893
  prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, StencilMode.disabled, colorMode);
18482
18894
  context.viewport.set([
18483
18895
  0,
@@ -18485,7 +18897,7 @@ function drawHillshade(painter, tileManager, layer, tileIDs, renderOptions) {
18485
18897
  painter.width,
18486
18898
  painter.height
18487
18899
  ]);
18488
- } else if (painter.renderPass === "translucent") {
18900
+ } else if (renderOptions.currentPass === "translucent") {
18489
18901
  if (useSubdivision) {
18490
18902
  const [stencilBorderless, stencilBorders, coords] = painter.stencilConfigForOverlapTwoPass(tileIDs);
18491
18903
  renderHillshade(painter, tileManager, layer, coords, stencilBorderless, depthMode, colorMode, false, isRenderingToTexture);
@@ -18530,7 +18942,7 @@ function prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, stenc
18530
18942
  const dem = tile.dem;
18531
18943
  if (!dem?.data) continue;
18532
18944
  if (!tile.needsHillshadePrepare) continue;
18533
- const tileSize = dem.dim;
18945
+ const hillshadeTextureSize = dem.dim + 2;
18534
18946
  const textureStride = dem.stride;
18535
18947
  const pixelData = dem.getPixels();
18536
18948
  context.activeTexture.set(gl.TEXTURE1);
@@ -18548,20 +18960,20 @@ function prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, stenc
18548
18960
  let fbo = tile.fbo;
18549
18961
  if (!fbo) {
18550
18962
  const renderTexture = new Texture(context, {
18551
- width: tileSize,
18552
- height: tileSize,
18963
+ width: hillshadeTextureSize,
18964
+ height: hillshadeTextureSize,
18553
18965
  data: null
18554
18966
  }, gl.RGBA);
18555
18967
  renderTexture.bind(textureFilter, gl.CLAMP_TO_EDGE);
18556
- fbo = tile.fbo = context.createFramebuffer(tileSize, tileSize, true, false);
18968
+ fbo = tile.fbo = context.createFramebuffer(hillshadeTextureSize, hillshadeTextureSize, true, false);
18557
18969
  fbo.colorAttachment.set(renderTexture.texture);
18558
18970
  }
18559
18971
  context.bindFramebuffer.set(fbo.framebuffer);
18560
18972
  context.viewport.set([
18561
18973
  0,
18562
18974
  0,
18563
- tileSize,
18564
- tileSize
18975
+ hillshadeTextureSize,
18976
+ hillshadeTextureSize
18565
18977
  ]);
18566
18978
  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
18979
  tile.needsHillshadePrepare = false;
@@ -18570,7 +18982,7 @@ function prepareHillshade(painter, tileManager, tileIDs, layer, depthMode, stenc
18570
18982
  //#endregion
18571
18983
  //#region src/webgl/draw/draw_color_relief.ts
18572
18984
  function drawColorRelief(painter, tileManager, layer, tileIDs, renderOptions) {
18573
- if (painter.renderPass !== "translucent") return;
18985
+ if (renderOptions.currentPass !== "translucent") return;
18574
18986
  if (!tileIDs.length) return;
18575
18987
  const { isRenderingToTexture } = renderOptions;
18576
18988
  const useSubdivision = painter.style.projection.useSubdivision;
@@ -18586,6 +18998,12 @@ function drawColorRelief(painter, tileManager, layer, tileIDs, renderOptions) {
18586
18998
  }
18587
18999
  }
18588
19000
  let textureMaxSize = 0;
19001
+ /**
19002
+ * Draws the color-relief tiles of one pass.
19003
+ *
19004
+ * A loaded raster-DEM tile can carry no DEM at all (e.g. an empty 204 response);
19005
+ * such tiles are skipped before the first-tile setup reads from them.
19006
+ */
18589
19007
  function renderColorRelief(painter, tileManager, layer, coords, stencilModes, depthMode, colorMode, useBorder, isRenderingToTexture) {
18590
19008
  const projection = painter.style.projection;
18591
19009
  const context = painter.context;
@@ -18599,6 +19017,7 @@ function renderColorRelief(painter, tileManager, layer, coords, stencilModes, de
18599
19017
  for (const coord of coords) {
18600
19018
  const tile = tileManager.getTile(coord);
18601
19019
  const dem = tile.dem;
19020
+ if (!dem?.data) continue;
18602
19021
  if (firstTile) {
18603
19022
  textureMaxSize ||= gl.getParameter(gl.MAX_TEXTURE_SIZE);
18604
19023
  const maxLength = textureMaxSize;
@@ -18610,7 +19029,6 @@ function renderColorRelief(painter, tileManager, layer, coords, stencilModes, de
18610
19029
  firstTile = false;
18611
19030
  colorRampSize = elevationTexture.size[0];
18612
19031
  }
18613
- if (!dem?.data) continue;
18614
19032
  const textureStride = dem.stride;
18615
19033
  context.activeTexture.set(gl.TEXTURE0);
18616
19034
  if (!tile.demTexture || tile.needsColorReliefPrepare) {
@@ -18644,7 +19062,7 @@ const cornerCoords = [
18644
19062
  new Point(0, EXTENT)
18645
19063
  ];
18646
19064
  function drawRaster(painter, tileManager, layer, tileIDs, renderOptions) {
18647
- if (painter.renderPass !== "translucent") return;
19065
+ if (renderOptions.currentPass !== "translucent") return;
18648
19066
  if (layer.paint.get("raster-opacity") === 0) return;
18649
19067
  if (!tileIDs.length) return;
18650
19068
  const { isRenderingToTexture } = renderOptions;
@@ -18785,7 +19203,7 @@ function drawBackground(painter, tileManager, layer, coords, renderOptions) {
18785
19203
  const image = layer.paint.get("background-pattern");
18786
19204
  if (painter.isPatternMissing(image)) return;
18787
19205
  const pass = !image && color.a === 1 && opacity === 1 && painter.opaquePassEnabledForLayer() ? "opaque" : "translucent";
18788
- if (painter.renderPass !== pass) return;
19206
+ if (renderOptions.currentPass !== pass) return;
18789
19207
  const stencilMode = StencilMode.disabled;
18790
19208
  const depthMode = painter.getDepthModeForSublayer(0, pass === "opaque" ? DepthMode.ReadWrite : DepthMode.ReadOnly);
18791
19209
  const colorMode = painter.colorModeForRenderPass();
@@ -18942,7 +19360,7 @@ function drawCustom(painter, tileManager, layer, renderOptions) {
18942
19360
  }
18943
19361
  };
18944
19362
  const renderingMode = implementation.renderingMode ? implementation.renderingMode : "2d";
18945
- if (painter.renderPass === "offscreen") {
19363
+ if (renderOptions.currentPass === "offscreen") {
18946
19364
  const prerender = implementation.prerender;
18947
19365
  if (prerender) {
18948
19366
  painter.setCustomLayerDefaults();
@@ -18951,7 +19369,7 @@ function drawCustom(painter, tileManager, layer, renderOptions) {
18951
19369
  context.setDirty();
18952
19370
  painter.setBaseState();
18953
19371
  }
18954
- } else if (painter.renderPass === "translucent") {
19372
+ } else if (renderOptions.currentPass === "translucent") {
18955
19373
  painter.setCustomLayerDefaults();
18956
19374
  context.setColorMode(painter.colorModeForRenderPass());
18957
19375
  context.setStencilMode(StencilMode.disabled);
@@ -19028,7 +19446,7 @@ function drawTerrain(painter, terrain, tiles, renderOptions) {
19028
19446
  const texture = painter.renderToTexture.getTexture(tile);
19029
19447
  const terrainData = terrain.getTerrainData(tile.tileID);
19030
19448
  context.activeTexture.set(gl.TEXTURE0);
19031
- gl.bindTexture(gl.TEXTURE_2D, texture.texture);
19449
+ texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_LINEAR);
19032
19450
  const eleDelta = terrain.getSkirtLength(tr.zoom);
19033
19451
  const fogMatrix = tr.calculateFogMatrix(tile.tileID.toUnwrapped());
19034
19452
  const uniformValues = terrainUniformValues(eleDelta, fogMatrix, painter.style.sky, tr.pitch, isRenderingGlobe);
@@ -19096,25 +19514,8 @@ function drawAtmosphere(painter, sky, light) {
19096
19514
  const atmosphereBlend = sky.properties.get("atmosphere-blend") * projectionData.projectionTransition;
19097
19515
  if (atmosphereBlend === 0) return;
19098
19516
  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);
19517
+ const globePosition = getGlobeCenterInViewSpace(transform);
19518
+ const uniformValues = atmosphereUniformValues(sunPos, atmosphereBlend, globePosition, globeRadius, transform.inverseProjectionMatrix);
19118
19519
  const mesh = getMesh(context, sky);
19119
19520
  program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, ColorMode.alphaBlended, CullFaceMode.disabled, uniformValues, null, null, "atmosphere", mesh.vertexBuffer, mesh.indexBuffer, mesh.segments);
19120
19521
  }
@@ -19139,6 +19540,22 @@ const webglDrawFunctions = {
19139
19540
  terrainDepth: drawDepth
19140
19541
  };
19141
19542
  //#endregion
19543
+ //#region src/render/render_options.ts
19544
+ function createRenderOptions(transform, projection, terrain) {
19545
+ const projectionTransition = projection?.transitionState ?? 0;
19546
+ return {
19547
+ currentPass: "offscreen",
19548
+ currentLayer: 0,
19549
+ opaquePassCutoff: Infinity,
19550
+ depthRangeFor3D: [0, 1],
19551
+ isRenderingToTexture: false,
19552
+ transform,
19553
+ terrain,
19554
+ projectionTransition,
19555
+ isRenderingGlobe: projectionTransition > 0
19556
+ };
19557
+ }
19558
+ //#endregion
19142
19559
  //#region src/render/painter.ts
19143
19560
  /**
19144
19561
  * @internal
@@ -19408,38 +19825,36 @@ var Painter = class Painter {
19408
19825
  true,
19409
19826
  true
19410
19827
  ]);
19411
- } else if (this.renderPass === "opaque") return ColorMode.unblended;
19828
+ } else if (this.renderOptions.currentPass === "opaque") return ColorMode.unblended;
19412
19829
  else return ColorMode.alphaBlended;
19413
19830
  }
19414
19831
  getDepthModeForSublayer(n, mask, func) {
19415
19832
  if (!this.opaquePassEnabledForLayer()) return DepthMode.disabled;
19416
- const depth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon;
19833
+ const depth = 1 - ((1 + this.renderOptions.currentLayer) * this.numSublayers + n) * this.depthEpsilon;
19417
19834
  return new DepthMode(func || this.context.gl.LEQUAL, mask, [depth, depth]);
19418
19835
  }
19419
19836
  getDepthModeFor3D() {
19420
- return new DepthMode(this.context.gl.LEQUAL, DepthMode.ReadWrite, this.depthRangeFor3D);
19837
+ return new DepthMode(this.context.gl.LEQUAL, DepthMode.ReadWrite, this.renderOptions.depthRangeFor3D);
19421
19838
  }
19422
19839
  opaquePassEnabledForLayer() {
19423
- return this.currentLayer < this.opaquePassCutoff;
19840
+ return this.renderOptions.currentLayer < this.renderOptions.opaquePassCutoff;
19424
19841
  }
19425
19842
  render(style, options) {
19426
19843
  this.style = style;
19427
19844
  this.options = options;
19845
+ const renderOptions = this.renderOptions = createRenderOptions(this.transform, style.projection, style.map.terrain ?? null);
19428
19846
  this.lineAtlas = style.lineAtlas;
19429
19847
  this.imageManager = style.imageManager;
19430
19848
  this.patternAtlas = style.patternAtlas;
19431
19849
  this.glyphManager = style.glyphManager;
19432
19850
  this.symbolFadeChange = style.placement.symbolFadeChange(now());
19851
+ updateFrameUniformBuffer(this.context.frameUniformBuffer, this);
19433
19852
  this.imageManager.beginFrame();
19434
19853
  const layerIds = this.style._order;
19435
19854
  const tileManagers = this.style.tileManagers;
19436
19855
  const coordsAscending = {};
19437
19856
  const coordsDescending = {};
19438
19857
  const coordsDescendingSymbol = {};
19439
- const renderOptions = {
19440
- isRenderingToTexture: false,
19441
- isRenderingGlobe: style.projection?.transitionState > 0
19442
- };
19443
19858
  for (const id in tileManagers) {
19444
19859
  const tileManager = tileManagers[id];
19445
19860
  if (tileManager.used) tileManager.prepare(this.context);
@@ -19447,20 +19862,20 @@ var Painter = class Painter {
19447
19862
  coordsDescending[id] = coordsAscending[id].slice().reverse();
19448
19863
  coordsDescendingSymbol[id] = tileManager.getVisibleCoordinates(true).reverse();
19449
19864
  }
19450
- this.opaquePassCutoff = Infinity;
19865
+ renderOptions.opaquePassCutoff = Infinity;
19451
19866
  for (let i = 0; i < layerIds.length; i++) {
19452
19867
  const layerId = layerIds[i];
19453
19868
  if (this.style._layers[layerId].is3D()) {
19454
- this.opaquePassCutoff = i;
19869
+ renderOptions.opaquePassCutoff = i;
19455
19870
  break;
19456
19871
  }
19457
19872
  }
19458
19873
  this.maybeDrawDepth();
19459
19874
  if (this.renderToTexture) {
19460
19875
  this.renderToTexture.prepareForRender(this.style, this.transform.zoom);
19461
- this.opaquePassCutoff = 0;
19876
+ renderOptions.opaquePassCutoff = 0;
19462
19877
  }
19463
- this.renderPass = "offscreen";
19878
+ renderOptions.currentPass = "offscreen";
19464
19879
  for (const layerId of layerIds) {
19465
19880
  const layer = this.style._layers[layerId];
19466
19881
  if (!layer.hasOffscreenPass() || layer.isHidden(this.transform.zoom)) continue;
@@ -19482,21 +19897,23 @@ var Painter = class Painter {
19482
19897
  this.clearStencil();
19483
19898
  if (this.style.sky) this.drawFunctions.sky(this, this.style.sky);
19484
19899
  this._showOverdrawInspector = options.showOverdrawInspector;
19485
- this.depthRangeFor3D = [0, 1 - (style._order.length + 2) * this.numSublayers * this.depthEpsilon];
19900
+ renderOptions.depthRangeFor3D = [0, 1 - (style._order.length + 2) * this.numSublayers * this.depthEpsilon];
19486
19901
  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]];
19902
+ renderOptions.currentPass = "opaque";
19903
+ for (renderOptions.currentLayer = layerIds.length - 1; renderOptions.currentLayer >= 0; renderOptions.currentLayer--) {
19904
+ const layer = this.style._layers[layerIds[renderOptions.currentLayer]];
19905
+ if (layer.isHidden(this.transform.zoom)) continue;
19490
19906
  const tileManager = tileManagers[layer.source];
19491
19907
  const coords = coordsAscending[layer.source];
19492
19908
  this.renderTileClippingMasks(layer, coords, false);
19493
19909
  this.renderLayer(this, tileManager, layer, coords, renderOptions);
19494
19910
  }
19495
19911
  }
19496
- this.renderPass = "translucent";
19912
+ renderOptions.currentPass = "translucent";
19497
19913
  let globeDepthRendered = false;
19498
- for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) {
19499
- const layer = this.style._layers[layerIds[this.currentLayer]];
19914
+ for (renderOptions.currentLayer = 0; renderOptions.currentLayer < layerIds.length; renderOptions.currentLayer++) {
19915
+ const layer = this.style._layers[layerIds[renderOptions.currentLayer]];
19916
+ if (layer.isHidden(this.transform.zoom)) continue;
19500
19917
  const tileManager = tileManagers[layer.source];
19501
19918
  if (this.renderToTexture?.renderLayer(layer, renderOptions)) continue;
19502
19919
  if (!this.opaquePassEnabledForLayer() && !globeDepthRendered) {
@@ -19519,7 +19936,7 @@ var Painter = class Painter {
19519
19936
  * Update the depth framebuffer if the camera has moved or tiles have reloaded.
19520
19937
  */
19521
19938
  maybeDrawDepth() {
19522
- if (!this.style?.map?.terrain) return;
19939
+ if (!this.style?.projection || !this.style.map?.terrain) return;
19523
19940
  const prevMatrix = this.terrainFacilitator.matrix;
19524
19941
  const currMatrix = this.transform.modelViewProjectionMatrix;
19525
19942
  let doUpdate = this.terrainFacilitator.depthDirty;
@@ -19566,9 +19983,16 @@ var Painter = class Painter {
19566
19983
  const obj = this._rttObjectRecyclePool.pop();
19567
19984
  if (obj) {
19568
19985
  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];
19986
+ obj.texture.update({
19987
+ width: size,
19988
+ height: size,
19989
+ data: null
19990
+ }, {
19991
+ premultiply: false,
19992
+ useMipmap: true
19993
+ });
19994
+ obj.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_LINEAR);
19995
+ if (this.context.extTextureFilterAnisotropic) gl.texParameterf(gl.TEXTURE_2D, this.context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, this.context.extTextureFilterAnisotropicMax);
19572
19996
  obj.size = size;
19573
19997
  }
19574
19998
  return obj;
@@ -19577,8 +20001,11 @@ var Painter = class Painter {
19577
20001
  width: size,
19578
20002
  height: size,
19579
20003
  data: null
19580
- }, gl.RGBA);
19581
- texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
20004
+ }, gl.RGBA, {
20005
+ premultiply: false,
20006
+ useMipmap: true
20007
+ });
20008
+ texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_LINEAR);
19582
20009
  if (this.context.extTextureFilterAnisotropic) gl.texParameterf(gl.TEXTURE_2D, this.context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, this.context.extTextureFilterAnisotropicMax);
19583
20010
  return {
19584
20011
  texture,
@@ -19706,6 +20133,9 @@ var Painter = class Painter {
19706
20133
  if (this.tileExtentMesh) this.tileExtentMesh.vertexBuffer?.destroy();
19707
20134
  if (this.tileExtentMesh) this.tileExtentMesh.indexBuffer?.destroy();
19708
20135
  if (this.debugOverlayTexture) this.debugOverlayTexture.destroy();
20136
+ this.context.projectionUniformBuffer.destroy();
20137
+ this.context.terrainUniformBuffer.destroy();
20138
+ this.context.frameUniformBuffer.destroy();
19709
20139
  if (this.cache) {
19710
20140
  for (const key in this.cache) {
19711
20141
  const program = this.cache[key];
@@ -22419,6 +22849,11 @@ var Camera = class extends Evented {
22419
22849
  newTransform.apply(this.transform, true);
22420
22850
  this.transform = newTransform;
22421
22851
  this.cameraHelper = newCameraHelper;
22852
+ if (this._requestedCameraState) {
22853
+ const requestedCameraState = newTransform.clone();
22854
+ requestedCameraState.apply(this._requestedCameraState, true);
22855
+ this._requestedCameraState = requestedCameraState;
22856
+ }
22422
22857
  }
22423
22858
  getCenter() {
22424
22859
  return new LngLat(this.transform.center.lng, this.transform.center.lat);
@@ -22598,7 +23033,7 @@ var Camera = class extends Evented {
22598
23033
  }
22599
23034
  jumpTo(options, eventData) {
22600
23035
  this.stop();
22601
- if ("zoom" in options && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
23036
+ if (options.zoom !== void 0 && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
22602
23037
  const tr = this.getTransformForUpdate();
22603
23038
  let bearingChanged = false, pitchChanged = false;
22604
23039
  let rollChanged = false;
@@ -22606,16 +23041,16 @@ var Camera = class extends Evented {
22606
23041
  if (this.terrain) tr.setElevation(this.terrain.getElevationForLngLat(options.center ? LngLat.convert(options.center) : tr.center, tr));
22607
23042
  this.cameraHelper.handleJumpToCenterZoom(tr, options);
22608
23043
  const zoomChanged = tr.zoom !== oldZoom;
22609
- if ("elevation" in options && tr.elevation !== +options.elevation) tr.setElevation(+options.elevation);
22610
- if ("bearing" in options && tr.bearing !== +options.bearing) {
23044
+ if (options.elevation !== void 0 && tr.elevation !== +options.elevation) tr.setElevation(+options.elevation);
23045
+ if (options.bearing !== void 0 && tr.bearing !== +options.bearing) {
22611
23046
  bearingChanged = true;
22612
23047
  tr.setBearing(+options.bearing);
22613
23048
  }
22614
- if ("pitch" in options && tr.pitch !== +options.pitch) {
23049
+ if (options.pitch !== void 0 && tr.pitch !== +options.pitch) {
22615
23050
  pitchChanged = true;
22616
23051
  tr.setPitch(+options.pitch);
22617
23052
  }
22618
- if ("roll" in options && tr.roll !== +options.roll) {
23053
+ if (options.roll !== void 0 && tr.roll !== +options.roll) {
22619
23054
  rollChanged = true;
22620
23055
  tr.setRoll(+options.roll);
22621
23056
  }
@@ -22628,27 +23063,6 @@ var Camera = class extends Evented {
22628
23063
  if (rollChanged) this.fire(new MapMovementEvent("rollstart", eventData)).fire(new MapMovementEvent("roll", eventData)).fire(new MapMovementEvent("rollend", eventData));
22629
23064
  return this.fire(new MapMovementEvent("moveend", eventData));
22630
23065
  }
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
23066
  calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAlt, bearing, pitch, roll) {
22653
23067
  const centerInfo = this.transform.calculateCenterFromCameraLngLatAlt(cameraLngLat, cameraAlt, bearing, pitch);
22654
23068
  return {
@@ -22667,10 +23081,10 @@ var Camera = class extends Evented {
22667
23081
  duration: 500,
22668
23082
  easing: defaultEasing
22669
23083
  }, options);
22670
- if ("zoom" in options && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
23084
+ if (options.zoom !== void 0 && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
22671
23085
  if (options.animate === false || !options.essential && browser.prefersReducedMotion) options.duration = 0;
22672
23086
  const tr = this.getTransformForUpdate();
22673
- const startBearing = this.getBearing(), startPitch = tr.pitch, startRoll = tr.roll, bearing = "bearing" in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing, pitch = "pitch" in options ? +options.pitch : startPitch, roll = "roll" in options ? this._normalizeBearing(options.roll, startRoll) : startRoll, padding = "padding" in options ? options.padding : tr.padding;
23087
+ const startBearing = this.getBearing(), startPitch = tr.pitch, startRoll = tr.roll, bearing = options.bearing !== void 0 ? this._normalizeBearing(options.bearing, startBearing) : startBearing, pitch = options.pitch !== void 0 ? +options.pitch : startPitch, roll = options.roll !== void 0 ? this._normalizeBearing(options.roll, startRoll) : startRoll, padding = options.padding !== void 0 ? options.padding : tr.padding;
22674
23088
  const offsetAsPoint = Point.convert(options.offset);
22675
23089
  let around, aroundPoint;
22676
23090
  if (options.around) {
@@ -22776,7 +23190,7 @@ var Camera = class extends Evented {
22776
23190
  const cameraAltitude = tr.getCameraAltitude();
22777
23191
  const minAltitude = this.terrain ? this.terrain.getElevationForLngLatZoom(cameraLngLat, tr.zoom) : 0;
22778
23192
  if (cameraAltitude < minAltitude) {
22779
- const newCamera = this.calculateCameraOptionsFromTo(cameraLngLat, minAltitude, tr.center, tr.elevation);
23193
+ const newCamera = tr.calculateCameraOptionsFromTo(cameraLngLat, minAltitude, tr.center, tr.elevation);
22780
23194
  return {
22781
23195
  pitch: newCamera.pitch,
22782
23196
  zoom: newCamera.zoom
@@ -22856,12 +23270,12 @@ var Camera = class extends Evented {
22856
23270
  curve: 1.42,
22857
23271
  easing: defaultEasing
22858
23272
  }, options);
22859
- if ("zoom" in options && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
23273
+ if (options.zoom !== void 0 && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
22860
23274
  const tr = this.getTransformForUpdate(), startBearing = tr.bearing, startPitch = tr.pitch, startRoll = tr.roll, startPadding = tr.padding;
22861
- const bearing = "bearing" in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing;
22862
- const pitch = "pitch" in options ? +options.pitch : startPitch;
22863
- const roll = "roll" in options ? this._normalizeBearing(options.roll, startRoll) : startRoll;
22864
- const padding = "padding" in options ? options.padding : tr.padding;
23275
+ const bearing = options.bearing !== void 0 ? this._normalizeBearing(options.bearing, startBearing) : startBearing;
23276
+ const pitch = options.pitch !== void 0 ? +options.pitch : startPitch;
23277
+ const roll = options.roll !== void 0 ? this._normalizeBearing(options.roll, startRoll) : startRoll;
23278
+ const padding = options.padding !== void 0 ? options.padding : tr.padding;
22865
23279
  const offsetAsPoint = Point.convert(options.offset);
22866
23280
  let pointAtOffset = tr.centerPoint.add(offsetAsPoint);
22867
23281
  const locationAtOffset = tr.screenPointToLocation(pointAtOffset);
@@ -22916,9 +23330,9 @@ var Camera = class extends Evented {
22916
23330
  u = () => 0;
22917
23331
  w = (s) => Math.exp(k * rho * s);
22918
23332
  }
22919
- if ("duration" in options) options.duration = +options.duration;
23333
+ if (options.duration !== void 0) options.duration = +options.duration;
22920
23334
  else {
22921
- const V = "screenSpeed" in options ? +options.screenSpeed / rho : +options.speed;
23335
+ const V = options.screenSpeed !== void 0 ? +options.screenSpeed / rho : +options.speed;
22922
23336
  options.duration = 1e3 * S / V;
22923
23337
  }
22924
23338
  if (options.maxDuration && options.duration > options.maxDuration) options.duration = 0;
@@ -23219,13 +23633,23 @@ var TaskQueue = class {
23219
23633
  if (this._currentlyRunning) throw new Error("Attempting to run(), but is already running.");
23220
23634
  const queue = this._currentlyRunning = this._queue;
23221
23635
  this._queue = [];
23636
+ let failed = false;
23637
+ let firstError;
23222
23638
  for (const task of queue) {
23223
23639
  if (task.cancelled) continue;
23224
- task.callback(timeStamp);
23640
+ try {
23641
+ task.callback(timeStamp);
23642
+ } catch (error) {
23643
+ if (!failed) {
23644
+ failed = true;
23645
+ firstError = error;
23646
+ }
23647
+ }
23225
23648
  if (this._cleared) break;
23226
23649
  }
23227
23650
  this._cleared = false;
23228
23651
  this._currentlyRunning = false;
23652
+ if (failed) throw firstError;
23229
23653
  }
23230
23654
  clear() {
23231
23655
  if (this._currentlyRunning) this._cleared = true;
@@ -23233,6 +23657,48 @@ var TaskQueue = class {
23233
23657
  }
23234
23658
  };
23235
23659
  //#endregion
23660
+ //#region src/webgl/rtt_fingerprint.ts
23661
+ /**
23662
+ * What a render-to-texture tile's textures differ in from the state this frame would render them from,
23663
+ * least to most severe: `zoom` (the same layers and source tiles, evaluated at another zoom), `sourceTiles`
23664
+ * (other source tiles under the terrain tile), `visibleLayers` (a layer entered or left its zoom range) and
23665
+ * `revision` (the source data changed, or the textures were rendered without this source).
23666
+ *
23667
+ * @internal
23668
+ */
23669
+ const RTT_DIFFERENCES = [
23670
+ "none",
23671
+ "zoom",
23672
+ "sourceTiles",
23673
+ "visibleLayers",
23674
+ "revision"
23675
+ ];
23676
+ /**
23677
+ * Immutable value describing the state a render-to-texture tile's textures were rendered from: the source
23678
+ * tiles drawn into them, the source data revision, the map zoom (zoom-dependent style properties are
23679
+ * evaluated then) and the ids of the layers visible at that zoom.
23680
+ *
23681
+ * @internal
23682
+ */
23683
+ var RTTFingerprint = class {
23684
+ constructor(coords, revision, zoom, visibleLayerIds) {
23685
+ this._tileKeys = coords.map((c) => c.key).sort().join();
23686
+ this._revision = revision;
23687
+ this._zoom = zoom;
23688
+ this._visibleLayerIds = visibleLayerIds;
23689
+ }
23690
+ /**
23691
+ * The most severe difference between this fingerprint and the one the textures were rendered from,
23692
+ * `none` when they match. A missing fingerprint counts as a revision difference.
23693
+ */
23694
+ difference(other) {
23695
+ if (this._revision !== other?._revision) return "revision";
23696
+ if (this._visibleLayerIds !== other._visibleLayerIds) return "visibleLayers";
23697
+ if (this._tileKeys !== other._tileKeys) return "sourceTiles";
23698
+ return this._zoom === other._zoom ? "none" : "zoom";
23699
+ }
23700
+ };
23701
+ //#endregion
23236
23702
  //#region src/webgl/render_to_texture.ts
23237
23703
  /**
23238
23704
  * lookup table which layers should rendered to texture
@@ -23254,6 +23720,7 @@ const LAYERS_TO_TEXTURES = {
23254
23720
  */
23255
23721
  var RenderToTexture = class {
23256
23722
  constructor(painter, terrain) {
23723
+ this.needsFollowUpFrame = false;
23257
23724
  this.painter = painter;
23258
23725
  this.terrain = terrain;
23259
23726
  this.rttSize = terrain.tileManager.tileSize * terrain.qualityFactor;
@@ -23261,12 +23728,24 @@ var RenderToTexture = class {
23261
23728
  getTexture(tile) {
23262
23729
  return tile.getRTT(this._stacks.length - 1).texture;
23263
23730
  }
23731
+ /**
23732
+ * Collects the frame's tiles, layers and source fingerprints and releases the textures that need
23733
+ * re-rendering. Textures that differ only by zoom are kept while the zoom is changing or the map is moving
23734
+ * and re-rendered one tile per frame once it has stopped, nearest to the camera first; textures with other
23735
+ * source tiles under them are re-rendered one per frame too, `needsFollowUpFrame` bringing in the rest.
23736
+ * Textures whose visible layer set changed (a layer entered or left its zoom range) are kept while the zoom
23737
+ * is changing and then all re-rendered in the same frame, since a tile-by-tile change would show; a source
23738
+ * data change re-renders immediately.
23739
+ */
23264
23740
  prepareForRender(style, zoom) {
23741
+ const zoomChanged = zoom !== this._lastPrepareZoom;
23742
+ this._lastPrepareZoom = zoom;
23265
23743
  this._stacks = [];
23266
23744
  this._prevType = null;
23267
23745
  this._rttTiles = [];
23268
23746
  this._renderableTiles = this.terrain.tileManager.getRenderableTiles();
23269
23747
  this._renderableLayerIds = style._order.filter((id) => !style._layers[id].isHidden(zoom));
23748
+ const visibleLayerIds = this._renderableLayerIds.join();
23270
23749
  const rttSourceIds = /* @__PURE__ */ new Set();
23271
23750
  for (const layerId of this._renderableLayerIds) {
23272
23751
  const layer = style._layers[layerId];
@@ -23292,12 +23771,35 @@ var RenderToTexture = class {
23292
23771
  this._rttFingerprints[sourceId] = {};
23293
23772
  const fingerprints = this._rttFingerprints[sourceId];
23294
23773
  const revision = tileManager.getState().revision;
23295
- for (const key in coordsAscending) fingerprints[key] = `${coordsAscending[key].map((c) => c.key).sort().join()}#${revision}`;
23774
+ for (const key in coordsAscending) fingerprints[key] = new RTTFingerprint(coordsAscending[key], revision, zoom, visibleLayerIds);
23296
23775
  }
23297
- 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);
23776
+ this.needsFollowUpFrame = false;
23777
+ const moving = zoomChanged || this.painter.options.moving;
23778
+ let staleTileReleased = false;
23779
+ for (const tile of this._renderableTiles) {
23780
+ const difference = this._textureDifference(tile);
23781
+ if (difference === "none") continue;
23782
+ if (difference === "zoom" && moving || difference === "visibleLayers" && zoomChanged) this.needsFollowUpFrame = true;
23783
+ else if (difference === "zoom" || difference === "sourceTiles") {
23784
+ if (staleTileReleased) this.needsFollowUpFrame = true;
23785
+ else tile.releaseRTT(this.painter);
23786
+ staleTileReleased = true;
23787
+ } else tile.releaseRTT(this.painter);
23788
+ }
23789
+ }
23790
+ /**
23791
+ * The most severe difference, over the sources rendered to texture, between the tile's cached textures
23792
+ * and what this frame would render into them.
23793
+ */
23794
+ _textureDifference(tile) {
23795
+ let worst = "none";
23796
+ for (const source in this._rttFingerprints) {
23797
+ const frameFingerprint = this._rttFingerprints[source][tile.tileID.key];
23798
+ if (!frameFingerprint) continue;
23799
+ const difference = frameFingerprint.difference(tile.rttFingerprint[source]);
23800
+ if (RTT_DIFFERENCES.indexOf(difference) > RTT_DIFFERENCES.indexOf(worst)) worst = difference;
23300
23801
  }
23802
+ return worst;
23301
23803
  }
23302
23804
  /**
23303
23805
  * due that switching textures is relatively slow, the render
@@ -23351,6 +23853,7 @@ var RenderToTexture = class {
23351
23853
  painter.renderLayer(painter, painter.style.tileManagers[layer.source], layer, coords, options);
23352
23854
  if (layer.source) tile.rttFingerprint[layer.source] = this._rttFingerprints[layer.source][tile.tileID.key];
23353
23855
  }
23856
+ obj.texture.generateMipmap();
23354
23857
  }
23355
23858
  drawTerrain(this.painter, this.terrain, this._rttTiles, options);
23356
23859
  this._rttTiles = [];
@@ -23504,6 +24007,7 @@ var Map$1 = class extends Evented {
23504
24007
  this._renderTaskQueue = new TaskQueue();
23505
24008
  this._controls = [];
23506
24009
  this._mapId = uniqueId();
24010
+ this._styleUrl = null;
23507
24011
  this._missingStyleImageResolver = null;
23508
24012
  this._lostContextStyle = {
23509
24013
  style: null,
@@ -24396,6 +24900,7 @@ var Map$1 = class extends Evented {
24396
24900
  }
24397
24901
  /**
24398
24902
  * Given a camera 'from' position and a position to look at (`to`), calculates zoom and camera rotation and returns them as {@link CameraOptions}.
24903
+ * 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
24904
  * @param from - The camera to look from
24400
24905
  * @param altitudeFrom - The altitude of the camera to look from
24401
24906
  * @param to - The center to look at
@@ -24415,15 +24920,17 @@ var Map$1 = class extends Evented {
24415
24920
  */
24416
24921
  calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
24417
24922
  if (altitudeTo == null && this.terrain) altitudeTo = this.terrain.getElevationForLngLat(to, this._camera.transform);
24418
- return this._camera.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo);
24923
+ return this._camera.transform.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo ?? 0);
24419
24924
  }
24420
24925
  /**
24421
24926
  * Resizes the map according to the dimensions of its
24422
24927
  * `container` element.
24423
24928
  *
24424
24929
  * Checks if the map container size changed and updates the map if it has changed.
24425
- * This method must be called after the map's `container` is resized programmatically
24426
- * or when the map is shown after being initially hidden with CSS.
24930
+ * With the default `trackResize: true`, container size changes are picked up automatically,
24931
+ * including a container that becomes visible after being hidden with CSS. Call this method
24932
+ * explicitly when `trackResize` is `false`, or when the map's size changes in a way the
24933
+ * container's `ResizeObserver` cannot observe.
24427
24934
  *
24428
24935
  * Triggers the following events: `movestart`, `move`, `moveend`, and `resize`.
24429
24936
  *
@@ -24431,10 +24938,10 @@ var Map$1 = class extends Evented {
24431
24938
  * events that get triggered as a result of resize. This can be useful for differentiating the
24432
24939
  * source of an event (for example, user-initiated or programmatically-triggered events).
24433
24940
  * @example
24434
- * Resize the map when the map container is shown after being initially hidden with CSS.
24941
+ * Resize a map with `trackResize` disabled when its container is shown after being hidden with CSS.
24435
24942
  * ```ts
24436
24943
  * let mapDiv = document.getElementById('map');
24437
- * if (mapDiv.style.visibility === true) map.resize();
24944
+ * if (mapDiv.style.visibility === 'visible') map.resize();
24438
24945
  * ```
24439
24946
  */
24440
24947
  resize(eventData, constrainTransform = true) {
@@ -24484,6 +24991,8 @@ var Map$1 = class extends Evented {
24484
24991
  * @internal
24485
24992
  * Return the map's pixel ratio eventually scaled down to respect maxCanvasSize.
24486
24993
  * Internally you should use this and not getPixelRatio().
24994
+ * Warns once when the ratio is scaled down. The message carries no sizes: this runs on every
24995
+ * resize and `warnOnce` de-duplicates by message, so sizes would warn on every drag frame.
24487
24996
  */
24488
24997
  _getClampedPixelRatio(width, height) {
24489
24998
  const { 0: maxCanvasWidth, 1: maxCanvasHeight } = this._maxCanvasSize;
@@ -24492,7 +25001,9 @@ var Map$1 = class extends Evented {
24492
25001
  const canvasHeight = height * pixelRatio;
24493
25002
  const widthScaleFactor = canvasWidth > maxCanvasWidth ? maxCanvasWidth / canvasWidth : 1;
24494
25003
  const heightScaleFactor = canvasHeight > maxCanvasHeight ? maxCanvasHeight / canvasHeight : 1;
24495
- return Math.min(widthScaleFactor, heightScaleFactor) * pixelRatio;
25004
+ const scaleFactor = Math.min(widthScaleFactor, heightScaleFactor);
25005
+ 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.");
25006
+ return scaleFactor * pixelRatio;
24496
25007
  }
24497
25008
  /**
24498
25009
  * Returns the map's pixel ratio.
@@ -25164,6 +25675,7 @@ var Map$1 = class extends Evented {
25164
25675
  localIdeographFontFamily: this._localIdeographFontFamily,
25165
25676
  validate: this._validateStyle
25166
25677
  }, options);
25678
+ this._styleUrl = typeof style === "string" ? style : null;
25167
25679
  if (options.diff !== false && options.localIdeographFontFamily === this._localIdeographFontFamily && this.style && style) {
25168
25680
  this._diffStyle(style, options);
25169
25681
  return this;
@@ -25272,6 +25784,19 @@ var Map$1 = class extends Evented {
25272
25784
  if (this.style) return this.style.serialize();
25273
25785
  }
25274
25786
  /**
25787
+ * Returns the URL the map's style was loaded from.
25788
+ *
25789
+ * @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.
25790
+ *
25791
+ * @example
25792
+ * ```ts
25793
+ * const styleUrl = map.getStyleUrl();
25794
+ * ```
25795
+ */
25796
+ getStyleUrl() {
25797
+ return this._styleUrl;
25798
+ }
25799
+ /**
25275
25800
  * @internal
25276
25801
  * Returns the map's style and cloned images to restore context.
25277
25802
  * @returns An object containing the style and images.
@@ -25749,7 +26274,7 @@ var Map$1 = class extends Evented {
25749
26274
  * domains must support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).
25750
26275
  *
25751
26276
  * @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
26277
+ * @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
26278
  *
25754
26279
  * @example
25755
26280
  * Load an image from an external URL.
@@ -25761,7 +26286,9 @@ var Map$1 = class extends Evented {
25761
26286
  * @see [Add an icon to the map](https://maplibre.org/maplibre-gl-js/docs/examples/add-an-icon-to-the-map/)
25762
26287
  */
25763
26288
  async loadImage(url) {
25764
- return ImageRequest.getImage(await this._requestManager.transformRequest(url, "Image"), new AbortController());
26289
+ const response = await ImageRequest.getImage(await this._requestManager.transformRequest(url, "Image"), new AbortController());
26290
+ if (!response.data) throw new Error(`Could not load image ${url}: the response is empty`);
26291
+ return response;
25765
26292
  }
25766
26293
  /**
25767
26294
  * Returns an Array of strings containing the IDs of all images currently available in the map.
@@ -26387,6 +26914,16 @@ var Map$1 = class extends Evented {
26387
26914
  return [width, height];
26388
26915
  }
26389
26916
  /**
26917
+ * Determines if the initial resize event should be handled based on the container's dimensions.
26918
+ *
26919
+ * @returns `true` if the initial resize event should be handled, `false` otherwise.
26920
+ */
26921
+ _shouldHandleInitialResize() {
26922
+ if (!this._container?.clientWidth || !this._container.clientHeight) return false;
26923
+ const [width, height] = this._containerDimensions();
26924
+ return width !== this._camera.transform.width || height !== this._camera.transform.height;
26925
+ }
26926
+ /**
26390
26927
  * @internal
26391
26928
  * Sets up the ResizeObserver to track container size changes.
26392
26929
  * Uses the owning window's ResizeObserver for cross-window support.
@@ -26403,7 +26940,7 @@ var Map$1 = class extends Evented {
26403
26940
  this._resizeObserver = new ResizeObserverClass((entries) => {
26404
26941
  if (!initialResizeEventCaptured) {
26405
26942
  initialResizeEventCaptured = true;
26406
- return;
26943
+ if (!this._shouldHandleInitialResize()) return;
26407
26944
  }
26408
26945
  throttledResizeCallback(entries);
26409
26946
  });
@@ -26606,7 +27143,7 @@ var Map$1 = class extends Evented {
26606
27143
  }
26607
27144
  if (this.style && (this.style.hasTransitions() || crossFading)) this._styleDirty = true;
26608
27145
  if (this.style && !this._placementDirty) this.style._releaseSymbolFadeTiles();
26609
- const somethingDirty = this._sourcesDirty || this._styleDirty || this._placementDirty;
27146
+ const somethingDirty = this._sourcesDirty || this._styleDirty || this._placementDirty || this.painter.renderToTexture?.needsFollowUpFrame;
26610
27147
  if (somethingDirty || this._repaint) this.triggerRepaint();
26611
27148
  else if (!this.isMoving() && this.loaded()) this.fire(new MapLibreEvent("idle"));
26612
27149
  if (this._loaded && !this._fullyLoaded && !somethingDirty) this._fullyLoaded = true;
@@ -27093,6 +27630,87 @@ const ARROW_KEY_DELTAS = {
27093
27630
  };
27094
27631
  const KEYBOARD_DRAG_SMALL_STEP = 1;
27095
27632
  const KEYBOARD_DRAG_LARGE_STEP = 10;
27633
+ /** Fill color of the default marker when {@link MarkerOptions.color} is not given. */
27634
+ const DEFAULT_MARKER_COLOR = "#3FB1CE";
27635
+ /** Height in CSS pixels of the default marker SVG at scale 1. */
27636
+ const DEFAULT_MARKER_HEIGHT = 41;
27637
+ /** Width in CSS pixels of the default marker SVG at scale 1. */
27638
+ const DEFAULT_MARKER_WIDTH = 27;
27639
+ const SVG_NS = "http://www.w3.org/2000/svg";
27640
+ /** Creates an SVG element with the given attributes, set in the order given, and children. */
27641
+ function svgElement(tag, attributes, children = []) {
27642
+ const element = DOM.createNS(SVG_NS, tag);
27643
+ for (const name in attributes) element.setAttributeNS(null, name, attributes[name]);
27644
+ for (const child of children) element.appendChild(child);
27645
+ return element;
27646
+ }
27647
+ /** The default marker SVG at scale 1 in the default color, built on first use and cloned per marker. */
27648
+ let defaultMarkerTemplate;
27649
+ /**
27650
+ * Returns the shared default marker SVG, building it the first time it is asked for. Assembling
27651
+ * the pin takes about fifty DOM calls, so each default {@link Marker} deep-clones this template
27652
+ * and overrides only its size and its fill, see {@link defaultMarkerFillGroup}.
27653
+ */
27654
+ function getDefaultMarkerTemplate() {
27655
+ if (defaultMarkerTemplate) return defaultMarkerTemplate;
27656
+ const shadow = svgElement("g", {
27657
+ transform: "translate(3.0, 29.0)",
27658
+ fill: "#000000"
27659
+ }, [
27660
+ ["10.5", "5.25002273"],
27661
+ ["10.5", "5.25002273"],
27662
+ ["9.5", "4.77275007"],
27663
+ ["8.5", "4.29549936"],
27664
+ ["7.5", "3.81822308"],
27665
+ ["6.5", "3.34094679"],
27666
+ ["5.5", "2.86367051"],
27667
+ ["4.5", "2.38636864"]
27668
+ ].map(([rx, ry]) => svgElement("ellipse", {
27669
+ opacity: "0.04",
27670
+ cx: "10.5",
27671
+ cy: "5.80029008",
27672
+ rx,
27673
+ ry
27674
+ })));
27675
+ 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" })]);
27676
+ const border = svgElement("g", {
27677
+ opacity: "0.25",
27678
+ fill: "#000000"
27679
+ }, [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" })]);
27680
+ const maki = svgElement("g", {
27681
+ transform: "translate(6.0, 7.0)",
27682
+ fill: "#FFFFFF"
27683
+ });
27684
+ const circles = svgElement("g", { transform: "translate(8.0, 8.0)" }, [svgElement("circle", {
27685
+ fill: "#000000",
27686
+ opacity: "0.25",
27687
+ cx: "5.5",
27688
+ cy: "5.5",
27689
+ r: "5.4999962"
27690
+ }), svgElement("circle", {
27691
+ fill: "#FFFFFF",
27692
+ cx: "5.5",
27693
+ cy: "5.5",
27694
+ r: "5.4999962"
27695
+ })]);
27696
+ defaultMarkerTemplate = svgElement("svg", {
27697
+ display: "block",
27698
+ height: `${DEFAULT_MARKER_HEIGHT}px`,
27699
+ width: `${DEFAULT_MARKER_WIDTH}px`,
27700
+ viewBox: `0 0 ${DEFAULT_MARKER_WIDTH} ${DEFAULT_MARKER_HEIGHT}`
27701
+ }, [svgElement("g", { "fill-rule": "nonzero" }, [
27702
+ shadow,
27703
+ background,
27704
+ border,
27705
+ maki,
27706
+ circles
27707
+ ])]);
27708
+ return defaultMarkerTemplate;
27709
+ }
27710
+ /** The group of a default marker SVG that carries the pin's fill color: the second child of its single top-level group. */
27711
+ function defaultMarkerFillGroup(svg) {
27712
+ return svg.firstElementChild.children[1];
27713
+ }
27096
27714
  /**
27097
27715
  * The event class for marker drag events (`dragstart`, `drag` and `dragend`).
27098
27716
  *
@@ -27255,7 +27873,7 @@ var Marker = class extends Evented {
27255
27873
  }
27256
27874
  };
27257
27875
  this._anchor = options?.anchor || "center";
27258
- this._color = options?.color || "#3FB1CE";
27876
+ this._color = options?.color || DEFAULT_MARKER_COLOR;
27259
27877
  this._scale = options?.scale || 1;
27260
27878
  this._draggable = options?.draggable || false;
27261
27879
  this._clickTolerance = options?.clickTolerance || 0;
@@ -27272,102 +27890,10 @@ var Marker = class extends Evented {
27272
27890
  if (!options?.element) {
27273
27891
  this._defaultMarker = true;
27274
27892
  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`);
27893
+ const svg = getDefaultMarkerTemplate().cloneNode(true);
27894
+ svg.setAttributeNS(null, "height", `${DEFAULT_MARKER_HEIGHT * this._scale}px`);
27895
+ svg.setAttributeNS(null, "width", `${DEFAULT_MARKER_WIDTH * this._scale}px`);
27896
+ defaultMarkerFillGroup(svg).setAttributeNS(null, "fill", this._color);
27371
27897
  this._element.appendChild(svg);
27372
27898
  this._offset = Point.convert(options?.offset || [0, -14]);
27373
27899
  } else {
@@ -27484,8 +28010,8 @@ var Marker = class extends Evented {
27484
28010
  setLngLat(lnglat) {
27485
28011
  this._lngLat = LngLat.convert(lnglat);
27486
28012
  this._pos = null;
27487
- if (this._popup) this._popup.setLngLat(this._lngLat);
27488
28013
  this._update();
28014
+ if (this._popup) this._popup.setLngLat(this._lngLat);
27489
28015
  return this;
27490
28016
  }
27491
28017
  /**
@@ -29223,8 +29749,10 @@ function normalizePadding(padding) {
29223
29749
  const version = version$2;
29224
29750
  /**
29225
29751
  * Sets the map's [RTL text plugin](https://www.mapbox.com/mapbox-gl-js/plugins/#mapbox-gl-rtl-text).
29226
- * Necessary for supporting the Arabic and Hebrew languages, which are written right-to-left.
29227
29752
  *
29753
+ * @deprecated MapLibre shapes Arabic and reorders bidirectional text itself, so nothing has to be
29754
+ * loaded for right-to-left languages to be drawn correctly. A plugin set here still replaces the
29755
+ * built-in implementation, but this will be removed in a future release.
29228
29756
  * @param pluginURL - URL pointing to the Mapbox RTL text plugin source.
29229
29757
  * @param lazy - If set to `true`, maplibre will defer loading the plugin until rtl text is encountered,
29230
29758
  * rtl text will then be rendered only after the plugin finishes loading.
@@ -29243,6 +29771,8 @@ function setRTLTextPlugin(pluginURL, lazy) {
29243
29771
  * The status can be `unavailable` (i.e. not requested or removed), `loading`, `loaded` or `error`.
29244
29772
  * If the status is `loaded` and the plugin is requested again, an error will be thrown.
29245
29773
  *
29774
+ * @deprecated The status says nothing about whether right-to-left text can be drawn, which it always
29775
+ * can be. It reports only on a plugin set through the deprecated {@link setRTLTextPlugin}.
29246
29776
  * @example
29247
29777
  * ```ts
29248
29778
  * const pluginStatus = getRTLTextPluginStatus();