SplatExtension
The SplatExtension is a deck.gl layer extension that renders ScatterplotLayer points as soft gaussian "splats" instead of hard antialiased disks. It multiplies each fragment's alpha by a radial gaussian falloff from the point's center, so a disk fades to nothing at its rim. Overlapping splats blend into continuous surfaces, which reads as a colored point-cloud / "poor-man's-photogrammetry" look rather than a field of discs.
It is a pure fragment-stage effect — no extra attributes, no uniforms, no CPU cost, and no configuration props.
Installation#
import { SplatExtension } from '@poopdeck.gl/layers';
Usage#
AnimatedPointLayer installs it internally when splat: true (see AnimatedPointLayer.splat), but it can be applied to any ScatterplotLayer directly:
import { ScatterplotLayer } from '@deck.gl/layers';import { SplatExtension } from '@poopdeck.gl/layers';const layer = new ScatterplotLayer({id: 'splat-points',data: myData,extensions: [new SplatExtension()],getPosition: (d) => d.coordinates,getRadius: 8,billboard: true,});
It is stateless — a single shared instance can serve every sublayer of a family.
How it works#
- The fragment shader reads
geometry.uv, deck.gl's unit position within the point sprite (0 at the center, 1 at the disk edge), and computesr² = dot(geometry.uv, geometry.uv). - Alpha is multiplied — never replaced — by
exp(-3.0 · r²). At the disk edge (r² = 1) that factor is ≈ 0.05 (nearly transparent rim), giving a soft but still legible dot. The falloff constant is fixed and not exposed as a prop. - Because it multiplies into the existing alpha, it composes with whatever alpha earlier extensions in the list already wrote — the temporal fade/wake alpha from
TimeFilterExtensionand the categorical alpha fromCategoryColorExtensionboth survive underneath the splat shaping. Install it after those extensions in the layer'sextensionslist so it shapes the final alpha.
Pairs well with#
rgbColorColumns/colorVectorColumn(per-point camera RGB) — overlapping splats colored from projected camera returns read like a photograph sprayed onto the 3D structure.- A slightly larger
radiusand a touch of transparency (loweropacityor alpha infillColor). billboard: true, so every splat faces the camera.
Limitations#
- Relies on
geometry.uvsemantics, so it only applies toScatterplotLayer(and layers built on it, likeAnimatedPointLayer's point sublayers) — not path, polygon, or arc layers. - The gaussian falloff constant is fixed at build time; there is no prop to tune softness per layer instance.
- Adding a second
SplatExtensionto a layer that already has one (e.g. passing it viaextensionsto anAnimatedPointLayerwithsplat: true) does not error — deck concatenates same-hook injections with no dedup, and the injection body is braced so it stays idempotent, so the falloff simply squares toexp(-6.0 · r²): a tighter, dimmer dot. Install it once.