SDK JS
    Preparing search index...

    Interface Tiles3DSplatLayerOptions

    Options for Tiles3DSplatLayer. Only id and url (the tileset.json) are required — everything else defaults: 'spz' tiles decoded in a worker pool, the dataset auto-grounded onto the basemap or 3D terrain, and the renderer's texture-safe splat budget. When tuning, reach for maxScreenSpaceError (detail against memory) and budget first; a secured or token-gated tileset needs auth or requestInit, and datum decides whether the data drapes on the map or sits at its true absolute height.

    interface Tiles3DSplatLayerOptions {
        anchor?: { altitude?: number };
        attribution?: string;
        auth?: RequestAuthorizer;
        budget?: { maxBytes?: number; maxSplats?: number };
        castNSigma?: number;
        castOpacityThreshold?: number;
        clippingPlanes?: ClippingPlanesOptions;
        coverageGe?: number;
        coverageMaxPx?: number;
        datum?: VerticalDatum;
        debugBounds?: boolean;
        decoder?: "bvc" | GltfSplatDecoder | "spz";
        dilate?: number;
        discardPx?: number;
        displayMode?: "points" | "splats";
        flyTo?: boolean | { duration?: number; pitch?: number; zoom?: number };
        geoidN?: number;
        geometricErrorScale?: number;
        ground?: boolean;
        id: string;
        lodBlur?: number;
        lodFalloffPow?: number;
        maximumAttenuation?: number;
        maxScale?: number;
        maxScreenSpaceError?: number;
        minPx?: number;
        onError?: (error: unknown) => void;
        onLoaded?: () => void;
        onProgress?: (fraction: number) => void;
        opacity?: number;
        pointAttenuation?: boolean;
        pointScale?: number;
        requestInit?: RequestInit;
        shadows?: boolean;
        url: string;
        viewDependentLighting?: boolean;
        visible?: boolean;
        workers?: boolean;
    }
    Index

    Properties

    anchor?: { altitude?: number }

    Optional absolute altitude override (meters, WGS84). Defaults to auto-grounding (the measured dataset floor sits on the basemap / terrain). Camera lng/lat are always derived from the tileset root center.

    attribution?: string

    Dataset attribution shown in MapLibre's attribution control (also readable via Tiles3DSplatLayer.getAttribution).

    auth?: RequestAuthorizer

    Request authorizer for tile + tileset fetches. For secured ArcGIS scene layers, pass an ESRI authorizer (e.g. getEsriAuthorizer() from @bitruvius/esri-auth, or set one globally via configureEsriAuth() and omit this). Public/open tilesets need neither this nor requestInit.

    budget?: { maxBytes?: number; maxSplats?: number }

    Resident-memory budget. Defaults to the renderer's texture-safe ceiling (RECOMMENDED_MAX_SPLATS ≈ 13.4M splats / 2.4 GB). You MAY raise maxSplats for more far-field retention — up to the hard GL ceiling (ABSOLUTE_MAX_SPLATS ≈ 16.78M); above the recommended value, tiles near the texture wall are parked/retried (non-fatal) and may not fully refine. It's the caller's call — see the docs for recommended maxima. Each field defaults independently.

    castNSigma?: number

    Footprint half-extent (std-devs) for the shadow cast (default 0.4). Small by design: dense real surfaces stay watertight while sparse floater/junk splats shrink to nothing instead of stamping blob shadows; raise toward ~0.7 only if a sparse dataset shows shadow light-leaks.

    castOpacityThreshold?: number

    Splats whose opacity is below this don't cast a shadow (default 0.5; culls faint/foggy splats and much floater junk that would over-shadow).

    clippingPlanes?: ClippingPlanesOptions

    Clipping planes (geographic; see ClippingPlanesOptions) applied to this layer's splats (whole-splat cull by center in the color and shadow-cast passes). Change at runtime via Tiles3DSplatLayer.setClippingPlanes. Default none.

    coverageGe?: number

    Far-field coverage (splat mode): geometric-error screen floor — floor each splat to coverageGe·geometricError·focal/depth px, so only the sparse far field is grown (LOD- and distance-scaled, no near-field bloom unlike the flat minPx). Default 0 (OFF). EXPERIMENTAL: lod is the TILE geometricError (>> per-splat spacing), so this floors ~every splat to the cap and produces a cloud of uniform circles, not a selective gap fill — the wrong scale for splats. Live via Tiles3DSplatLayer.setCoverage.

    coverageMaxPx?: number

    HARD ceiling (device px) on the coverage-floor semi-axis — bounds the max coverage splat diameter to 2·this value regardless of depth/LOD, the guard that makes coverageGe safe. Default 0 = auto = 2·maxScreenSpaceError (≈ Cesium's 16px ceiling). Live via Tiles3DSplatLayer.setCoverage.

    Vertical datum for auto-placement (ignored when anchor.altitude is set):

    • 'basemap' (default): drop the measured ground onto the flat map (z=0) or onto 3D terrain under the anchor.
    • 'ellipsoid': place the ground at its true WGS84 ellipsoid height.
    • 'orthometric': place the ground at mean sea level (ellipsoid − geoid). Switch live with Tiles3DSplatLayer.setDatum.
    debugBounds?: boolean

    DEV: draw each tile's 3D bounding volume (OBB) as a colored wireframe, on demand as tiles load — green = ready, yellow = loading, orange = deferred. Default false. Toggle live with Tiles3DSplatLayer.setDebugBounds.

    decoder?: "bvc" | GltfSplatDecoder | "spz"

    Tile decoder: 'spz' (default, Esri/Cesium spz_2) | 'bvc' | a custom impl.

    To benchmark against a reference implementation, construct it yourself and pass the instance. The SDK used to expose a 'spz-legacy' string for this, backed by an unpublished package — which meant the published bundle carried an import no consumer could resolve. An injected decoder keeps that baseline available to whoever has the package, and out of everyone else's build.

    dilate?: number

    Constant EWA gap-fill dilation (px², default 0.3 = Cesium's value) added to every splat's screen footprint — closes sub-pixel voids without dimming. Raise slightly for a fuller surface (uniform, not distance-scaled; bounded). Live via Tiles3DSplatLayer.setCoverage.

    discardPx?: number

    Sub-pixel discard (device px, 0 = off): drop splats whose major on-screen diameter is below this to cut far-field overdraw (Cesium's sub-2px cull) — applied AFTER the coverage/minPx floors so floored splats survive. Too high re-thins the far field; 0 disables it. Default 1. Live via Tiles3DSplatLayer.setCoverage.

    displayMode?: "points" | "splats"

    Render mode: 'splats' (default, EWA gaussians) | 'points' — draw each splat CENTER as a round point sized to its own screen footprint (the point-cloud look; lighter). Same geometry, different display. Toggle live with Tiles3DSplatLayer.setDisplayMode.

    flyTo?: boolean | { duration?: number; pitch?: number; zoom?: number }

    Fly the map to the dataset as soon as its location is known (default: no camera change — the consumer owns the camera). true uses sensible defaults (zoom 16.5, pitch 60°, 1.2 s); pass an object to tune. Handy when swapping datasets so the view follows.

    geoidN?: number

    Optional — you should not normally need this.* The geoid undulation N (m) at the dataset, used to place absolutely-georeferenced data on mean-sea-level terrain. The SDK resolves it automatically (it fetches the EGM96 grid on demand and samples it at the dataset), so pass this only to override that — e.g. for a dataset referenced to a local vertical datum EGM96 does not model.

    An override shifts placement by the DIFFERENCE between your value and the EGM96 undulation at the dataset — so passing the conventional EGM96 value for your area is a no-op rather than a ~30 m jump.

    geometricErrorScale?: number

    Multiplier on the point-attenuation spacing (Cesium geometricErrorScale). Default 1.

    ground?: boolean

    Measure + ground the dataset onto z=0 / terrain (default true). When false, the root center is placed at anchor.altitude ?? 0.

    id: string

    Layer id.

    lodBlur?: number

    Far-field coverage: extra splat/point size (m) at the coarsest LOD to fill the voids between sparse splats while finer tiles stream (Cesium/Esri "fuller at distance"). Default 1 (on); 0 disables it. Tune live with Tiles3DSplatLayer.setCoverage.

    lodFalloffPow?: number

    LOD distance-falloff exponent for the refine decision. 1 = standard 3D-Tiles SSE, so the refine cusp lands exactly where Cesium's does at the same maxScreenSpaceError (lean far field — the A/B-confirmed default; the far field is kept full by bigger coarse splats, not by over-refining). <1 (e.g. 0.6) keeps higher detail further out (richer, heavier). Default: the engine value (1).

    maximumAttenuation?: number

    Point-attenuation diameter ceiling, px (Cesium maximumAttenuation). Default 16.

    maxScale?: number

    Max splat major-axis (m) before the floater cull discards it (default 8). Coarse-LOD splats legitimately span metres; raise this so the big coarse gap-fillers survive and tile the far field (the Cesium "bigger coarse splats" fullness — true-size, cannot blob). Live via Tiles3DSplatLayer.setCoverage.

    maxScreenSpaceError?: number

    Target screen-space error in pixels (Cesium's maximumScreenSpaceError). Lower = more detail (more tiles + memory); higher = coarser + lighter. Default 16 (Cesium-matched lean default). Tune live with Tiles3DSplatLayer.setMaxScreenSpaceError.

    minPx?: number

    Far-field coverage: screen-space MINIMUM splat/point radius (px) — grows far/sparse splats so they overlap into a continuous surface instead of going grainy. Default 0 (off). Live via Tiles3DSplatLayer.setCoverage.

    onError?: (error: unknown) => void

    Fired if the tileset fails to load/initialize (e.g. an unauthorized Cesium ion source). The layer stays inert; nothing renders.

    onLoaded?: () => void

    Fired once the working set first fully resolves.

    onProgress?: (fraction: number) => void

    Fired with the working-set load fraction (0–1) as it streams + settles (complements onLoaded, which fires once at first full resolve).

    opacity?: number

    Initial opacity 0–1 (default 1) — fade the splats over the basemap. Live via Tiles3DSplatLayer.setOpacity.

    pointAttenuation?: boolean

    Point-mode geometric-error attenuation (Cesium PointCloudShading): size points by their LOD spacing (geometricError·focal/depth) so far/coarse points stay dense instead of ballooning to the full splat footprint. Default ON — the point-cloud look. Tune live with Tiles3DSplatLayer.setCoverage. Set false to size by the full EWA footprint.

    pointScale?: number

    Point-mode size multiplier (1 = the computed point size).

    requestInit?: RequestInit

    Static auth/headers for tile + tileset fetches (e.g. a Cesium ion Bearer token). The simple escape hatch; superseded by auth when both are set.

    shadows?: boolean

    Cast + receive cascaded sun shadows (default false). When on, the splats cast depth footprints into the shared ShadowCoordinator atlas (so they shadow meshes/terrain) and self-shadow by sampling it. Requires an active geo-sun (sun above the horizon). Toggle live with Tiles3DSplatLayer.setShadows.

    url: string

    URL of the 3D-Tiles tileset.json.

    viewDependentLighting?: boolean

    Degree-1 view-dependent lighting (spherical harmonics). Default true; false is flatter + a touch lighter. Live via Tiles3DSplatLayer.setViewDependentLighting.

    visible?: boolean

    Initial visibility (default true). Toggle live with Tiles3DSplatLayer.setVisible.

    workers?: boolean

    Decode tiles off the main thread in a Web Worker pool (default TRUE) — keeps the heavy rANS/entropy decode from janking the render thread on large streaming models. Set false to decode on the main thread. Auto-falls back to main-thread where Web Workers are unavailable. Ignored when decoder is a custom instance.