Spark cone-foveation detail scale BEHIND the viewer (default 0.2). Lower = coarser.
Spark cone-foveation detail scale at the edge of the foveation cone (default 0.4). Lower = coarser splats OFF-CENTER, freeing the shared LOD splat budget for the visible cone — on a phone's ~60-75° AR view the no-foveation cone (90°) covers the screen, so this costs little visible quality.
Parallel chunk fetch/decode workers while paging (each can saturate a core).
Spark lodRenderScale — minimum on-screen pixel size for LOD splat selection. HIGHER is coarser/cheaper: 1 selects splats down to 1px, values up to ~5 are "often indistinguishable" per Spark's docs while skipping sub-pixel splats.
Multiplier on Spark's per-device LOD splat budget (defaultSplatTarget:
Android 1M, iOS 1.5M, Quest 500k, desktop 2.5M). Lower is cheaper.
Cap on Spark's resident paged-splat pool (0 = Spark's device default: iOS 6.3M, other mobile 8.4M, desktop 16.8M splats). Bounds streaming MEMORY growth — zooming into a large paged scene otherwise pages splats in until the tab dies (observed: iOS Safari page crash on zoom). Only effective before the shared pager is created (applied at renderer creation; runtime quality changes cannot shrink the pool).
Maximum on-screen pixel radius per splat (Spark default 512). Caps the worst near-camera overdraw where single splats cover huge screen regions.
Spherical-harmonics bands to fetch/keep (0-3). SH data dominates splat decode cost, memory and bandwidth — 0 drops view-dependent color but is a step change in CPU/memory load.
Maximum standard deviations of the Gaussian to rasterize. Rendered quad AREA — and with it splat fill cost — scales with the square: √8 (Spark default) → √4 halves splat overdraw. Spark documents √4..√9 as acceptable.
Minimum peak alpha for a splat to render at all — Spark culls whole splats below it in the VERTEX stage (the quad never rasterizes). Spark's default (0.5/255) culls nothing; raising the floor a few /255 removes the large faint "fog" splats that cost maximal overdraw for minimal visual contribution. Splat-only fill lever, used by the deeper adaptation levels.
Minimum milliseconds between splat re-sorts. Spark's own default is 0 (sort back-to-back whenever the view moved ≥1mm/~2.5°), which keeps a worker core saturated during any interaction.
Multiplier on Context.resolutionScaleFactor — the LAST-RESORT fill lever, used only by the single deepest adaptation level after every splat-local knob (LOD, overdraw caps, foveation, alpha floor) is exhausted, and like every step it must verifiably buy fps or it reverts. Presets keep 1.
View-cone sort-cull half-angle in RADIANS (>= PI disables): splats beyond
this angle off the view direction are excluded from sorting AND rendering
(fork feature, SparkRenderer.sortCullHalfAngle) — vertex + sort work scale
with what is visible. Must comfortably exceed the camera's half-diagonal
FOV plus rotation-per-sort margin; the fork force-sorts on rotation past
a third of the margin. Device-measured at 110 deg: +20% fps and one
adaptation level of quality headroom (Pixel, flat). ?splatcull=<degrees>
overrides.
Framebuffer scale for XR sessions (1 = native XR resolution). Splat content is soft and tolerates resolution reduction well; fill cost drops with the square. Applied as a DEFAULT for the next session start (WebXR cannot change it mid-session) — an explicit NeedleXRSession.framebufferScaleFactor wins.
XR frame-rate cap (0 = uncapped). AR splat rendering pins the GPU and heats phones within a minute; running at 30 roughly halves the power draw. Applied through Context.xrFrameRateLimit → WebXR updateTargetFrameRate where the runtime supports it (never by engine-side frame skipping — that flickers on runtimes without a reprojecting compositor).
Concrete Spark settings a GaussianSplatQuality resolves to.