All Radix examples

Spark examples on Radix

Ports of the SparkJS 2.3.1 examples to Radix (@sparkjsdev/radix) as it is, without changes to the renderer: what it can do today, and what it lacks. Each page runs on WebGPU, or on the WebGL2 backend with ?gpu=webgpu-gl (the footer of each page switches). The sources are TypeScript in examples/spark/; npm run build builds the library and these pages (types stripped) into dist/ and build/examples/, and npm run serve serves the repo. Assets load from sparkjs.dev and the other original hosts.

What Radix lacks for the rest

Small additions the ports suggest

Each is worked around in js/ today; the workaround shows how often it is needed.

  1. Per-object opacity and tint in SplatObjectParams: the carousel, interactivity, raycasting, procedural text and editor ports wrap fromSplats in a generator whose bind sets two uniforms (js/objects.js).
  2. Per-object values and world matrices for generators: Spark gives each mesh its own world modifier; splat-flow and the transitions effects bind each object's index and world matrices so one generator can run a world-space effect per object (js/worldEffect.js). Radix now hands every generator the object's matrices and the view origin (its context, which also places the SH); a per-object id would remove the rest.
  3. A CPU splat raycast in core/: js/raycast.js accumulates each splat's Gaussian opacity along the ray and stops at 50% coverage; taking the first splat over an opacity threshold misses the visible surface in grass and foliage.
  4. LoD selection over a loaded lodTree: LoD files draw their leaves through an index list (loadSplatFile in js/files.js); a budgeted selection would unblock the LoD examples for files that already carry trees.

Notes from porting: pages with lit three.js meshes need createRenderer({ directCanvas: false }) (the splats adapt to the output pass); a CubeCamera renders splats on the CPU sort once each face camera's view is sorted (js/cube.js); animated modifiers on the CPU sort call requestSort() every frame.

Shared helpers in js/

Each port is a complete program: it makes its scene, camera, renderer, CameraControls and animation loop itself. Simple ports draw through Radix's SplatRenderer and SplatCollection directly; larger ones use SplatSet / SplatModel. What they have in common is written once on Radix's public API (each file's header says more). The links open the built JavaScript; the TypeScript sources are in examples/spark/js/.

page.js
windowRenderer(): createRenderer (WebGPU, or WebGL2 with ?gpu=webgpu-gl) sized to the window, added to the page and resized with it; examplePage(): status line, legend, load progress, footer links, error capture, and the signal that tells the smoke check the page has drawn.
files.js
Splat files on the GPU with their spherical harmonics, which Radix loads and draws seen from each view: loadSplatFile() (a file on the GPU, a LoD file's leaves as an index list), fileOf() and fileObject() (a SplatObject for a loaded file, with optional modifiers).
objects.js
Spark's SplatMesh on Radix, for the larger ports: SplatModel (an Object3D placing a file or a generator, with opacity, tint and raycasts; SH from Radix) and SplatSet (one SplatRenderer whose collection follows the models shown); raycastSplats() for files drawn without models.
raycast.js
SplatPicker: CPU ray picking against Gaussian ellipsoids, accumulating opacity along the ray.
worldEffect.js
Spark's per-mesh world modifiers: one generator that binds each object's index and world matrices.
construct.js
Splats built on the CPU: SplatBuilder, text, image and grid splats.
sdf.js
Spark's SDF edits (spheres that tint, light or displace splats) as a world-space TSL modifier.
snow.js
Spark's snowBox snow and rain particles as a TSL generator.
cube.js
Cube maps of splats with a CubeCamera (each face sorted on the CPU sort) and their readback.
xr.js
WebXR on either backend: the Enter VR button, reference space, one view for the head, emulator fixes.
assets.js
Spark's asset names to their hosted URLs (?assets= points at a local copy), and GLB loading with optional unlit materials.
examples.js
Every Spark example with its status, what it uses and what blocks it: this page and the smoke check (scripts/check-examples.mjs) read it.
example.css
The status line, legend and footer styles.