npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@poopdeck.gl/three

v0.4.0

Published

Three.js + TSL (Three Shading Language / WebGPU) renderer for SpatioTemporal Tiles — an independent, GPU-native alternative to the deck.gl renderer, with optional react-three-fiber bindings. First-class AV LIDAR cockpit (oriented Gaussian surfels in a loc

Downloads

695

Readme

@poopdeck.gl/three

A Three.js + TSL (Three Shading Language / WebGPU) renderer for SpatioTemporal Tiles — an independent, GPU-native alternative to the deck.gl renderer (@poopdeck.gl/layers). It consumes the same decoded tiles from @poopdeck.gl/core and the same playback clock from @poopdeck.gl/playback, and renders them through a single WebGPURenderer (with automatic WebGL2 fallback) using TSL node materials.

The first-class target is the AV LIDAR cockpit: oriented anisotropic Gaussian surfels and billboard point splats animated by a soft temporal Gaussian, in a local ENU metric frame — the kind of surface-splatting that is awkward in a 2D map renderer but natural in Three.

@poopdeck.gl/core (tiles)  ─┐
                            ├─►  @poopdeck.gl/three  ──►  WebGPURenderer (WebGL2 fallback)
@poopdeck.gl/playback (clock)┘        │
                                      └─►  @poopdeck.gl/three/r3f  (react-three-fiber)

Why Three + TSL

  • Surface splatting in 3D. Surfels are oriented elliptical disks with a radial Gaussian and a temporal Gaussian, depth-tested with depth-write on (no back-to-front sort). TSL compiles the same node graph to WGSL (WebGPU) or GLSL (WebGL2).
  • A metric world. AV tiles are georeferenced lon/lat (+ z metres) about a scene origin. The local ENU projection inverts that to a Z-up metric frame where 1 world unit = 1 metre, so the baked surfel orientation quaternions drop straight in with no mercator dance.
  • Same data, same clock. No new tile format, no second playback engine — it reads BinaryFeatures and TimeController exactly like the deck renderer.

Install

npm install @poopdeck.gl/three three
# for the react-three-fiber bindings:
npm install @react-three/fiber @react-three/drei react react-dom

Peers: three ≥ 0.171 (required); react ≥ 19 / @react-three/fiber ≥ 9 / @react-three/drei ≥ 10 are optional peers used only by the /r3f subpath.

Quick start (react-three-fiber)

import { SttCanvas, SttSurfelLayer } from "@poopdeck.gl/three/r3f";

<SttCanvas
  anchor={{ longitude: -79.933, latitude: 40.456 }} // world origin
  timeOrigin={dataset.timeRange.start}              // common f32 time base
  timeRange={dataset.timeRange}
  getTime={() => timeController.getTime()}
>
  <SttSurfelLayer
    url="https://tiles.example.com/scene/lidar/manifest.json"
    temporalSigma={180}
    rgbColumns={["r", "g", "b"]}
  />
</SttCanvas>;

<SttCanvas> owns the WebGPURenderer (WebGL2 fallback), a Z-up camera with OrbitControls, loads each child layer's archive, frames the camera, and reads getTime() every frame to drive the temporal filter.

Without React, the same wiring is imperative: build an SttScene (engine export), scene.addLayer(new SurfelLayer({...}), manifestUrl), add scene.root to your Three scene, await scene.load(), then call scene.setTime(t) from your render loop.

Layers

| Layer | Renders | Notes | | --- | --- | --- | | SurfelLayer | Oriented Gaussian surfels | hero LIDAR mode; temporalSigma, cumulative (worldbuild) | | PointCloudLayer | Billboard point splats | window / wake (scan) / cumulative; categorical or r,g,b colour; splat soft Gaussian | | BoundingBoxLayer | Tracked-object 3D boxes | CPU keyframe interpolation by track_id, 12-edge outlines + velocity arrows | | StaticPathLayer | Map lines (lane dividers) | flat ground decals, categorical colour | | StaticPolygonLayer | Map polygons (drivable area) | pre-baked triangles or earcut | | EgoLayer | Ego trail + marker | provides the follow-camera target |

All animated layers share the TSL time-filter (window / wake / trail / cumulative / none) — the node mirror of deck's TimeFilterExtension, pinned by the CPU reference math in time-filter-math.ts.

Geo rendering & interaction

All of the following are opt-in and backward-compatible (omit them and the renderer behaves exactly as before). WebGPU-first; features that need WebGPU degrade gracefully on the WebGL2 fallback.

| Feature | How to enable | Notes | | --- | --- | --- | | Projection | <SttCanvas projection={new MercatorProjection(c)} /> / new GlobeProjection(c, EARTH_RADIUS, { datum: 'wgs84' }) | default is local-ENU; Mercator = exact web-mercator, Globe = ECEF with an orbit rig | | Streaming | <SttCanvas streaming /> or scene.addLayer(l, url, { streaming: true }) | viewport-driven LOD / frustum cull / eviction / prefetch via StreamingTileSource; eager load-everything stays the default | | GPU picking + hover | <SttCanvas onPick={…} onHover={…} /> | GPU id-buffer picks instanced clouds; CPU ray-OBB picks boxes | | Atmosphere / sky / day-night | <SttCanvas atmosphere /> or <SttAtmosphere /> | physically-based sky + sun + aerial perspective (@takram/three-atmosphere, WebGPU only); sun tracks the playhead | | 3D Tiles / terrain / photorealistic | <SttTiles3D source={{ google: { apiToken } }} globeControls /> | OGC 3D Tiles via 3d-tiles-renderer — self-hosted url, Google Photorealistic, or Cesium Ion — with ellipsoid-aware GlobeControls |

The street basemap for flat scenes is a host-owned maplibre/mapbox map that the renderer camera-syncs beneath the transparent canvas (BasemapOverlay) — not an in-engine tile layer.

Architecture

  • Engine (framework-agnostic): the WebGPURenderer bootstrap, the SttScene orchestrator + tile loader, the TSL materials, and the tile→geometry layer adapters. No React.
  • /r3f: a thin react-three-fiber <Canvas> binding that drives the engine.

Status

Pure-function logic (projection round-trip, quaternion math, time-filter alpha, colour expansion, tile→attribute wiring) is unit-tested. The GPU material + renderer paths have no headless coverage (no WebGL/WebGPU in CI) and are verified in-browser. See the parity roadmap.

Docs

MIT.