Create the layer. No network happens until it is added to a map; loading starts in onAdd.
See Tiles3DMeshLayerOptions. Only id + url are required.
ReadonlyidA unique layer id.
ReadonlyrenderingEither "2d" or "3d". Defaults to "2d".
ReadonlytypeThe layer's type. Must be "custom".
Revert to the default (no-sun) lighting — the clearSun half of SunLightable (used when the
geo-sun system is disabled). Clearing lastSun also gates off the cast-shadow pass.
Representative ellipsoidal elevation (m) of the rendered data — for framing the camera at the data's height WITHOUT terrain (the data is placed absolutely). null when nothing is rendered yet.
The dataset attribution string this layer contributes, if any.
Unique data attributions of the currently-visible tiles (the required dynamic
credits). Empty until tiles with asset.copyright are rendered. RAW service text —
render with textContent, or escape it, if you put it in the DOM yourself.
The dataset's camera target [lng, lat] (degrees) — handy for driving your own flyTo.
[lng, lat] in degrees, or null until the root center is known.
The dataset's geographic footprint as [west, south, east, north] in degrees.
[west, south, east, north] in degrees, or null until the root resolves.
3D Tiles declares no extent the way I3S does, so this is derived from the root bounding volume: the OBB's eight corners are converted to geodetic and bounded. Corners, not centre plus radius — an OBB is oriented, so a radius would inflate a long thin tileset (a transport corridor, a coastline) into a square many times its real area, and the whole point of a footprint is deciding whether the thing is on screen.
A planet-scale tileset (Google's, for instance) legitimately returns most of the globe here; that is the honest answer, and a caller sizing budgets should treat "always on screen" accordingly rather than reading it as an error.
Whether this layer is extracting hard edges. Seeds the settings panel's toggle.
MapLibre CustomLayerInterface hook — invoked when the layer is added with map.addLayer;
initializes GL resources and begins streaming.
MapLibre CustomLayerInterface hook — invoked when the layer is removed with map.removeLayer;
releases GL resources and stops streaming.
Pick the BIM feature under a canvas pixel. Renders the offscreen feature-id pass over the visible
tiles, decodes the hit, then reads that feature's per-feature metadata (3D Tiles batch table /
EXT_structural_metadata) from the resident tile — synchronous (metadata is CPU-resident).
Canvas X in CSS pixels, top-left origin (e.g. a MapLibre click event's e.point.x).
Canvas Y in CSS pixels, top-left origin (e.g. e.point.y).
{ featureOrdinal, properties } for the hit feature (properties is null when the
tile carries no metadata), or null on a miss / before the first frame.
Resolve a canvas point to the 3D geographic position of the frontmost rendered mesh surface — the screen→scene primitive behind measurement and slice placement. GPU pick pass + window-depth readback, reconstructed through the inverse frame matrix (sub-decimetre at city-scale ranges).
Canvas X in CSS pixels, top-left origin (e.g. a MapLibre click event's e.point.x).
Canvas Y in CSS pixels, top-left origin.
Snap radius in CSS pixels (default 0 = exact pixel): the nearest mesh hit within the radius wins, so a click slightly off an edge still lands on the mesh.
The picked position (lng/lat degrees, height metres above the rendered ground datum,
plus the cross-layer-comparable depth01), or null on a miss / before the first frame.
Optional method called during a render frame to allow a layer to prepare resources or render into a texture.
The layer cannot make any assumptions about the current GL state and must bind a framebuffer before rendering.
Nearest obstruction distance per height row through a forward corridor — ONE synthetic forward-looking orthographic pick pass over the walker's cross-section. The ObstructionProbeable contract; see it for why an overhead height probe cannot answer this. On a photogrammetry mesh this is what stops a walker at a building facade.
The corridor; see ObstructionProbeOptions.
Distance in metres per row (index 0 = lowest), NaN where clear, null when this
layer cannot answer.
Working-set load fraction (0–1): drawn tiles over drawn + still-pending.
Called during a render frame allowing the layer to draw into the GL context.
The layer can assume blending and depth state is set to allow the layer to properly blend and clip other layers. The layer cannot make any other assumptions about the current GL state.
If the layer needs to render to a texture, it should implement the prerender method
to do this and only use the render method for drawing directly into the main framebuffer.
The blend function is set to gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA). This expects
colors to be provided in premultiplied alpha form where the r, g and b values are already
multiplied by the a value. If you are unable to provide colors in premultiplied form you
may want to change the blend function to
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA).
Sample the height of this layer's topmost rendered surface at each position — ONE synthetic
top-down orthographic pick pass over the stations' bbox, then a per-station grid lookup (the
"buildings" line on an elevation profile). Samples the currently-RESIDENT tiles; positions in
unloaded areas return null.
lng/lat in degrees.
Optionalopts: SurfaceSampleOptionsOptional: gridPx sets the overhead pass's long-axis resolution (default 1024;
small values like 64 for cheap point probes), marginM the padding around the stations, and
maxHeightM a CUT so the reading is the highest surface BELOW it rather than the topmost
(see SurfaceSampleOptions.maxHeightM).
Height in metres above the rendered ground datum per point, or null where this
layer has no surface.
Toggle the DEBUG tile bounding-volume (OBB) wireframe overlay live (placement QA).
Resize the resident-memory budget live (the runtime equivalent of the budget ctor option).
maxBytes = resident VRAM budget in bytes. Shrinking evicts far/out-of-view tiles
on the next frame; growing lets the far LOD refill.
Replace this layer's clipping planes at runtime. Planes are geographic
(ClippingPlanesOptions) and survive re-anchors; null (or an empty or
disabled set) removes clipping and restores byte-identical rendering.
The new plane set, or null to clear.
Switch the vertical-datum placement live (rigid vertical shift; no re-stream).
Hard-edge overlay: the model's silhouettes and creases drawn over the surface.
The overlay's look and extraction settings, or null to hide it.
Edges are EXTRACTED per tile at decode — no 3D Tiles service ships them — so turning them on for a layer built without them re-streams the tileset. The style half (colour, opacity, width, overshoot) is uniforms and is free; only enabling, MeshEdgeOptions.creaseAngle and MeshEdgeOptions.maxEdgesPerTile force the re-stream.
Worth it on discrete-feature datasets — Cesium OSM Buildings, individual building services — where each feature keeps its own outline (extraction welds by position AND feature id). On photogrammetry (Google, integrated meshes) there are no features to separate and every tessellation fold is a crease, so it is off by default and best left off there.
Set the screen-space-error target (px) live.
Fade the mesh over the basemap.
Opacity in [0, 1] (clamped); 0 = transparent, 1 = opaque.
Toggle cast shadows at runtime (the setShadows half of SunLightable).
true to cast shadows (needs a sun via Tiles3DMeshLayer.setSunState),
false to disable.
Adopt (or clear) the shared vector-drape atlas — satisfies the DrapeReceiver contract, so
enableVectorDrape drives this layer directly. Stashed until the renderer exists.
Apply a 3D Tiles declarative style over per-feature metadata — show (an expression that's
falsy → the feature is hidden) and/or color (a color()/rgb()/rgba() expression → recolor +
opacity). Expressions use the 3D Tiles style language (${prop}, comparisons, ternary, …) over
the tile's batch-table / structural-metadata properties. Compiled once; evaluated per feature
only on change → the GPU pays one texture lookup at draw time (the same style system the I3S BSL
filter uses).
{ show?, color? } 3D Tiles style-language expression strings, or null to clear
the style (show everything, no recolor).
Show/hide without removing the layer (streaming continues).
true to show, false to hide.
Live streaming stats for a debug HUD / perf overlay.
The engine's MeshEngineStats (rendered / resident / loading / in-flight counts and
bytes), or null until the engine is up.
Streams an OGC 3D-Tiles textured-mesh tileset (b3dm / glb, Draco geometry with KTX2/JPEG/PNG textures) and renders it georeferenced — a MapLibre
CustomLayerInterface, added withmap.addLayer. Onlyidandurlare required (Tiles3DMeshLayerOptions): decode runs in a worker pool, and the dataset is seated on the basemap or 3D terrain from a ground measured off the decoded tiles. For a planet-scale tileset (Cesium OSM Buildings, Google Photorealistic) passanchor.lng/anchor.latfor the area being viewed — its root box spans the globe, so there is no usable local frame to derive from it.Requires a WebGL2 context — on WebGL1 the layer goes inert and draws nothing — and renders under the mercator projection only: under a non-affine (globe) projection it hides itself. The visible tiles' data credits (Google's dynamic per-region attributions) are published into MapLibre's attribution control and reported through Tiles3DMeshLayerOptions.onAttributions.
Example