Luxar Viewer API Documentation - v2026.9.22
    Preparing search index...

    Interface UrlParams

    All URL parameters recognized by the viewer, as a typed snapshot.

    Produced once by readUrlParams and threaded through the app; every consumer that wants a URL-derived value accepts the relevant field via options rather than reading window.location itself. Adding a new recognized parameter means adding a field here and a line to readUrlParams.

    interface UrlParams {
        src: string | null;
        theme: string | null;
        title: string | null;
        control: string | null;
        controlToken: string | null;
        controlAllowCrossOrigin: boolean;
        panel: string | null;
        debug: boolean;
        kiosk: boolean;
        noCache: boolean;
        noSliceCache: boolean;
        noOpfs: boolean;
        opfsReadConcurrency: number | null;
        cacheDebug: boolean;
        clearCache: boolean;
        lodFade: boolean;
        allowLinks: boolean;
        lodEnergyComp: boolean;
        lodFinest: boolean;
        lodBias: number | null;
        blendWarmup: boolean;
        depthSort: boolean;
        densityGuard: boolean;
        densityCap: number | null;
        noPrefetch: boolean;
        prefetchDebug: boolean;
        cacheStats: boolean;
        renderer: "webgpu" | "webgl" | null;
        webgpuForceWebGL: boolean;
        perfTimestamp: boolean;
        gpuBudgetMB: number | null;
        cacheBudgetMB: number | null;
        dpr: number | null;
        input: InputProfileOverride | null;
        lineJoin: LineJoinStyleName | null;
        linePrimitive: LinePrimitive | null;
        bakeEnv: boolean;
        probe: string | null;
        envResolution: number | null;
    }
    Index
    src: string | null

    Dataset source URL (?src=...). Null when not provided.

    theme: string | null

    Theme override (?theme=light etc). Null when not provided.

    title: string | null

    Browser tab title (?title=...). luxar serve --open derives it from the dataset file name so several open viewer tabs are tellable apart; a scene's authored viewer_config.title overrides it at load.

    control: string | null

    Remote-control socket URL, already resolved and validated (?control, or ?control=ws://host/control to split the origin). Null when control is off — which is the default — or when the supplied value was refused. See normalizeControlSocketUrl.

    controlToken: string | null

    Shared secret presented to the hub as ?token= (?controlToken=...), matching luxar serve --control-token. Null when the hub is open.

    A token in a query string lands in browser history and in the address bar of whatever tablet is driving the display. That is acceptable for a LAN kiosk and is not a substitute for not exposing the hub to a network you do not trust.

    controlAllowCrossOrigin: boolean

    Permit a cross-origin control socket (?controlAllowCrossOrigin). Off by default so a crafted link cannot point the display at someone else's hub.

    panel: string | null

    Alternative control-panel module (?panel=/my-panel.js), resolved and validated same-origin. Null when absent or refused.

    Read only by control.html; the viewer itself ignores it. See normalizePanelModuleUrl.

    debug: boolean

    Enable the window.__luxarDebug interface (?debug).

    kiosk: boolean

    ?kiosk — lock this display down for unattended public use.

    A hard override over the scene's authored ui.kiosk block, because this is the OPERATOR's channel: a store that predates the block, or one borrowed for an exhibit it was never authored for, still has to be lockable from the launch command. See config/kiosk.ts.

    noCache: boolean

    Disable all cache layers (?noCache).

    noSliceCache: boolean

    Disable only the SliceCache / S-cache (?noSliceCache).

    noOpfs: boolean

    Disable only the L2 OPFS persistent tier (?noOpfs); L0/L1/S-cache stay on. The deterministic sibling of the OPFS circuit breaker — use it in environments whose OPFS is known to stall (automated Chromium).

    opfsReadConcurrency: number | null

    Override the page-wide OPFS read cap (?opfsReadConcurrency=N).

    cacheDebug: boolean

    Verbose cache logging (?cacheDebug).

    clearCache: boolean

    Clear caches on init (?clearCache).

    lodFade: boolean

    Whether the substitutive-LOD cross-fade is enabled: blend adjacent LOD levels' opacity as the camera zooms across their boundary instead of a hard visibility swap, for blendable (additive/luminous/volumetric) layers (anti-popping). On by default; pass ?noLodFade to disable it (e.g. to compare against the hard swap or isolate a rendering issue).

    allowLinks: boolean

    Whether a picked element's authored link may be opened on left-click (issue #1917). On by default; pass ?noLinks to disable it.

    The switch an embedder showing third-party scenes wants: .zattrs is untrusted, so this guarantees no navigation can originate in the data. It suppresses the navigation, the two link items in the right-click menu and the pointer cursor; Copy still works, since the clipboard is not navigation.

    lodEnergyComp: boolean

    Whether streaming brightness compensation is enabled: as a blendable (additive/luminous/volumetric) LOD leaf's additive ladder streams in, scale its opacity by 1/e(k) so the partial prefix renders at full-level brightness instead of brightening up as chunks arrive (anti-popping on the time axis, orthogonal to lodFade's distance axis). On by default; pass ?noLodEnergy to disable it (e.g. to compare against the uncompensated brightening ramp).

    lodFinest: boolean

    Force the finest LOD level regardless of projected screen coverage (?lodFinest). For high-quality still/video capture — the gallery harness appends it — where a coarse level would look blurry even though the subject is small in frame. Off by default (opt-in, unlike the three on-by-default flags above).

    lodBias: number | null

    Session-wide replacement-LOD bias (?lodBias=<positive number>), in screen-area units. 2 advances an occupancy-halved ladder by one level; 4 by two. Null keeps the neutral 1 default.

    blendWarmup: boolean

    WebGL-only blend warm-up. On by default; pass ?noBlendWarmup to disable the off-interaction-path pre-linking of reachable blend-mode program variants.

    depthSort: boolean

    Whether gsplat depth sorting is enabled (depth-sorting Phases 2-3): the async worker sort that keeps normal-mode splats composited back-to-front, plus the per-frame camera-motion re-sort scheduler. On by default; pass ?depthSort=0 (also false/off) to disable it — normal-mode gsplats then keep the identity (storage) order, which pins deterministic output for E2E/visual runs and reproduces pre-Phase-2 behavior for comparison.

    densityGuard: boolean

    Projected-density guard (per-node keep-fraction thinning + refinement rung cap on over-drawn nodes; config.densityGuard). On by default; ?noDensityGuard disables it for the session — the A/B lever for the audit bench and for reproducing an overdraw report.

    densityCap: number | null

    Session-only override of the density guard's blendable cap (?densityCap=8, elements per drawing-buffer pixel; config.densityGuard.capElementsPerPixel is 4). Both consumers follow it — the shader keep-fraction ladder and the refinement rung gate — so a threshold sweep is one URL edit per arm, no rebuild and nothing persisted. The non-blendable cap (1) only moves when the override is below it, so it stays the tighter of the two. Null/invalid ⇒ the configured cap.

    noPrefetch: boolean

    Disable adjacent-chunk prefetching (?noPrefetch).

    prefetchDebug: boolean

    Verbose prefetch logging (?prefetchDebug).

    cacheStats: boolean

    Auto-open the data-loading monitor in expanded mode on the Cache tab (?cacheStats). Useful for measuring L0/L1/L2 hit rates without having to find the monitor's keyboard shortcut first.

    renderer: "webgpu" | "webgl" | null

    Force a specific rendering backend regardless of the default resolution. Useful for per-load A/B comparisons and for diagnosing TSL-vs-GLSL divergences without restarting the dev server.

    • ?renderer=webgl — THREE.WebGLRenderer + GLSL ShaderMaterial (the production default).
    • ?renderer=webgpu — opt into WebGPURenderer + TSL NodeMaterial. The renderer internally dispatches to a real WebGPU adapter when available or falls back to its WebGL2 backend otherwise.
    • Unset (null) — fall back to the build-time VITE_LUXAR_USE_WEBGPU env var (opt-in to WebGPU); if that is also unset, the default is webgl.

    Any other value is normalized to null (defer to env / default).

    webgpuForceWebGL: boolean

    Diagnostic flag (?webgpuForceWebgl) that keeps the WebGPURenderer / TSL NodeMaterial pipeline selected but asks Three.js to back it with its internal WebGL2 backend instead of a native WebGPU adapter. Ignored when renderer resolves to webgl.

    perfTimestamp: boolean

    Opt-in to GPU timestamp queries (?perfTimestamp). Only honored under WebGPURenderer with a backend that exposes the timestamp-query feature. When set, the renderer is constructed with { trackTimestamp: true } and the perf bench reads per-frame GPU time via renderer.resolveTimestampsAsync('render'). Has a small runtime cost so the perf bench is the only intended caller; never set on the production viewer URL.

    gpuBudgetMB: number | null

    Override the adaptive GPU-geometry byte budget, in megabytes (?gpuBudgetMB=1536). Pins the single VRAM budget shared by the buffer pool and LOD-group retention, bypassing the auto-size heuristic. Useful for large scenes on high-VRAM machines (raise it) or for testing eviction on constrained ones (lower it). 0 disables the byte budget (unbounded resident geometry). Null/invalid (missing or negative) ⇒ auto-size from navigator.deviceMemory.

    cacheBudgetMB: number | null

    Override the total in-memory cache pool (L0 + L1 + S-cache), in megabytes (?cacheBudgetMB=1536). Used where performance.memory is unavailable — WKWebView (the native app) and Safari — so heap-aware sizing has a real budget to split instead of the tiny fixed fallback. The native launcher injects it automatically. Its implied non-cache remainder also replaces the heap-derived GPU-geometry signal in either direction. Null/invalid ⇒ fall back to the measured heap, then to the fixed config sizes. See cache/heap-budget.ts.

    dpr: number | null

    Pin a fixed device pixel ratio and disable adaptive DPR for the session (?dpr=1). The value is clamped to [0.25, native DPR] at apply time and the adaptive-resolution toggle is locked off so persisted settings can't silently re-enable it. Primarily for deterministic E2E/visual-regression runs, agent:debug sessions, and bug repros. Null/invalid (missing, non-numeric, <= 0) ⇒ normal adaptive behavior.

    input: InputProfileOverride | null

    Force the session's JS input profile (?input=touch|mouse): pointer flags, hover capability, touch points, and device tier. This changes device-class fallback budgets (touch only — mouse keeps the detected tier), primary-tip pen routing, the Safari gesture-canceller gate, and whether the help overlay lists its Touch section; touch additionally applies the mobile rendering budgets (adaptive-DPR floor and refresh ceiling, high-DPR cap, GPU-byte and element-texture ceilings, data-worker count) and skips the blend-variant program warm-up. Stylesheets and non-pen gesture routing keep following the real media features and PointerEvent.pointerType, so a faithful check still needs device emulation or a real device. null (missing or unrecognised) ⇒ detect from the browser. See utils/input-capabilities.ts.

    lineJoin: LineJoinStyleName | null

    Force a line join style for the session (?lineJoin=none|miter).

    Overrides whatever each node authored, which is exactly its purpose: it is a debugging and workaround lever, so it must win over the scene file. Precedence is ?lineJoin= > authored node attribute > the built-in default. null (missing or unrecognised) means "no override" — distinct from 'none', which is an explicit request for no join geometry. See types/line-join.ts.

    linePrimitive: LinePrimitive | null

    Select the line rendering primitive for the session (?linePrimitive=screen-space|capsule, issue #1352). The session's strongest word: it overrides the Advanced → Line primitive policy setting (whose auto mode otherwise sizes the scene before material build — see types/line-primitive.ts).

    capsule (the default) profiles the 2D point-to-segment distance in pixel space — direction-stable end-on, bisector-cut joins; screen-space is the classic flat quad. Session-wide by design (a renderer implementation choice, not scene content — there is no authored per-node attribute). null (missing or unrecognised) means the built-in default. See types/line-primitive.ts.

    bakeEnv: boolean

    Bake the scene environment (?bakeEnv, driven by luxar env bake): once the load settles, capture the scene-derived cube map at probe / envResolution, expose the container on __luxarDebug.environment.lastBake and download it. See rendering/environment/bake.ts.

    probe: string | null

    Probe for the bake (?probe=auto|node:<path>|x,y,z). Null → the scene's config or auto.

    envResolution: number | null

    Cube face size for the bake (?envResolution=128). Null → the scene's config or 128.