gaussian-splat-lite 0.1.16 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/CHANGELOG.md +41 -2
  2. package/CONTRIBUTING.md +18 -33
  3. package/NOTICE +4 -0
  4. package/README.md +93 -195
  5. package/THIRD_PARTY_LICENSES.md +59 -0
  6. package/dist/assets/worker-4CsCmbvY.js.map +1 -0
  7. package/dist/assets/worker-BaSb7of7.js.map +1 -0
  8. package/dist/assets/worker-C6AaRsfh.js.map +1 -0
  9. package/dist/assets/worker-Cy3sOEjr.js.map +1 -0
  10. package/dist/assets/worker-Dtvtj5Dv.js.map +1 -0
  11. package/dist/assets/worker-F1Ec5oZ9.js.map +1 -0
  12. package/dist/gaussian-splat-lite.cjs +32613 -4121
  13. package/dist/gaussian-splat-lite.cjs.map +1 -1
  14. package/dist/gaussian-splat-lite.min.cjs +465 -42
  15. package/dist/gaussian-splat-lite.min.cjs.map +1 -1
  16. package/dist/gaussian-splat-lite.module.js +11146 -4146
  17. package/dist/gaussian-splat-lite.module.js.map +1 -1
  18. package/dist/gaussian-splat-lite.module.min.js +7437 -2491
  19. package/dist/gaussian-splat-lite.module.min.js.map +1 -1
  20. package/dist/types/data/IndexedSplats.d.cts +68 -0
  21. package/dist/types/data/IndexedSplats.d.ts +68 -0
  22. package/dist/types/data/RadPagedSplats.d.cts +69 -0
  23. package/dist/types/data/RadPagedSplats.d.ts +69 -0
  24. package/dist/types/data/SogRegionSplats.d.cts +19 -0
  25. package/dist/types/data/SogRegionSplats.d.ts +19 -0
  26. package/dist/types/data/SplatOpacityTable.d.cts +31 -0
  27. package/dist/types/data/SplatOpacityTable.d.ts +31 -0
  28. package/dist/types/{Splats.d.cts → data/Splats.d.cts} +14 -7
  29. package/dist/types/{Splats.d.ts → data/Splats.d.ts} +14 -7
  30. package/dist/types/{defines.d.cts → data/defines.d.cts} +5 -1
  31. package/dist/types/{defines.d.ts → data/defines.d.ts} +5 -1
  32. package/dist/types/{splatCodec.d.cts → data/splatCodec.d.cts} +4 -2
  33. package/dist/types/{splatCodec.d.ts → data/splatCodec.d.ts} +4 -2
  34. package/dist/types/data/splatData.d.cts +11 -0
  35. package/dist/types/data/splatData.d.ts +11 -0
  36. package/dist/types/data/splatRange.d.cts +3 -0
  37. package/dist/types/data/splatRange.d.ts +3 -0
  38. package/dist/types/data/textureLayout.d.cts +9 -0
  39. package/dist/types/data/textureLayout.d.ts +9 -0
  40. package/dist/types/data/unpack.d.cts +9 -0
  41. package/dist/types/data/unpack.d.ts +9 -0
  42. package/dist/types/index.d.cts +18 -12
  43. package/dist/types/index.d.ts +18 -12
  44. package/dist/types/loaders/SplatLoader.d.cts +16 -0
  45. package/dist/types/loaders/SplatLoader.d.ts +16 -0
  46. package/dist/types/loaders/assetUrl.d.cts +2 -0
  47. package/dist/types/loaders/assetUrl.d.ts +2 -0
  48. package/dist/types/loaders/loadSplatData.d.cts +21 -0
  49. package/dist/types/loaders/loadSplatData.d.ts +21 -0
  50. package/dist/types/loaders/loadTypes.d.cts +46 -0
  51. package/dist/types/loaders/loadTypes.d.ts +46 -0
  52. package/dist/types/{postDecode.d.cts → loaders/postDecode/builder.d.cts} +7 -164
  53. package/dist/types/{postDecode.d.ts → loaders/postDecode/builder.d.ts} +7 -164
  54. package/dist/types/loaders/postDecode/compiler.d.cts +15 -0
  55. package/dist/types/loaders/postDecode/compiler.d.ts +15 -0
  56. package/dist/types/loaders/postDecode/operations.d.cts +3 -0
  57. package/dist/types/loaders/postDecode/operations.d.ts +3 -0
  58. package/dist/types/loaders/postDecode/program.d.cts +13 -0
  59. package/dist/types/loaders/postDecode/program.d.ts +13 -0
  60. package/dist/types/loaders/postDecode/protocol.d.cts +164 -0
  61. package/dist/types/loaders/postDecode/protocol.d.ts +164 -0
  62. package/dist/types/loaders/postDecode/registers.d.cts +12 -0
  63. package/dist/types/loaders/postDecode/registers.d.ts +12 -0
  64. package/dist/types/loaders/postDecode/runtime.d.cts +2 -0
  65. package/dist/types/loaders/postDecode/runtime.d.ts +2 -0
  66. package/dist/types/loaders/rad/RadSource.d.cts +42 -0
  67. package/dist/types/loaders/rad/RadSource.d.ts +42 -0
  68. package/dist/types/loaders/rad/radFormat.d.cts +55 -0
  69. package/dist/types/loaders/rad/radFormat.d.ts +55 -0
  70. package/dist/types/loaders/rad.d.cts +14 -0
  71. package/dist/types/loaders/rad.d.ts +14 -0
  72. package/dist/types/loaders/sog/SogSource.d.cts +5 -0
  73. package/dist/types/loaders/sog/SogSource.d.ts +5 -0
  74. package/dist/types/loaders/sog/sogZip.d.cts +17 -0
  75. package/dist/types/loaders/sog/sogZip.d.ts +17 -0
  76. package/dist/types/loaders/sog.d.cts +9 -0
  77. package/dist/types/loaders/sog.d.ts +9 -0
  78. package/dist/types/loaders/source.d.cts +22 -0
  79. package/dist/types/loaders/source.d.ts +22 -0
  80. package/dist/types/loaders/stream/StreamByteBudget.d.cts +7 -0
  81. package/dist/types/loaders/stream/StreamByteBudget.d.ts +7 -0
  82. package/dist/types/loaders/stream/StreamWorkerPool.d.cts +27 -0
  83. package/dist/types/loaders/stream/StreamWorkerPool.d.ts +27 -0
  84. package/dist/types/loaders/stream/rad-stream/RadStreamBatch.d.cts +12 -0
  85. package/dist/types/loaders/stream/rad-stream/RadStreamBatch.d.ts +12 -0
  86. package/dist/types/loaders/stream/rad-stream/RadStreamLoader.d.cts +39 -0
  87. package/dist/types/loaders/stream/rad-stream/RadStreamLoader.d.ts +39 -0
  88. package/dist/types/loaders/stream/rad-stream/RadStreamScheduler.d.cts +81 -0
  89. package/dist/types/loaders/stream/rad-stream/RadStreamScheduler.d.ts +81 -0
  90. package/dist/types/loaders/stream/rad-stream/RadStreamWorker.d.cts +6 -0
  91. package/dist/types/loaders/stream/rad-stream/RadStreamWorker.d.ts +6 -0
  92. package/dist/types/loaders/stream/rad-stream/radFade.d.cts +16 -0
  93. package/dist/types/loaders/stream/rad-stream/radFade.d.ts +16 -0
  94. package/dist/types/loaders/stream/rad-stream/radLod.d.cts +31 -0
  95. package/dist/types/loaders/stream/rad-stream/radLod.d.ts +31 -0
  96. package/dist/types/loaders/stream/rad-stream/worker.d.cts +36 -0
  97. package/dist/types/loaders/stream/rad-stream/worker.d.ts +36 -0
  98. package/dist/types/loaders/stream/rad-stream/workerHandlers.d.cts +38 -0
  99. package/dist/types/loaders/stream/rad-stream/workerHandlers.d.ts +38 -0
  100. package/dist/types/loaders/stream/sog-stream/SogStreamBatch.d.cts +18 -0
  101. package/dist/types/loaders/stream/sog-stream/SogStreamBatch.d.ts +18 -0
  102. package/dist/types/loaders/stream/sog-stream/SogStreamLoader.d.cts +50 -0
  103. package/dist/types/loaders/stream/sog-stream/SogStreamLoader.d.ts +50 -0
  104. package/dist/types/loaders/stream/sog-stream/SogStreamScheduler.d.cts +64 -0
  105. package/dist/types/loaders/stream/sog-stream/SogStreamScheduler.d.ts +64 -0
  106. package/dist/types/loaders/stream/sog-stream/SogStreamWorker.d.cts +6 -0
  107. package/dist/types/loaders/stream/sog-stream/SogStreamWorker.d.ts +6 -0
  108. package/dist/types/loaders/stream/sog-stream/sogLod.d.cts +61 -0
  109. package/dist/types/loaders/stream/sog-stream/sogLod.d.ts +61 -0
  110. package/dist/types/loaders/stream/sog-stream/sogVisibility.d.cts +28 -0
  111. package/dist/types/loaders/stream/sog-stream/sogVisibility.d.ts +28 -0
  112. package/dist/types/loaders/stream/sog-stream/worker.d.cts +40 -0
  113. package/dist/types/loaders/stream/sog-stream/worker.d.ts +40 -0
  114. package/dist/types/loaders/stream/sog-stream/workerHandlers.d.cts +47 -0
  115. package/dist/types/loaders/stream/sog-stream/workerHandlers.d.ts +47 -0
  116. package/dist/types/loaders/stream/streamOptions.d.cts +44 -0
  117. package/dist/types/loaders/stream/streamOptions.d.ts +44 -0
  118. package/dist/types/loaders/workerDecode.d.cts +13 -0
  119. package/dist/types/loaders/workerDecode.d.ts +13 -0
  120. package/dist/types/{GaussianSplatRenderer.d.cts → rendering/GaussianSplatRenderer.d.cts} +116 -22
  121. package/dist/types/{GaussianSplatRenderer.d.ts → rendering/GaussianSplatRenderer.d.ts} +116 -22
  122. package/dist/types/{cameraRelative.d.cts → rendering/SortCenterCache.d.cts} +0 -10
  123. package/dist/types/{cameraRelative.d.ts → rendering/SortCenterCache.d.ts} +0 -10
  124. package/dist/types/{SplatAccumulator.d.cts → rendering/SplatAccumulator.d.cts} +14 -17
  125. package/dist/types/{SplatAccumulator.d.ts → rendering/SplatAccumulator.d.ts} +14 -17
  126. package/dist/types/rendering/SplatCapture.d.cts +51 -0
  127. package/dist/types/rendering/SplatCapture.d.ts +51 -0
  128. package/dist/types/rendering/SplatGeometry.d.cts +8 -0
  129. package/dist/types/rendering/SplatGeometry.d.ts +8 -0
  130. package/dist/types/rendering/StochasticResolvePass.d.cts +68 -0
  131. package/dist/types/rendering/StochasticResolvePass.d.ts +68 -0
  132. package/dist/types/rendering/backend.d.cts +25 -0
  133. package/dist/types/rendering/backend.d.ts +25 -0
  134. package/dist/types/rendering/rendererUtils.d.cts +15 -0
  135. package/dist/types/rendering/rendererUtils.d.ts +15 -0
  136. package/dist/types/rendering/stochastic.d.cts +19 -0
  137. package/dist/types/rendering/stochastic.d.ts +19 -0
  138. package/dist/types/rendering/tsl/GenerateProgram.d.cts +24 -0
  139. package/dist/types/rendering/tsl/GenerateProgram.d.ts +24 -0
  140. package/dist/types/rendering/tsl/ProjectionProgram.d.cts +37 -0
  141. package/dist/types/rendering/tsl/ProjectionProgram.d.ts +37 -0
  142. package/dist/types/rendering/tsl/ResolveMaterial.d.cts +4 -0
  143. package/dist/types/rendering/tsl/ResolveMaterial.d.ts +4 -0
  144. package/dist/types/rendering/tsl/SplatBackend.d.cts +17 -0
  145. package/dist/types/rendering/tsl/SplatBackend.d.ts +17 -0
  146. package/dist/types/rendering/tsl/SplatMaterial.d.cts +27 -0
  147. package/dist/types/rendering/tsl/SplatMaterial.d.ts +27 -0
  148. package/dist/types/rendering/tsl/shaderUtils.d.cts +18 -0
  149. package/dist/types/rendering/tsl/shaderUtils.d.ts +18 -0
  150. package/dist/types/rendering/tsl/viewUniforms.d.cts +16 -0
  151. package/dist/types/rendering/tsl/viewUniforms.d.ts +16 -0
  152. package/dist/types/rendering/uniforms.d.cts +93 -0
  153. package/dist/types/rendering/uniforms.d.ts +93 -0
  154. package/dist/types/rendering/webgl/AccumulatorGenerator.d.cts +16 -0
  155. package/dist/types/rendering/webgl/AccumulatorGenerator.d.ts +16 -0
  156. package/dist/types/rendering/webgl/ResolveMaterial.d.cts +3 -0
  157. package/dist/types/rendering/webgl/ResolveMaterial.d.ts +3 -0
  158. package/dist/types/rendering/webgl/SplatBackend.d.cts +20 -0
  159. package/dist/types/rendering/webgl/SplatBackend.d.ts +20 -0
  160. package/dist/types/rendering/webgl/textureUtils.d.cts +3 -0
  161. package/dist/types/rendering/webgl/textureUtils.d.ts +3 -0
  162. package/dist/types/rendering/webgl-fallback/AccumulatorGenerator.d.cts +13 -0
  163. package/dist/types/rendering/webgl-fallback/AccumulatorGenerator.d.ts +13 -0
  164. package/dist/types/rendering/webgl-fallback/SplatBackend.d.cts +15 -0
  165. package/dist/types/rendering/webgl-fallback/SplatBackend.d.ts +15 -0
  166. package/dist/types/rendering/webgpu/ProjectedSplats.d.cts +42 -0
  167. package/dist/types/rendering/webgpu/ProjectedSplats.d.ts +42 -0
  168. package/dist/types/rendering/webgpu/ProjectionCache.d.cts +34 -0
  169. package/dist/types/rendering/webgpu/ProjectionCache.d.ts +34 -0
  170. package/dist/types/rendering/webgpu/RadixSort.d.cts +44 -0
  171. package/dist/types/rendering/webgpu/RadixSort.d.ts +44 -0
  172. package/dist/types/rendering/webgpu/SplatBackend.d.cts +19 -0
  173. package/dist/types/rendering/webgpu/SplatBackend.d.ts +19 -0
  174. package/dist/types/runtime/SplatWorker.d.cts +19 -0
  175. package/dist/types/runtime/SplatWorker.d.ts +19 -0
  176. package/dist/types/runtime/WorkerRpc.d.cts +25 -0
  177. package/dist/types/runtime/WorkerRpc.d.ts +25 -0
  178. package/dist/types/runtime/abort.d.cts +8 -0
  179. package/dist/types/runtime/abort.d.ts +8 -0
  180. package/dist/types/runtime/wasm.d.cts +4 -0
  181. package/dist/types/runtime/wasm.d.ts +4 -0
  182. package/dist/types/{worker.d.cts → runtime/worker.d.cts} +3 -19
  183. package/dist/types/{worker.d.ts → runtime/worker.d.ts} +3 -19
  184. package/dist/types/runtime/workerServer.d.cts +2 -0
  185. package/dist/types/runtime/workerServer.d.ts +2 -0
  186. package/dist/types/{SplatMesh.d.cts → scene/SplatMesh.d.cts} +6 -6
  187. package/dist/types/{SplatMesh.d.ts → scene/SplatMesh.d.ts} +6 -6
  188. package/dist/types/utils/index.d.cts +7 -0
  189. package/dist/types/utils/index.d.ts +7 -0
  190. package/dist/types/{float16.d.cts → utils/numeric.d.cts} +2 -0
  191. package/dist/types/{float16.d.ts → utils/numeric.d.ts} +2 -0
  192. package/dist/types/utils/three.d.cts +7 -0
  193. package/dist/types/utils/three.d.ts +7 -0
  194. package/dist/types/{splatTransform.d.cts → utils/transforms.d.cts} +9 -0
  195. package/dist/types/{splatTransform.d.ts → utils/transforms.d.ts} +9 -0
  196. package/docs/Architecture.md +125 -0
  197. package/docs/GaussianSplatRenderer.md +137 -25
  198. package/docs/PostDecode.md +24 -38
  199. package/docs/RadStreamScheduler.md +103 -0
  200. package/docs/SogStreamScheduler.md +67 -0
  201. package/docs/SplatAccumulator.md +11 -9
  202. package/docs/SplatEdit.md +9 -39
  203. package/docs/SplatFileType.md +7 -10
  204. package/docs/SplatLoader.md +39 -1
  205. package/docs/SplatMesh.md +72 -14
  206. package/docs/Splats.md +27 -25
  207. package/package.json +15 -11
  208. package/dist/assets/worker-C26a7h-J.js.map +0 -1
  209. package/dist/assets/worker-Cx-xVLFg.js.map +0 -1
  210. package/dist/types/SplatGeometry.d.cts +0 -4
  211. package/dist/types/SplatGeometry.d.ts +0 -4
  212. package/dist/types/SplatLoader.d.cts +0 -34
  213. package/dist/types/SplatLoader.d.ts +0 -34
  214. package/dist/types/SplatWorker.d.cts +0 -32
  215. package/dist/types/SplatWorker.d.ts +0 -32
  216. package/dist/types/postDecodeRuntime.d.cts +0 -19
  217. package/dist/types/postDecodeRuntime.d.ts +0 -19
  218. package/dist/types/utils.d.cts +0 -28
  219. package/dist/types/utils.d.ts +0 -28
  220. package/dist/types/wasm.d.cts +0 -2
  221. package/dist/types/wasm.d.ts +0 -2
  222. package/dist/types/workerIdleTimeout.d.cts +0 -12
  223. package/dist/types/workerIdleTimeout.d.ts +0 -12
  224. /package/dist/types/{shaders.d.cts → rendering/webgl/shaders.d.cts} +0 -0
  225. /package/dist/types/{shaders.d.ts → rendering/webgl/shaders.d.ts} +0 -0
  226. /package/dist/types/{transferable.d.cts → runtime/transferable.d.cts} +0 -0
  227. /package/dist/types/{transferable.d.ts → runtime/transferable.d.ts} +0 -0
  228. /package/dist/types/{SplatEdit.d.cts → scene/SplatEdit.d.cts} +0 -0
  229. /package/dist/types/{SplatEdit.d.ts → scene/SplatEdit.d.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,44 @@ and this project follows [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.0] - 2026-09-09
11
+
12
+ ### Added
13
+
14
+ - Added `WebGPURenderer` support for native WebGPU, `forceWebGL`, and automatic WebGL2 fallback, using shared TSL shaders. Native WebGPU projects and culls Splats before 32-bit GPU sorting and indirect drawing; both WebGL backends use asynchronous Worker/WASM sorting. The new read-only `synchronousSort` property reports the backend's sorting mode.
15
+ - Added `stochastic` and `autoStochastic` for sorting-free transparency, plus `renderDepth` for companion depth draws with stochastic alpha coverage. Automatic mode uses stochastic rendering during camera motion until a fresh sort is ready.
16
+ - Added `StochasticResolvePass` for spatial noise reduction through direct scene composition, WebGL `EffectComposer`, or a custom render graph. Manual stochastic rendering and per-eye resolve support WebGL/WebGPU XR; automatic switching is disabled in XR.
17
+ - Added SOG V1/V2 loading from ZIP bundles or directory metadata through the existing loading APIs, with HTTP Range access, concurrent property-image downloads, and grouped decoding.
18
+ - Added Spark RAD version 1 loading for monolithic `.rad` files and split files with external `.radc` pages, including all property codecs and SH0–SH3/codebooks. Ordinary loading detects the RAD0 signature and extracts leaf records before applying `postDecode`.
19
+ - Added `RadStreamScheduler` and `SogStreamScheduler` for camera-driven LOD and on-demand loading of RAD pages and Streamed SOG `lod-meta.json` scenes. Both support WebGL/WebGPU rendering, SDF edits, raycasting, visibility fades, LOD crossfades, cancellation, retries, and streaming statistics.
20
+ - Added shared streaming controls for Splat budgets, upload allowance, load concurrency, and cooldown retirement. Defaults are 3,000,000 Splats, 8 MiB per update, four concurrent loads, 100 cooldown ticks, and 200 ms fades. LOD workers run separately from decoding workers and coalesce pending requests to the latest view; fixed source slots, compact visible indices, and partial uploads reduce repeated work.
21
+ - Added `resolveFile` for local SOG companion images and RAD pages, accepting synchronous or asynchronous URL, Blob, or byte-array results with cancellation support.
22
+ - Added an optional `AbortSignal` to `SplatLoader.loadAsync()`. Disposing loaded sources or replacing their initialization cancels pending downloads and decoding.
23
+ - Added `Splats.extractRange()` to copy packed records, spherical harmonics, and sort centers into an independent source.
24
+ - Added Splat record indices to raycast hits and `RadStreamScheduler.getGlobalIndex()` to map current batch indices to stable file-global RAD node indices.
25
+ - Added viewer backend switching, output color-space and stochastic controls, WebGPU Inspector integration, and a toggleable grid with X/Z reference axes. The viewer accepts SOG/RAD files, streamed scene URLs, and multi-file selection or drop for local split assets.
26
+
27
+ ### Changed
28
+
29
+ - Updated the Three.js peer dependency from `>=0.185.1` to `>=0.186.0`, pinned development to `0.186.0`, and removed compatibility workarounds fixed upstream.
30
+ - Replaced `stream` and `streamLength` loading inputs with `file: Blob` (including `File`) in `Splats` and `SplatMesh`. PLY/SPZ files stream inside the worker; local SOG/RAD files use random reads. Existing `url` and `fileBytes` inputs remain available.
31
+ - Changed the default `preBlurAmount` from `0` to `0.3` and `blurAmount` from `0.3` to `0`, expanding projected Splats without the previous blur opacity compensation. Set them to `0` and `0.3`, respectively, to restore the previous behavior.
32
+ - Corrected `minPixelRadius` to use screen pixels independently of `focalAdjustment`. Its default remains `1`; divide previous values by `focalAdjustment` to preserve the old cutoff.
33
+ - Increased the default `SplatMesh.minRaycastOpacity` from `0.1` to `0.15`.
34
+ - Moved built-in Splat color conversion to vertex shaders and trimmed wide-kernel coverage using a conservative alpha bound while preserving the full-support visibility cutoff. Native WebGPU projection quantization can produce slight visual differences, and equal-depth Splats have no guaranteed source order.
35
+ - Unified PLY/SPZ/SOG/RAD decoding around the platform-independent Rust library and shared receiver output, with thin WASM bridges. Reused PLY batches and SPZ decompression buffers, and reduced packed-buffer reads, writes, and temporary allocations.
36
+ - Reorganized source code into data, loaders, runtime, scene, rendering, and utility modules while preserving existing package entry-point exports. Extracted offscreen capture, shared packed-data loading, and separate post-decode building, compilation and execution modules without changing public APIs. Simplified the README and API references, and added architecture and streaming guides.
37
+ - Updated the viewer to use reversed depth buffers where supported and allow only one GPU frame in flight while retaining pending redraws and processing camera input. Replaced the bundled Lion model with Multi Material Splats by hybridherbst in SPZ v4 with SH3 data and CC BY 4.0 attribution.
38
+ - Changed `npm run dev` to serve source directly through Vite, consolidated WASM builds into a cross-platform Node script, and split ES module and CommonJS bundle builds. Removed `build:watch` and the platform-specific WASM scripts.
39
+
40
+ ### Fixed
41
+
42
+ - Corrected shared SH exponent selection in Rust and TypeScript so coefficients between powers of two no longer saturate at the lower power. Preserved finite color channels when another channel is NaN, and preserved the SH2 coefficient stored alongside SH1 when updating SH1. The packed layout and shader decoding are unchanged.
43
+ - Rebuilt Splat textures when either source buffer, typed-array offset, or length changes, preventing stale GPU data.
44
+ - Validated legacy SPZ gzip header and payload checksums, decoded sizes, trailers, and trailing data. Validated SPZ v4 Zstandard checksums and declared frame sizes against the stream table, rejecting corrupt or inconsistent files.
45
+ - Corrected WebXR projection to use each eye's viewport dimensions instead of the full drawing buffer.
46
+ - Recreated terminated WebGL sorting workers on the next sort and discarded late sorting results after renderer disposal.
47
+
10
48
  ## [0.1.16] - 2026-09-03
11
49
 
12
50
  ### Changed
@@ -43,7 +81,7 @@ and this project follows [Semantic Versioning](https://semver.org/).
43
81
 
44
82
  ### Added
45
83
 
46
- - Added `tan`, `asin`, `atan`, and vector-aware `atan2(y, x)` operations to the experimental post-decode expression API.
84
+ - Added `tan`, `asin`, `atan`, and vector-aware `atan2(y, x)` operations to the post-decode expression API.
47
85
 
48
86
  ## [0.1.12] - 2026-08-31
49
87
 
@@ -193,7 +231,8 @@ and this project follows [Semantic Versioning](https://semver.org/).
193
231
 
194
232
  - Initial public release of the Three.js Gaussian Splatting renderer.
195
233
 
196
- [Unreleased]: https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/compare/v0.1.16...HEAD
234
+ [Unreleased]: https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/compare/v1.0.0...HEAD
235
+ [1.0.0]: https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/compare/v0.1.16...v1.0.0
197
236
  [0.1.16]: https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/compare/v0.1.15...v0.1.16
198
237
  [0.1.15]: https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/compare/v0.1.14...v0.1.15
199
238
  [0.1.14]: https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/compare/v0.1.13...v0.1.14
package/CONTRIBUTING.md CHANGED
@@ -1,62 +1,52 @@
1
1
  # Contributing
2
2
 
3
- Thanks for contributing to `gaussian-splat-lite`.
4
-
5
3
  ## Development setup
6
4
 
7
- Building the WebAssembly module requires Node.js 20.9 or newer, a Rust
8
- toolchain installed through `rustup`, and the `wasm32-unknown-unknown` target.
5
+ Requires Node.js 20.9+, Rust via `rustup`, and the `wasm32-unknown-unknown` target.
9
6
 
10
7
  ```bash
11
8
  npm ci
12
9
  npm run build:wasm
10
+ npm run dev
13
11
  ```
14
12
 
15
- Start the local viewer with `npm run dev`.
13
+ Check WebGL2, WebGPU, and WebGPU · WebGL2 in the viewer. For depth changes, compare mesh occlusion and transparent edges; disable **Automatic stochastic** to expose **Force Splat depth**.
14
+
15
+ See [Source architecture](docs/Architecture.md) for module responsibilities and backend boundaries.
16
16
 
17
17
  ## Validation
18
18
 
19
- Run the complete release check before opening a pull request:
19
+ Before opening a pull request:
20
20
 
21
21
  ```bash
22
22
  npm run release:check
23
23
  ```
24
24
 
25
- This builds the WebAssembly module and example site, type-checks and lints the
26
- source, runs the tests, builds the package, and verifies the npm tarball.
25
+ Builds WASM, the viewer, and the package; runs type checks, lint, tests, and npm package validation.
27
26
 
28
- When dependency updates introduce or change install scripts, review them and
29
- update the pinned `allowScripts` entries with `npm approve-scripts`.
27
+ Review new or changed dependency install scripts and update `allowScripts` with `npm approve-scripts`.
30
28
 
31
29
  ## Pull requests
32
30
 
33
31
  - Keep changes focused on one problem.
34
- - Update the README and API docs when public behavior changes.
32
+ - Update the relevant API docs when behavior changes; keep the README focused on setup and capabilities.
35
33
  - Add or update tests for behavior that can be exercised without WebGL.
36
- - Include a minimal reproduction and captures for rendering changes when
37
- possible.
34
+ - Include a minimal reproduction and captures for rendering changes where possible.
38
35
  - Add user-visible changes to the `Unreleased` section of `CHANGELOG.md`.
39
- - Do not commit generated `dist/`, `site-dist/`, Rust `target/`, or wasm-pack
40
- `pkg/` directories.
36
+ - Do not commit generated `dist/`, `site-dist/`, Rust `target/`, or wasm-pack `pkg/` directories.
41
37
 
42
38
  ## Maintainer releases
43
39
 
44
- The npm package is published by `.github/workflows/publish.yml` when a matching
45
- `v*` tag is pushed. The workflow rejects tags that do not match the version in
46
- `package.json`, skips versions already present on npm, and creates the GitHub
47
- release from `CHANGELOG.md`.
40
+ Pushing a `v*` tag runs `.github/workflows/publish.yml`. It requires a matching `package.json` version, skips existing npm versions, and creates the GitHub release from `CHANGELOG.md`.
48
41
 
49
- Before the first automated release, make the GitHub repository public, then
50
- publish the package once from a maintainer account so that its npm settings
51
- exist:
42
+ To publish manually from a maintainer account:
52
43
 
53
44
  ```bash
54
45
  npm run release:check
55
46
  npm publish --access public
56
47
  ```
57
48
 
58
- Then, using a current npm CLI, configure GitHub Actions as the trusted publisher
59
- for future releases:
49
+ Configure GitHub Actions as the trusted publisher with a current npm CLI:
60
50
 
61
51
  ```bash
62
52
  npm trust github gaussian-splat-lite \
@@ -65,15 +55,10 @@ npm trust github gaussian-splat-lite \
65
55
  --allow-publish
66
56
  ```
67
57
 
68
- The same setting is available under the package's npm **Settings → Trusted
69
- Publisher** page. The workflow uses short-lived OIDC credentials, so no
70
- `NPM_TOKEN` repository secret is required after this setup.
58
+ Alternatively, use npm **Settings → Trusted Publisher**. The workflow uses OIDC; no `NPM_TOKEN` secret is needed.
71
59
 
72
60
  For each release:
73
61
 
74
- 1. Move the relevant changelog entries from `Unreleased` into a dated version
75
- section.
76
- 2. Update `package.json` and `package-lock.json` with
77
- `npm version <version> --no-git-tag-version`.
78
- 3. Run `npm run release:check`, commit the release changes, then create and push
79
- `v<version>`.
62
+ 1. Move `Unreleased` entries into a dated version section.
63
+ 2. Run `npm version <version> --no-git-tag-version` to update both package files.
64
+ 3. Run `npm run release:check`, commit, then create and push `v<version>`.
package/NOTICE CHANGED
@@ -5,6 +5,10 @@ This product includes software derived from SparkJS v2.1.0,
5
5
  Copyright © 2025 WORLD LABS TECHNOLOGIES, INC., licensed under the MIT
6
6
  License. See THIRD_PARTY_LICENSES.md for the complete license notice.
7
7
 
8
+ This product includes software adapted from SuperSplat 3.0.0-alpha,
9
+ Copyright (c) 2011-2026 PlayCanvas Ltd., licensed under the MIT License.
10
+ See THIRD_PARTY_LICENSES.md for the complete license notice.
11
+
8
12
  This product includes ruzstd v0.7.3,
9
13
  Copyright © 2019 Moritz Borcherding, licensed under the MIT License.
10
14
  See THIRD_PARTY_LICENSES.md for the complete license notice.
package/README.md CHANGED
@@ -6,34 +6,26 @@
6
6
  [![CI](https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/actions/workflows/ci.yml/badge.svg)](https://github.com/WilliamLiu-1997/Gaussian-Splat-Lite/actions/workflows/ci.yml)
7
7
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
8
8
 
9
+ **Three.js Gaussian Splatting · WebGPU · Depth Rendering · Streaming**
10
+
9
11
  <p align="center">
10
12
  <img src="./Gaussian-Splat-Lite.svg" alt="Gaussian Splat Lite" width="1000">
11
13
  </p>
12
14
 
13
15
  </div>
14
16
 
15
- `Gaussian-Splat-Lite` is a lightweight 3D Gaussian Splatting renderer for Three.js. It is based on the overall architecture of [SparkJS](https://github.com/sparkjsdev/spark), simplified and adapted to retain a stable, general-purpose Gaussian Splat rendering pipeline while removing LoD, paging, dynamic shader graphs, and broad format compatibility layers. It also fixes SparkJS precision issues with large GIS/ECEF world coordinates and provides faster depth sorting and raycasting implementations.
16
-
17
- It works alongside standard Three.js scenes, cameras, meshes, and render loops, and supports unified generation, sorting, and blended rendering of multiple Splat objects.
17
+ A lightweight 3D Gaussian Splatting renderer for **Three.js**, with **WebGPU/WebGL2**, **depth rendering for scene occlusion**, and **large-scene streaming**. Load PLY/SPZ/SOG/RAD files into standard Three.js scenes, stream RAD and SOG scenes with camera-driven LOD, and render multiple Splat objects together.
18
18
 
19
19
  ## Features
20
20
 
21
- - Native integration with the Three.js scene graph and rendering pipeline
22
- - Multiple `SplatMesh` objects rendered with correct global sorting
23
- - `.ply` and `.spz` file support
24
- - URL, in-memory byte, and standard `ReadableStream` inputs
25
- - Rust/WebAssembly file decoding, depth sorting, and raycasting
26
- - 3DGS rendering with configurable anti-aliasing
27
- - Spherical harmonics, offscreen rendering, and environment-map rendering
28
- - SDF-based color and opacity editing
29
- - Camera-relative rendering for large GIS/ECEF world coordinates
30
- - TypeScript declarations, ESM, and CommonJS builds
31
-
32
- ## Requirements
33
-
34
- - A modern browser with WebGL2, WebAssembly, Web Workers, and ES modules
35
- - Three.js `0.185.1` or newer
36
- - Correct CORS headers when loading Splat files from another origin
21
+ | Focus | What you get |
22
+ | --- | --- |
23
+ | **WebGPU / WebGL2** | Shared Three.js scene API with GPU sorting on native WebGPU and asynchronous Worker/WASM sorting on both WebGL2 backends |
24
+ | **Depth Rendering** | Separate unsorted depth draw with stochastic coverage at transparent edges |
25
+ | **Large-scene streaming** | RAD tree LOD and SOG `lod-meta.json` scenes with camera-driven selection, on-demand loading, worker decoding, caching, and opacity crossfades for smooth LOD changes on both backends |
26
+ | **Stochastic rendering** | Sorting-free rendering for responsive camera movement, with optional spatial resolve to reduce noise |
27
+ | **SDF edits** | Region-based color and opacity editing without moving Splats |
28
+ | **Data and precision** | PLY/SPZ/SOG/RAD from URLs, files, or bytes; camera-relative rendering for large GIS/ECEF coordinates |
37
29
 
38
30
  ## Installation
39
31
 
@@ -41,44 +33,42 @@ It works alongside standard Three.js scenes, cameras, meshes, and render loops,
41
33
  npm install gaussian-splat-lite three
42
34
  ```
43
35
 
36
+ Requires Three.js `>=0.186.0`.
37
+
44
38
  ## Quick start
45
39
 
40
+ `SplatMesh` is a scene object. One `GaussianSplatRenderer` handles generation, sorting, and drawing for all visible Splat objects.
41
+
42
+ ### WebGPU
43
+
46
44
  ```js
47
45
  import * as THREE from "three";
46
+ import { WebGPURenderer } from "three/webgpu";
48
47
  import { GaussianSplatRenderer, SplatMesh } from "gaussian-splat-lite";
49
48
 
49
+ const renderer = new WebGPURenderer({ antialias: false });
50
+ await renderer.init(); // Initialize before constructing GaussianSplatRenderer.
51
+ renderer.setPixelRatio(window.devicePixelRatio);
52
+ renderer.setSize(window.innerWidth, window.innerHeight);
53
+ document.body.appendChild(renderer.domElement);
54
+
50
55
  const scene = new THREE.Scene();
51
56
  const camera = new THREE.PerspectiveCamera(
52
- 60,
53
- window.innerWidth / window.innerHeight,
54
- 0.1,
55
- 1000,
57
+ 60, window.innerWidth / window.innerHeight, 0.1, 1000,
56
58
  );
57
59
  camera.position.set(0, 0, 3);
58
60
 
59
- const renderer = new THREE.WebGLRenderer({
60
- antialias: false,
61
- powerPreference: "high-performance",
61
+ const splatRenderer = new GaussianSplatRenderer({
62
+ renderer,
63
+ renderDepth: true, // Add Splat depth after the sorted color draw.
62
64
  });
63
- renderer.setPixelRatio(window.devicePixelRatio);
64
- renderer.setSize(window.innerWidth, window.innerHeight);
65
- document.body.appendChild(renderer.domElement);
66
-
67
- // One GaussianSplatRenderer is normally enough for each Three.js renderer.
68
- const splatRenderer = new GaussianSplatRenderer({ renderer });
69
65
  scene.add(splatRenderer);
70
66
 
71
67
  const splat = new SplatMesh({ url: "/assets/scene.spz" });
72
68
  scene.add(splat);
73
-
74
- // Wait before reading loaded data such as the count or bounding box.
75
69
  await splat.initialized;
76
- console.log(`Loaded ${splat.numSplats} splats`);
77
-
78
- renderer.setAnimationLoop(() => {
79
- renderer.render(scene, camera);
80
- });
81
70
 
71
+ renderer.setAnimationLoop(() => renderer.render(scene, camera));
82
72
  window.addEventListener("resize", () => {
83
73
  camera.aspect = window.innerWidth / window.innerHeight;
84
74
  camera.updateProjectionMatrix();
@@ -86,206 +76,114 @@ window.addEventListener("resize", () => {
86
76
  });
87
77
  ```
88
78
 
89
- `GaussianSplatRenderer` is itself a Three.js scene object. It collects visible `SplatMesh` objects, generates GPU data, sorts the combined collection, and draws it. Application code continues to use the standard `renderer.render(scene, camera)` call; it does not need to issue a separate draw call for each Splat.
79
+ ### WebGL2
90
80
 
91
- Some PLY/SPZ data uses a `+Y`-down, `+Z`-forward convention. If a model appears upside down or faces the wrong direction, rotate the object without changing its decoded data:
81
+ `WebGPURenderer` automatically falls back to its WebGL2 backend when WebGPU is unavailable. To force this backend while keeping TSL materials:
92
82
 
93
83
  ```js
94
- splat.quaternion.set(1, 0, 0, 0); // Rotate 180 degrees around X.
84
+ const renderer = new WebGPURenderer({ antialias: false, forceWebGL: true });
85
+ await renderer.init();
95
86
  ```
96
87
 
97
- ## Loading data
98
-
99
- ### From a URL
88
+ For the classic WebGL renderer, replace the WebGPU renderer creation and initialization with:
100
89
 
101
90
  ```js
102
- const splat = new SplatMesh({
103
- url: "/assets/model.ply", // .spz is also supported.
104
- onProgress: (event) => {
105
- if (event.lengthComputable) {
106
- console.log(`${Math.round((event.loaded / event.total) * 100)}%`);
107
- }
108
- },
109
- onLoad: (mesh) => console.log(mesh.numSplats),
110
- });
111
-
112
- scene.add(splat);
113
- await splat.initialized;
91
+ const renderer = new THREE.WebGLRenderer({ antialias: false });
114
92
  ```
115
93
 
116
- ### From a File or ReadableStream
94
+ Keep the rest of the example, including `renderDepth`.
117
95
 
118
- This form is suitable for file pickers, drag and drop, and large local files. The data is decoded locally by WebAssembly and is not automatically uploaded anywhere.
96
+ ## Streaming large scenes
119
97
 
120
- ```js
121
- import { SplatFileType, SplatMesh } from "gaussian-splat-lite";
122
-
123
- const file = fileInput.files[0];
124
- const fileType = file.name.toLowerCase().endsWith(".spz")
125
- ? SplatFileType.SPZ
126
- : SplatFileType.PLY;
127
-
128
- const splat = new SplatMesh({
129
- fileName: file.name,
130
- fileType,
131
- stream: file.stream(),
132
- streamLength: file.size,
133
- onProgress: ({ loaded, total }) => console.log(loaded, total),
134
- });
98
+ Use `RadStreamScheduler` for RAD files with a LOD tree, or `SogStreamScheduler` for SOG scenes indexed by `lod-meta.json`. Both work with the same `GaussianSplatRenderer` on WebGPU and WebGL2, loading and retaining data as the camera moves.
135
99
 
136
- scene.add(splat);
137
- await splat.initialized;
138
- ```
139
-
140
- Complete in-memory file data can also be supplied:
100
+ For RAD, replace the `SplatMesh` loading and animation loop in the quick start with:
141
101
 
142
102
  ```js
143
- const bytes = new Uint8Array(await file.arrayBuffer());
144
- const splat = new SplatMesh({
145
- fileBytes: bytes,
146
- fileType: SplatFileType.SPZ,
147
- });
148
- ```
103
+ import { RadStreamScheduler } from "gaussian-splat-lite";
149
104
 
150
- **`Experimental`** Decoded values can be transformed in the worker with a
151
- serializable, per-Splat expression. The library continues to own packed arrays
152
- and encoding:
105
+ const streaming = new RadStreamScheduler({
106
+ url: "/assets/scene.rad",
107
+ splatBudget: 3_000_000,
108
+ fadeDurationMs: 200, // Smooth LOD transitions (default).
109
+ });
110
+ scene.add(streaming.group);
111
+ await streaming.initialized;
153
112
 
154
- ```js
155
- import { postDecode } from "gaussian-splat-lite";
113
+ const size = new THREE.Vector2();
114
+ renderer.setAnimationLoop(() => {
115
+ renderer.getDrawingBufferSize(size);
116
+ streaming.update(camera, { width: size.x, height: size.y });
117
+ renderer.render(scene, camera);
118
+ });
156
119
 
157
- const transform = postDecode.define(({ splat, op }) => ({
158
- position: op.add(splat.position, [1, 0, 0]),
159
- color: op.mul(splat.color, [1, 0.8, 0.8]),
160
- }));
120
+ // The update loop must be running before awaiting the first visible data.
121
+ await streaming.firstRenderable;
161
122
 
162
- const splat = new SplatMesh({ fileBytes: bytes, postDecode: transform });
123
+ // When removing the model:
124
+ // streaming.dispose();
125
+ // streaming.group.removeFromParent();
163
126
  ```
164
127
 
165
- See [`postDecode`](docs/PostDecode.md) for external attributes, opacity,
166
- quaternions, scale, and spherical harmonics.
167
-
168
- When the input URL does not have a recognizable extension, specify `fileType` explicitly or provide a `.ply` / `.spz` name through `fileName`.
169
-
170
- ### Creating Splats in code
128
+ For streamed SOG, use this constructor and call `streaming.update(camera)` before rendering each frame; the group and readiness lifecycle are the same:
171
129
 
172
130
  ```js
173
- import * as THREE from "three";
174
- import { SplatMesh } from "gaussian-splat-lite";
175
-
176
- const splat = new SplatMesh({
177
- maxSplats: 100,
178
- constructSplats: (data) => {
179
- data.pushSplats([{
180
- center: new THREE.Vector3(0, 0, 0),
181
- scales: new THREE.Vector3(0.2, 0.1, 0.1),
182
- quaternion: new THREE.Quaternion(),
183
- opacity: 1, // Raw opacity; 0..1 alpha, >1 LoD coverage (max 1000).
184
- color: new THREE.Color(0x4f8cff),
185
- sh: [], // Optional: 0, 3, 8, or 15 coefficients for SH0/1/2/3.
186
- }]);
187
- },
188
- });
189
-
190
- scene.add(splat);
191
- await splat.initialized;
192
- ```
193
-
194
- ## Core concepts and public API
195
-
196
- | API | Purpose |
197
- | --- | --- |
198
- | [`GaussianSplatRenderer`](docs/GaussianSplatRenderer.md) | Integrates with Three.js and generates, sorts, and draws every visible Splat |
199
- | [`SplatMesh`](docs/SplatMesh.md) | A transformable, visible, and raycastable Gaussian Splat scene object |
200
- | [`SplatLoader`](docs/SplatLoader.md) | A Three.js Loader-style PLY/SPZ decoder |
201
- | [`Splats`](docs/Splats.md) | The built-in mutable Splat source, with decoded reads and aligned batch mutation |
202
- | [`SplatEdit`](docs/SplatEdit.md) / [`SplatEditSdf`](docs/SplatEdit.md) | SDF-region RGBA editing objects |
203
- | [`SplatAccumulator`](docs/SplatAccumulator.md) | A low-level generation buffer used by the renderer; normally internal |
204
- | [`SplatFileType`](docs/SplatFileType.md) | File type enum containing `PLY` and `SPZ` |
205
- | [`postDecode`](docs/PostDecode.md) | **`Experimental`** Serializable per-Splat expressions executed inside the decode worker |
206
-
207
- ## Large world coordinates / GIS / ECEF
208
-
209
- The renderer keeps large translations separate from float32 local coordinates. Rendering subtracts the camera origin while values are still JavaScript double-precision numbers, and sorting stores one float64 world origin per `SplatMesh` alongside its float32 local centers. This happens automatically and does not move scene objects or change the world-coordinate behavior of `SplatMesh`, Raycaster, or SDF edits.
210
-
211
- Source Splat centers should still remain local to their mesh wherever possible. Precision already lost by storing absolute ECEF coordinates in a float32 source cannot be recovered during rendering.
212
-
213
- ## Manual updates and animation
131
+ import { SogStreamScheduler } from "gaussian-splat-lite";
214
132
 
215
- By default, the renderer automatically detects object-count, transform, appearance, and camera changes. Use `onFrame` for per-frame animation:
216
-
217
- ```js
218
- const splat = new SplatMesh({
219
- url: "/assets/model.spz",
220
- onFrame: ({ mesh, time }) => {
221
- mesh.rotation.y = time * 0.2;
222
- },
133
+ const streaming = new SogStreamScheduler({
134
+ url: "/assets/scene/lod-meta.json",
135
+ splatBudget: 3_000_000,
136
+ fadeDurationMs: 200, // Smooth LOD transitions (default).
223
137
  });
224
138
  ```
225
139
 
226
- When automatic updates are disabled, call `update()` after the scene or camera changes:
140
+ ## Depth Rendering
227
141
 
228
- ```js
229
- const splatRenderer = new GaussianSplatRenderer({
230
- renderer,
231
- autoUpdate: false,
232
- });
233
-
234
- await splatRenderer.update({ scene, camera });
235
- renderer.render(scene, camera);
236
- ```
142
+ **`renderDepth` adds a dedicated depth draw while keeping sorted color blending.** Both WebGPU and WebGL2 support it.
237
143
 
238
- ## Offscreen rendering
144
+ | Setting | Default | Purpose |
145
+ | --- | --- | --- |
146
+ | `renderDepth` | `false` | Adds Splat depth for geometry drawn later, including transparent meshes |
147
+ | `stochastic` | `false` | Forces sorting-free stochastic rendering with direct depth writes |
148
+ | `autoStochastic` | `false` | Uses stochastic rendering during motion and enables companion depth on sorted frames |
239
149
 
240
- ```js
241
- const captureRenderer = new GaussianSplatRenderer({
242
- renderer,
243
- target: {
244
- width: 1920,
245
- height: 1080,
246
- superXY: 2,
247
- },
248
- });
249
- scene.add(captureRenderer);
150
+ With default depth settings, the companion draw uses unsorted Splats on non-stochastic frames and samples alpha coverage so transparent edges do not become solid. Stochastic frames already write their own depth.
250
151
 
251
- await captureRenderer.update({ scene, camera });
252
- const rgba = await captureRenderer.renderReadTarget({ scene, camera });
253
- // rgba is a 1920 * 1080 * 4 Uint8Array.
254
- ```
152
+ ## Documentation
255
153
 
256
- If the same scene also contains a `GaussianSplatRenderer` used for canvas display, control the instances with `layers` or `visible` as appropriate so that both are not rendered as ordinary scene objects during the same pass.
154
+ - [GaussianSplatRenderer](docs/GaussianSplatRenderer.md) — Rendering, sorting, depth, resolve, and XR.
155
+ - [SplatMesh](docs/SplatMesh.md) — Loading, transforms, animation, and raycasting.
156
+ - [SplatLoader](docs/SplatLoader.md) — File loading.
157
+ - [RadStreamScheduler](docs/RadStreamScheduler.md) — Spark RAD decoding, tree LOD and on-demand paging.
158
+ - [SogStreamScheduler](docs/SogStreamScheduler.md) — Streamed SOG, camera-driven LOD and caching.
159
+ - [Splats](docs/Splats.md) — Data access and updates.
160
+ - [SplatFileType](docs/SplatFileType.md) — PLY/SPZ/SOG/RAD formats.
161
+ - [SplatEdit / SplatEditSdf](docs/SplatEdit.md) — Color and opacity editing.
162
+ - [postDecode](docs/PostDecode.md) — Per-Splat transformations during decoding.
163
+ - [SplatAccumulator](docs/SplatAccumulator.md) — Low-level GPU buffers.
257
164
 
258
165
  ## Development
259
166
 
260
- Building from source requires Node.js 20.9 or newer, a Rust toolchain installed through `rustup`, and the `wasm32-unknown-unknown` target. `build:wasm` installs `wasm-pack` through Cargo when it is not already available.
167
+ Requires Node.js 20.9+, Rust via `rustup`, and the `wasm32-unknown-unknown` target. `build:wasm` installs `wasm-pack` through Cargo if needed.
261
168
 
262
169
  ```sh
263
- npm install
170
+ npm ci
264
171
  npm run build:wasm
265
- npm run build
266
- npm test
172
+ npm run dev
267
173
  ```
268
174
 
269
- Start the local PLY/SPZ viewer with:
175
+ Open the URL printed by Vite (normally `http://localhost:8080/`) and drop a `.ply`, `.spz`, `.sog`, or `.rad` file into the viewer, choose a local file, or load one from an HTTP(S) URL. For split SOG, select or drop `meta.json` together with its `.webp` images; for split RAD, include the header and its `.radc` pages. Files are decoded locally. Choose **WebGL2 / WebGPU / WebGPU · WebGL2** in the viewer to compare backends; disable automatic stochastic mode to expose the **Force Splat depth** control.
270
176
 
271
- ```sh
272
- npm run dev
273
- ```
177
+ The viewer enables `reversedDepthBuffer` for depth precision on WebGPU and both WebGL2 backends. WebGL2 uses it when `EXT_clip_control` is available.
274
178
 
275
- Open the local URL printed by Vite, normally `http://localhost:8080/`. Drag a `.ply` or `.spz` file onto the viewer, or use its file picker. Files are decoded locally and are not uploaded.
179
+ For streaming, load a RAD file or enter a SOG `lod-meta.json` URL. The viewer streams RAD files with a LOD tree automatically and falls back to ordinary loading when no tree is present. Move the camera to see LOD selection and on-demand loading.
276
180
 
277
- Other useful commands:
181
+ See [Contributing](CONTRIBUTING.md#validation) for validation and release commands. `npm run build` emits ESM, CommonJS, TypeScript declarations, and source maps in `dist/`.
278
182
 
279
- ```sh
280
- npm run build:watch
281
- npm run check
282
- npm run lint
283
- npm run format
284
- npm run release:check
285
- ```
183
+ ## Acknowledgements
286
184
 
287
- The package build emits ESM and CommonJS bundles in `dist/`, together with TypeScript declarations and source maps.
185
+ The overall architecture of Gaussian Splat Lite draws on [Spark](https://github.com/sparkjsdev/spark) and [SuperSplat](https://github.com/playcanvas/supersplat).
288
186
 
289
187
  ## License
290
188
 
291
- Gaussian Splat Lite is licensed under the [Apache License 2.0](LICENSE). Required attribution notices are provided in [NOTICE](NOTICE), and bundled third-party licenses are listed in [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md).
189
+ Licensed under [Apache 2.0](LICENSE). See [NOTICE](NOTICE) and [third-party licenses](THIRD_PARTY_LICENSES.md) for attribution.
@@ -26,6 +26,32 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
26
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
27
  THE SOFTWARE.
28
28
 
29
+ ## SuperSplat 3.0.0-alpha
30
+
31
+ Gaussian Splat Lite includes software adapted from SuperSplat 3.0.0-alpha.
32
+
33
+ MIT License
34
+
35
+ Copyright (c) 2011-2026 PlayCanvas Ltd.
36
+
37
+ Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ of this software and associated documentation files (the "Software"), to deal
39
+ in the Software without restriction, including without limitation the rights
40
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ copies of the Software, and to permit persons to whom the Software is
42
+ furnished to do so, subject to the following conditions:
43
+
44
+ The above copyright notice and this permission notice shall be included in
45
+ all copies or substantial portions of the Software.
46
+
47
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ THE SOFTWARE.
54
+
29
55
  ## ruzstd 0.7.3
30
56
 
31
57
  Gaussian Splat Lite includes ruzstd 0.7.3 in its WebAssembly build.
@@ -51,3 +77,36 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
77
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
78
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
53
79
  SOFTWARE.
80
+
81
+ ## SOG decoding dependencies
82
+
83
+ The WebAssembly build includes image-webp 0.2.4, png 0.17.16,
84
+ serde/serde_core 1.0.229, and serde_json 1.0.151 under the MIT license.
85
+
86
+ png: Copyright (c) 2015 nwin
87
+
88
+ MIT License
89
+
90
+ Permission is hereby granted, free of charge, to any
91
+ person obtaining a copy of this software and associated
92
+ documentation files (the "Software"), to deal in the
93
+ Software without restriction, including without
94
+ limitation the rights to use, copy, modify, merge,
95
+ publish, distribute, sublicense, and/or sell copies of
96
+ the Software, and to permit persons to whom the Software
97
+ is furnished to do so, subject to the following
98
+ conditions:
99
+
100
+ The above copyright notice and this permission notice
101
+ shall be included in all copies or substantial portions
102
+ of the Software.
103
+
104
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
105
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
106
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
107
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
108
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
109
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
110
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
111
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
112
+ DEALINGS IN THE SOFTWARE.