examples.ts
examples/spark/js/examples.ts · raw · open the example · all examples · site home
Exports: ExampleEXAMPLESpagesOf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
// Every Spark 2.3.1 example (sparkjsdev/spark examples/ at tag v2.3.1) and
// what became of it here. The index page lists these; the smoke check
// (scripts/check-examples.mjs) loads every page of a ported or
// partial entry. status: "ported" | "partial" | "blocked" | "removed".
// pages the port's pages (default [`${name}/index.html`]); listed: on sparkjs.dev
// uses what in Radix (or the shared js/) it exercises
// gaps what Radix lacks for it (partial and blocked entries)
// xr needs an XR session to show everything (checked on desktop only)
// smoke query string the smoke check loads the pages with
// smokeWait ms the smoke check waits before its screenshot (default 1500)
export interface Example {
name: string;
title: string;
status: "ported" | "partial" | "blocked" | "removed";
listed?: boolean;
pages?: string[];
uses?: string;
gaps?: string;
xr?: boolean;
smoke?: string;
smokeWait?: number;
}
export const EXAMPLES: Example[] = [
{ name: "hello-world", title: "Hello World", status: "ported", listed: true, pages: ["hello-world/index.html", "hello-world/carousel.html"], uses: "loadSplats, SplatCollection.arrays, per-object opacity through the generator's bind (carousel)" },
{ name: "envmap", title: "Environment Map", status: "ported", listed: true, uses: "a CubeCamera rendering the splats (one GPU sort per face) into the duck's envMap" },
{ name: "interactivity", title: "Interactivity", status: "ported", listed: true, uses: "per-object opacity fades, splats depth-tested against a lit GLB table with shadows, the scans' degree-3 spherical harmonics (Radix's, seen from each view)" },
{ name: "multiple-splats", title: "Multiple Splats", status: "ported", listed: true, uses: "one GpuArrays drawn as six objects with their own matrices" },
{ name: "multiple-viewpoints", title: "Multiple Viewpoints", status: "ported", listed: true, uses: "one SplatRenderer rendered from three cameras into render targets" },
{ name: "procedural-splats", title: "Procedural Splats", status: "ported", listed: true, uses: "splats built on the CPU (Splats.make / encoder): a 500k Sierpinski pyramid, stars, text and image splats" },
{ name: "raycasting", title: "Raycasting", status: "ported", listed: true, uses: "THREE.Raycaster against splats (a CPU ellipsoid test, js/raycast.js), per-object tint" },
{ name: "dynamic-lighting", title: "Dynamic Lighting", status: "ported", listed: true, uses: "Spark's SDF edits as a world-space modifier (js/sdf.js)" },
{ name: "particle-animation", title: "Particle Animation", status: "ported", listed: true, uses: "CPU-built splats re-uploaded every frame (GpuArrays.upload)" },
{ name: "particle-simulation", title: "Particle Simulation", status: "ported", listed: true, uses: "Spark's snowBox as a TSL generator (js/snow.js), sorted with a scan" },
{ name: "splat-painter", title: "Splat Painter", status: "ported", listed: true, uses: "a GpuArrayWriter brush rewriting stored splats, restore by copyFrom, readback and SPZ export" },
{ name: "splat-reveal-effects", title: "Splat Reveal Effects", status: "ported", listed: true, smokeWait: 8000, uses: "object-space TSL modifiers driven by uniforms", gaps: "Sutro (SOGS zip) is left out" },
{ name: "splat-shader-effects", title: "Splat Shader Effects", status: "ported", listed: true, uses: "object-space TSL modifiers driven by uniforms" },
{ name: "splat-dissolve-effects", title: "Splat Dissolve Effects", status: "ported", listed: true, uses: "an object-space TSL modifier driven by time" },
{ name: "splat-transitions", title: "Splat Transitions", status: "ported", listed: true, uses: "four effect demos: world-space modifiers over several objects, text splats, GLB environments" },
{ name: "stochastic", title: "Stochastic", status: "removed", listed: true, gaps: "listed on sparkjs.dev but no longer in Spark's examples" },
{ name: "sogs", title: "SOGS Compression", status: "blocked", listed: true, gaps: "Radix reads PLY, SPZ, RAD and RDX only: no SOG / SOGS (.sog, .zip) decoder" },
{ name: "webxr", title: "WebXR", status: "ported", listed: true, xr: true, uses: "WebXR on either backend, hand joints as a generator, fingertip SDF edits" },
{ name: "glsl", title: "GLSL Shaders", status: "ported", listed: true, uses: "an object modifier (fromSplats modifiers) plus a world modifier (the renderer's)" },
{ name: "debug-color", title: "Debug Coloring", status: "ported", listed: true, uses: "GpuSplats.normalOf and view-space depth in per-object modifiers" },
{ name: "depth-of-field", title: "Depth of Field", status: "ported", listed: true, uses: "the focalDistance and apertureTan params" },
{ name: "splat-texture", title: "Splat Texture", status: "removed", listed: true, gaps: "listed on sparkjs.dev but no longer in Spark's examples" },
{ name: "editor", title: "Editor", status: "partial", listed: true, smoke: "?url=https://sparkjs.dev/assets/splats/butterfly.spz", uses: "several files, per-file transforms and opacity, text and grid splats, bounds, normal color and clip box, render params, layouts, the four methods", gaps: "no LoD (build, traverse, foveation), no .splat / .ksplat / .zip / .sog" },
{ name: "viewer", title: "Viewer", status: "ported", listed: true, smoke: "?url=https://sparkjs.dev/assets/splats/butterfly.spz", uses: "drag and drop, URLs, PLY / SPZ / RAD / RDX, SPZ export (writeSplats)", gaps: "no .splat / .ksplat / .zip / .sog" },
{ name: "basic-xr", title: "Basic XR", status: "ported", listed: true, xr: true, uses: "WebXR on either backend with CameraControls' XR rig; the LoD file's leaves through an index list", gaps: "draws every leaf where Spark draws a LoD budget (no LoD selection)" },
{ name: "interactive-holes", title: "Interactive Holes", status: "ported", listed: true, uses: "a uniform array of 128 click spheres over the stored centers, raycasts through the holes (centers edited in the picker's CPU copy, as Spark edits only its CPU array)" },
{ name: "lofi", title: "Lofi Worlds", status: "partial", listed: true, uses: "a cache of worlds as GpuArrays freed in release, a generator blending two worlds by splat index, world modifiers, snow and rain, audio", gaps: "WebXR hands and spotlights checked in the emulator only" },
{ name: "mobile-joystick", title: "Mobile On-Screen Joystick", status: "ported", listed: true, uses: "CameraControls plus a touch joystick" },
{ name: "render-cube-depth", title: "Render Cube Depthmap", status: "ported", listed: true, uses: "cube renders read back, depth as color from a view-space modifier, falloff 0" },
{ name: "lod-on-demand", title: "LoD-on-demand", status: "blocked", listed: true, gaps: "Radix does not build LoD trees" },
{ name: "nonlod", title: "Simultaneous Non-LoD + LoD", status: "blocked", listed: true, gaps: "Radix neither builds LoD trees nor selects LoD subsets" },
{ name: "extsplats", title: "Extended Splats encoding", status: "ported", listed: true, uses: "packedSplats (half-float centers) against extSplats (float32) 1000 units out" },
{ name: "streaming-lod", title: "Streaming LoDs", status: "blocked", listed: true, gaps: "no paged RAD loading over range requests, no LoD selection" },
{ name: "multi-lod", title: "Multiple Streaming LoDs", status: "blocked", listed: true, gaps: "no paged RAD loading, no LoD selection or page budget across objects" },
{ name: "on-demand", title: "On-demand Rendering", status: "blocked", listed: true, gaps: "its scene is a 40M-splat paged RAD (no paged loading or LoD selection); rendering on demand itself maps to SplatRenderer.onInvalidate" },
{ name: "interactive-deform", title: "Interactive Deform", status: "ported", uses: "a raycast hit and drag driving a world-space deformation" },
{ name: "interactive-ripples", title: "Interactive Ripples", status: "ported", uses: "a raycast hit starting an object-space shockwave" },
{ name: "splat-flow", title: "Splat Flow", status: "ported", uses: "a world modifier over three objects keyed on splat index, CPU bounds, a GLB environment" },
{ name: "splat-portal", title: "Splat Portal", status: "ported", uses: "two scenes with their own SplatRenderers rendered into targets shown through portal meshes", gaps: "Sutro (SOGS zip) swapped for another scan" },
{ name: "lod", title: "LoD", status: "blocked", gaps: "Radix neither builds LoD trees nor selects LoD subsets (foveation)" },
{ name: "portal", title: "Portal", status: "blocked", gaps: "needs a custom splat fragment shader (disk clip) and SplatSkinning" },
{ name: "newportal", title: "Multi-Portal", status: "blocked", gaps: "needs SparkPortals (linked portal passes) and paged loading" },
];
// The pages of an entry that has a port
export function pagesOf(example: Example) {
return example.pages ?? [`${example.name}/index.html`];
}