gaussian-splat-lite 1.2.0 → 1.2.2

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 (63) hide show
  1. package/CHANGELOG.md +44 -2
  2. package/README.md +22 -13
  3. package/dist/gaussian-splat-lite.cjs +819 -88
  4. package/dist/gaussian-splat-lite.cjs.map +1 -1
  5. package/dist/gaussian-splat-lite.min.cjs +81 -20
  6. package/dist/gaussian-splat-lite.min.cjs.map +1 -1
  7. package/dist/gaussian-splat-lite.module.js +821 -90
  8. package/dist/gaussian-splat-lite.module.js.map +1 -1
  9. package/dist/gaussian-splat-lite.module.min.js +2984 -2427
  10. package/dist/gaussian-splat-lite.module.min.js.map +1 -1
  11. package/dist/types/addons/TAANode.d.cts +4 -2
  12. package/dist/types/addons/TAANode.d.ts +4 -2
  13. package/dist/types/addons/TAAPass.d.cts +6 -15
  14. package/dist/types/addons/TAAPass.d.ts +6 -15
  15. package/dist/types/addons/taaShared.d.cts +4 -2
  16. package/dist/types/addons/taaShared.d.ts +4 -2
  17. package/dist/types/capture/SplatCapture.d.cts +66 -0
  18. package/dist/types/capture/SplatCapture.d.ts +66 -0
  19. package/dist/types/capture/WebGLCapture.d.cts +13 -0
  20. package/dist/types/capture/WebGLCapture.d.ts +13 -0
  21. package/dist/types/capture/WebGPUCapture.d.cts +17 -0
  22. package/dist/types/capture/WebGPUCapture.d.ts +17 -0
  23. package/dist/types/capture/pixels.d.cts +5 -0
  24. package/dist/types/capture/pixels.d.ts +5 -0
  25. package/dist/types/capture/rendererState.d.cts +3 -0
  26. package/dist/types/capture/rendererState.d.ts +3 -0
  27. package/dist/types/capture/sceneView.d.cts +3 -0
  28. package/dist/types/capture/sceneView.d.ts +3 -0
  29. package/dist/types/index.d.cts +1 -1
  30. package/dist/types/index.d.ts +1 -1
  31. package/dist/types/rendering/GaussianSplatRenderer.d.cts +17 -11
  32. package/dist/types/rendering/GaussianSplatRenderer.d.ts +17 -11
  33. package/dist/types/rendering/SplatAccumulator.d.cts +2 -1
  34. package/dist/types/rendering/SplatAccumulator.d.ts +2 -1
  35. package/dist/types/rendering/backend.d.cts +1 -1
  36. package/dist/types/rendering/backend.d.ts +1 -1
  37. package/dist/types/rendering/rendererUtils.d.cts +1 -5
  38. package/dist/types/rendering/rendererUtils.d.ts +1 -5
  39. package/dist/types/rendering/tsl/ProjectionProgram.d.cts +2 -0
  40. package/dist/types/rendering/tsl/ProjectionProgram.d.ts +2 -0
  41. package/dist/types/rendering/tsl/SplatMaterial.d.cts +1 -0
  42. package/dist/types/rendering/tsl/SplatMaterial.d.ts +1 -0
  43. package/dist/types/rendering/tsl/tslCompat.d.cts +1 -0
  44. package/dist/types/rendering/tsl/tslCompat.d.ts +1 -0
  45. package/dist/types/rendering/uniforms.d.cts +3 -3
  46. package/dist/types/rendering/uniforms.d.ts +3 -3
  47. package/dist/types/scene/SplatMesh.d.cts +1 -1
  48. package/dist/types/scene/SplatMesh.d.ts +1 -1
  49. package/docs/Architecture.md +54 -3
  50. package/docs/GaussianSplatRenderer.md +71 -55
  51. package/docs/PostDecode.md +52 -36
  52. package/docs/RadStreamScheduler.md +53 -41
  53. package/docs/SogStreamScheduler.md +49 -39
  54. package/docs/SplatCapture.md +147 -0
  55. package/docs/SplatEdit.md +33 -26
  56. package/docs/SplatFileType.md +11 -13
  57. package/docs/SplatLoader.md +19 -14
  58. package/docs/SplatMesh.md +69 -49
  59. package/docs/Splats.md +33 -26
  60. package/docs/StochasticRendering.md +27 -30
  61. package/docs/TAAPass.md +98 -73
  62. package/package.json +1 -1
  63. package/docs/SplatAccumulator.md +0 -37
@@ -1 +1 @@
1
- {"version":3,"file":"gaussian-splat-lite.cjs","sources":["../src/runtime/transferable.ts","../rust/gaussian-splat-rs/pkg/gaussian_splat_rs.js","../virtual:decode-64","../src/runtime/wasm.ts","../src/runtime/WorkerRpc.ts","../src/runtime/abort.ts","../src/runtime/SplatWorker.ts","../src/utils/three.ts","../src/rendering/SortCenterCache.ts","../src/data/defines.ts","../src/data/textureLayout.ts","../src/utils/transforms.ts","../src/scene/SplatEdit.ts","../src/utils/numeric.ts","../src/data/splatCodec.ts","../src/data/splatData.ts","../src/data/unpack.ts","../src/data/Splats.ts","../src/data/raycast.ts","../src/scene/SplatMesh.ts","../src/rendering/rendererUtils.ts","../src/rendering/tsl/tslCompat.ts","../src/rendering/tsl/shaderUtils.ts","../src/rendering/tsl/GenerateProgram.ts","../src/rendering/blueNoise.ts","../src/rendering/uniforms.ts","../src/rendering/webgl/shaders/splatDefines.glsl","../src/rendering/webgl/shaders/splatFragment.glsl","../src/rendering/webgl/shaders/splatVertex.glsl","../src/rendering/webgl/shaders.ts","../src/rendering/webgl/shaders/splatGenerate.glsl","../src/rendering/webgl/textureUtils.ts","../src/rendering/webgl/AccumulatorGenerator.ts","../src/rendering/webgl-fallback/AccumulatorGenerator.ts","../src/rendering/SplatAccumulator.ts","../src/rendering/SplatGeometry.ts","../src/rendering/tsl/ProjectionProgram.ts","../src/rendering/tsl/viewUniforms.ts","../src/rendering/tsl/SplatMaterial.ts","../src/rendering/tsl/SplatBackend.ts","../src/rendering/webgl/OrderingTexture.ts","../src/rendering/webgl-fallback/SplatBackend.ts","../src/rendering/webgl/SplatMaterial.ts","../src/rendering/webgl/SplatBackend.ts","../src/addons/taaShared.ts","../src/rendering/webgpu/ProjectionCache.ts","../src/rendering/webgpu/RadixSort.ts","../src/rendering/webgpu/ProjectedSplats.ts","../src/rendering/webgpu/SplatBackend.ts","../src/rendering/backend.ts","../src/rendering/GaussianSplatRenderer.ts","../src/addons/TAAPass.ts","../src/addons/TAANode.ts","../src/loaders/assetUrl.ts","../src/loaders/postDecode/protocol.ts","../src/loaders/postDecode/builder.ts","../src/loaders/postDecode/optimizer.ts","../src/loaders/postDecode/compiler.ts","../src/loaders/postDecode/program.ts","../src/loaders/loadSplatData.ts","../src/loaders/SplatLoader.ts","../src/data/SplatOpacityTable.ts","../src/data/IndexedSplats.ts","../src/data/RadPagedSplats.ts","../src/runtime/retry.ts","../src/loaders/rad/radFormat.ts","../src/loaders/stream/StreamByteBudget.ts","../src/loaders/stream/StreamCameras.ts","../src/loaders/stream/streamOptions.ts","../src/loaders/stream/rad-stream/RadStreamBatch.ts","../src/loaders/source.ts","../src/loaders/rad/RadSource.ts","../src/loaders/stream/StreamWorkerPool.ts","../src/loaders/stream/rad-stream/RadStreamWorker.ts","../src/loaders/stream/rad-stream/RadStreamLoader.ts","../src/loaders/stream/rad-stream/radLod.ts","../src/loaders/stream/rad-stream/RadStreamScheduler.ts","../src/data/SogRegionSplats.ts","../src/loaders/stream/sog-stream/SogStreamBatch.ts","../src/loaders/stream/sog-stream/SogStreamWorker.ts","../src/loaders/stream/sog-stream/SogStreamLoader.ts","../src/loaders/stream/sog-stream/sogLod.ts","../src/loaders/stream/sog-stream/sogVisibility.ts","../src/loaders/stream/sog-stream/SogStreamScheduler.ts"],"sourcesContent":["// Recursively finds all ArrayBuffers in an object for structured-clone transfer.\nexport function getTransferable(ctx: unknown): Transferable[] {\n const buffers = new Set<Transferable>();\n const seen = new Set();\n\n function traverse(obj: unknown) {\n if (!obj || typeof obj !== \"object\" || seen.has(obj)) return;\n seen.add(obj);\n\n if (obj instanceof ArrayBuffer) {\n buffers.add(obj);\n } else if (ArrayBuffer.isView(obj)) {\n buffers.add(obj.buffer as ArrayBuffer);\n } else {\n Object.values(obj).forEach(traverse);\n }\n }\n\n traverse(ctx);\n return [...buffers];\n}\n","/* @ts-self-types=\"./gaussian_splat_rs.d.ts\" */\n\nexport class ChunkDecoder {\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ChunkDecoder.prototype);\n obj.__wbg_ptr = ptr;\n ChunkDecoderFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ChunkDecoderFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_chunkdecoder_free(ptr, 0);\n }\n /**\n * @returns {any}\n */\n finish() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.chunkdecoder_finish(ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * @param {Uint8Array} bytes\n */\n push(bytes) {\n const ret = wasm.chunkdecoder_push(this.__wbg_ptr, bytes);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {number} size\n */\n set_expected_input_size(size) {\n const ret = wasm.chunkdecoder_set_expected_input_size(this.__wbg_ptr, size);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n}\nif (Symbol.dispose) ChunkDecoder.prototype[Symbol.dispose] = ChunkDecoder.prototype.free;\n\n/**\n * Owns only dataset metadata and the requested SH codebooks. Call the generated\n * `free()` method when a load finishes or its stream scheduler is disposed.\n */\nexport class RadDecoder {\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n RadDecoderFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_raddecoder_free(ptr, 0);\n }\n /**\n * @param {Uint8Array} bytes\n * @returns {any}\n */\n decode_chunk(bytes) {\n const ret = wasm.raddecoder_decode_chunk(this.__wbg_ptr, bytes);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * Initialize from the root already validated by the first decode worker.\n * @param {Uint8Array} bytes\n */\n initialize_codebooks(bytes) {\n const ret = wasm.raddecoder_initialize_codebooks(this.__wbg_ptr, bytes);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {string} meta_json\n * @param {number} max_sh\n */\n constructor(meta_json, max_sh) {\n const ptr0 = passStringToWasm0(meta_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.raddecoder_new(ptr0, len0, max_sh);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n this.__wbg_ptr = ret[0] >>> 0;\n RadDecoderFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n}\nif (Symbol.dispose) RadDecoder.prototype[Symbol.dispose] = RadDecoder.prototype.free;\n\nexport class RadLodTree {\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n RadLodTreeFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_radlodtree_free(ptr, 0);\n }\n /**\n * @param {string} meta_json\n */\n constructor(meta_json) {\n const ptr0 = passStringToWasm0(meta_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.radlodtree_new(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n this.__wbg_ptr = ret[0] >>> 0;\n RadLodTreeFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @param {number} index\n * @param {number | null} [generation]\n */\n release_chunk(index, generation) {\n wasm.radlodtree_release_chunk(this.__wbg_ptr, index, !isLikeNone(generation), isLikeNone(generation) ? 0 : generation);\n }\n /**\n * @param {number} index\n * @param {number} generation\n * @param {Float32Array} centers\n * @param {Float32Array} radii\n * @param {Uint32Array} child_start\n * @param {Uint16Array} child_count\n */\n retain_chunk(index, generation, centers, radii, child_start, child_count) {\n const ret = wasm.radlodtree_retain_chunk(this.__wbg_ptr, index, generation, centers, radii, child_start, child_count);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {Float64Array} views\n * @param {Uint32Array} resident_chunks\n * @param {number} budget\n * @param {number} threshold\n * @param {number} hysteresis\n * @returns {any}\n */\n select(views, resident_chunks, budget, threshold, hysteresis) {\n const ret = wasm.radlodtree_select(this.__wbg_ptr, views, resident_chunks, budget, threshold, hysteresis);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n}\nif (Symbol.dispose) RadLodTree.prototype[Symbol.dispose] = RadLodTree.prototype.free;\n\nexport class SogDecodeSession {\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n SogDecodeSessionFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_sogdecodesession_free(ptr, 0);\n }\n /**\n * @param {Array<any>} chunks\n * @param {number} method\n * @param {number} uncompressed_size\n * @param {number} crc\n */\n decode_asset(chunks, method, uncompressed_size, crc) {\n const ret = wasm.sogdecodesession_decode_asset(this.__wbg_ptr, chunks, method, uncompressed_size, crc);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @returns {boolean}\n */\n decode_batch() {\n const ret = wasm.sogdecodesession_decode_batch(this.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ret[0] !== 0;\n }\n /**\n * @returns {object}\n */\n finish() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.sogdecodesession_finish(ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * @param {string} metadata\n */\n constructor(metadata) {\n const ptr0 = passStringToWasm0(metadata, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.sogdecodesession_new(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n this.__wbg_ptr = ret[0] >>> 0;\n SogDecodeSessionFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @returns {string}\n */\n plan() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.sogdecodesession_plan(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n}\nif (Symbol.dispose) SogDecodeSession.prototype[Symbol.dispose] = SogDecodeSession.prototype.free;\n\n/**\n * @param {Uint8Array} bytes\n * @returns {any}\n */\nexport function decode_rad_header(bytes) {\n const ret = wasm.decode_rad_header(bytes);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n}\n\n/**\n * @param {Uint8Array} bytes\n * @param {number} method\n * @param {number} size\n * @param {number} crc\n * @returns {string}\n */\nexport function decode_sog_meta(bytes, method, size, crc) {\n let deferred2_0;\n let deferred2_1;\n try {\n const ret = wasm.decode_sog_meta(bytes, method, size, crc);\n var ptr1 = ret[0];\n var len1 = ret[1];\n if (ret[3]) {\n ptr1 = 0; len1 = 0;\n throw takeFromExternrefTable0(ret[2]);\n }\n deferred2_0 = ptr1;\n deferred2_1 = len1;\n return getStringFromWasm0(ptr1, len1);\n } finally {\n wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);\n }\n}\n\n/**\n * @param {string | null} [file_type]\n * @param {string | null} [path_name]\n * @returns {ChunkDecoder}\n */\nexport function decode_to_splats(file_type, path_name) {\n var ptr0 = isLikeNone(file_type) ? 0 : passStringToWasm0(file_type, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len0 = WASM_VECTOR_LEN;\n var ptr1 = isLikeNone(path_name) ? 0 : passStringToWasm0(path_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len1 = WASM_VECTOR_LEN;\n const ret = wasm.decode_to_splats(ptr0, len0, ptr1, len1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ChunkDecoder.__wrap(ret[0]);\n}\n\n/**\n * @returns {Uint32Array}\n */\nexport function get_raycast_buffer() {\n const ret = wasm.get_raycast_buffer();\n return ret;\n}\n\n/**\n * @returns {Uint32Array}\n */\nexport function get_raycast_buffer2() {\n const ret = wasm.get_raycast_buffer2();\n return ret;\n}\n\n/**\n * Record indices corresponding one-for-one to the last raycast distances.\n * This view is valid until the next call to `raycast_splat_buffers`.\n * @returns {Uint32Array}\n */\nexport function get_raycast_indices() {\n const ret = wasm.get_raycast_indices();\n return ret;\n}\n\n/**\n * @param {number} count\n * @param {Array<any>} arrays\n * @param {Uint32Array | null | undefined} sort_centers\n * @param {Uint32Array | null | undefined} source_ids\n * @param {Float32Array} center_only_bounds\n * @param {Float32Array} bounds\n * @param {Float32Array | null | undefined} bounds_blocks\n * @param {Float32Array} spatial_bounds\n * @param {Function | null} [progress]\n * @returns {Uint32Array}\n */\nexport function morton_reorder(count, arrays, sort_centers, source_ids, center_only_bounds, bounds, bounds_blocks, spatial_bounds, progress) {\n const ret = wasm.morton_reorder(count, arrays, isLikeNone(sort_centers) ? 0 : addToExternrefTable0(sort_centers), isLikeNone(source_ids) ? 0 : addToExternrefTable0(source_ids), center_only_bounds, bounds, isLikeNone(bounds_blocks) ? 0 : addToExternrefTable0(bounds_blocks), spatial_bounds, isLikeNone(progress) ? 0 : addToExternrefTable0(progress));\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n}\n\n/**\n * @param {number} origin_x\n * @param {number} origin_y\n * @param {number} origin_z\n * @param {number} dir_x\n * @param {number} dir_y\n * @param {number} dir_z\n * @param {number} min_opacity\n * @param {number} near\n * @param {number} far\n * @param {number} count\n * @returns {Float32Array}\n */\nexport function raycast_splat_buffers(origin_x, origin_y, origin_z, dir_x, dir_y, dir_z, min_opacity, near, far, count) {\n const ret = wasm.raycast_splat_buffers(origin_x, origin_y, origin_z, dir_x, dir_y, dir_z, min_opacity, near, far, count);\n return ret;\n}\n\n/**\n * @param {Uint32Array} center_update_range_indices\n * @param {Float32Array} update_centers\n * @param {Uint32Array} matrix_update_range_indices\n * @param {Float64Array} update_matrices\n * @param {Uint32Array} range_mesh_ids\n * @param {Uint32Array} range_bases\n * @param {Uint32Array} range_counts\n */\nexport function set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts) {\n wasm.set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts);\n}\n\n/**\n * @param {number} num_splats\n * @param {number} camera_x\n * @param {number} camera_y\n * @param {number} camera_z\n * @param {number} direction_x\n * @param {number} direction_y\n * @param {number} direction_z\n * @param {boolean} radial\n * @param {boolean} fast_sort\n * @param {boolean} front_sort\n * @param {Uint32Array} ordering\n * @returns {number}\n */\nexport function sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, fast_sort, front_sort, ordering) {\n const ret = wasm.sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, fast_sort, front_sort, ordering);\n return ret >>> 0;\n}\n\n/**\n * Remains readable after an allocation abort, which otherwise looks like any\n * other `unreachable` trap to JavaScript. The failed instance is then retired.\n * @returns {boolean}\n */\nexport function wasm_allocation_failed() {\n const ret = wasm.wasm_allocation_failed();\n return ret !== 0;\n}\n\nexport function wasm_start() {\n wasm.wasm_start();\n}\n\nfunction __wbg_get_imports() {\n const import0 = {\n __proto__: null,\n __wbg___wbindgen_debug_string_dd5d2d07ce9e6c57: function(arg0, arg1) {\n const ret = debugString(arg1);\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg___wbindgen_throw_81fc77679af83bc6: function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n },\n __wbg_call_368fa9c372d473ba: function() { return handleError(function (arg0, arg1, arg2, arg3) {\n const ret = arg0.call(arg1, arg2, arg3);\n return ret;\n }, arguments); },\n __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {\n let deferred0_0;\n let deferred0_1;\n try {\n deferred0_0 = arg0;\n deferred0_1 = arg1;\n console.error(getStringFromWasm0(arg0, arg1));\n } finally {\n wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);\n }\n },\n __wbg_get_index_983d655608220248: function(arg0, arg1) {\n const ret = arg0[arg1 >>> 0];\n return ret;\n },\n __wbg_get_unchecked_7d7babe32e9e6a54: function(arg0, arg1) {\n const ret = arg0[arg1 >>> 0];\n return ret;\n },\n __wbg_instanceof_Uint32Array_1048c66d96e96680: function(arg0) {\n let result;\n try {\n result = arg0 instanceof Uint32Array;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n },\n __wbg_length_0c32cb8543c8e4c8: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_1e701798fdcaa3b4: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_526c0f6e4ebae15d: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_6e821edde497a532: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_a4ca9e78359b5f1f: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_fd4646b401926788: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_new_227d7c05414eb861: function() {\n const ret = new Error();\n return ret;\n },\n __wbg_new_4f9fafbb3909af72: function() {\n const ret = new Object();\n return ret;\n },\n __wbg_new_e3b04b4d53d1b593: function(arg0, arg1) {\n const ret = new Error(getStringFromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_from_slice_798885084b9cc1d2: function(arg0, arg1) {\n const ret = new Uint32Array(getArrayU32FromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_from_slice_d4e6804502a531e5: function(arg0, arg1) {\n const ret = new Uint16Array(getArrayU16FromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_from_slice_d85ad974cf8f6f35: function(arg0, arg1) {\n const ret = new Float32Array(getArrayF32FromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_with_length_26bffbe236bf73f9: function(arg0) {\n const ret = new Float32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_new_with_length_41a22191b9bdfd66: function(arg0) {\n const ret = new Uint32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_parse_545d11396395fbbd: function() { return handleError(function (arg0, arg1) {\n const ret = JSON.parse(getStringFromWasm0(arg0, arg1));\n return ret;\n }, arguments); },\n __wbg_prototypesetcall_021fd89d67217368: function(arg0, arg1, arg2) {\n Float64Array.prototype.set.call(getArrayF64FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_3e05eb9545565046: function(arg0, arg1, arg2) {\n Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_64c287a27cc24d27: function(arg0, arg1, arg2) {\n Uint16Array.prototype.set.call(getArrayU16FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_66c8e1fb820946be: function(arg0, arg1, arg2) {\n Float32Array.prototype.set.call(getArrayF32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_e42275e601e14eeb: function(arg0, arg1, arg2) {\n Uint32Array.prototype.set.call(getArrayU32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_set_448126769bf7c181: function(arg0, arg1, arg2) {\n arg0.set(getArrayU32FromWasm0(arg1, arg2));\n },\n __wbg_set_8ee2d34facb8466e: function() { return handleError(function (arg0, arg1, arg2) {\n const ret = Reflect.set(arg0, arg1, arg2);\n return ret;\n }, arguments); },\n __wbg_set_a98c8da6557e63de: function(arg0, arg1, arg2) {\n arg0.set(getArrayF32FromWasm0(arg1, arg2));\n },\n __wbg_set_index_a561936dd7004b5a: function(arg0, arg1, arg2) {\n arg0[arg1 >>> 0] = arg2;\n },\n __wbg_set_length_3995d60e8394cd98: function(arg0, arg1) {\n arg0.length = arg1 >>> 0;\n },\n __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {\n const ret = arg1.stack;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg_subarray_0f98d3fb634508ad: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_1230568a23d546e8: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_4342405c1ffc86d6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_d51e89458b3fdbf6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbindgen_cast_0000000000000001: function(arg0) {\n // Cast intrinsic for `F64 -> Externref`.\n const ret = arg0;\n return ret;\n },\n __wbindgen_cast_0000000000000002: function(arg0, arg1) {\n // Cast intrinsic for `Ref(Slice(F32)) -> NamedExternref(\"Float32Array\")`.\n const ret = getArrayF32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000003: function(arg0, arg1) {\n // Cast intrinsic for `Ref(Slice(U32)) -> NamedExternref(\"Uint32Array\")`.\n const ret = getArrayU32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000004: function(arg0, arg1) {\n // Cast intrinsic for `Ref(String) -> Externref`.\n const ret = getStringFromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_init_externref_table: function() {\n const table = wasm.__wbindgen_externrefs;\n const offset = table.grow(4);\n table.set(0, undefined);\n table.set(offset + 0, undefined);\n table.set(offset + 1, null);\n table.set(offset + 2, true);\n table.set(offset + 3, false);\n },\n };\n return {\n __proto__: null,\n \"./gaussian_splat_rs_bg.js\": import0,\n };\n}\n\nconst ChunkDecoderFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_chunkdecoder_free(ptr >>> 0, 1));\nconst RadDecoderFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_raddecoder_free(ptr >>> 0, 1));\nconst RadLodTreeFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_radlodtree_free(ptr >>> 0, 1));\nconst SogDecodeSessionFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_sogdecodesession_free(ptr >>> 0, 1));\n\nfunction addToExternrefTable0(obj) {\n const idx = wasm.__externref_table_alloc();\n wasm.__wbindgen_externrefs.set(idx, obj);\n return idx;\n}\n\nfunction debugString(val) {\n // primitive types\n const type = typeof val;\n if (type == 'number' || type == 'boolean' || val == null) {\n return `${val}`;\n }\n if (type == 'string') {\n return `\"${val}\"`;\n }\n if (type == 'symbol') {\n const description = val.description;\n if (description == null) {\n return 'Symbol';\n } else {\n return `Symbol(${description})`;\n }\n }\n if (type == 'function') {\n const name = val.name;\n if (typeof name == 'string' && name.length > 0) {\n return `Function(${name})`;\n } else {\n return 'Function';\n }\n }\n // objects\n if (Array.isArray(val)) {\n const length = val.length;\n let debug = '[';\n if (length > 0) {\n debug += debugString(val[0]);\n }\n for(let i = 1; i < length; i++) {\n debug += ', ' + debugString(val[i]);\n }\n debug += ']';\n return debug;\n }\n // Test for built-in\n const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n let className;\n if (builtInMatches && builtInMatches.length > 1) {\n className = builtInMatches[1];\n } else {\n // Failed to match the standard '[object ClassName]'\n return toString.call(val);\n }\n if (className == 'Object') {\n // we're a user defined class or Object\n // JSON.stringify avoids problems with cycles, and is generally much\n // easier than looping through ownProperties of `val`.\n try {\n return 'Object(' + JSON.stringify(val) + ')';\n } catch (_) {\n return 'Object';\n }\n }\n // errors\n if (val instanceof Error) {\n return `${val.name}: ${val.message}\\n${val.stack}`;\n }\n // TODO we could test for more things here, like `Set`s and `Map`s.\n return className;\n}\n\nfunction getArrayF32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n}\n\nfunction getArrayF64FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);\n}\n\nfunction getArrayU16FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint16ArrayMemory0().subarray(ptr / 2, ptr / 2 + len);\n}\n\nfunction getArrayU32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nlet cachedDataViewMemory0 = null;\nfunction getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n}\n\nlet cachedFloat32ArrayMemory0 = null;\nfunction getFloat32ArrayMemory0() {\n if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {\n cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);\n }\n return cachedFloat32ArrayMemory0;\n}\n\nlet cachedFloat64ArrayMemory0 = null;\nfunction getFloat64ArrayMemory0() {\n if (cachedFloat64ArrayMemory0 === null || cachedFloat64ArrayMemory0.byteLength === 0) {\n cachedFloat64ArrayMemory0 = new Float64Array(wasm.memory.buffer);\n }\n return cachedFloat64ArrayMemory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return decodeText(ptr, len);\n}\n\nlet cachedUint16ArrayMemory0 = null;\nfunction getUint16ArrayMemory0() {\n if (cachedUint16ArrayMemory0 === null || cachedUint16ArrayMemory0.byteLength === 0) {\n cachedUint16ArrayMemory0 = new Uint16Array(wasm.memory.buffer);\n }\n return cachedUint16ArrayMemory0;\n}\n\nlet cachedUint32ArrayMemory0 = null;\nfunction getUint32ArrayMemory0() {\n if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {\n cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);\n }\n return cachedUint32ArrayMemory0;\n}\n\nlet cachedUint8ArrayMemory0 = null;\nfunction getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n}\n\nfunction handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n const idx = addToExternrefTable0(e);\n wasm.__wbindgen_exn_store(idx);\n }\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n if (realloc === undefined) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n\n const mem = getUint8ArrayMemory0();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7F) break;\n mem[ptr + offset] = code;\n }\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = cachedTextEncoder.encodeInto(arg, view);\n\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n\n WASM_VECTOR_LEN = offset;\n return ptr;\n}\n\nfunction takeFromExternrefTable0(idx) {\n const value = wasm.__wbindgen_externrefs.get(idx);\n wasm.__externref_table_dealloc(idx);\n return value;\n}\n\nlet cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\ncachedTextDecoder.decode();\nconst MAX_SAFARI_DECODE_BYTES = 2146435072;\nlet numBytesDecoded = 0;\nfunction decodeText(ptr, len) {\n numBytesDecoded += len;\n if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n numBytesDecoded = len;\n }\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n\nconst cachedTextEncoder = new TextEncoder();\n\nif (!('encodeInto' in cachedTextEncoder)) {\n cachedTextEncoder.encodeInto = function (arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n };\n}\n\nlet WASM_VECTOR_LEN = 0;\n\nlet wasmModule, wasm;\nfunction __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n wasmModule = module;\n cachedDataViewMemory0 = null;\n cachedFloat32ArrayMemory0 = null;\n cachedFloat64ArrayMemory0 = null;\n cachedUint16ArrayMemory0 = null;\n cachedUint32ArrayMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n wasm.__wbindgen_start();\n return wasm;\n}\n\nasync function __wbg_load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n } catch (e) {\n const validResponse = module.ok && expectedResponseType(module.type);\n\n if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {\n console.warn(\"`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else { throw e; }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n } else {\n return instance;\n }\n }\n\n function expectedResponseType(type) {\n switch (type) {\n case 'basic': case 'cors': case 'default': return true;\n }\n return false;\n }\n}\n\nfunction initSync(module) {\n if (wasm !== undefined) return wasm;\n\n\n if (module !== undefined) {\n if (Object.getPrototypeOf(module) === Object.prototype) {\n ({module} = module)\n } else {\n console.warn('using deprecated parameters for `initSync()`; pass a single object instead')\n }\n }\n\n const imports = __wbg_get_imports();\n if (!(module instanceof WebAssembly.Module)) {\n module = new WebAssembly.Module(module);\n }\n const instance = new WebAssembly.Instance(module, imports);\n return __wbg_finalize_init(instance, module);\n}\n\nasync function __wbg_init(module_or_path) {\n if (wasm !== undefined) return wasm;\n\n\n if (module_or_path !== undefined) {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({module_or_path} = module_or_path)\n } else {\n console.warn('using deprecated parameters for the initialization function; pass a single object instead')\n }\n }\n\n\n const imports = __wbg_get_imports();\n\n if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {\n module_or_path = fetch(module_or_path);\n }\n\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nexport { initSync, __wbg_init as default };\n","function b64ToUint6(nChr) {\n return nChr > 64 && nChr < 91\n ? nChr - 65\n : nChr > 96 && nChr < 123\n ? nChr - 71\n : nChr > 47 && nChr < 58\n ? nChr + 4\n : nChr === 43\n ? 62\n : nChr === 47\n ? 63\n : 0\n}\n\nfunction base64ToUint8(sBase64, nBlocksSize) {\n const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, \"\")\n const nInLen = sB64Enc.length\n const nOutLen = nBlocksSize\n ? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize\n : (nInLen * 3 + 1) >> 2\n const taBytes = new Uint8Array(nOutLen)\n\n let nMod3\n let nMod4\n let nUint24 = 0\n let nOutIdx = 0\n for (let nInIdx = 0; nInIdx < nInLen; nInIdx++) {\n nMod4 = nInIdx & 3\n nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4))\n if (nMod4 === 3 || nInLen - nInIdx === 1) {\n nMod3 = 0\n while (nMod3 < 3 && nOutIdx < nOutLen) {\n taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255\n nMod3++\n nOutIdx++\n }\n nUint24 = 0\n }\n }\n\n return taBytes\n}\nfunction toUint8(b64) {\n if (typeof Uint8Array.fromBase64 === \"function\") return Uint8Array.fromBase64(b64)\n let bin = atob(b64)\n let len = bin.length\n let bytes = new Uint8Array(len)\n for (let i = 0; i < len; i++) {\n bytes[i] = bin.charCodeAt(i)\n }\n return bytes\n}\n\nconst decode64 = typeof atob === \"function\" ? toUint8 : base64ToUint8\n\nexport default decode64\n","import initWasm from \"gaussian-splat-rs\";\nimport wasmBytes from \"gaussian-splat-rs/gaussian_splat_rs_bg.wasm?arraybuffer&base64\";\n\nexport const WASM_MODULE = WebAssembly.compile(wasmBytes);\n\nlet initialized = false;\n\n/** Initializes the main-thread WASM instance used by raycasting. */\nexport const WASM_READY = initWasm({ module_or_path: WASM_MODULE }).then(() => {\n initialized = true;\n});\n// Consumers still receive the rejection; loading the module alone must not\n// create an unhandled rejection when WebAssembly initialization fails.\nvoid WASM_READY.catch(() => {});\n\nexport function isInitialized() {\n return initialized;\n}\n","import { getTransferable } from \"./transferable\";\nimport { WASM_MODULE } from \"./wasm\";\n\ntype PromiseRecord = {\n resolve: (value: unknown) => void;\n reject: (reason?: unknown) => void;\n onStatus?: (data: unknown) => void | Promise<void>;\n statusQueue: Promise<void>;\n};\n\n/** Transport/cache loss is recoverable by obtaining a fresh worker. */\nexport class WorkerTerminatedError extends Error {\n constructor(reason: unknown = \"Worker terminated\") {\n super(String(reason));\n this.name = \"WorkerTerminatedError\";\n }\n}\n\n/** Typed main-thread transport shared by ordinary and streaming workers. */\nexport class WorkerRpc<\n Handlers extends { [K in keyof Handlers]: (...args: never[]) => unknown },\n> {\n messages: Record<number, PromiseRecord> = {};\n peakWasmMemoryBytes = 0;\n disposed = false;\n static currentId = 0;\n\n constructor(\n readonly worker: Worker,\n private readonly onDispose?: () => void,\n ) {\n this.worker.onmessage = (event) => this.onMessage(event);\n this.worker.onerror = (event) =>\n this.dispose(new WorkerTerminatedError(event.message));\n this.worker.onmessageerror = () =>\n this.dispose(new WorkerTerminatedError(\"Invalid worker message\"));\n void WASM_MODULE.then((module) => {\n if (!this.disposed)\n this.worker.postMessage({ name: \"init-wasm\", module });\n }).catch((error) => this.dispose(error));\n }\n\n onMessage(event: MessageEvent) {\n const { id, result, error, fatal, status, wasmMemoryBytes } = event.data;\n const promise = this.messages[id];\n if (fatal) {\n // Every pending call failed with this instance, not a transient transport\n // loss. Keep the fatal classification when retiring the worker.\n Object.defineProperty(error, \"fatal\", { value: true });\n this.dispose(error);\n return;\n }\n if (!promise) return;\n\n if (status !== undefined) {\n const handle = () => {\n if (this.messages[id] === promise) return promise.onStatus?.(status);\n };\n promise.statusQueue = promise.statusQueue.then(handle);\n void promise.statusQueue.catch((error) => this.dispose(error));\n return;\n }\n\n this.peakWasmMemoryBytes = Math.max(\n this.peakWasmMemoryBytes,\n wasmMemoryBytes,\n );\n void promise.statusQueue\n .then(() => {\n if (error !== undefined) throw error;\n return result;\n })\n .then(promise.resolve, promise.reject);\n }\n\n async call<Name extends keyof Handlers>(\n name: Name,\n args: Parameters<Handlers[Name]>[0],\n options: {\n onStatus?: (data: unknown) => void | Promise<void>;\n signal?: AbortSignal;\n } = {},\n ): Promise<Awaited<ReturnType<Handlers[Name]>>> {\n type Result = Awaited<ReturnType<Handlers[Name]>>;\n options.signal?.throwIfAborted();\n if (this.disposed) throw new WorkerTerminatedError();\n const id = ++WorkerRpc.currentId;\n const promise = new Promise<Result>((resolve, reject) => {\n this.messages[id] = {\n resolve: (value) => resolve(value as Result),\n reject,\n onStatus: options.onStatus,\n statusQueue: Promise.resolve(),\n };\n });\n // Pool jobs own their worker exclusively. Termination also interrupts\n // synchronous WASM decoding and releases its linear memory immediately.\n const abort = () => this.dispose(options.signal?.reason);\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n try {\n this.worker.postMessage(\n { id, name, args },\n { transfer: getTransferable(args) },\n );\n return await promise;\n } finally {\n delete this.messages[id];\n options.signal?.removeEventListener(\"abort\", abort);\n }\n }\n\n dispose(reason: unknown = new Error(\"Worker terminated\")) {\n if (this.disposed) return;\n this.disposed = true;\n this.worker.terminate();\n\n const messages = Object.values(this.messages);\n this.messages = {};\n for (const message of messages) {\n message.reject(reason);\n }\n this.onDispose?.();\n }\n}\n","/** Reject promptly on cancellation while still observing the underlying task. */\nexport function abortable<T>(\n task: Promise<T>,\n signal?: AbortSignal,\n): Promise<T> {\n if (!signal) return task;\n return new Promise<T>((resolve, reject) => {\n const abort = () => reject(signal.reason);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (signal.aborted) abort();\n void task.then(resolve, reject).finally(() => {\n signal.removeEventListener(\"abort\", abort);\n });\n });\n}\n\n/** Link lifetime and per-request cancellation without retaining completed listeners. */\nexport function linkedAbortController(...signals: (AbortSignal | undefined)[]) {\n const controller = new AbortController();\n const listeners = signals.flatMap((signal) => {\n if (!signal) return [];\n const abort = () => controller.abort(signal.reason);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (signal.aborted) abort();\n return [{ signal, abort }];\n });\n return {\n controller,\n signal: controller.signal,\n cleanup() {\n for (const { signal, abort } of listeners)\n signal.removeEventListener(\"abort\", abort);\n },\n };\n}\n","import { WorkerRpc } from \"./WorkerRpc\";\nimport { abortable } from \"./abort\";\nimport type { RpcHandlers } from \"./worker\";\nimport BundledWorker from \"./worker?worker&inline\";\n\nexport class SplatWorker extends WorkerRpc<RpcHandlers> {\n constructor(onDispose?: () => void) {\n super(new BundledWorker(), onDispose);\n }\n}\n\nconst MEBIBYTE = 1024 * 1024;\n\nconst SMALL_WORKER_MEMORY_BYTES = 64 * MEBIBYTE;\nconst LARGE_WORKER_MEMORY_BYTES = 256 * MEBIBYTE;\nconst SMALL_WORKER_IDLE_TIMEOUT_MS = 3 * 60 * 1000;\nconst LARGE_WORKER_IDLE_TIMEOUT_MS = 3 * 1000;\n\n/**\n * Keep small workers around for reuse, while releasing workers whose WASM\n * linear memory has grown large much sooner.\n */\nfunction getWorkerIdleTimeoutMs(peakWasmMemoryBytes: number): number {\n const clampedMemoryBytes = Math.min(\n LARGE_WORKER_MEMORY_BYTES,\n Math.max(SMALL_WORKER_MEMORY_BYTES, peakWasmMemoryBytes),\n );\n const memoryRatio =\n (clampedMemoryBytes - SMALL_WORKER_MEMORY_BYTES) /\n (LARGE_WORKER_MEMORY_BYTES - SMALL_WORKER_MEMORY_BYTES);\n\n return Math.round(\n SMALL_WORKER_IDLE_TIMEOUT_MS +\n memoryRatio *\n (LARGE_WORKER_IDLE_TIMEOUT_MS - SMALL_WORKER_IDLE_TIMEOUT_MS),\n );\n}\n\n/**\n * Prefer the smallest idle worker so workers with large WASM heaps can reach\n * their shorter expiry timers. Equal-sized workers retain LIFO behavior.\n */\nfunction getWorkerReuseIndex(\n workers: readonly { peakWasmMemoryBytes: number }[],\n): number {\n let selectedIndex = -1;\n let selectedMemoryBytes = Number.POSITIVE_INFINITY;\n\n for (let index = workers.length - 1; index >= 0; index -= 1) {\n const memoryBytes = workers[index].peakWasmMemoryBytes;\n if (memoryBytes < selectedMemoryBytes) {\n selectedIndex = index;\n selectedMemoryBytes = memoryBytes;\n }\n }\n\n return selectedIndex;\n}\n\nclass SplatWorkerPool {\n private heavyJobs: Promise<void> = Promise.resolve();\n numWorkers = 0;\n freelist: SplatWorker[] = [];\n idleWorkerTimeouts = new Map<SplatWorker, ReturnType<typeof setTimeout>>();\n queue: ((worker: SplatWorker) => void)[] = [];\n\n constructor(private readonly maxWorkers = 4) {}\n\n async withWorker<T>(\n callback: (worker: SplatWorker) => Promise<T>,\n memoryHeavy = false,\n signal?: AbortSignal,\n ): Promise<T> {\n signal?.throwIfAborted();\n if (memoryHeavy) {\n const next = this.heavyJobs.then(() =>\n this.withWorker(callback, false, signal),\n );\n this.heavyJobs = next.then(\n () => {},\n () => {},\n );\n return abortable(next, signal);\n }\n\n return abortable(\n this.allocWorker().then(async (worker) => {\n try {\n signal?.throwIfAborted();\n return await callback(worker);\n } finally {\n this.freeWorker(worker);\n }\n }),\n signal,\n );\n }\n\n async allocWorker(): Promise<SplatWorker> {\n for (let index = this.freelist.length - 1; index >= 0; index--) {\n const worker = this.freelist[index];\n if (!worker.disposed) continue;\n clearTimeout(this.idleWorkerTimeouts.get(worker));\n this.idleWorkerTimeouts.delete(worker);\n this.freelist.splice(index, 1);\n this.numWorkers -= 1;\n }\n const workerIndex = getWorkerReuseIndex(this.freelist);\n if (workerIndex !== -1) {\n const worker = this.freelist.splice(workerIndex, 1)[0];\n clearTimeout(this.idleWorkerTimeouts.get(worker));\n this.idleWorkerTimeouts.delete(worker);\n return worker;\n }\n\n if (this.numWorkers < this.maxWorkers) {\n const worker = new SplatWorker();\n this.numWorkers += 1;\n return worker;\n }\n\n return new Promise((resolve) => {\n this.queue.push(resolve);\n });\n }\n\n freeWorker(worker: SplatWorker) {\n if (worker.disposed) {\n this.numWorkers -= 1;\n const waiter = this.queue.shift();\n if (waiter) {\n this.numWorkers += 1;\n waiter(new SplatWorker());\n }\n return;\n }\n const waiter = this.queue.shift();\n if (waiter) {\n waiter(worker);\n return;\n }\n\n this.freelist.push(worker);\n const timeout = setTimeout(() => {\n this.idleWorkerTimeouts.delete(worker);\n // Removing an idle worker elsewhere cancels this timer.\n this.freelist.splice(this.freelist.indexOf(worker), 1);\n worker.dispose();\n this.numWorkers -= 1;\n }, getWorkerIdleTimeoutMs(worker.peakWasmMemoryBytes));\n this.idleWorkerTimeouts.set(worker, timeout);\n }\n}\n\nexport const workerPool = new SplatWorkerPool();\n","import * as THREE from \"three\";\n\nexport function resolveTimer(timer?: THREE.Timer): {\n timer: THREE.Timer;\n ownsTimer: boolean;\n} {\n return {\n timer: timer ?? new THREE.Timer(),\n // A caller-supplied timer may be shared with other systems, so only update\n // the timer that Gaussian Splat Lite creates and owns itself.\n ownsTimer: timer === undefined,\n };\n}\n\nexport const threeRevision = Number.parseInt(THREE.REVISION);\n","import type { SplatMesh } from \"../scene/SplatMesh\";\nimport type { SplatAccumulator, SplatMapping } from \"./SplatAccumulator\";\n\ntype SortCenterEntry = {\n meshId: number;\n centerVersion: number;\n sortVersion: number;\n};\n\n/** Tracks raw-center and matrix revisions cached by the sort worker. */\nexport class SortCenterCache {\n private entries = new Map<SplatMesh, SortCenterEntry>();\n private freeMeshIds: number[] = [];\n private nextMeshId = 0;\n\n private allocateMeshId() {\n return this.freeMeshIds.pop() ?? this.nextMeshId++;\n }\n\n dispose() {\n this.entries.clear();\n this.freeMeshIds.length = 0;\n this.nextMeshId = 0;\n }\n\n prepare(current: SplatAccumulator) {\n const { mapping } = current;\n // Commit the versions captured now, even if the mapping changes before\n // the worker accepts this state.\n const committed: {\n entry: SortCenterEntry;\n centerVersion: number;\n sortVersion: number;\n }[] = [];\n const rangeMeshIds = new Uint32Array(mapping.length);\n const rangeBases = new Uint32Array(mapping.length);\n const rangeCounts = new Uint32Array(mapping.length);\n const retiredEntries = new Map(this.entries);\n const changedCenters: {\n source: SplatMapping[\"source\"];\n count: number;\n rangeIndex: number;\n }[] = [];\n const changedMatrices: {\n matrixWorld: SplatMapping[\"matrixWorld\"];\n rangeIndex: number;\n }[] = [];\n let updateCount = 0;\n\n mapping.forEach(\n (\n { node, source, matrixWorld, base, count, centerVersion, sortVersion },\n rangeIndex,\n ) => {\n retiredEntries.delete(node);\n let entry = this.entries.get(node);\n if (!entry) {\n // Store a provisional entry immediately so a failed worker call can\n // retry with the same ID. Its sentinel version forces a re-upload.\n entry = {\n meshId: this.allocateMeshId(),\n centerVersion: -1,\n sortVersion: -1,\n };\n this.entries.set(node, entry);\n }\n\n committed.push({ entry, centerVersion, sortVersion });\n rangeMeshIds[rangeIndex] = entry.meshId;\n rangeBases[rangeIndex] = base;\n rangeCounts[rangeIndex] = count;\n\n if (entry.centerVersion !== centerVersion) {\n changedCenters.push({\n source,\n count,\n rangeIndex,\n });\n updateCount += count;\n }\n if (entry.sortVersion !== sortVersion) {\n changedMatrices.push({\n matrixWorld,\n rangeIndex,\n });\n }\n },\n );\n\n const centerUpdateRangeIndices = new Uint32Array(changedCenters.length);\n const updateCenters = new Float32Array(updateCount * 3);\n\n let updateBase = 0;\n changedCenters.forEach(({ source, count, rangeIndex }, updateIndex) => {\n centerUpdateRangeIndices[updateIndex] = rangeIndex;\n\n if (!source) throw new Error(\"Splat mapping has no source\");\n source.copySortCenters(updateCenters, updateBase * 3, count);\n updateBase += count;\n });\n\n const matrixUpdateRangeIndices = new Uint32Array(changedMatrices.length);\n const updateMatrices = new Float64Array(changedMatrices.length * 16);\n changedMatrices.forEach(({ matrixWorld, rangeIndex }, updateIndex) => {\n matrixUpdateRangeIndices[updateIndex] = rangeIndex;\n updateMatrices.set(matrixWorld.elements, updateIndex * 16);\n });\n\n return {\n payload: {\n centerUpdateRangeIndices,\n updateCenters,\n matrixUpdateRangeIndices,\n updateMatrices,\n rangeMeshIds,\n rangeBases,\n rangeCounts,\n },\n commit: () => {\n // The renderer serializes updates and skips commit after disposal.\n for (const { entry, centerVersion, sortVersion } of committed) {\n entry.centerVersion = centerVersion;\n entry.sortVersion = sortVersion;\n }\n // Recycle IDs only after the worker accepted the replacement state.\n // A mesh that later becomes active again gets a fresh entry and must\n // upload all of its centers before using its recycled ID.\n for (const [node, entry] of retiredEntries) {\n this.entries.delete(node);\n this.freeMeshIds.push(entry.meshId);\n }\n },\n };\n }\n}\n","// Gsplats are stored in textures that are 2^11 x 2^11 x up to 2^11\n// Most WebGL2 implementations support 2D textures up to 2^12 x 2^12 (max 16M Gsplats)\n// 2D array textures and 3D textures up to 2^11 x 2^11 x 2^11 (max 8G Gsplats),\n// so we use 2D array textures for our representation for higher limits.\n\nexport const SPLAT_TEX_WIDTH_BITS = 11;\nexport const SPLAT_TEX_HEIGHT_BITS = 11;\n\nexport const SPLAT_TEX_WIDTH = 1 << SPLAT_TEX_WIDTH_BITS; // 2048\nexport const SPLAT_TEX_HEIGHT = 1 << SPLAT_TEX_HEIGHT_BITS; // 2048\nexport const SPLAT_TEX_MIN_HEIGHT = 1;\n\n/** Valid block shifts include zero (one opacity per Splat). */\nexport const SPLAT_BLOCKS_DISABLED = 32;\n\nexport enum SplatFileType {\n PLY = \"ply\",\n SPZ = \"spz\",\n SOG = \"sog\",\n RAD = \"rad\",\n}\n\nexport type SplatExtra = {\n sh1?: Uint32Array;\n sh2?: Uint32Array;\n sh3a?: Uint32Array;\n sh3b?: Uint32Array;\n};\n\n/** Morton storage records per cached spatial bounds block. */\nexport const SPLAT_BOUNDS_BLOCK_SIZE = 256;\n\nexport type SplatResult = {\n numSplats: number;\n splatArrays: [Uint32Array, Uint32Array];\n sortCenters?: Float32Array;\n /** Storage index to original source index; absent for identity order. */\n sourceIds?: Uint32Array;\n /** Local finite center bounds: min XYZ followed by max XYZ. */\n centerOnlyBoundingBox?: Float32Array;\n /** Local scale/rotation bounds at source alpha 0.01, including kernel shape. */\n boundingBox?: Float32Array;\n /** Per 256 records: min/max XYZ at source alpha 0.01, including scale, rotation and shape. */\n spatialBounds?: Float32Array;\n extra: SplatExtra;\n};\n\n/** Spatially reordered records with source IDs and cached local bounds. */\nexport type ReorderedSplatResult = SplatResult & {\n sourceIds: Uint32Array;\n centerOnlyBoundingBox: Float32Array;\n boundingBox: Float32Array;\n spatialBounds: Float32Array;\n};\n","import * as THREE from \"three\";\nimport {\n SPLAT_TEX_HEIGHT,\n SPLAT_TEX_MIN_HEIGHT,\n SPLAT_TEX_WIDTH,\n} from \"./defines\";\n\n// Keep rows compact for small sources and power-of-two layers for large ones.\n// 256 layers is the WebGL2 minimum; larger devices need no special layout.\nexport function getTextureSize(\n numSplats: number,\n maxLayers = 256,\n): {\n width: number;\n height: number;\n depth: number;\n maxSplats: number;\n} {\n const width = SPLAT_TEX_WIDTH;\n const rows = Math.ceil(Math.max(1, numSplats) / width);\n const height =\n rows <= SPLAT_TEX_HEIGHT\n ? Math.max(SPLAT_TEX_MIN_HEIGHT, rows)\n : Math.min(\n SPLAT_TEX_HEIGHT,\n 2 ** Math.ceil(Math.log2(Math.ceil(rows / maxLayers))),\n );\n const depth = Math.ceil(Math.max(1, numSplats) / (width * height));\n return { width, height, depth, maxSplats: width * height * depth };\n}\n\nexport const emptyUintTexture = /* @__PURE__ */ (() => {\n const texture = new THREE.DataTexture(\n new Uint32Array(4),\n 1,\n 1,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n );\n texture.needsUpdate = true;\n return texture;\n})();\n\nexport const emptySplatTexture = /* @__PURE__ */ (() => {\n const { width, height, depth, maxSplats } = getTextureSize(1);\n const texture = new THREE.DataArrayTexture(\n new Uint32Array(maxSplats * 4),\n width,\n height,\n depth,\n );\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.needsUpdate = true;\n return texture;\n})();\n","import * as THREE from \"three\";\n\nconst rotationMatrix = new THREE.Matrix4();\nconst axisX = new THREE.Vector3();\nconst axisY = new THREE.Vector3();\nconst axisZ = new THREE.Vector3();\nconst sourceAxis = new THREE.Vector3();\n\n/**\n * Extracts the positive per-axis scale and approximate rotation used by the\n * PlayCanvas-style splat work-buffer transform.\n *\n * Unlike Matrix4.decompose(), this remains finite when a model scale axis is\n * zero. When possible, the missing basis axis is reconstructed from the other\n * two so degenerate transforms retain a stable orientation.\n */\nexport function decomposeSplatTransform(\n matrix: THREE.Matrix4,\n scale: THREE.Vector3,\n rotation: THREE.Quaternion,\n) {\n const source = matrix.elements;\n const sx = Math.hypot(source[0], source[1], source[2]);\n const sy = Math.hypot(source[4], source[5], source[6]);\n const sz = Math.hypot(source[8], source[9], source[10]);\n scale.set(sx, sy, sz);\n\n axisX.set(source[0], source[1], source[2]);\n axisY.set(source[4], source[5], source[6]);\n axisZ.set(source[8], source[9], source[10]);\n if (sx > 0) axisX.multiplyScalar(1 / sx);\n if (sy > 0) axisY.multiplyScalar(1 / sy);\n if (sz > 0) axisZ.multiplyScalar(1 / sz);\n\n const nonZeroAxes = Number(sx > 0) + Number(sy > 0) + Number(sz > 0);\n if (nonZeroAxes === 0) {\n rotation.identity();\n return false;\n }\n\n if (nonZeroAxes === 1) {\n const localAxis = sx > 0 ? 0 : sy > 0 ? 1 : 2;\n sourceAxis.set(\n localAxis === 0 ? 1 : 0,\n localAxis === 1 ? 1 : 0,\n localAxis === 2 ? 1 : 0,\n );\n rotation\n .setFromUnitVectors(\n sourceAxis,\n localAxis === 0 ? axisX : localAxis === 1 ? axisY : axisZ,\n )\n .normalize();\n return false;\n }\n\n if (sx === 0) axisX.copy(axisY).cross(axisZ).normalize();\n if (sy === 0) axisY.copy(axisZ).cross(axisX).normalize();\n if (sz === 0) axisZ.copy(axisX).cross(axisY).normalize();\n const reflected = matrix.determinant() < 0;\n if (reflected) axisX.negate();\n\n rotationMatrix.makeBasis(axisX, axisY, axisZ);\n rotation.setFromRotationMatrix(rotationMatrix).normalize();\n return reflected;\n}\n\n/**\n * Re-expresses an affine transform so it consumes positions relative to\n * `origin` instead of absolute world positions.\n *\n * If `matrix` maps p to A * p + t, the rebased matrix maps (p - origin) to\n * A * (p - origin) + (A * origin + t), which is the same result without doing\n * a large-coordinate subtraction in float32 shader code.\n */\nexport function rebaseAffineTransform(\n matrix: THREE.Matrix4,\n origin: THREE.Vector3,\n) {\n const elements = matrix.elements;\n const x = origin.x;\n const y = origin.y;\n const z = origin.z;\n\n const tx = elements[0] * x + elements[4] * y + elements[8] * z + elements[12];\n const ty = elements[1] * x + elements[5] * y + elements[9] * z + elements[13];\n const tz =\n elements[2] * x + elements[6] * y + elements[10] * z + elements[14];\n\n elements[12] = tx;\n elements[13] = ty;\n elements[14] = tz;\n return matrix;\n}\n","import * as THREE from \"three\";\n\nimport { emptyUintTexture } from \"../data/textureLayout\";\nimport { rebaseAffineTransform } from \"../utils/transforms\";\n\nexport enum SplatEditSdfType {\n ALL = \"all\",\n PLANE = \"plane\",\n SPHERE = \"sphere\",\n BOX = \"box\",\n ELLIPSOID = \"ellipsoid\",\n CYLINDER = \"cylinder\",\n CAPSULE = \"capsule\",\n INFINITE_CONE = \"infinite_cone\",\n}\n\n/** RGBA-only operations supported by the SDF pipeline. */\nexport enum SplatEditRgbaBlendMode {\n MULTIPLY_RGBA = \"multiply_rgba\",\n SET_RGBA = \"set_rgba\",\n ADD_RGBA = \"add_rgba\",\n}\n\nexport type SplatEditSdfColor = {\n r?: number;\n g?: number;\n b?: number;\n};\n\nexport type SplatEditSdfOptions = {\n type?: SplatEditSdfType;\n invert?: boolean;\n opacity?: number;\n color?: SplatEditSdfColor;\n radius?: number;\n};\n\n/** A signed-distance shape carrying optional color and opacity channels. */\nexport class SplatEditSdf extends THREE.Object3D {\n type: SplatEditSdfType;\n invert: boolean;\n opacity?: number;\n color: SplatEditSdfColor;\n radius: number;\n\n constructor(options: SplatEditSdfOptions = {}) {\n super();\n this.type = options.type ?? SplatEditSdfType.SPHERE;\n this.invert = options.invert ?? false;\n this.opacity = options.opacity;\n this.color = options.color ?? {};\n this.radius = options.radius ?? 0;\n }\n}\n\nexport type SplatEditOptions = {\n name?: string;\n rgbaBlendMode?: SplatEditRgbaBlendMode;\n sdfSmooth?: number;\n softEdge?: number;\n invert?: boolean;\n sdfs?: SplatEditSdf[];\n};\n\n/** An ordered RGBA operation evaluated over one or more SDF shapes. */\nexport class SplatEdit extends THREE.Object3D {\n ordering: number;\n rgbaBlendMode: SplatEditRgbaBlendMode;\n sdfSmooth: number;\n softEdge: number;\n invert: boolean;\n sdfs: SplatEditSdf[] | null;\n\n static nextOrdering = 1;\n\n constructor(options: SplatEditOptions = {}) {\n super();\n this.rgbaBlendMode =\n options.rgbaBlendMode ?? SplatEditRgbaBlendMode.MULTIPLY_RGBA;\n this.sdfSmooth = options.sdfSmooth ?? 0;\n this.softEdge = options.softEdge ?? 0;\n this.invert = options.invert ?? false;\n this.sdfs = options.sdfs ?? null;\n this.ordering = SplatEdit.nextOrdering++;\n this.name = options.name ?? `Edit ${this.ordering}`;\n }\n\n addSdf(sdf: SplatEditSdf) {\n this.sdfs ??= [];\n if (!this.sdfs.includes(sdf)) {\n this.sdfs.push(sdf);\n }\n }\n\n removeSdf(sdf: SplatEditSdf) {\n if (this.sdfs) {\n this.sdfs = this.sdfs.filter((candidate) => candidate !== sdf);\n }\n }\n}\n\nexport type SplatEditGroup = { edit: SplatEdit; sdfs: SplatEditSdf[] };\n\nconst SDF_TEXELS = 6;\nconst SDF_RGBA_MASK_SHIFT = 16;\nconst MIN_CAPACITY = 16;\nconst scratchFloat = new Float32Array(1);\nconst scratchUint = new Uint32Array(scratchFloat.buffer);\n\n/** Encodes SDF geometry/RGBA and edit operations as regular integer textures. */\nexport class SplatEdits {\n maxSdfs: number;\n numSdfs = 0;\n sdfData: Uint32Array;\n sdfTexture: THREE.DataTexture;\n\n maxEdits: number;\n numEdits = 0;\n editData: Uint32Array;\n editTexture: THREE.DataTexture;\n\n constructor({ maxSdfs = 0, maxEdits = 0 } = {}) {\n this.maxSdfs = Math.max(MIN_CAPACITY, maxSdfs);\n this.sdfData = new Uint32Array(this.maxSdfs * SDF_TEXELS * 4);\n this.sdfTexture = makeUintTexture(this.sdfData, SDF_TEXELS, this.maxSdfs);\n\n this.maxEdits = Math.max(MIN_CAPACITY, maxEdits);\n this.editData = new Uint32Array(this.maxEdits * 4);\n this.editTexture = makeUintTexture(this.editData, 1, this.maxEdits);\n }\n\n dispose() {\n this.sdfTexture.dispose();\n this.editTexture.dispose();\n }\n\n update(\n groups: SplatEditGroup[],\n coordinateOrigin?: THREE.Vector3,\n ): { updated: boolean } {\n const sdfCount = groups.reduce(\n (total, group) => total + group.sdfs.length,\n 0,\n );\n let updated = this.ensureCapacity(sdfCount, groups.length);\n\n if (this.numSdfs !== sdfCount || this.numEdits !== groups.length) {\n this.numSdfs = sdfCount;\n this.numEdits = groups.length;\n updated = true;\n }\n\n const sizes = new THREE.Vector4();\n const inverseOwnScale = new THREE.Vector3();\n const worldToSdf = new THREE.Matrix4();\n let sdfIndex = 0;\n let sdfUpdated = false;\n let editUpdated = false;\n\n groups.forEach(({ edit, sdfs }, editIndex) => {\n editUpdated =\n this.encodeEdit(editIndex, edit, sdfIndex, sdfs.length) || editUpdated;\n\n for (const sdf of sdfs) {\n sdf.updateWorldMatrix(true, false);\n worldToSdf.copy(sdf.matrixWorld);\n // These shapes already use scale as dimensions. Preserve their\n // independent corner/cap radius instead of scaling it a second time.\n const dimensional =\n sdf.type === SplatEditSdfType.BOX ||\n sdf.type === SplatEditSdfType.ELLIPSOID ||\n sdf.type === SplatEditSdfType.CAPSULE;\n sizes.set(\n dimensional ? Math.abs(sdf.scale.x) : 1,\n dimensional ? Math.abs(sdf.scale.y) : 1,\n dimensional ? Math.abs(sdf.scale.z) : 1,\n sdf.radius,\n );\n const collapsed = worldToSdf.determinant() === 0;\n if (dimensional && !collapsed)\n worldToSdf.scale(\n inverseOwnScale.set(\n 1 / sdf.scale.x,\n 1 / sdf.scale.y,\n 1 / sdf.scale.z,\n ),\n );\n const e = worldToSdf.elements;\n const distanceScale = collapsed\n ? 0\n : Math.min(\n Math.hypot(e[0], e[1], e[2]),\n Math.hypot(e[4], e[5], e[6]),\n Math.hypot(e[8], e[9], e[10]),\n );\n worldToSdf.invert();\n if (coordinateOrigin)\n rebaseAffineTransform(worldToSdf, coordinateOrigin);\n sdfUpdated =\n this.encodeSdf(sdfIndex, sdf, worldToSdf, distanceScale, sizes) ||\n sdfUpdated;\n sdfIndex += 1;\n }\n });\n\n if (sdfUpdated) {\n this.sdfTexture.needsUpdate = true;\n }\n if (editUpdated) {\n this.editTexture.needsUpdate = true;\n }\n return { updated: updated || sdfUpdated || editUpdated };\n }\n\n private ensureCapacity(sdfs: number, edits: number) {\n let updated = false;\n if (sdfs > this.maxSdfs) {\n this.maxSdfs = Math.max(sdfs, this.maxSdfs * 2);\n this.sdfTexture.dispose();\n this.sdfData = new Uint32Array(this.maxSdfs * SDF_TEXELS * 4);\n this.sdfTexture = makeUintTexture(this.sdfData, SDF_TEXELS, this.maxSdfs);\n updated = true;\n }\n if (edits > this.maxEdits) {\n this.maxEdits = Math.max(edits, this.maxEdits * 2);\n this.editTexture.dispose();\n this.editData = new Uint32Array(this.maxEdits * 4);\n this.editTexture = makeUintTexture(this.editData, 1, this.maxEdits);\n updated = true;\n }\n return updated;\n }\n\n private encodeEdit(\n index: number,\n edit: SplatEdit,\n sdfFirst: number,\n sdfCount: number,\n ) {\n if (sdfFirst > 0xffff || sdfCount > 0xffff) {\n throw new Error(\"An SDF edit supports at most 65535 shapes\");\n }\n const base = index * 4;\n const blend = rgbaBlendModeToNumber(edit.rgbaBlendMode);\n const flags = blend | (edit.invert ? 1 << 8 : 0);\n let updated = this.setEditUint(base, flags);\n updated =\n this.setEditUint(base + 1, sdfFirst | (sdfCount << 16)) || updated;\n updated = this.setEditFloat(base + 2, edit.softEdge) || updated;\n updated = this.setEditFloat(base + 3, edit.sdfSmooth) || updated;\n return updated;\n }\n\n private encodeSdf(\n index: number,\n sdf: SplatEditSdf,\n matrix: THREE.Matrix4,\n distanceScale: number,\n sizes: THREE.Vector4,\n ) {\n const base = index * SDF_TEXELS * 4;\n const color = sdf.color;\n const rgbaMask =\n (color.r === undefined ? 0 : 1) |\n (color.g === undefined ? 0 : 1 << 1) |\n (color.b === undefined ? 0 : 1 << 2) |\n (sdf.opacity === undefined ? 0 : 1 << 3);\n const flags =\n sdfTypeToNumber(sdf.type) |\n (sdf.invert ? 1 << 8 : 0) |\n (rgbaMask << SDF_RGBA_MASK_SHIFT);\n const e = matrix.elements;\n let updated = this.setSdfFloat(base, e[12]);\n updated = this.setSdfFloat(base + 1, e[13]) || updated;\n updated = this.setSdfFloat(base + 2, e[14]) || updated;\n updated = this.setSdfUint(base + 3, flags) || updated;\n for (let axis = 0; axis < 3; axis++) {\n updated = this.setSdfFloat(base + 4 + axis, e[axis]) || updated;\n updated = this.setSdfFloat(base + 8 + axis, e[4 + axis]) || updated;\n updated = this.setSdfFloat(base + 20 + axis, e[8 + axis]) || updated;\n }\n updated = this.setSdfFloat(base + 23, distanceScale) || updated;\n\n updated = this.setSdfFloat(base + 12, sizes.x) || updated;\n updated = this.setSdfFloat(base + 13, sizes.y) || updated;\n updated = this.setSdfFloat(base + 14, sizes.z) || updated;\n updated = this.setSdfFloat(base + 15, sizes.w) || updated;\n\n updated = this.setSdfFloat(base + 16, color.r ?? 0) || updated;\n updated = this.setSdfFloat(base + 17, color.g ?? 0) || updated;\n updated = this.setSdfFloat(base + 18, color.b ?? 0) || updated;\n updated = this.setSdfFloat(base + 19, sdf.opacity ?? 0) || updated;\n return updated;\n }\n\n private setSdfUint(offset: number, value: number) {\n const updated = this.sdfData[offset] !== value;\n this.sdfData[offset] = value;\n return updated;\n }\n\n private setSdfFloat(offset: number, value: number) {\n scratchFloat[0] = value;\n return this.setSdfUint(offset, scratchUint[0]);\n }\n\n private setEditUint(offset: number, value: number) {\n const updated = this.editData[offset] !== value;\n this.editData[offset] = value;\n return updated;\n }\n\n private setEditFloat(offset: number, value: number) {\n scratchFloat[0] = value;\n return this.setEditUint(offset, scratchUint[0]);\n }\n\n static emptyTexture = emptyUintTexture;\n}\n\nfunction rgbaBlendModeToNumber(mode: SplatEditRgbaBlendMode) {\n switch (mode) {\n case SplatEditRgbaBlendMode.MULTIPLY_RGBA:\n return 0;\n case SplatEditRgbaBlendMode.SET_RGBA:\n return 1;\n case SplatEditRgbaBlendMode.ADD_RGBA:\n return 2;\n }\n}\n\nfunction sdfTypeToNumber(type: SplatEditSdfType) {\n switch (type) {\n case SplatEditSdfType.ALL:\n return 0;\n case SplatEditSdfType.PLANE:\n return 1;\n case SplatEditSdfType.SPHERE:\n return 2;\n case SplatEditSdfType.BOX:\n return 3;\n case SplatEditSdfType.ELLIPSOID:\n return 4;\n case SplatEditSdfType.CYLINDER:\n return 5;\n case SplatEditSdfType.CAPSULE:\n return 6;\n case SplatEditSdfType.INFINITE_CONE:\n return 7;\n }\n}\n\nfunction makeUintTexture(data: Uint32Array, width: number, height: number) {\n const texture = new THREE.DataTexture(\n data,\n width,\n height,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n );\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n","const f32 = new Float32Array(1);\nconst u32 = new Uint32Array(f32.buffer);\nconst supportsFloat16Array = \"Float16Array\" in globalThis;\nconst f16 = supportsFloat16Array\n ? new globalThis[\"Float16Array\" as keyof typeof globalThis](1)\n : null;\nconst u16 = new Uint16Array(f16?.buffer);\n\nfunction toHalfNative(value: number): number {\n f16[0] = value;\n return u16[0];\n}\n\nfunction roundEven(value: number): number {\n const integer = Math.floor(value);\n const fraction = value - integer;\n return (\n integer +\n Number(fraction > 0.5 || (fraction === 0.5 && (integer & 1) !== 0))\n );\n}\n\nfunction toHalfJs(value: number): number {\n const sign = value < 0 || Object.is(value, -0) ? 0x8000 : 0;\n const magnitude = Math.abs(value);\n if (Number.isNaN(magnitude)) return 0x7e00;\n if (magnitude >= 65520) return sign | 0x7c00;\n if (magnitude < 2 ** -14) return sign | roundEven(magnitude * 2 ** 24);\n // Round the original double, avoiding double rounding through float32.\n f32[0] = magnitude;\n const exponent = ((u32[0] >>> 23) & 0xff) - 127;\n const mantissa = roundEven(magnitude * 2 ** (10 - exponent));\n return sign | ((exponent + 14) * 1024 + mantissa);\n}\n\nfunction fromHalfNative(value: number): number {\n u16[0] = value;\n return f16[0];\n}\n\nfunction fromHalfJs(value: number): number {\n const sign = (value >>> 15) & 1;\n const exponent = (value >>> 10) & 0x1f;\n const fraction = value & 0x3ff;\n let bits: number;\n\n if (exponent === 0) {\n if (fraction === 0) {\n bits = sign << 31;\n } else {\n let mantissa = fraction;\n let adjustedExponent = -14;\n while ((mantissa & 0x400) === 0) {\n mantissa <<= 1;\n adjustedExponent -= 1;\n }\n bits =\n (sign << 31) |\n ((adjustedExponent + 127) << 23) |\n ((mantissa & 0x3ff) << 13);\n }\n } else if (exponent === 0x1f) {\n bits = (sign << 31) | (fraction === 0 ? 0x7f80_0000 : 0x7fc0_0000);\n } else {\n bits = (sign << 31) | ((exponent - 15 + 127) << 23) | (fraction << 13);\n }\n\n u32[0] = bits;\n return f32[0];\n}\n\nexport const toHalf = supportsFloat16Array ? toHalfNative : toHalfJs;\nexport const fromHalf = supportsFloat16Array ? fromHalfNative : fromHalfJs;\n\nconst f32buffer = new Float32Array(1);\nconst u32buffer = new Uint32Array(f32buffer.buffer);\n\n// Reinterpret the bits of a float32 as a uint32\nexport function floatBitsToUint(f: number): number {\n f32buffer[0] = f;\n return u32buffer[0];\n}\n\n// Reinterpret the bits of a uint32 as a float32\nexport function uintBitsToFloat(u: number): number {\n u32buffer[0] = u;\n return f32buffer[0];\n}\n","import { fromHalf, toHalf } from \"../utils/numeric\";\n\nconst F32_EPSILON = 1.192_092_895_507_812_5e-7;\nconst ENCODED_IDENTITY_QUATERNION = (512 << 10) | 1023;\n\n// Keep JS double precision; the destination array controls decode precision.\nconst QUAT_ROTATION_LOOKUP = Float64Array.from({ length: 4096 * 2 }, (_, i) => {\n const halfTheta = ((i >>> 1) / 4095) * 0.5 * Math.PI;\n return i & 1 ? Math.cos(halfTheta) : Math.sin(halfTheta);\n});\nconst SH_SCALE_LOOKUP = Float64Array.from(\n { length: 32 },\n (_, exponent) => 2 ** (exponent - 15) / 255,\n);\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.min(max, Math.max(min, value));\n}\n\nexport function decodeSplatOpacity(word: number) {\n const shapeAmount = fromHalf(word >>> 16);\n if (shapeAmount > 0) {\n const kernelShape = Math.min(shapeAmount, 1) * 4 + 1;\n return Math.exp((kernelShape * kernelShape - 1) / Math.E);\n }\n return fromHalf(word & 0xffff);\n}\n\nexport function encodeSplatOpacity(opacity: number) {\n if (opacity > 0 && opacity <= 1) return toHalf(opacity);\n const value = Math.max(opacity || 0, 0);\n if (value > 1) {\n const shapeAmount = 0.25 * (Math.sqrt(Math.log(value) * Math.E + 1) - 1);\n // Match the renderer's shape range [0, 1].\n return (toHalf(1) | (toHalf(Math.min(shapeAmount, 1)) << 16)) >>> 0;\n }\n return toHalf(value);\n}\n\ntype CodecOutput = Float32Array | number[];\n\n// NaN channels encode as zero without affecting the shared exponent. All\n// magnitudes are nonnegative, so Math.round also gives ties away from zero.\n// Keep JS precision here; the destination array controls decode precision.\nexport function encodeShRgb(red: number, green: number, blue: number) {\n const maxAbsolute = Math.max(\n Math.abs(red) || 0,\n Math.abs(green) || 0,\n Math.abs(blue) || 0,\n );\n // The shared exponent must cover the largest channel before quantization.\n const exponent = clamp(Math.ceil(Math.log2(maxAbsolute)) + 15, 0, 31);\n const divisor = 2 ** (exponent - 15) / 255;\n const encodedRed = Math.round(clamp(Math.abs(red) / divisor, 0, 255));\n const encodedGreen = Math.round(clamp(Math.abs(green) / divisor, 0, 255));\n const encodedBlue = Math.round(clamp(Math.abs(blue) / divisor, 0, 255));\n const signs = (red < 0 ? 1 : 0) | (green < 0 ? 2 : 0) | (blue < 0 ? 4 : 0);\n return (\n (encodedRed |\n (encodedGreen << 8) |\n (encodedBlue << 16) |\n (((exponent << 3) | signs) << 24)) >>>\n 0\n );\n}\n\nexport function decodeShRgbToArray(\n word: number,\n output: CodecOutput,\n base = 0,\n stride = 1,\n) {\n const exponentAndSigns = word >>> 24;\n const multiplier = SH_SCALE_LOOKUP[exponentAndSigns >>> 3];\n for (let component = 0; component < 3; component += 1) {\n const magnitude = ((word >>> (component * 8)) & 0xff) * multiplier;\n output[base + component * stride] =\n exponentAndSigns & (1 << component) ? -magnitude : magnitude;\n }\n}\n\nexport function decodeQuatOctXy1010R12ToArray(\n word: number,\n output: CodecOutput,\n base = 0,\n stride = 1,\n) {\n const u = word & 0x3ff;\n const v = (word >>> 10) & 0x3ff;\n const angle = word >>> 20;\n let x = (u / 1023) * 2 - 1;\n let y = (v / 1023) * 2 - 1;\n const z = 1 - Math.abs(x) - Math.abs(y);\n const fold = Math.max(-z, 0);\n x += x >= 0 ? -fold : fold;\n y += y >= 0 ? -fold : fold;\n const inverseLength = 1 / Math.sqrt(x * x + y * y + z * z);\n const sine = QUAT_ROTATION_LOOKUP[angle * 2];\n output[base] = x * inverseLength * sine;\n output[base + stride] = y * inverseLength * sine;\n output[base + stride * 2] = z * inverseLength * sine;\n output[base + stride * 3] = QUAT_ROTATION_LOOKUP[angle * 2 + 1];\n}\n\nfunction encodeQuaternion(\n qx: number,\n qy: number,\n qz: number,\n qw: number,\n minimumLengthSquared: number,\n) {\n const lengthSquared = qx * qx + qy * qy + qz * qz + qw * qw;\n if (\n !Number.isFinite(lengthSquared) ||\n lengthSquared <= minimumLengthSquared\n ) {\n return undefined;\n }\n if (qx === 0 && qy === 0 && qz === 0) {\n return ENCODED_IDENTITY_QUATERNION;\n }\n\n const inverseLength = 1 / Math.sqrt(lengthSquared);\n let x = qx * inverseLength;\n let y = qy * inverseLength;\n let z = qz * inverseLength;\n let w = qw * inverseLength;\n if (w < 0) {\n x = -x;\n y = -y;\n z = -z;\n w = -w;\n }\n\n const theta = 2 * Math.acos(clamp(w, 0, 1));\n const sine = Math.sin(theta * 0.5);\n const axisX = Math.abs(sine) < 1e-6 ? 1 : x / sine;\n const axisY = Math.abs(sine) < 1e-6 ? 0 : y / sine;\n const axisZ = Math.abs(sine) < 1e-6 ? 0 : z / sine;\n const sum = Math.abs(axisX) + Math.abs(axisY) + Math.abs(axisZ);\n let octX = axisX / sum;\n let octY = axisY / sum;\n if (axisZ < 0) {\n const previousX = octX;\n octX = (1 - Math.abs(octY)) * (octX >= 0 ? 1 : -1);\n octY = (1 - Math.abs(previousX)) * (octY >= 0 ? 1 : -1);\n }\n\n const u = Math.round(clamp((octX * 0.5 + 0.5) * 1023, 0, 1023));\n const v = Math.round(clamp((octY * 0.5 + 0.5) * 1023, 0, 1023));\n const angle = Math.round(clamp((theta / Math.PI) * 4095, 0, 4095));\n return ((angle << 20) | (v << 10) | u) >>> 0;\n}\n\nexport function encodeQuatOctXy1010R12(\n qx: number,\n qy: number,\n qz: number,\n qw: number,\n): number {\n return (encodeQuaternion(qx, qy, qz, qw, 0) ?? 0) >>> 0;\n}\n\nexport function tryEncodeQuatOctXy1010R12(\n qx: number,\n qy: number,\n qz: number,\n qw: number,\n) {\n return encodeQuaternion(qx, qy, qz, qw, F32_EPSILON);\n}\n","import type { SplatExtra } from \"./defines\";\n\nexport const SH_KEYS = [\"sh1\", \"sh2\", \"sh3a\", \"sh3b\"] as const;\nexport const SH_ARRAY_COUNTS = [0, 1, 2, 4] as const;\n\n/** Merge cached min XYZ / max XYZ values without decoding records. */\nexport function unionSplatBounds(\n target: Float32Array,\n source: Float32Array,\n offset = 0,\n) {\n for (let axis = 0; axis < 3; axis++) {\n target[axis] = Math.min(target[axis], source[offset + axis]);\n target[axis + 3] = Math.max(target[axis + 3], source[offset + axis + 3]);\n }\n}\n\nexport function resetSplatBounds(bounds: Float32Array) {\n bounds.fill(Number.POSITIVE_INFINITY, 0, 3);\n bounds.fill(Number.NEGATIVE_INFINITY, 3, 6);\n}\n\nexport function getSplatShDegree(extra: SplatExtra) {\n return !extra.sh1 ? 0 : !extra.sh2 ? 1 : !extra.sh3a || !extra.sh3b ? 2 : 3;\n}\n\n/** Packed texture storage; capacity includes padding, but excludes sort centers. */\nexport function getSplatTextureBytes(capacity: number, numSh: number) {\n return capacity * (2 + SH_ARRAY_COUNTS[numSh]) * 16;\n}\n\n/** Retained CPU arrays, including sort centers and extra attribute buffers. */\nexport function getSplatByteLength(data: {\n splatArrays: readonly Uint32Array[];\n sortCenters?: Float32Array;\n sourceIds?: Uint32Array;\n centerOnlyBoundingBox?: Float32Array;\n boundingBox?: Float32Array;\n spatialBounds?: Float32Array;\n extra: SplatExtra;\n}) {\n let bytes =\n (data.sortCenters?.byteLength ?? 0) +\n (data.sourceIds?.byteLength ?? 0) +\n (data.centerOnlyBoundingBox?.byteLength ?? 0) +\n (data.boundingBox?.byteLength ?? 0) +\n (data.spatialBounds?.byteLength ?? 0);\n for (const array of data.splatArrays) bytes += array.byteLength;\n for (const array of Object.values(data.extra))\n bytes += array?.byteLength ?? 0;\n return bytes;\n}\n","import * as THREE from \"three\";\nimport { fromHalf, uintBitsToFloat } from \"../utils/numeric\";\nimport {\n decodeQuatOctXy1010R12ToArray,\n decodeSplatOpacity,\n} from \"./splatCodec\";\n\nexport function decodeSplat(\n splatArrays: [Uint32Array, Uint32Array],\n index: number,\n result = {\n center: new THREE.Vector3(),\n scales: new THREE.Vector3(),\n quaternion: new THREE.Quaternion(),\n color: new THREE.Color(),\n opacity: 0,\n },\n): {\n center: THREE.Vector3;\n scales: THREE.Vector3;\n quaternion: THREE.Quaternion;\n color: THREE.Color;\n opacity: number;\n} {\n const i4 = index * 4;\n const [splatA, splatB] = splatArrays;\n result.center.x = uintBitsToFloat(splatA[i4]);\n result.center.y = uintBitsToFloat(splatA[i4 + 1]);\n result.center.z = uintBitsToFloat(splatA[i4 + 2]);\n result.opacity = decodeSplatOpacity(splatA[i4 + 3]);\n result.color.r = fromHalf(splatB[i4] & 0xffff);\n result.color.g = fromHalf(splatB[i4] >>> 16);\n result.color.b = fromHalf(splatB[i4 + 1] & 0xffff);\n result.scales.x = Math.exp(fromHalf(splatB[i4 + 1] >>> 16));\n result.scales.y = Math.exp(fromHalf(splatB[i4 + 2] & 0xffff));\n result.scales.z = Math.exp(fromHalf(splatB[i4 + 2] >>> 16));\n decodeQuatOctXy1010R12(splatB[i4 + 3], result.quaternion);\n return result;\n}\n\nconst decodedQuaternion = [0, 0, 0, 1];\n\nexport function decodeQuatOctXy1010R12(\n encoded: number,\n out: THREE.Quaternion,\n): THREE.Quaternion {\n decodeQuatOctXy1010R12ToArray(encoded, decodedQuaternion);\n out.set(\n decodedQuaternion[0],\n decodedQuaternion[1],\n decodedQuaternion[2],\n decodedQuaternion[3],\n );\n return out;\n}\n","import * as THREE from \"three\";\n\nimport type {\n SplatFileResolver,\n SplatProgressEvent,\n} from \"../loaders/loadTypes\";\nimport type { SplatPostDecodeProgram } from \"../loaders/postDecode/program\";\nimport {\n type ReorderedSplatResult,\n SPLAT_BLOCKS_DISABLED,\n SPLAT_BOUNDS_BLOCK_SIZE,\n SPLAT_TEX_WIDTH_BITS,\n type SplatExtra,\n type SplatFileType,\n type SplatResult,\n} from \"./defines\";\nimport type { RaycastRangeCallback, SplatRaycastQuery } from \"./raycast\";\nimport { decodeShRgbToArray } from \"./splatCodec\";\nimport {\n SH_KEYS,\n getSplatByteLength,\n getSplatShDegree,\n resetSplatBounds,\n} from \"./splatData\";\nimport { getTextureSize } from \"./textureLayout\";\nimport { decodeSplat } from \"./unpack\";\n\ntype SplatShTextures = {\n sh1?: THREE.DataArrayTexture;\n sh2?: THREE.DataArrayTexture;\n sh3a?: THREE.DataArrayTexture;\n sh3b?: THREE.DataArrayTexture;\n};\n\nconst SH_COUNTS = [0, 3, 8, 15] as const;\n\ntype DecodedSplat = ReturnType<typeof decodeSplat>;\ntype DecodedSplatWithSh = DecodedSplat & { sh: THREE.Color[] };\n\nexport type SplatsOptions = {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n /** Resolve external SOG images or RAD chunks by metadata filename. */\n resolveFile?: SplatFileResolver;\n /** Declarative per-splat transform executed in the decode worker. */\n postDecode?: SplatPostDecodeProgram;\n onProgress?: (event: SplatProgressEvent) => void;\n};\n\ntype SplatsState = ReorderedSplatResult & {\n maxSplats: number;\n};\n\nfunction validateInitializationInputs(options: SplatsOptions) {\n if (\"splatArrays\" in options)\n throw new Error(\n \"splatArrays initialization is not supported; use url, file, or fileBytes\",\n );\n const inputs: string[] = [];\n if (options.url !== undefined) inputs.push(\"url\");\n if (options.file !== undefined) inputs.push(\"file\");\n if (options.fileBytes !== undefined) inputs.push(\"fileBytes\");\n if (inputs.length > 1) {\n throw new Error(\n `Splats initialization inputs are mutually exclusive; provide only one of url, file, or fileBytes (received: ${inputs.join(\", \")})`,\n );\n }\n return inputs.length > 0;\n}\n\nfunction createDecodedState(data: ReorderedSplatResult): SplatsState {\n const [first, second] = data.splatArrays;\n if (first.length !== second.length) {\n throw new Error(\"splatArrays must have the same length\");\n }\n if (first.length % 4 !== 0) {\n throw new Error(\"splatArrays must contain complete four-word records\");\n }\n\n const inputCapacity = first.length / 4;\n const numSplats = data.numSplats;\n if (\n !Number.isSafeInteger(numSplats) ||\n numSplats < 0 ||\n numSplats > inputCapacity\n ) {\n throw new Error(\"numSplats must be an integer within splatArrays\");\n }\n if (\n data.sortCenters !== undefined &&\n data.sortCenters.length < numSplats * 3\n ) {\n throw new Error(\"sortCenters is smaller than numSplats\");\n }\n if (data.sourceIds.length < numSplats)\n throw new Error(\"sourceIds is smaller than numSplats\");\n if (data.centerOnlyBoundingBox?.length !== 6)\n throw new Error(\"Decoded center bounds must contain six values\");\n if (data.boundingBox?.length !== 6)\n throw new Error(\"Decoded bounds must contain six values\");\n if (\n data.spatialBounds?.length !==\n Math.ceil(numSplats / SPLAT_BOUNDS_BLOCK_SIZE) * 6\n )\n throw new Error(\"Incorrect spatial bounds block length\");\n const maxSplats = getTextureSize(inputCapacity).maxSplats;\n let splatArrays = data.splatArrays;\n if (maxSplats !== inputCapacity) {\n splatArrays = [\n new Uint32Array(maxSplats * 4),\n new Uint32Array(maxSplats * 4),\n ];\n splatArrays[0].set(first);\n splatArrays[1].set(second);\n }\n return { ...data, maxSplats, splatArrays };\n}\n\nfunction createEmptyState(): SplatsState {\n const bounds = new Float32Array(6);\n resetSplatBounds(bounds);\n return {\n maxSplats: 0,\n numSplats: 0,\n splatArrays: [new Uint32Array(0), new Uint32Array(0)],\n sourceIds: new Uint32Array(0),\n spatialBounds: new Float32Array(0),\n centerOnlyBoundingBox: bounds,\n boundingBox: bounds.slice(),\n extra: {},\n };\n}\n\n/** An encoded splat source with two 16-byte texture records per splat. */\nexport class Splats {\n maxSplats = 0;\n numSplats = 0;\n private splatArrays: [Uint32Array, Uint32Array] = [\n new Uint32Array(0),\n new Uint32Array(0),\n ];\n private sortCenters?: Float32Array;\n protected sourceIds!: Uint32Array;\n protected centerOnlyBounds!: Float32Array;\n protected bounds!: Float32Array;\n private spatialBounds!: Float32Array;\n private extra: SplatExtra = {};\n\n initialized: Promise<Splats>;\n isInitialized = false;\n needsUpdate = true;\n\n private textures: [THREE.DataArrayTexture, THREE.DataArrayTexture];\n private shTextures: SplatShTextures = {};\n private loadController?: AbortController;\n\n constructor(options: SplatsOptions = {}) {\n this.textures = [Splats.emptyTexture, Splats.emptyTexture];\n this.initialized = Promise.resolve(this);\n this.initialize(options);\n }\n\n initialize(options: SplatsOptions = {}): Promise<Splats> {\n const isAsync = validateInitializationInputs(options);\n const state = createEmptyState();\n this.loadController?.abort();\n const controller = isAsync ? new AbortController() : undefined;\n this.loadController = controller;\n\n this.isInitialized = false;\n this.commitState(state);\n\n if (controller) {\n // Publish the readiness promise before starting the file load.\n this.initialized = Promise.resolve()\n .then(() => {\n controller.signal.throwIfAborted();\n return this.asyncInitialize(options, controller.signal);\n })\n .then((state) => {\n if (this.loadController === controller) {\n this.commitState(state);\n this.isInitialized = true;\n }\n return this;\n })\n .finally(() => {\n if (this.loadController === controller)\n this.loadController = undefined;\n });\n // Disposing may cancel a load whose readiness promise was not observed.\n void this.initialized.catch(() => {});\n } else {\n this.isInitialized = true;\n this.initialized = Promise.resolve(this);\n }\n\n return this.initialized;\n }\n\n private commitState(state: SplatsState) {\n this.disposeTextures();\n this.maxSplats = state.maxSplats;\n this.numSplats = state.numSplats;\n this.splatArrays = state.splatArrays;\n this.sortCenters = state.sortCenters;\n this.sourceIds = state.sourceIds;\n this.centerOnlyBounds = state.centerOnlyBoundingBox;\n this.bounds = state.boundingBox;\n this.spatialBounds = state.spatialBounds;\n this.extra = state.extra;\n this.needsUpdate = true;\n }\n\n /** @internal Adopt a loader result with precomputed bounds. */\n initializeDecoded(data: ReorderedSplatResult) {\n const state = createDecodedState(data);\n this.initialize();\n this.commitState(state);\n }\n\n private async asyncInitialize(\n options: SplatsOptions,\n signal: AbortSignal,\n ): Promise<SplatsState> {\n const { loadSplatData } = await import(\"../loaders/loadSplatData\");\n const decoded = await loadSplatData({ ...options, signal });\n return createDecodedState(decoded);\n }\n\n dispose() {\n this.loadController?.abort();\n this.loadController = undefined;\n this.isInitialized = false;\n this.commitState(createEmptyState());\n }\n\n private disposeTextures() {\n this.disposeMainTextures();\n for (const texture of Object.values(this.shTextures)) {\n texture?.dispose();\n }\n this.shTextures = {};\n }\n\n getNumSplats() {\n return this.numSplats;\n }\n\n /** @internal Copy cached local bounds into the target box. */\n getBoundingBox(centersOnly = true, target = new THREE.Box3()): THREE.Box3 {\n if (!this.isInitialized) throw new Error(\"Splats is not initialized\");\n const bounds = centersOnly ? this.centerOnlyBounds : this.bounds;\n target.min.fromArray(bounds, 0);\n target.max.fromArray(bounds, 3);\n return target;\n }\n\n getNumSh() {\n return getSplatShDegree(this.extra);\n }\n\n /** Current retained bytes for encoded Splat, sort-center, and SH arrays. */\n getByteLength() {\n return getSplatByteLength({\n splatArrays: this.splatArrays,\n sortCenters: this.sortCenters,\n sourceIds: this.sourceIds,\n centerOnlyBoundingBox: this.centerOnlyBounds,\n boundingBox: this.bounds,\n spatialBounds: this.spatialBounds,\n extra: this.extra,\n });\n }\n\n /** @internal Consume owned arrays for transfer to a streaming worker. */\n takeData(): SplatResult & { sourceIds: Uint32Array } {\n if (!this.isInitialized) throw new Error(\"Splats is not initialized\");\n const data = {\n numSplats: this.numSplats,\n splatArrays: this.splatArrays,\n sortCenters: this.sortCenters,\n sourceIds: this.sourceIds,\n centerOnlyBoundingBox: this.centerOnlyBounds,\n boundingBox: this.bounds,\n spatialBounds: this.spatialBounds,\n extra: this.extra,\n } satisfies SplatResult;\n this.dispose();\n return data;\n }\n\n /** Original source ID, retained across reordering and range extraction. */\n getSourceIndex(index: number) {\n if (!Number.isSafeInteger(index) || index < 0 || index >= this.numSplats)\n throw new Error(\"Invalid splat index\");\n return this.sourceIds[index];\n }\n\n getSplat(index: number): DecodedSplatWithSh;\n getSplat(index: number, includeSh: true): DecodedSplatWithSh;\n getSplat(index: number, includeSh: false): DecodedSplat;\n getSplat(index: number, includeSh: boolean): DecodedSplat;\n getSplat(index: number, includeSh = true) {\n if (index < 0 || index >= this.numSplats) {\n throw new Error(\"Invalid splat index\");\n }\n const splat = decodeSplat(this.splatArrays, index);\n return includeSh\n ? { ...splat, sh: decodeSplatSh(this.extra, index, this.getNumSh()) }\n : splat;\n }\n\n /** @internal Consecutive visible records surviving spatial block picking. */\n forEachRaycastRange(\n query: SplatRaycastQuery,\n callback: RaycastRangeCallback,\n ) {\n query.forEachRange(this.spatialBounds, this.numSplats, callback);\n }\n\n copySplatRecords(\n firstTarget: Uint32Array,\n secondTarget: Uint32Array,\n sourceStart: number,\n count: number,\n ) {\n const wordStart = sourceStart * 4;\n const wordEnd = wordStart + count * 4;\n firstTarget.set(this.splatArrays[0].subarray(wordStart, wordEnd));\n secondTarget.set(this.splatArrays[1].subarray(wordStart, wordEnd));\n }\n\n copySortCenters(target: Float32Array, targetStart: number, count: number) {\n if (count > this.numSplats || targetStart + count * 3 > target.length) {\n throw new Error(\"Invalid sort center copy range\");\n }\n target.set(this.getSortCenters().subarray(0, count * 3), targetStart);\n }\n\n private getSortCenters() {\n if (this.sortCenters) return this.sortCenters;\n const centers = new Float32Array(this.numSplats * 3);\n const [splatA, splatB] = this.splatArrays;\n const centerView = new Float32Array(\n splatA.buffer,\n splatA.byteOffset,\n splatA.length,\n );\n for (let index = 0; index < this.numSplats; index += 1) {\n const i3 = index * 3;\n const i4 = index * 4;\n const disabled =\n splatB[i4 + 1] >>> 16 === 0xfc00 && splatB[i4 + 2] === 0xfc00fc00;\n centers[i3] = disabled ? Number.NaN : centerView[i4];\n centers[i3 + 1] = disabled ? Number.NaN : centerView[i4 + 1];\n centers[i3 + 2] = disabled ? Number.NaN : centerView[i4 + 2];\n }\n this.sortCenters = centers;\n return centers;\n }\n\n forEachCenter(\n callback: (index: number, x: number, y: number, z: number) => void,\n ) {\n const centers = this.getSortCenters();\n for (let index = 0; index < this.numSplats; index += 1) {\n const i3 = index * 3;\n callback(index, centers[i3], centers[i3 + 1], centers[i3 + 2]);\n }\n }\n\n forEachSplat(\n callback: (\n index: number,\n center: THREE.Vector3,\n scales: THREE.Vector3,\n quaternion: THREE.Quaternion,\n opacity: number,\n color: THREE.Color,\n ) => void,\n ) {\n let splat: ReturnType<typeof decodeSplat> | undefined;\n for (let index = 0; index < this.numSplats; index += 1) {\n splat = decodeSplat(this.splatArrays, index, splat);\n callback(\n index,\n splat.center,\n splat.scales,\n splat.quaternion,\n splat.opacity,\n splat.color,\n );\n }\n }\n\n setTextureUniforms(uniforms: Record<string, THREE.IUniform>) {\n const [splats, splats2] = this.getSplatTextures();\n const sh = this.getShTextures();\n const height = (splats.image as { height: number }).height;\n const layerBits = SPLAT_TEX_WIDTH_BITS + Math.ceil(Math.log2(height));\n uniforms.sourceLayerBits.value = layerBits;\n uniforms.sourceLayerMask.value = 2 ** layerBits - 1;\n uniforms.sourceBlockBits.value = SPLAT_BLOCKS_DISABLED;\n uniforms.sourceBlocks.value = Splats.emptyTexture;\n uniforms.sourceOpacities.value = Splats.emptyTexture;\n uniforms.sourceIndexed.value = false;\n uniforms.sourceIndices.value = Splats.emptyTexture;\n uniforms.sourceSplats.value = splats;\n uniforms.sourceSplats2.value = splats2;\n uniforms.sh1Texture.value = sh.sh1 ?? Splats.emptyTexture;\n uniforms.sh2Texture.value = sh.sh2 ?? Splats.emptyTexture;\n uniforms.sh3TextureA.value = sh.sh3a ?? Splats.emptyTexture;\n uniforms.sh3TextureB.value = sh.sh3b ?? Splats.emptyTexture;\n this.needsUpdate = false;\n }\n\n private getSplatTextures() {\n if (this.maxSplats === 0 || this.splatArrays[0].length === 0) {\n return [Splats.emptyTexture, Splats.emptyTexture] as const;\n }\n\n if (this.textures[0] === Splats.emptyTexture) {\n const { width, height, depth } = getTextureSize(this.maxSplats);\n this.textures = [\n newUintArrayTexture(this.splatArrays[0], width, height, depth),\n newUintArrayTexture(this.splatArrays[1], width, height, depth),\n ];\n } else if (this.needsUpdate) {\n this.textures[0].needsUpdate = true;\n this.textures[1].needsUpdate = true;\n }\n return this.textures;\n }\n\n private disposeMainTextures() {\n for (const texture of this.textures) {\n if (texture !== Splats.emptyTexture) {\n texture.dispose();\n }\n }\n this.textures = [Splats.emptyTexture, Splats.emptyTexture];\n }\n\n private getShTextures(): SplatShTextures {\n for (const key of SH_KEYS) {\n this.shTextures[key] = this.ensureShTexture(key, this.shTextures[key]);\n }\n return this.shTextures;\n }\n\n private ensureShTexture(\n key: (typeof SH_KEYS)[number],\n current?: THREE.DataArrayTexture,\n ) {\n if (current) {\n if (this.needsUpdate) current.needsUpdate = true;\n return current;\n }\n const data = this.extra[key];\n if (!data) return undefined;\n const { width, height, depth, maxSplats } = getTextureSize(\n Math.max(1, data.length / 4),\n );\n let padded = data;\n if (data.length < maxSplats * 4) {\n padded = new Uint32Array(maxSplats * 4);\n padded.set(data);\n this.extra[key] = padded;\n }\n return newUintArrayTexture(padded, width, height, depth);\n }\n\n static emptyTexture = newUintArrayTexture(new Uint32Array(4), 1, 1, 1);\n}\n\nfunction newUintArrayTexture(\n data: Uint32Array,\n width: number,\n height: number,\n depth: number,\n) {\n const texture = new THREE.DataArrayTexture(data, width, height, depth);\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n\nfunction decodeSplatSh(extra: SplatExtra, index: number, degree: number) {\n const count = SH_COUNTS[degree];\n const result = new Array<THREE.Color>(count);\n const rgb = [0, 0, 0];\n const base = index * 4;\n for (let coefficient = 0; coefficient < count; coefficient += 1) {\n const data = extra[SH_KEYS[coefficient >> 2]];\n const word = data?.[base + (coefficient & 3)] ?? 0;\n decodeShRgbToArray(word, rgb);\n result[coefficient] = new THREE.Color(rgb[0], rgb[1], rgb[2]);\n }\n return result;\n}\n","import type { Vector3 } from \"three\";\nimport { SPLAT_BOUNDS_BLOCK_SIZE } from \"./defines\";\n\n/** Picking uses the same f32 ray and world-distance parameter as WASM. */\nexport class SplatRaycastQuery {\n private readonly origin: Float32Array;\n private readonly direction: Float32Array;\n private readonly near: number;\n private readonly far: number;\n\n constructor(origin: Vector3, direction: Vector3, near: number, far: number) {\n this.origin = Float32Array.of(origin.x, origin.y, origin.z);\n this.direction = Float32Array.of(direction.x, direction.y, direction.z);\n this.near = Math.fround(near);\n this.far = Math.fround(far);\n }\n\n /** Visit consecutive candidate records in one Morton-ordered chunk. */\n forEachRange(\n bounds: Float32Array,\n count: number,\n callback: RaycastRangeCallback,\n ) {\n let start = -1;\n for (let base = 0; base < count; base += SPLAT_BOUNDS_BLOCK_SIZE) {\n if (this.intersects(bounds, (base / SPLAT_BOUNDS_BLOCK_SIZE) * 6)) {\n if (start < 0) start = base;\n } else if (start >= 0) {\n callback(start, base - start);\n start = -1;\n }\n }\n if (start >= 0) callback(start, count - start);\n }\n\n private intersects(bounds: Float32Array, offset: number) {\n if (bounds[offset] > bounds[offset + 3]) return false;\n // Invalid bounds retain the per-Splat path.\n for (let i = offset; i < offset + 6; i++) {\n if (!Number.isFinite(bounds[i])) return true;\n }\n let near = this.near;\n let far = this.far;\n for (let axis = 0; axis < 3; axis++) {\n const origin = this.origin[axis];\n const direction = this.direction[axis];\n const min = bounds[offset + axis];\n const max = bounds[offset + axis + 3];\n // Enclose rounding in the f32 sphere/ellipsoid arithmetic, including\n // cancellation for distant rays and very thin Splats.\n const padding =\n 1e-5 * (Math.abs(origin) + Math.max(Math.abs(min), Math.abs(max)));\n if (direction === 0) {\n if (origin < min - padding || origin > max + padding) return false;\n } else {\n const a = (min - padding - origin) / direction;\n const b = (max + padding - origin) / direction;\n near = Math.max(near, Math.min(a, b));\n far = Math.min(far, Math.max(a, b));\n if (near > far) return false;\n }\n }\n return true;\n }\n}\n\nexport type RaycastRangeCallback = (start: number, count: number) => void;\n","import * as THREE from \"three\";\n\nimport {\n get_raycast_buffer,\n get_raycast_buffer2,\n get_raycast_indices,\n raycast_splat_buffers,\n} from \"gaussian-splat-rs\";\nimport { Splats } from \"../data/Splats\";\nimport type { SplatFileType } from \"../data/defines\";\nimport { SplatRaycastQuery } from \"../data/raycast\";\nimport type {\n SplatFileResolver,\n SplatProgressEvent,\n} from \"../loaders/loadTypes\";\nimport type { SplatPostDecodeProgram } from \"../loaders/postDecode/program\";\nimport * as wasm from \"../runtime/wasm\";\nimport { SplatEdit, SplatEditSdf, SplatEdits } from \"./SplatEdit\";\n\nlet raycastVisibleIndices = new Uint32Array(0);\nconst raycastWorldToMesh = new THREE.Matrix4();\nconst raycastDirectionMatrix = new THREE.Matrix3();\nconst raycastOrigin = new THREE.Vector3();\nconst raycastDirection = new THREE.Vector3();\n\nexport type SplatMeshOptions = {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n resolveFile?: SplatFileResolver;\n /** Declarative per-splat transform executed in the decode worker. */\n postDecode?: SplatPostDecodeProgram;\n splats?: Splats;\n onProgress?: (event: SplatProgressEvent) => void;\n onLoad?: (mesh: SplatMesh) => Promise<void> | void;\n editable?: boolean;\n raycastable?: boolean;\n minRaycastOpacity?: number;\n onFrame?: (context: {\n mesh: SplatMesh;\n time: number;\n deltaTime: number;\n }) => void;\n};\n\nexport type SplatMeshFrameContext = {\n time: number;\n deltaTime: number;\n globalEdits: SplatEdit[];\n};\n\nexport type SplatIntersection = THREE.Intersection<SplatMesh> & {\n /** Current readable index in this mesh's Splats. */\n index: number;\n /** Original file index; for streamed SOG, relative to this batch's chunk. */\n sourceIndex: number;\n};\n\nfunction validateSplatMeshInitializationInputs(options: SplatMeshOptions) {\n const inputs: string[] = [];\n if (options.url !== undefined) inputs.push(\"url\");\n if (options.file !== undefined) inputs.push(\"file\");\n if (options.fileBytes !== undefined) inputs.push(\"fileBytes\");\n if (options.splats !== undefined) inputs.push(\"splats\");\n if (inputs.length > 1) {\n throw new Error(\n `SplatMesh initialization inputs are mutually exclusive; provide only one of url, file, fileBytes, or splats (received: ${inputs.join(\", \")})`,\n );\n }\n}\n\n/** A scene object backed by a fixed encoded splat source and RGBA SDF edits. */\nexport class SplatMesh extends THREE.Object3D {\n private lastInitialization?: Promise<Splats>;\n private readiness!: Promise<SplatMesh>;\n private onLoad?: SplatMeshOptions[\"onLoad\"];\n\n get isInitialized() {\n return this.splats?.isInitialized ?? false;\n }\n\n get initialized(): Promise<SplatMesh> {\n const source = this.splats;\n if (!source) return Promise.resolve(this);\n const pending = source.initialized;\n if (pending !== this.lastInitialization) {\n this.lastInitialization = pending;\n this.readiness = pending.then(\n async () => {\n if (pending !== this.splats?.initialized) return this.initialized;\n this.numSplats = source.getNumSplats();\n this.updateMappingVersion();\n await this.onLoad?.(this);\n return this;\n },\n (error) => {\n if (pending !== this.splats?.initialized) return this.initialized;\n throw error;\n },\n );\n void this.readiness.catch(() => {});\n }\n return this.readiness;\n }\n\n splats?: Splats;\n\n numSplats = 0;\n recolor = new THREE.Color(1, 1, 1);\n opacity = 1;\n maxSh = 3;\n\n edits: SplatEdit[] | null = null;\n editable: boolean;\n raycastable: boolean;\n minRaycastOpacity: number;\n sdfEdits: SplatEdits | null = null;\n\n onFrame?: SplatMeshOptions[\"onFrame\"];\n\n version = 0;\n sortVersion = 0;\n centerVersion = 0;\n mappingVersion = 0;\n\n private lastSplats?: Splats;\n private lastNumSplats = -1;\n private lastMaxSh = -1;\n private lastMatrixWorld = new THREE.Matrix4();\n private hasLastMatrixWorld = false;\n private lastRecolor = new THREE.Vector4().setScalar(Number.NaN);\n private sdfCoordinateOrigin = new THREE.Vector3();\n\n constructor(options: SplatMeshOptions = {}) {\n super();\n\n if (options.splats && !(options.splats instanceof Splats)) {\n throw new TypeError(\"SplatMesh splats must be a Splats instance\");\n }\n validateSplatMeshInitializationInputs(options);\n this.splats =\n options.splats ??\n new Splats({\n url: options.url,\n file: options.file,\n fileBytes: options.fileBytes,\n fileType: options.fileType,\n fileName: options.fileName,\n resolveFile: options.resolveFile,\n postDecode: options.postDecode,\n onProgress: options.onProgress,\n });\n\n this.numSplats = this.splats.getNumSplats();\n this.editable = options.editable ?? true;\n this.raycastable = options.raycastable ?? true;\n this.minRaycastOpacity = options.minRaycastOpacity ?? 0.15;\n this.onFrame = options.onFrame;\n\n this.onLoad = options.onLoad;\n void this.initialized;\n }\n\n forEachSplat(\n callback: (\n index: number,\n center: THREE.Vector3,\n scales: THREE.Vector3,\n quaternion: THREE.Quaternion,\n opacity: number,\n color: THREE.Color,\n ) => void,\n ) {\n this.splats?.forEachSplat(callback);\n }\n\n dispose() {\n super.dispose();\n\n this.sdfEdits?.dispose();\n this.sdfEdits = null;\n this.splats?.dispose();\n this.splats = undefined;\n this.numSplats = 0;\n this.updateMappingVersion();\n }\n\n /** Copy cached local bounds; false includes scale/rotation and shape at source alpha 0.01. */\n getBoundingBox(centersOnly = true, target = new THREE.Box3()): THREE.Box3 {\n if (!this.isInitialized) {\n throw new Error(\n \"Cannot get bounding box before SplatMesh is initialized\",\n );\n }\n return (\n this.splats?.getBoundingBox(centersOnly, target) ?? target.makeEmpty()\n );\n }\n\n frameUpdate({ time, deltaTime, globalEdits }: SplatMeshFrameContext) {\n this.onFrame?.({ mesh: this, time, deltaTime });\n\n const source = this.splats;\n if (!source) {\n return;\n }\n // Follow source reinitialization even when callers only keep rendering.\n void this.initialized;\n let updated = false;\n let centersUpdated = false;\n let transformUpdated = false;\n const count = source.getNumSplats();\n if (source !== this.lastSplats) {\n this.lastSplats = source;\n updated = true;\n centersUpdated = true;\n }\n if (count !== this.lastNumSplats) {\n this.lastNumSplats = count;\n this.numSplats = count;\n this.mappingVersion += 1;\n updated = true;\n centersUpdated = true;\n }\n if (source.needsUpdate) {\n updated = true;\n centersUpdated = true;\n }\n if (this.maxSh !== this.lastMaxSh) {\n this.lastMaxSh = this.maxSh;\n updated = true;\n }\n\n this.updateWorldMatrix(true, false);\n if (\n !this.hasLastMatrixWorld ||\n !this.lastMatrixWorld.equals(this.matrixWorld)\n ) {\n this.lastMatrixWorld.copy(this.matrixWorld);\n this.hasLastMatrixWorld = true;\n updated = true;\n transformUpdated = true;\n }\n\n const recolor = new THREE.Vector4(\n this.recolor.r,\n this.recolor.g,\n this.recolor.b,\n THREE.MathUtils.clamp(this.opacity, 0, 1),\n );\n if (!recolor.equals(this.lastRecolor)) {\n this.lastRecolor.copy(recolor);\n updated = true;\n }\n\n const edits = new Set<SplatEdit>();\n if (this.editable) {\n for (const edit of globalEdits) edits.add(edit);\n if (this.edits) {\n for (const edit of this.edits) edits.add(edit);\n } else {\n this.traverseVisible((node) => {\n if (node instanceof SplatEdit) edits.add(node);\n });\n }\n }\n const orderedEdits = Array.from(edits).sort(\n (left, right) => left.ordering - right.ordering,\n );\n const groups = orderedEdits.map((edit) => {\n if (edit.sdfs) return { edit, sdfs: edit.sdfs };\n const sdfs: SplatEditSdf[] = [];\n edit.traverseVisible((node) => {\n if (node instanceof SplatEditSdf) sdfs.push(node);\n });\n return { edit, sdfs };\n });\n\n if (groups.length > 0 && !this.sdfEdits) {\n this.sdfEdits = new SplatEdits({\n maxEdits: groups.length,\n maxSdfs: groups.reduce((total, group) => total + group.sdfs.length, 0),\n });\n updated = true;\n }\n const sdfCoordinateOrigin = this.sdfCoordinateOrigin.setFromMatrixPosition(\n this.matrixWorld,\n );\n if (this.sdfEdits?.update(groups, sdfCoordinateOrigin).updated) {\n // RGBA-only SDF changes preserve centers and their existing sort order.\n updated = true;\n }\n\n if (updated) {\n this.version += 1;\n if (centersUpdated || transformUpdated) this.sortVersion += 1;\n if (centersUpdated) this.centerVersion += 1;\n }\n }\n\n updateVersion({ sort = true }: { sort?: boolean } = {}) {\n this.version += 1;\n if (sort) {\n this.sortVersion += 1;\n this.centerVersion += 1;\n }\n }\n\n updateMappingVersion() {\n this.mappingVersion += 1;\n this.updateVersion();\n }\n\n set needsUpdate(value: boolean) {\n if (value) this.updateVersion();\n }\n\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n if (!wasm.isInitialized() || !this.raycastable || !this.splats) {\n return;\n }\n\n const { near, far, ray } = raycaster;\n if (\n this.numSplats === 0 ||\n !Number.isFinite(this.minRaycastOpacity) ||\n this.minRaycastOpacity >= 1 ||\n near > far\n ) {\n return;\n }\n const worldToMesh = raycastWorldToMesh.copy(this.matrixWorld).invert();\n const origin = raycastOrigin.copy(ray.origin).applyMatrix4(worldToMesh);\n const direction = raycastDirection\n .copy(ray.direction)\n .applyMatrix3(raycastDirectionMatrix.setFromMatrix4(worldToMesh));\n const buffer = get_raycast_buffer();\n const buffer2 = get_raycast_buffer2();\n const capacity = buffer.length / 4;\n const splats = this.splats;\n\n if (raycastVisibleIndices.length !== capacity)\n raycastVisibleIndices = new Uint32Array(capacity);\n let count = 0;\n const flush = () => {\n const distances = raycast_splat_buffers(\n origin.x,\n origin.y,\n origin.z,\n direction.x,\n direction.y,\n direction.z,\n this.minRaycastOpacity,\n near,\n far,\n count,\n );\n const hitIndices = get_raycast_indices();\n\n for (let index = 0; index < distances.length; index += 1) {\n const distance = distances[index];\n const splatIndex = raycastVisibleIndices[hitIndices[index]];\n const hit: SplatIntersection = {\n distance,\n point: ray.at(distance, new THREE.Vector3()),\n object: this,\n index: splatIndex,\n sourceIndex: splats.getSourceIndex(splatIndex),\n };\n intersects.push(hit);\n }\n count = 0;\n };\n const query = new SplatRaycastQuery(origin, direction, near, far);\n splats.forEachRaycastRange(query, (start, length) => {\n for (let base = start; base < start + length; ) {\n const copied = Math.min(capacity - count, start + length - base);\n splats.copySplatRecords(\n buffer.subarray(count * 4),\n buffer2.subarray(count * 4),\n base,\n copied,\n );\n for (let i = 0; i < copied; i++)\n raycastVisibleIndices[count + i] = base + i;\n count += copied;\n base += copied;\n if (count === capacity) flush();\n }\n });\n if (count) flush();\n }\n}\n","import * as THREE from \"three\";\n\ntype WebGPURenderer = import(\"three/webgpu\").WebGPURenderer;\n\nexport type GaussianSplatCompatibleRenderer =\n | THREE.WebGLRenderer\n | WebGPURenderer;\n\nexport function isWebGPURenderer(\n renderer: GaussianSplatCompatibleRenderer,\n): renderer is WebGPURenderer {\n return \"isWebGPURenderer\" in renderer && renderer.isWebGPURenderer === true;\n}\n\nexport function usesNativeWebGPU(\n renderer: GaussianSplatCompatibleRenderer,\n): renderer is WebGPURenderer & { backend: { isWebGPUBackend: true } } {\n return (\n isWebGPURenderer(renderer) &&\n (renderer.backend as { isWebGPUBackend?: boolean }).isWebGPUBackend === true\n );\n}\n\n/**\n * The eyes of a WebXR camera, or the camera itself. An ArrayCamera without\n * eyes draws as a single view.\n */\nexport function getViews(camera: THREE.Camera): THREE.Camera[] {\n const array = camera as THREE.ArrayCamera;\n return array.isArrayCamera && array.cameras.length > 0\n ? array.cameras\n : [camera];\n}\n\nconst viewVectorTmp = new THREE.Vector3();\n\n/**\n * Stores the views' mean position and forward direction: the camera's pose,\n * or for WebXR eyes the shared head. Reads world matrices as Three composed\n * them with any camera rig.\n */\nexport function getMeanViewPose(\n views: readonly THREE.Camera[],\n position: THREE.Vector3,\n direction: THREE.Vector3,\n) {\n position.set(0, 0, 0);\n direction.set(0, 0, 0);\n for (const view of views) {\n position.add(viewVectorTmp.setFromMatrixPosition(view.matrixWorld));\n direction.add(\n viewVectorTmp.setFromMatrixColumn(view.matrixWorld, 2).normalize(),\n );\n }\n position.divideScalar(views.length);\n direction.normalize().negate();\n}\n\nexport function getRenderFrame(renderer: GaussianSplatCompatibleRenderer) {\n return isWebGPURenderer(renderer)\n ? renderer.info.render.calls\n : renderer.info.render.frame;\n}\n\ntype XRRenderTarget = THREE.RenderTarget & { isXRRenderTarget?: boolean };\n\nexport function isXRRenderTarget(\n renderTarget: THREE.RenderTarget | null,\n): boolean {\n return (renderTarget as XRRenderTarget | null)?.isXRRenderTarget === true;\n}\n\nexport function assertSupportedRenderer(\n renderer: GaussianSplatCompatibleRenderer,\n) {\n if (!isWebGPURenderer(renderer)) return;\n if (renderer.initialized !== true) {\n throw new Error(\n \"Initialize WebGPURenderer with await renderer.init() before using Gaussian Splat Lite\",\n );\n }\n const backend = renderer.backend as {\n isWebGPUBackend?: boolean;\n isWebGLBackend?: boolean;\n };\n if (backend.isWebGPUBackend !== true && backend.isWebGLBackend !== true) {\n throw new Error(\"Gaussian Splat Lite requires a WebGPU or WebGL backend\");\n }\n}\n\nexport function setRendererRenderTarget(\n renderer: GaussianSplatCompatibleRenderer,\n target: THREE.RenderTarget | null,\n activeCubeFace?: number,\n activeMipmapLevel?: number,\n) {\n renderer.setRenderTarget(\n target as THREE.WebGLRenderTarget | null,\n activeCubeFace,\n activeMipmapLevel,\n );\n}\n","import type { Camera, Texture } from \"three\";\nimport * as TSL from \"three/tsl\";\nimport type {\n ComputeNode,\n IndirectStorageBufferAttribute,\n Node,\n NodeBuilder,\n StorageBufferAttribute,\n StorageBufferNode,\n TextureNode,\n WorkgroupInfoNode,\n} from \"three/webgpu\";\n\n// @types/three r186 omits these fluent operations. Keep the additions on\n// interfaces used by these shaders, preserving their result types.\ndeclare module \"three/src/nodes/core/Node.js\" {\n interface IntegerExtensions<TInteger> {\n min(value: Node<TInteger> | number): Node<TInteger>;\n max(value: Node<TInteger> | number): Node<TInteger>;\n }\n interface IntOrVecExtensions<TNodeType> {\n shiftRight(value: Node<TNodeType> | number): Node<TNodeType>;\n clamp(low: Node<TNodeType>, high: Node<TNodeType>): Node<TNodeType>;\n }\n interface NumOrBoolVec4Extensions<TNumOrBool> {\n element(index: Node<\"int\"> | Node<\"uint\"> | number): Node<TNumOrBool>;\n }\n interface Mat4Extensions {\n element(index: Node<\"int\"> | Node<\"uint\"> | number): Node<\"vec4\">;\n }\n interface FloatOrVecExtensions<TNodeType> {\n negateAssign(): Node<TNodeType>;\n }\n}\n\ntype FloatToUint = {\n float: \"uint\";\n vec2: \"uvec2\";\n vec3: \"uvec3\";\n vec4: \"uvec4\";\n};\ntype UintToFloat = {\n uint: \"float\";\n uvec2: \"vec2\";\n uvec3: \"vec3\";\n uvec4: \"vec4\";\n};\ntype UintWorkgroup = WorkgroupInfoNode & {\n element(index: Node<\"uint\"> | Node<\"int\"> | number): Node<\"uint\">;\n setName(name: string): UintWorkgroup;\n};\n\n// Only override incomplete declarations; every other export keeps Three's\n// original overloads. These assertions do not wrap or replace runtime nodes.\ntype Compatibility = {\n floatBitsToUint<T extends keyof FloatToUint>(\n value: Node<T>,\n ): Node<FloatToUint[T]>;\n uintBitsToFloat<T extends keyof UintToFloat>(\n value: Node<T>,\n ): Node<UintToFloat[T]>;\n packHalf2x16(value: Node<\"vec2\">): Node<\"uint\">;\n unpackHalf2x16(value: Node<\"uint\">): Node<\"vec2\">;\n packSnorm2x16(value: Node<\"vec2\">): Node<\"uint\">;\n unpackSnorm2x16(value: Node<\"uint\">): Node<\"vec2\">;\n storage(\n value: StorageBufferAttribute,\n type: \"uint\",\n count?: number,\n ): StorageBufferNode<\"uint\">;\n workgroupArray(type: \"uint\", count: number): UintWorkgroup;\n builtin(name: \"gl_ViewID_OVR\"): Node<\"uint\">;\n countOneBits(value: Node<\"uint\">): Node<\"uint\">;\n ivec2: typeof TSL.ivec2 &\n ((x: Node<\"uint\">, y: Node<\"uint\">) => Node<\"ivec2\">);\n ivec3: typeof TSL.ivec3 &\n ((x: Node<\"uint\">, y: Node<\"uint\">, z: Node<\"uint\">) => Node<\"ivec3\">);\n Loop: typeof TSL.Loop &\n (<Name extends string, Type extends \"int\" | \"uint\">(\n params: {\n name: Name;\n type: Type;\n start: Node<Type>;\n end: Node<Type>;\n condition: string;\n },\n callback: (inputs: Record<Name, Node<Type>>) => void,\n ) => ReturnType<typeof TSL.Loop>);\n};\n\nexport const N = TSL as unknown as Omit<typeof TSL, keyof Compatibility> &\n Compatibility;\n\n/** Packed integer texture loads are incorrectly declared as vec4 upstream. */\nexport function uintTexture(texture: Texture): TextureNode<\"uvec4\"> {\n return TSL.texture<\"uvec4\">(texture).setSampler(false);\n}\n\n/** NodeBuilder.camera is present when building a material shader. */\nexport function materialCamera(builder: NodeBuilder): Camera {\n return (builder as NodeBuilder & { camera: Camera }).camera;\n}\n\n/** r186 supports an indirect attribute, but its declaration lists only counts. */\nexport function setIndirectDispatch(\n node: ComputeNode,\n dispatch: IndirectStorageBufferAttribute,\n) {\n (node as { dispatchSize: unknown }).dispatchSize = dispatch;\n}\n","import * as THREE from \"three\";\nimport * as TSL from \"three/tsl\";\nimport {\n type Node,\n NodeUpdateType,\n type TextureNode,\n type UniformNode,\n} from \"three/webgpu\";\nimport {\n SPLAT_TEX_HEIGHT_BITS,\n SPLAT_TEX_WIDTH_BITS,\n} from \"../../data/defines\";\nimport type { Uniforms } from \"../uniforms\";\n\nimport { N, uintTexture } from \"./tslCompat\";\nexport { N } from \"./tslCompat\";\n\nconst SPLAT_TEX_LAYER_BITS = SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS;\n\nconst SPLAT_TEX_WIDTH_MASK = (1 << SPLAT_TEX_WIDTH_BITS) - 1;\n\nconst SPLAT_TEX_HEIGHT_MASK = (1 << SPLAT_TEX_HEIGHT_BITS) - 1;\n\nexport const E = Math.E;\n\nexport type UniformType =\n | \"bool\"\n | \"float\"\n | \"int\"\n | \"uint\"\n | \"vec2\"\n | \"vec3\"\n | \"vec4\"\n | \"mat3\"\n | \"mat4\";\n\nexport function uniformBinding<Type extends UniformType>(\n uniforms: Uniforms,\n name: string,\n type: Type,\n): UniformNode<Type, unknown> {\n const uniform = TSL.uniform as <T extends UniformType>(\n value: unknown,\n type: T,\n ) => UniformNode<T, unknown>;\n return uniform(uniforms[name].value, type).onObjectUpdate(\n () => uniforms[name].value,\n );\n}\n\nexport function textureBinding(\n uniforms: Uniforms,\n name: string,\n array = false,\n) {\n const data = new Uint32Array(4);\n const placeholder = array\n ? new THREE.DataArrayTexture(data, 1, 1, 1)\n : new THREE.DataTexture(data, 1, 1);\n placeholder.format = THREE.RGBAIntegerFormat;\n placeholder.type = THREE.UnsignedIntType;\n placeholder.magFilter = THREE.NearestFilter;\n placeholder.minFilter = THREE.NearestFilter;\n placeholder.generateMipmaps = false;\n placeholder.needsUpdate = true;\n\n const getTexture = () => uniforms[name].value as THREE.Texture;\n return uintTexture(placeholder).onObjectUpdate(getTexture);\n}\n\nexport function load2D<T extends TextureNode<unknown>>(\n binding: T,\n coord: Node<\"ivec2\">,\n): T {\n const texel = binding.load(coord);\n texel.updateMatrix = false;\n return updateTextureLoad(binding, texel);\n}\n\nexport function loadArray<T extends TextureNode<unknown>>(\n binding: T,\n coord: Node<\"ivec3\">,\n): T {\n return updateTextureLoad(binding, binding.load(coord.xy).depth(coord.z));\n}\n\nfunction updateTextureLoad<T extends TextureNode<unknown>>(\n binding: T,\n texel: T,\n) {\n texel.updateBeforeType = NodeUpdateType.OBJECT;\n texel.updateBefore = (frame) => {\n // Bind the real texture before r186's texture update or r187's shared\n // uniforms derive the GL render-target Y flip.\n frame.updateNode(binding);\n return undefined;\n };\n return texel;\n}\n\nexport const splatTexCoord = N.Fn(([index]: [Node<\"uint\">]) => {\n const value = N.uint(index);\n return N.ivec3(\n N.int(value.bitAnd(SPLAT_TEX_WIDTH_MASK)),\n N.int(value.shiftRight(SPLAT_TEX_WIDTH_BITS).bitAnd(SPLAT_TEX_HEIGHT_MASK)),\n N.int(value.shiftRight(SPLAT_TEX_LAYER_BITS)),\n );\n});\n\nexport const quatVec = N.Fn(\n ([quaternion, vector]: [Node<\"vec4\">, Node<\"vec3\">]) => {\n const t = quaternion.xyz.cross(vector).mul(2);\n return vector.add(quaternion.w.mul(t)).add(quaternion.xyz.cross(t));\n },\n);\n\nexport const quatQuat = N.Fn(\n ([first, second]: [Node<\"vec4\">, Node<\"vec4\">]) => {\n return N.vec4(\n first.w\n .mul(second.x)\n .add(first.x.mul(second.w))\n .add(first.y.mul(second.z))\n .sub(first.z.mul(second.y)),\n first.w\n .mul(second.y)\n .sub(first.x.mul(second.z))\n .add(first.y.mul(second.w))\n .add(first.z.mul(second.x)),\n first.w\n .mul(second.z)\n .add(first.x.mul(second.y))\n .sub(first.y.mul(second.x))\n .add(first.z.mul(second.w)),\n first.w\n .mul(second.w)\n .sub(first.x.mul(second.x))\n .sub(first.y.mul(second.y))\n .sub(first.z.mul(second.z)),\n );\n },\n);\n\nexport const decodeCenter = N.Fn(([data]: [Node<\"uvec4\">]) => {\n return N.uintBitsToFloat(data.xyz);\n});\n\nexport const decodeAlphaShape = N.Fn(([data]: [Node<\"uvec4\">]) => {\n return N.unpackHalf2x16(data.w);\n});\n\nexport const decodeRgba = N.Fn(\n ([data, alpha]: [Node<\"uvec4\">, Node<\"float\">]) => {\n return N.vec4(N.unpackHalf2x16(data.x), N.unpackHalf2x16(data.y).x, alpha);\n },\n);\n\nexport const decodeLnScales = N.Fn(([data]: [Node<\"uvec4\">]) => {\n return N.vec3(N.unpackHalf2x16(data.y).y, N.unpackHalf2x16(data.z));\n});\n\nexport const decodeQuaternion = N.Fn(([encodedValue]: [Node<\"uint\">]) => {\n const encoded = N.uint(encodedValue);\n const quantU = encoded.bitAnd(0x3ff);\n const quantV = encoded.shiftRight(10).bitAnd(0x3ff);\n const angleInt = encoded.shiftRight(20);\n const folded = N.vec2(N.float(quantU), N.float(quantV))\n .div(1023)\n .mul(2)\n .sub(1);\n const axis = N.vec3(\n folded,\n N.float(1).sub(folded.x.abs()).sub(folded.y.abs()),\n ).toVar();\n const t = axis.z.negate().max(0);\n axis.x.addAssign(N.select(axis.x.greaterThanEqual(0), t.negate(), t));\n axis.y.addAssign(N.select(axis.y.greaterThanEqual(0), t.negate(), t));\n axis.assign(axis.normalize());\n\n const halfTheta = N.float(angleInt)\n .div(4095)\n .mul(Math.PI * 0.5);\n return N.vec4(axis.mul(halfTheta.sin()), halfTheta.cos());\n});\n","import type { Node } from \"three/webgpu\";\nimport { SPLAT_TEX_WIDTH, SPLAT_TEX_WIDTH_BITS } from \"../../data/defines\";\nimport type { Uniforms } from \"../uniforms\";\nimport {\n E,\n N,\n type UniformType,\n decodeAlphaShape,\n decodeCenter,\n decodeLnScales,\n decodeQuaternion,\n decodeRgba,\n load2D,\n loadArray,\n quatQuat,\n quatVec,\n splatTexCoord,\n textureBinding,\n uniformBinding,\n} from \"./shaderUtils\";\n\n// Finite sentinel for empty/unbounded SDFs. Runtime infinity arithmetic is not\n// portable in WGSL, and smooth ALL shapes otherwise evaluate exp(inf - inf).\nconst SDF_DISTANCE_LIMIT = 1e20;\n\ntype ShInputs = [\n first: Node<\"uvec4\">,\n second: Node<\"uvec4\">,\n direction: Node<\"vec3\">,\n];\n\ntype DeferredColor = {\n coord: Node<\"ivec3\">;\n center: Node<\"vec3\">;\n scale: Node<\"vec3\">;\n offset: Node<\"vec3\">;\n};\n\nconst encodeQuaternion = N.Fn(([input]: [Node<\"vec4\">]) => {\n const quaternion = N.select(input.w.lessThan(0), input.negate(), input);\n const theta = quaternion.w.clamp(0, 1).acos().mul(2);\n const sum = quaternion.x\n .abs()\n .add(quaternion.y.abs())\n .add(quaternion.z.abs());\n const projected = N.select(\n sum.lessThan(1e-6),\n N.vec2(1, 0),\n quaternion.xy.div(sum.max(1e-6)),\n ).toVar();\n N.If(quaternion.z.lessThan(0), () => {\n const oldX = projected.x.toVar();\n projected.x.assign(\n N.float(1)\n .sub(projected.y.abs())\n .mul(N.select(projected.x.greaterThanEqual(0), 1, -1)),\n );\n projected.y.assign(\n N.float(1)\n .sub(oldX.abs())\n .mul(N.select(projected.y.greaterThanEqual(0), 1, -1)),\n );\n });\n\n const quantized = projected\n .mul(0.5)\n .add(0.5)\n .mul(1023)\n .round()\n .clamp(0, 1023);\n const quantU = N.uint(quantized.x);\n const quantV = N.uint(quantized.y);\n const angle = N.uint(theta.div(Math.PI).mul(4095).round().clamp(0, 4095));\n return angle.shiftLeft(20).bitOr(quantV.shiftLeft(10)).bitOr(quantU);\n});\n\nconst decodeShRgb = N.Fn(([encoded]: [Node<\"uint\">]) => {\n const biasedBase = encoded.shiftRight(27).bitAnd(0x1f);\n const divisor = N.uintBitsToFloat(biasedBase.add(112).shiftLeft(23)).div(255);\n const rgb = N.vec3(\n N.float(encoded.bitAnd(0xff)),\n N.float(encoded.shiftRight(8).bitAnd(0xff)),\n N.float(encoded.shiftRight(16).bitAnd(0xff)),\n )\n .mul(divisor)\n .toVar();\n return N.vec3(\n N.select(\n encoded.bitAnd(0x1000000).notEqual(N.uint(0)),\n rgb.x.negate(),\n rgb.x,\n ),\n N.select(\n encoded.bitAnd(0x2000000).notEqual(N.uint(0)),\n rgb.y.negate(),\n rgb.y,\n ),\n N.select(\n encoded.bitAnd(0x4000000).notEqual(N.uint(0)),\n rgb.z.negate(),\n rgb.z,\n ),\n );\n}).setLayout({\n name: \"gslDecodeShRgb\",\n type: \"vec3\",\n inputs: [{ name: \"encoded\", type: \"uint\" }],\n});\n\nconst decodeSemanticOpacity = N.Fn(\n ([alpha, shapeAmount]: [Node<\"float\">, Node<\"float\">]) => {\n const result = alpha.toVar();\n N.If(shapeAmount.greaterThan(0), () => {\n const kernelShape = shapeAmount.min(1).mul(4).add(1);\n const kernelOpacity = kernelShape.mul(kernelShape).sub(1).div(E).exp();\n result.assign(alpha.mul(kernelOpacity));\n });\n return result;\n },\n);\n\nconst encodeWideSemanticOpacity = N.Fn(([opacity]: [Node<\"float\">]) => {\n return opacity.log().mul(E).add(1).sqrt().sub(1).mul(0.25).min(1);\n});\n\nexport function createGenerateProgram({ uniforms }: { uniforms: Uniforms }) {\n const bindUniform = <Type extends UniformType>(name: string, type: Type) =>\n uniformBinding(uniforms, name, type);\n const bindTexture = (name: string, array = false) =>\n textureBinding(uniforms, name, array);\n\n const targetCount = bindUniform(\"targetCount\", \"uint\");\n const stochasticSeedBase = bindUniform(\"stochasticSeedBase\", \"uint\");\n const sourceSplats = bindTexture(\"sourceSplats\", true);\n const sourceSplats2 = bindTexture(\"sourceSplats2\", true);\n const sourceLayerBits = bindUniform(\"sourceLayerBits\", \"uint\");\n const sourceLayerMask = bindUniform(\"sourceLayerMask\", \"uint\");\n const sourceBlockBits = bindUniform(\"sourceBlockBits\", \"uint\");\n const sourceBlocks = bindTexture(\"sourceBlocks\", true);\n const sourceOpacities = bindTexture(\"sourceOpacities\", true);\n const sourceIndexed = bindUniform(\"sourceIndexed\", \"bool\");\n const sourceIndices = bindTexture(\"sourceIndices\", true);\n const numSh = bindUniform(\"numSh\", \"int\");\n const sh1Texture = bindTexture(\"sh1Texture\", true);\n const sh2Texture = bindTexture(\"sh2Texture\", true);\n const sh3TextureA = bindTexture(\"sh3TextureA\", true);\n const sh3TextureB = bindTexture(\"sh3TextureB\", true);\n const objectBasis = bindUniform(\"objectBasis\", \"mat3\");\n const objectOffset = bindUniform(\"objectOffset\", \"vec3\");\n const objectLnScale = bindUniform(\"objectLnScale\", \"vec3\");\n const objectQuaternion = bindUniform(\"objectQuaternion\", \"vec4\");\n const objectReflected = bindUniform(\"objectReflected\", \"bool\");\n const recolor = bindUniform(\"recolor\", \"vec4\");\n const numSdfs = bindUniform(\"numSdfs\", \"int\");\n const numEdits = bindUniform(\"numEdits\", \"int\");\n const sdfTexture = bindTexture(\"sdfTexture\");\n const editTexture = bindTexture(\"editTexture\");\n\n const evaluateSH1 = N.Fn(\n ([data, direction]: [Node<\"uvec4\">, Node<\"vec3\">]) => {\n return decodeShRgb(data.x)\n .mul(direction.y.mul(-0.4886025))\n .add(decodeShRgb(data.y).mul(direction.z.mul(0.4886025)))\n .add(decodeShRgb(data.z).mul(direction.x.mul(-0.4886025)));\n },\n );\n\n const evaluateSH12 = N.Fn(([first, second, direction]: ShInputs) => {\n const result = evaluateSH1(first, direction).toVar();\n result.addAssign(\n decodeShRgb(first.w).mul(direction.x.mul(direction.y).mul(1.0925484)),\n );\n result.addAssign(\n decodeShRgb(second.x).mul(direction.y.mul(direction.z).mul(-1.0925484)),\n );\n result.addAssign(\n decodeShRgb(second.y).mul(\n direction.z\n .mul(direction.z)\n .mul(2)\n .sub(direction.x.mul(direction.x))\n .sub(direction.y.mul(direction.y))\n .mul(0.3153915),\n ),\n );\n result.addAssign(\n decodeShRgb(second.z).mul(direction.x.mul(direction.z).mul(-1.0925484)),\n );\n result.addAssign(\n decodeShRgb(second.w).mul(\n direction.x\n .mul(direction.x)\n .sub(direction.y.mul(direction.y))\n .mul(0.5462742),\n ),\n );\n return result;\n });\n\n const evaluateSH3 = N.Fn(([first, second, direction]: ShInputs) => {\n const xx = direction.x.mul(direction.x);\n const yy = direction.y.mul(direction.y);\n const zz = direction.z.mul(direction.z);\n return decodeShRgb(first.x)\n .mul(direction.y.mul(xx.mul(3).sub(yy)).mul(-0.5900436))\n .add(\n decodeShRgb(first.y).mul(\n direction.x.mul(direction.y).mul(direction.z).mul(2.8906114),\n ),\n )\n .add(\n decodeShRgb(first.z).mul(\n direction.y.mul(zz.mul(4).sub(xx).sub(yy)).mul(-0.4570458),\n ),\n )\n .add(\n decodeShRgb(first.w).mul(\n direction.z\n .mul(zz.mul(2).sub(xx.mul(3)).sub(yy.mul(3)))\n .mul(0.3731763),\n ),\n )\n .add(\n decodeShRgb(second.x).mul(\n direction.x.mul(zz.mul(4).sub(xx).sub(yy)).mul(-0.4570458),\n ),\n )\n .add(\n decodeShRgb(second.y).mul(direction.z.mul(xx.sub(yy)).mul(1.4453057)),\n )\n .add(\n decodeShRgb(second.z).mul(\n direction.x.mul(xx.sub(yy.mul(3))).mul(-0.5900436),\n ),\n );\n });\n\n const evaluateSH = N.Fn(\n ([coord, direction]: [Node<\"ivec3\">, Node<\"vec3\">]) => {\n const result = N.vec3(0).toVar();\n N.If(numSh.equal(N.int(1)), () => {\n result.assign(evaluateSH1(loadArray(sh1Texture, coord), direction));\n }).ElseIf(numSh.greaterThanEqual(N.int(2)), () => {\n result.assign(\n evaluateSH12(\n loadArray(sh1Texture, coord),\n loadArray(sh2Texture, coord),\n direction,\n ),\n );\n N.If(numSh.greaterThanEqual(N.int(3)), () => {\n result.addAssign(\n evaluateSH3(\n loadArray(sh3TextureA, coord),\n loadArray(sh3TextureB, coord),\n direction,\n ),\n );\n });\n });\n return result;\n },\n );\n\n const addShColor = (\n rgb: Node<\"vec3\">,\n coord: Node<\"ivec3\">,\n center: Node<\"vec3\">,\n ) => {\n N.If(numSh.greaterThan(N.int(0)), () => {\n const inverseObjectQuaternion = N.vec4(\n objectQuaternion.xyz.negate(),\n objectQuaternion.w,\n );\n const sourceViewDirection = quatVec(\n inverseObjectQuaternion,\n center.add(objectOffset),\n )\n .normalize()\n .toVar();\n N.If(objectReflected, () => {\n sourceViewDirection.x.negateAssign();\n });\n rgb.addAssign(evaluateSH(coord, sourceViewDirection));\n });\n };\n\n const generateValues = (\n index: Node<\"uint\">,\n deferredColor?: DeferredColor,\n ) => {\n const valid = N.bool(false).toVar();\n const center = N.vec3(0).toVar();\n const lnScales = N.vec3(0).toVar();\n const quaternion = N.vec4(0, 0, 0, 1).toVar();\n const rgba = N.vec4(0).toVar();\n const shapeAmount = N.float(0).toVar();\n const stochasticSeed = N.uint(0).toVar();\n\n N.If(index.lessThan(targetCount), () => {\n const sourceIndex = N.uint(index).toVar();\n N.If(sourceIndexed, () => {\n const indices = loadArray(\n sourceIndices,\n splatTexCoord(index.shiftRight(2)),\n );\n sourceIndex.assign(indices.element(index.bitAnd(3)));\n });\n // Use the source record, not its position in the visible-index list.\n stochasticSeed.assign(sourceIndex.bitXor(stochasticSeedBase));\n const blockOpacity = N.float(1).toVar();\n N.If(sourceBlockBits.lessThan(N.uint(32)), () => {\n const blockMask = sourceLayerMask.shiftRight(sourceBlockBits);\n const block = sourceIndex.shiftRight(sourceBlockBits);\n const group = loadArray(\n sourceBlocks,\n N.ivec3(\n N.int(block.bitAnd(blockMask.min(N.uint(SPLAT_TEX_WIDTH - 1)))),\n N.int(block.bitAnd(blockMask).shiftRight(SPLAT_TEX_WIDTH_BITS)),\n N.int(sourceIndex.shiftRight(sourceLayerBits)),\n ),\n ).r;\n blockOpacity.assign(\n N.uintBitsToFloat(loadArray(sourceOpacities, splatTexCoord(group)).r),\n );\n });\n const coord = N.ivec3(\n N.int(sourceIndex.bitAnd(SPLAT_TEX_WIDTH - 1)),\n N.int(\n sourceIndex.bitAnd(sourceLayerMask).shiftRight(SPLAT_TEX_WIDTH_BITS),\n ),\n N.int(sourceIndex.shiftRight(sourceLayerBits)),\n );\n const sourceA = loadArray(sourceSplats, coord);\n const sourceB = loadArray(sourceSplats2, coord);\n // Deleted scales are three packed -infinity half floats. Inspect their\n // bits before unpacking so the shader never has to compare infinities.\n const isDeleted = sourceB.y\n .shiftRight(16)\n .equal(N.uint(0xfc00))\n .and(sourceB.z.equal(N.uint(0xfc00fc00)));\n N.If(isDeleted.not().and(blockOpacity.greaterThan(0)), () => {\n const alphaShape = decodeAlphaShape(sourceA);\n valid.assign(true);\n center.assign(objectBasis.mul(decodeCenter(sourceA)));\n lnScales.assign(decodeLnScales(sourceB).add(objectLnScale));\n const sourceQuaternion = decodeQuaternion(sourceB.w).toVar();\n N.If(objectReflected, () => {\n sourceQuaternion.yz.negateAssign();\n });\n quaternion.assign(quatQuat(objectQuaternion, sourceQuaternion));\n rgba.assign(decodeRgba(sourceB, alphaShape.x));\n shapeAmount.assign(alphaShape.y);\n\n if (deferredColor) {\n deferredColor.coord.assign(coord);\n deferredColor.center.assign(center);\n } else {\n addShColor(rgba.rgb, coord, center);\n }\n\n const editPosition = center.toVar();\n center.addAssign(objectOffset);\n const semanticOpacityDecoded = N.bool(false).toVar();\n\n N.Loop(\n { start: N.int(0), end: numEdits, type: \"int\", condition: \"<\" },\n ({ i: editIndex }) => {\n const edit = load2D(editTexture, N.ivec2(N.int(0), editIndex));\n const blendMode = edit.x.bitAnd(0xff);\n const invert = edit.x.bitAnd(0x100).notEqual(N.uint(0));\n const sdfFirst = N.int(edit.y.bitAnd(0xffff));\n const sdfCount = N.int(edit.y.shiftRight(16));\n const softEdge = N.uintBitsToFloat(edit.z);\n const smoothAmount = N.uintBitsToFloat(edit.w);\n const distanceAccum = N.select(\n smoothAmount.equal(0),\n SDF_DISTANCE_LIMIT,\n 0,\n ).toVar();\n const maxExponent = N.float(0).toVar();\n const sdfRgba = N.vec4(0).toVar();\n const sdfRgbaMask = N.vec4(0).toVar();\n const sdfLast = sdfFirst.add(sdfCount).min(numSdfs);\n\n N.Loop(\n {\n start: sdfFirst,\n end: sdfLast,\n type: \"int\",\n condition: \"<\",\n name: \"sdfIndex\",\n },\n ({ sdfIndex }: { sdfIndex: Node<\"int\"> }) => {\n const data0 = load2D(\n sdfTexture,\n N.ivec2(N.int(0), sdfIndex),\n ).toVar();\n const data1 = load2D(\n sdfTexture,\n N.ivec2(N.int(1), sdfIndex),\n ).toVar();\n const data2 = load2D(\n sdfTexture,\n N.ivec2(N.int(2), sdfIndex),\n ).toVar();\n const data3 = load2D(\n sdfTexture,\n N.ivec2(N.int(3), sdfIndex),\n ).toVar();\n const data4 = load2D(\n sdfTexture,\n N.ivec2(N.int(4), sdfIndex),\n ).toVar();\n const flags = data0.w;\n const sdfCenter = N.uintBitsToFloat(data0.xyz);\n const data5 = load2D(sdfTexture, N.ivec2(N.int(5), sdfIndex));\n N.If(N.uintBitsToFloat(data5.w).lessThanEqual(0), () => {\n N.Continue();\n });\n const sdfBasis = N.mat3(\n N.uintBitsToFloat(data1.xyz),\n N.uintBitsToFloat(data2.xyz),\n N.uintBitsToFloat(data5.xyz),\n );\n // These expressions are shared by mutually exclusive branches.\n // Materialize them here so TSL cannot first cache them in just\n // one shape/blend branch and leave the others uninitialized.\n const sizes = N.uintBitsToFloat(data3).toVar();\n const value = N.uintBitsToFloat(data4).toVar();\n const valueMask = N.vec4(\n N.select(flags.bitAnd(0x10000).notEqual(N.uint(0)), 1, 0),\n N.select(flags.bitAnd(0x20000).notEqual(N.uint(0)), 1, 0),\n N.select(flags.bitAnd(0x40000).notEqual(N.uint(0)), 1, 0),\n N.select(flags.bitAnd(0x80000).notEqual(N.uint(0)), 1, 0),\n ).toVar();\n const sdfPosition = sdfBasis\n .mul(editPosition)\n .add(sdfCenter)\n .toVar();\n const sdfType = flags.bitAnd(0xff);\n const distance = N.float(SDF_DISTANCE_LIMIT).toVar();\n\n N.If(sdfType.equal(N.uint(0)), () => {\n distance.assign(-SDF_DISTANCE_LIMIT);\n })\n .ElseIf(sdfType.equal(N.uint(1)), () => {\n distance.assign(sdfPosition.z);\n })\n .ElseIf(sdfType.equal(N.uint(2)), () => {\n distance.assign(sdfPosition.length().sub(sizes.w));\n })\n .ElseIf(sdfType.equal(N.uint(3)), () => {\n const q = sdfPosition.abs().sub(sizes.xyz).add(sizes.w);\n distance.assign(\n q\n .max(0)\n .length()\n .add(q.x.max(q.y.max(q.z)).min(0))\n .sub(sizes.w),\n );\n })\n .ElseIf(sdfType.equal(N.uint(4)), () => {\n const radii = sizes.xyz.abs();\n N.If(N.all(radii.greaterThan(N.vec3(0))), () => {\n const scaledPosition = sdfPosition.div(radii);\n const k0 = scaledPosition.length();\n const k1 = scaledPosition.div(radii).length();\n // The approximation divides by zero at the center;\n // its exact signed distance there is the shortest radius.\n distance.assign(\n radii.x.min(radii.y).min(radii.z).negate(),\n );\n N.If(k1.greaterThan(0), () => {\n distance.assign(k0.mul(k0.sub(1)).div(k1));\n });\n });\n })\n .ElseIf(sdfType.equal(N.uint(5)), () => {\n const d = N.vec2(sdfPosition.xz.length(), sdfPosition.y)\n .abs()\n .sub(sizes.wy);\n distance.assign(d.x.max(d.y).min(0).add(d.max(0).length()));\n })\n .ElseIf(sdfType.equal(N.uint(6)), () => {\n sdfPosition.y.subAssign(\n sdfPosition.y.clamp(sizes.y.mul(-0.5), sizes.y.mul(0.5)),\n );\n distance.assign(sdfPosition.length().sub(sizes.w));\n })\n .ElseIf(sdfType.equal(N.uint(7)), () => {\n const angle = sizes.w.mul(Math.PI * 0.25);\n const c = N.vec2(angle.sin(), angle.cos());\n const q = N.vec2(\n sdfPosition.xy.length(),\n sdfPosition.z.negate(),\n );\n const sign = N.select(\n q.x.mul(c.y).sub(q.y.mul(c.x)).lessThan(0),\n -1,\n 1,\n );\n distance.assign(\n q\n .sub(c.mul(q.dot(c).max(0)))\n .length()\n .mul(sign),\n );\n });\n\n distance.mulAssign(N.uintBitsToFloat(data5.w));\n N.If(flags.bitAnd(0x100).notEqual(N.uint(0)), () => {\n distance.negateAssign();\n });\n\n N.If(smoothAmount.equal(0), () => {\n N.If(distance.lessThan(distanceAccum), () => {\n distanceAccum.assign(distance);\n sdfRgba.assign(value.mul(valueMask));\n sdfRgbaMask.assign(valueMask);\n });\n }).Else(() => {\n const exponent = distance.negate().div(smoothAmount).toVar();\n N.If(distanceAccum.equal(0), () => {\n maxExponent.assign(exponent);\n }).ElseIf(exponent.greaterThan(maxExponent), () => {\n const rescale = maxExponent.sub(exponent).exp();\n distanceAccum.mulAssign(rescale);\n sdfRgba.mulAssign(rescale);\n sdfRgbaMask.mulAssign(rescale);\n maxExponent.assign(exponent);\n });\n const weight = exponent.sub(maxExponent).exp();\n distanceAccum.addAssign(weight);\n sdfRgba.addAssign(weight.mul(value).mul(valueMask));\n sdfRgbaMask.addAssign(weight.mul(valueMask));\n });\n },\n );\n\n const distance = distanceAccum.toVar();\n N.If(smoothAmount.notEqual(0), () => {\n N.If(distanceAccum.equal(0), () => {\n distance.assign(SDF_DISTANCE_LIMIT);\n }).Else(() => {\n sdfRgba.divAssign(distanceAccum);\n sdfRgbaMask.divAssign(distanceAccum);\n distance.assign(\n distanceAccum\n .log()\n .negate()\n .sub(maxExponent)\n .mul(smoothAmount),\n );\n });\n });\n N.If(invert, () => {\n distance.negateAssign();\n });\n const amount = N.select(\n softEdge.equal(0),\n N.select(distance.lessThan(0), 1, 0),\n distance.negate().div(softEdge).add(0.5).clamp(0, 1),\n );\n const editOpacity = amount\n .greaterThan(0)\n .and(sdfRgbaMask.a.greaterThan(0));\n N.If(editOpacity.and(semanticOpacityDecoded.not()), () => {\n rgba.a.assign(\n decodeSemanticOpacity(rgba.a.clamp(0, 1), shapeAmount),\n );\n semanticOpacityDecoded.assign(true);\n });\n\n // Alpha keeps the original per-edit operations. Native rendering\n // composes RGB edits so SH can wait for the final visibility test.\n const input = deferredColor ? rgba.a : rgba;\n const value = deferredColor ? sdfRgba.a : sdfRgba;\n const mask = deferredColor ? sdfRgbaMask.a : sdfRgbaMask;\n const one = deferredColor ? N.float(1) : N.vec4(1);\n const target = input.toVar();\n N.If(blendMode.equal(N.uint(0)), () => {\n target.assign(input.mul(one.add(value).sub(mask)));\n if (deferredColor) {\n const scale = N.vec3(1)\n .add(sdfRgba.rgb.sub(sdfRgbaMask.rgb).mul(amount))\n .toVar();\n deferredColor.scale.mulAssign(scale);\n deferredColor.offset.mulAssign(scale);\n }\n })\n .ElseIf(blendMode.equal(N.uint(1)), () => {\n target.assign(input.mul(one.sub(mask)).add(value));\n if (deferredColor) {\n const scale = N.vec3(1)\n .sub(sdfRgbaMask.rgb.mul(amount))\n .toVar();\n deferredColor.scale.mulAssign(scale);\n deferredColor.offset.assign(\n deferredColor.offset\n .mul(scale)\n .add(sdfRgba.rgb.mul(amount)),\n );\n }\n })\n .ElseIf(blendMode.equal(N.uint(2)), () => {\n target.assign(input.add(value));\n if (deferredColor)\n deferredColor.offset.addAssign(sdfRgba.rgb.mul(amount));\n });\n input.assign(N.mix(input, target, amount));\n },\n );\n\n if (!deferredColor) rgba.rgb.mulAssign(recolor.rgb);\n const opacityScale = recolor.a.mul(blockOpacity);\n N.If(\n semanticOpacityDecoded.not().and(opacityScale.greaterThanEqual(1)),\n () => {\n rgba.a.assign(rgba.a.clamp(0, 1));\n },\n ).Else(() => {\n N.If(semanticOpacityDecoded.not(), () => {\n rgba.a.assign(\n decodeSemanticOpacity(rgba.a.clamp(0, 1), shapeAmount),\n );\n });\n const semanticOpacity = rgba.a.mul(opacityScale);\n N.If(semanticOpacity.lessThanEqual(1), () => {\n rgba.a.assign(semanticOpacity.clamp(0, 1));\n shapeAmount.assign(0);\n }).Else(() => {\n rgba.a.assign(1);\n shapeAmount.assign(encodeWideSemanticOpacity(semanticOpacity));\n });\n });\n });\n });\n\n return {\n valid,\n center,\n lnScales,\n quaternion,\n rgba,\n shapeAmount,\n stochasticSeed,\n };\n };\n\n const packAccumulator = (generated: ReturnType<typeof generateValues>) => {\n const accumulatorA = N.uvec4(0).toVar();\n const accumulatorB = N.uvec4(0).toVar();\n\n N.If(generated.valid, () => {\n accumulatorA.assign(\n N.uvec4(\n N.floatBitsToUint(generated.center),\n N.packHalf2x16(\n N.vec2(generated.rgba.a, generated.shapeAmount).clamp(0, 1),\n ),\n ),\n );\n accumulatorB.assign(\n N.uvec4(\n N.packHalf2x16(generated.rgba.rg),\n N.packHalf2x16(N.vec2(generated.rgba.b, generated.lnScales.x)),\n N.packHalf2x16(generated.lnScales.yz),\n encodeQuaternion(generated.quaternion),\n ),\n );\n });\n\n return {\n accumulatorA,\n accumulatorB,\n stochasticSeed: generated.stochasticSeed,\n };\n };\n\n const generateAccumulator = (index: Node<\"uint\">) =>\n packAccumulator(generateValues(index));\n\n // SDFs update alpha and compose RGB scale/offset in one traversal. Apply the\n // composed color transform after visibility and SH. Composition preserves\n // the affine edit semantics, but can change float32 rounding between edits.\n const prepare = (index: Node<\"uint\">) => {\n const color = {\n coord: N.ivec3(0).toVar(),\n center: N.vec3(0).toVar(),\n scale: N.vec3(1).toVar(),\n offset: N.vec3(0).toVar(),\n };\n const generated = generateValues(index, color);\n return {\n ...generated,\n // Call in the branch that passes projection and screen-footprint culling.\n resolveRgb: () => {\n const rgb = generated.rgba.rgb.toVar();\n addShColor(rgb, color.coord, color.center);\n rgb.assign(rgb.mul(color.scale).add(color.offset));\n rgb.mulAssign(recolor.rgb);\n // Preserve the accumulator's half-float color quantization before\n // the nonnegative clamp and vertex color conversion.\n return N.vec3(\n N.unpackHalf2x16(N.packHalf2x16(rgb.rg)),\n N.unpackHalf2x16(N.packHalf2x16(N.vec2(rgb.b, 0))).x,\n ).max(0);\n },\n };\n };\n\n return Object.assign(generateAccumulator, { prepare });\n}\n","import * as THREE from \"three\";\nimport ranks from \"./blueNoise32.bin?arraybuffer&base64\";\n\n/** Tileable 32-frame STBN atlas generated by scripts/generate-blue-noise.js. */\nexport function createBlueNoiseTexture() {\n // Three's WebGPU backend supports R32UI; keep the embedded ranks at 16 bits.\n const texture = new THREE.DataTexture(\n Uint32Array.from(new Uint16Array(ranks)),\n 32,\n 32 * 32,\n THREE.RedIntegerFormat,\n THREE.UnsignedIntType,\n );\n texture.name = \"GaussianSplatSpatiotemporalBlueNoise\";\n texture.needsUpdate = true;\n return texture;\n}\n","import * as THREE from \"three\";\nimport {\n SPLAT_BLOCKS_DISABLED,\n SPLAT_TEX_HEIGHT_BITS,\n SPLAT_TEX_WIDTH_BITS,\n} from \"../data/defines\";\nimport { emptySplatTexture } from \"../data/textureLayout\";\nimport { SplatEdits } from \"../scene/SplatEdit\";\nimport { createBlueNoiseTexture } from \"./blueNoise\";\n\nexport type Uniforms = Record<string, THREE.IUniform>;\n\nexport const ORDERING_TEXTURE_WIDTH = 4096;\nexport const SPLATS_PER_ORDERING_ROW = ORDERING_TEXTURE_WIDTH * 4;\n\nexport const emptyOrdering = new THREE.DataTexture(\n new Uint32Array(SPLATS_PER_ORDERING_ROW),\n ORDERING_TEXTURE_WIDTH,\n 1,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n);\nemptyOrdering.needsUpdate = true;\n\nexport const DEFAULT_MIN_ALPHA = 0.5 / 255;\n\nexport function makeSplatUniforms() {\n const emptySplats: THREE.Texture = emptySplatTexture;\n const uniforms = {\n // Size of render viewport in pixels\n renderSize: { value: new THREE.Vector2() },\n viewportOrigin: { value: new THREE.Vector2() },\n renderOrigin: { value: new THREE.Vector3() },\n // Near and far plane distances\n near: { value: 0.1 },\n far: { value: 1000.0 },\n // SplatAccumulator to view transformation quaternion\n renderToViewQuat: { value: new THREE.Quaternion() },\n // SplatAccumulator to view transformation translation\n renderToViewPos: { value: new THREE.Vector3() },\n // SplatAccumulator to view transformation uniform scale\n renderToViewScale: { value: 1 },\n // Maximum distance (in stddevs) from Gsplat center to render\n maxStdDev: { value: 1.0 },\n // Minimum pixel radius for splat rendering\n minPixelRadius: { value: 1.0 },\n // Maximum pixel radius for splat rendering\n maxPixelRadius: { value: 256.0 },\n // Minimum alpha value for splat rendering\n minAlpha: { value: DEFAULT_MIN_ALPHA },\n // Add to projected 2D splat covariance diagonal (thickens and brightens)\n preBlurAmount: { value: 0.3 },\n // Add to 2D splat covariance diagonal and adjust opacity (anti-aliasing)\n blurAmount: { value: 0.0 },\n // Clip Gsplats that are clipXY times beyond the +-1 frustum bounds\n clipXY: { value: 1.25 },\n // Debug renderSize scale factor\n focalAdjustment: { value: 2.0 },\n // Whether to decode stored sRGB Splat colors before blending\n encodeLinear: { value: false },\n // Exact draw count; the final instance may contain unused quads.\n splatCount: { value: 0 },\n // Back-to-front sort ordering of splat indices\n ordering: { type: \"t\", value: emptyOrdering },\n // Gsplat collection to render\n splats: { type: \"t\", value: emptySplats },\n splats2: { type: \"t\", value: emptySplats },\n stochasticSeeds: { type: \"t\", value: emptySplats },\n stochasticNoise: { value: createBlueNoiseTexture() },\n stochasticSample: { value: 0 },\n // Manual stochastic transparency\n stochastic: { value: false },\n stochasticOrdering: { value: false },\n };\n return uniforms;\n}\n\nexport function makeGenerateUniforms(): Uniforms {\n return {\n targetLayer: { value: 0 },\n targetBase: { value: 0 },\n targetCount: { value: 0 },\n // Stable mesh identity, independent of accumulator layout and visibility.\n stochasticSeedBase: { value: 0 },\n sourceSplats: { value: emptySplatTexture },\n sourceSplats2: { value: emptySplatTexture },\n sourceLayerBits: { value: SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS },\n // Precompute masks on the CPU: ANGLE/D3D11 can miscompile dynamic shifts\n // used to construct a mask, leaving layer bits in the texture Y coordinate.\n sourceLayerMask: {\n value: (1 << (SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS)) - 1,\n },\n sourceBlockBits: { value: SPLAT_BLOCKS_DISABLED },\n sourceBlocks: { value: emptySplatTexture },\n sourceOpacities: { value: emptySplatTexture },\n sourceIndexed: { value: false },\n sourceIndices: { value: emptySplatTexture },\n numSh: { value: 0 },\n sh1Texture: { value: emptySplatTexture },\n sh2Texture: { value: emptySplatTexture },\n sh3TextureA: { value: emptySplatTexture },\n sh3TextureB: { value: emptySplatTexture },\n objectBasis: { value: new THREE.Matrix3() },\n objectOffset: { value: new THREE.Vector3() },\n objectLnScale: { value: new THREE.Vector3() },\n objectQuaternion: { value: new THREE.Quaternion() },\n objectReflected: { value: false },\n recolor: { value: new THREE.Vector4(1, 1, 1, 1) },\n numSdfs: { value: 0 },\n numEdits: { value: 0 },\n sdfTexture: { value: SplatEdits.emptyTexture },\n editTexture: { value: SplatEdits.emptyTexture },\n };\n}\n","const uint SPLAT_TEX_WIDTH_BITS = 11u;\nconst uint SPLAT_TEX_HEIGHT_BITS = 11u;\nconst uint SPLAT_TEX_LAYER_BITS = SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS;\n\nconst uint SPLAT_TEX_WIDTH = 1u << SPLAT_TEX_WIDTH_BITS;\nconst uint SPLAT_TEX_HEIGHT = 1u << SPLAT_TEX_HEIGHT_BITS;\n\nconst uint SPLAT_TEX_WIDTH_MASK = SPLAT_TEX_WIDTH - 1u;\nconst uint SPLAT_TEX_HEIGHT_MASK = SPLAT_TEX_HEIGHT - 1u;\n\nconst float PI = 3.1415926535897932384626433832795;\n\nvec3 srgbToLinear(vec3 rgb) {\n // Match Three's sRGB transfer.\n return mix(\n pow(rgb * 0.9478672986 + vec3(0.0521327014), vec3(2.4)),\n rgb * 0.0773993808, lessThanEqual(rgb, vec3(0.04045)));\n}\n\nuint encodeQuatOctXy1010R12(vec4 q) {\n // Ensure minimal representation: flip if q.w is negative.\n if (q.w < 0.0) {\n q = -q;\n }\n // Compute rotation angle: θ = 2 * acos(q.w) ∈ [0,π]\n float theta = 2.0 * acos(clamp(q.w, 0.0, 1.0));\n\n // --- Folded Octahedral Mapping (inline) ---\n // q.xyz = axis * sin(theta / 2). The common sine factor cancels during\n // octahedral normalization, so the rotation axis need not be recovered.\n float sum = abs(q.x) + abs(q.y) + abs(q.z);\n // Use the canonical +X axis when the vector part is too small to project.\n vec2 p = (sum < 1e-6) ? vec2(1.0, 0.0) : q.xy / sum;\n // Fold the lower hemisphere.\n if (q.z < 0.0) {\n float oldPx = p.x;\n p.x = (1.0 - abs(p.y)) * (p.x >= 0.0 ? 1.0 : -1.0);\n p.y = (1.0 - abs(oldPx)) * (p.y >= 0.0 ? 1.0 : -1.0);\n }\n // Remap from [-1,1] to [0,1]\n float u_f = p.x * 0.5 + 0.5;\n float v_f = p.y * 0.5 + 0.5;\n // Quantize to 10 bits (0 to 1023)\n uint quantU = uint(clamp(round(u_f * 1023.0), 0.0, 1023.0));\n uint quantV = uint(clamp(round(v_f * 1023.0), 0.0, 1023.0));\n \n // --- Angle Quantization ---\n // Quantize θ ∈ [0,π] to 12 bits (0 to 4095)\n uint angleInt = uint(clamp(round((theta / PI) * 4095.0), 0.0, 4095.0));\n \n // Pack bits: bits [0–9]: quantU, [10–19]: quantV, [20–31]: angleInt.\n return (angleInt << 20u) | (quantV << 10u) | quantU;\n}\n\nvec4 decodeQuatOctXy1010R12(uint encoded) {\n // Extract the fields.\n uint quantU = encoded & uint(0x3FFu); // bits 0–9\n uint quantV = (encoded >> 10u) & uint(0x3FFu); // bits 10–19\n uint angleInt = encoded >> 20u; // bits 20–31\n\n // Recover u and v in [0,1], then map to [-1,1].\n float u_f = float(quantU) / 1023.0;\n float v_f = float(quantV) / 1023.0;\n vec2 f = vec2(u_f * 2.0 - 1.0, v_f * 2.0 - 1.0);\n\n vec3 axis = vec3(f.xy, 1.0 - abs(f.x) - abs(f.y));\n float t = max(-axis.z, 0.0);\n axis.x += (axis.x >= 0.0) ? -t : t;\n axis.y += (axis.y >= 0.0) ? -t : t;\n axis = normalize(axis);\n \n // Decode the angle θ ∈ [0,π].\n float theta = (float(angleInt) / 4095.0) * PI;\n float halfTheta = theta * 0.5;\n float s = sin(halfTheta);\n float w = cos(halfTheta);\n \n return vec4(axis * s, w);\n}\n\nvec3 decodeSplatCenter(uvec4 splatData) {\n return vec3(\n uintBitsToFloat(splatData.x),\n uintBitsToFloat(splatData.y),\n uintBitsToFloat(splatData.z)\n );\n}\n\n// Encode a Splat whose scale is already logarithmic into the standard\n// two-record representation. The first record's final word stores alpha and\n// special-kernel shape amount as float16.\nvoid encodeSplatLnScale(\n out uvec4 splatData, out uvec4 splatData2,\n vec3 center, vec3 lnScales, vec4 quaternion, vec4 rgba, float shapeAmount\n) {\n splatData.x = floatBitsToUint(center.x);\n splatData.y = floatBitsToUint(center.y);\n splatData.z = floatBitsToUint(center.z);\n splatData.w = packHalf2x16(clamp(vec2(rgba.a, shapeAmount), 0.0, 1.0));\n\n splatData2.x = packHalf2x16(rgba.rg);\n splatData2.y = packHalf2x16(vec2(rgba.b, lnScales.x));\n splatData2.z = packHalf2x16(lnScales.yz);\n splatData2.w = encodeQuatOctXy1010R12(quaternion);\n}\n\nvec2 decodeSplatAlphaShapeAmount(uvec4 splatData) {\n return unpackHalf2x16(splatData.w);\n}\n\nvoid decodeSplatAttributesLnScale(\n uvec4 splatData2,\n float alpha,\n out vec3 lnScales, out vec4 quaternion, out vec4 rgba\n) {\n rgba.a = alpha;\n\n rgba.rg = unpackHalf2x16(splatData2.x);\n vec2 split = unpackHalf2x16(splatData2.y);\n rgba.b = split.x;\n lnScales.x = split.y;\n lnScales.yz = unpackHalf2x16(splatData2.z);\n quaternion = decodeQuatOctXy1010R12(splatData2.w);\n}\n\nvec3 decodeSplatShRgb(uint encoded) {\n uint biasedBase = (encoded >> 27u) & 0x1fu;\n // Re-bias the exponent from the packed bias of 15 to float32's bias of 127,\n // then construct the exact power of two directly (127 - 15 = 112).\n float divisor = uintBitsToFloat((biasedBase + 112u) << 23u) / 255.0;\n\n vec3 rgb = vec3(uvec3(encoded & 0xffu, (encoded >> 8u) & 0xffu, (encoded >> 16u) & 0xffu));\n rgb *= divisor;\n\n return vec3(\n ((encoded & 0x1000000u) != 0u) ? -rgb.r : rgb.r,\n ((encoded & 0x2000000u) != 0u) ? -rgb.g : rgb.g,\n ((encoded & 0x4000000u) != 0u) ? -rgb.b : rgb.b\n );\n}\n\n// Rotate vector v by quaternion q\nvec3 quatVec(vec4 q, vec3 v) {\n // Rotate vector v by quaternion q\n vec3 t = 2.0 * cross(q.xyz, v);\n return v + q.w * t + cross(q.xyz, t);\n}\n\n// Apply quaternion q1 after quaternion q2\nvec4 quatQuat(vec4 q1, vec4 q2) {\n return vec4(\n q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,\n q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x,\n q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w,\n q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n );\n}\n\nmat3 scaleQuaternionToMatrix(vec3 s, vec4 q) {\n // Compute the matrix of scaling by s then rotating by q\n return mat3(\n s.x * (1.0 - 2.0 * (q.y * q.y + q.z * q.z)),\n s.x * (2.0 * (q.x * q.y + q.w * q.z)),\n s.x * (2.0 * (q.x * q.z - q.w * q.y)),\n s.y * (2.0 * (q.x * q.y - q.w * q.z)),\n s.y * (1.0 - 2.0 * (q.x * q.x + q.z * q.z)),\n s.y * (2.0 * (q.y * q.z + q.w * q.x)),\n s.z * (2.0 * (q.x * q.z + q.w * q.y)),\n s.z * (2.0 * (q.y * q.z - q.w * q.x)),\n s.z * (1.0 - 2.0 * (q.x * q.x + q.y * q.y))\n );\n}\n\nivec3 splatTexCoord(int index) {\n uint x = uint(index) & SPLAT_TEX_WIDTH_MASK;\n uint y = (uint(index) >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK;\n uint z = uint(index) >> SPLAT_TEX_LAYER_BITS;\n return ivec3(x, y, z);\n}\n","\nprecision highp float;\nprecision highp int;\n\nuniform float minAlpha;\n#if GSL_STOCHASTIC\nuniform highp usampler2D stochasticNoise;\n#endif\n\nout vec4 fragColor;\n\nflat in uvec4 vSplat;\nin vec2 vSplatUv;\n#if GSL_STOCHASTIC\n// Noise tile offset: x in bits 0-4, y from bit 5.\nflat in uint vStochasticOffset;\n#endif\n\n#include <logdepthbuf_pars_fragment>\n\nvoid main() {\n float z2 = dot(vSplatUv, vSplatUv);\n if (z2 > uintBitsToFloat(vSplat.w)) {\n discard;\n }\n\n vec2 blueKernelPower = unpackHalf2x16(vSplat.y);\n float kernelPower = blueKernelPower.y;\n float kernelAlpha = exp(-0.5 * z2);\n if (kernelPower != 0.0) {\n kernelAlpha = 1.0 - pow(1.0 - kernelAlpha, kernelPower);\n }\n float alpha = uintBitsToFloat(vSplat.z) * kernelAlpha;\n\n if (alpha < minAlpha) {\n discard;\n }\n #if GSL_STOCHASTIC\n uvec2 offset = uvec2(vStochasticOffset, vStochasticOffset >> 5u);\n ivec2 coord = ivec2((uvec2(gl_FragCoord.xy) + offset) & uvec2(31u));\n coord.y += int(vStochasticOffset >> 10u) * 32;\n float randomValue = (float(texelFetch(stochasticNoise, coord, 0).r) + 0.5) / 32768.0;\n if (randomValue >= alpha) {\n discard;\n }\n #endif\n\n // Decode color only after the fragment survives coverage tests.\n vec4 rgba = vec4(unpackHalf2x16(vSplat.x), blueKernelPower.x, alpha);\n\n #if GSL_STOCHASTIC\n fragColor = vec4(rgba.rgb, 1.0);\n #elif defined(PREMULTIPLIED_ALPHA)\n fragColor = vec4(rgba.rgb * rgba.a, rgba.a);\n #else\n fragColor = rgba;\n #endif\n\n #include <logdepthbuf_fragment>\n}\n","\nprecision highp float;\nprecision highp int;\nprecision highp usampler2DArray;\n\n#include <splatDefines>\n\nflat out uvec4 vSplat;\nout vec2 vSplatUv;\n#if GSL_STOCHASTIC\n// Noise atlas offset: x in bits 0-4, y in 5-9, temporal slice in 10-14.\nflat out uint vStochasticOffset;\n#endif\n\nuniform vec2 renderSize;\nuniform vec4 renderToViewQuat;\nuniform vec3 renderToViewPos;\n// Uniform scale of the render-to-view transform (1.0 unless the camera is scaled)\nuniform float renderToViewScale;\nuniform float maxStdDev;\nuniform float minPixelRadius;\nuniform float maxPixelRadius;\nuniform float minAlpha;\nuniform float blurAmount;\nuniform float preBlurAmount;\nuniform float clipXY;\nuniform float focalAdjustment;\nuniform bool encodeLinear;\nuniform uint splatCount;\n\nuniform usampler2D ordering;\nuniform usampler2DArray splats;\nuniform usampler2DArray splats2;\n\n#if GSL_STOCHASTIC\nuniform bool stochasticOrdering;\nuniform uint stochasticSample;\nuniform vec2 viewportOrigin;\nuniform usampler2DArray stochasticSeeds;\n#endif\n\n// Required by logdepthbuf_pars_vertex (normally defined in three.js #include <common>)\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == -1.0;\n}\n\n#include <logdepthbuf_pars_vertex>\n\n// Chris Wellons' \"prospector\" mix, constant across each Splat's fragments.\nuint hashU32(uint value) {\n value ^= value >> 16u;\n value *= 0x7feb352du;\n value ^= value >> 15u;\n value *= 0x846ca68bu;\n value ^= value >> 16u;\n return value;\n}\n\nfloat gaussianSupportRadius(float alpha, float maximumRadius) {\n if (minAlpha <= 0.0) return maximumRadius;\n float radiusSquared = 2.0 * log(alpha / minAlpha);\n return min(maximumRadius, sqrt(max(0.0, radiusSquared)));\n}\n\nfloat wideSupportRadius(float alpha, float power, float maximumRadius) {\n if (minAlpha <= 0.0) return maximumRadius;\n // 1 - (1 - x)^power <= power * x for power >= 1. Only remove\n // coverage that cannot reach minAlpha, without inverting pow near 1.\n float radiusSquared = 2.0 * log(alpha * power / minAlpha);\n return min(maximumRadius, sqrt(max(0.0, radiusSquared)));\n}\n\nvoid main() {\n // Default to outside the frustum so it's discarded if we return early\n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n\n uint index = uint(gl_InstanceID) * uint(SPLATS_PER_INSTANCE) + uint(position.z);\n if (index >= splatCount) return;\n\n uint splatIndex;\n #if GSL_STOCHASTIC\n if (!stochasticOrdering) {\n // Use source indices when stochastic ordering is disabled or not ready.\n splatIndex = index;\n } else\n #endif\n {\n ivec2 orderingCoord = ivec2(int((index >> 2u) & 4095u), int(index >> 14u));\n splatIndex = texelFetch(ordering, orderingCoord, 0)[index & 3u];\n }\n if (splatIndex == 0xffffffffu) {\n // Special value reserved for \"no splat\"\n return;\n }\n\n ivec3 texCoord = splatTexCoord(int(splatIndex));\n uvec4 splat1 = texelFetch(splats, texCoord, 0);\n vec2 alphaShapeAmount = decodeSplatAlphaShapeAmount(splat1);\n float alpha = alphaShapeAmount.x;\n if ((alpha == 0.0) || (alpha < minAlpha)) {\n return;\n }\n vec3 center = decodeSplatCenter(splat1);\n // Compute the view space center of the splat\n vec3 viewCenter = renderToViewScale * quatVec(renderToViewQuat, center) + renderToViewPos;\n\n // Discard splats behind the camera\n if (isPerspectiveMatrix(projectionMatrix) && viewCenter.z >= 0.0) {\n return;\n }\n\n // Compute the clip space center of the splat\n vec4 clipCenter = projectionMatrix * vec4(viewCenter, 1.0);\n\n // Discard splats outside near/far planes\n if (abs(clipCenter.z) >= clipCenter.w) {\n return;\n }\n\n // Discard splats more than clipXY times outside the XY frustum\n float clip = clipXY * clipCenter.w;\n if (abs(clipCenter.x) > clip || abs(clipCenter.y) > clip) {\n return;\n }\n\n // The second record is only needed by splats whose centers survive the\n // view-frustum checks above.\n vec3 lnScales;\n vec4 quaternion, rgba;\n uvec4 splat2 = texelFetch(splats2, texCoord, 0);\n decodeSplatAttributesLnScale(splat2, alpha, lnScales, quaternion, rgba);\n vec3 scales = exp(lnScales);\n if (all(equal(scales, vec3(0.0)))) {\n return;\n }\n\n // Match the reference 3DGS rasterizer by clamping SH-evaluated RGB positive.\n rgba.rgb = max(rgba.rgb, vec3(0.0));\n\n // Decode the shape amount independently from mesh/SDF opacity, which\n // remains in the main splat's alpha.\n float kernelShape = 1.0 + 4.0 * min(alphaShapeAmount.y, 1.0);\n // Zero marks the ordinary Gaussian path; wider kernels reuse this power\n // for every covered fragment.\n float kernelPower = 0.0;\n if (kernelShape > 1.0) {\n kernelPower = exp(\n (kernelShape * kernelShape - 1.0) / 2.718281828459045\n );\n }\n\n // Expand wider shape kernels until alpha is nearly zero before clipping.\n float maximumSupportRadius = maxStdDev\n + 0.7 * max(kernelShape - 1.0, 0.0);\n float supportRadius = maximumSupportRadius;\n\n scales *= renderToViewScale;\n\n // Compute view space quaternion of splat\n vec4 viewQuaternion = quatQuat(renderToViewQuat, quaternion);\n\n // Compute the scaled rotation basis of the splat.\n mat3 RS = scaleQuaternionToMatrix(scales, viewQuaternion);\n\n // Compute the two relevant columns of the projection Jacobian.\n vec2 scaledRenderSize = renderSize * focalAdjustment;\n vec2 focal = 0.5 * scaledRenderSize * vec2(projectionMatrix[0][0], projectionMatrix[1][1]);\n\n vec3 j0;\n vec3 j1;\n if (isOrthographic) {\n j0 = vec3(focal.x, 0.0, 0.0);\n j1 = vec3(0.0, focal.y, 0.0);\n } else {\n float invZ = 1.0 / viewCenter.z;\n vec2 J1 = focal * invZ;\n vec2 J2 = -(J1 * viewCenter.xy) * invZ;\n j0 = vec3(J1.x, 0.0, J2.x);\n j1 = vec3(0.0, J1.y, J2.y);\n }\n\n // Project only the 2D covariance entries that are consumed below:\n // j^T * RS * RS^T * j = dot(RS^T * j, RS^T * j).\n vec3 p0 = transpose(RS) * j0;\n vec3 p1 = transpose(RS) * j1;\n float a = dot(p0, p0);\n float b = dot(p0, p1);\n float d = dot(p1, p1);\n\n // Optionally pre-blur the splat to match non-antialias optimized splats\n a += preBlurAmount;\n d += preBlurAmount;\n\n float detOrig = a * d - b * b;\n // Do convolution with a 0.5-pixel Gaussian for anti-aliasing: sqrt(0.3) ~= 0.5\n a += blurAmount;\n d += blurAmount;\n float det = a * d - b * b;\n if (det <= 0.0) return;\n\n // Compute anti-aliasing intensity scaling factor\n float blurAdjust = sqrt(max(0.0, detOrig / det));\n alpha *= blurAdjust;\n if (!(alpha > 0.0) || alpha < minAlpha) {\n return;\n }\n\n // Only cover fragments that can reach minAlpha for either kernel.\n if (kernelPower == 0.0) {\n supportRadius = gaussianSupportRadius(alpha, supportRadius);\n } else {\n supportRadius = wideSupportRadius(alpha, kernelPower, supportRadius);\n }\n vSplatUv = position.xy * supportRadius;\n\n // Compute the eigenvalue and eigenvectors of the 2D covariance matrix\n float eigenAvg = 0.5 * (a + d);\n float eigenDelta = length(vec2(0.5 * (a - d), b));\n float eigen1 = eigenAvg + eigenDelta;\n // Keep a small positive minor axis when subtraction rounds to zero.\n float eigen2 = max(eigenAvg - eigenDelta, 1e-4);\n\n vec2 eigenVec1 = (abs(b) > 0.001)\n ? normalize(vec2(b, eigen1 - a))\n : ((a >= d) ? vec2(1.0, 0.0) : vec2(0.0, 1.0));\n vec2 eigenVec2 = vec2(eigenVec1.y, -eigenVec1.x);\n\n // Apply maxPixelRadius to the original support first, then shrink both the\n // quad and its UV extent by the same ratio to preserve the Gaussian profile.\n float maxProjectedRadius = maxPixelRadius * focalAdjustment;\n float scale1 = min(maxProjectedRadius, maximumSupportRadius * sqrt(eigen1));\n float scale2 = min(maxProjectedRadius, maximumSupportRadius * sqrt(eigen2));\n float supportScale = (maximumSupportRadius > 0.0)\n ? supportRadius / maximumSupportRadius\n : 0.0;\n // Wide kernels previously used their full support for the size cutoff.\n // Keep that visibility decision when trimming only their transparent tails.\n float cullScale = (kernelPower == 0.0) ? supportScale : 1.0;\n // Projected radii use scaledRenderSize; convert the screen-pixel cutoff too.\n float minProjectedRadius = minPixelRadius * focalAdjustment;\n if (scale1 * cullScale < minProjectedRadius && scale2 * cullScale < minProjectedRadius) {\n return;\n }\n scale1 *= supportScale;\n scale2 *= supportScale;\n\n #if GSL_STOCHASTIC\n // Fetch stable coverage seeds only after all projection cutoffs pass.\n // Keep XY fixed so consecutive samples follow the same STBN time sequence.\n // Independent per-Splat XYZ offsets decorrelate overlapping coverage tests.\n uint seed = texelFetch(stochasticSeeds, texCoord, 0).r;\n uint hash = hashU32(seed);\n uvec2 offset = uvec2(hash, hash >> 5u) - uvec2(viewportOrigin);\n uint phase = ((hash >> 10u) + stochasticSample) & 31u;\n vStochasticOffset = (offset.x & 31u) | ((offset.y & 31u) << 5u) | (phase << 10u);\n #endif\n\n // RGB is constant across the quad, so convert before rasterization.\n if (encodeLinear) {\n rgba.rgb = srgbToLinear(rgba.rgb);\n }\n // Match the TSL varying layout: half RGB/kernel power, float32 alpha/radius.\n vec3 rgb = min(rgba.rgb, vec3(65504.0));\n vSplat = uvec4(\n packHalf2x16(rgb.rg),\n packHalf2x16(vec2(rgb.b, kernelPower)),\n floatBitsToUint(alpha),\n floatBitsToUint(supportRadius * supportRadius)\n );\n\n // Compute the NDC coordinates for the ellipsoid's diagonal axes.\n vec2 pixelOffset = position.x * eigenVec1 * scale1 + position.y * eigenVec2 * scale2;\n vec2 ndcOffset = (2.0 / scaledRenderSize) * pixelOffset;\n\n // Compute NDC center of the splat\n vec3 ndcCenter = clipCenter.xyz / clipCenter.w;\n vec3 ndc = vec3(ndcCenter.xy + ndcOffset, ndcCenter.z);\n\n gl_Position = vec4(ndc.xy * clipCenter.w, clipCenter.zw);\n #include <logdepthbuf_vertex>\n}\n","import * as THREE from \"three\";\n\nimport splatDefines from \"./shaders/splatDefines.glsl\";\nimport splatFragment from \"./shaders/splatFragment.glsl\";\nimport splatVertex from \"./shaders/splatVertex.glsl\";\n\nlet shaders: Record<string, string> | null = null;\n\nexport function getShaders(): Record<string, string> {\n if (!shaders) {\n // @ts-ignore\n THREE.ShaderChunk.splatDefines = splatDefines;\n shaders = {\n splatVertex,\n splatFragment,\n };\n }\n return shaders;\n}\n","precision highp float;\nprecision highp int;\nprecision highp usampler2D;\nprecision highp usampler2DArray;\n\n#include <splatDefines>\n\nuniform uint targetLayer;\nuniform int targetBase;\nuniform int targetCount;\nuniform uint stochasticSeedBase;\n\nuniform usampler2DArray sourceSplats;\nuniform usampler2DArray sourceSplats2;\nuniform uint sourceLayerBits;\nuniform uint sourceLayerMask;\nuniform uint sourceBlockBits;\nuniform usampler2DArray sourceBlocks;\nuniform usampler2DArray sourceOpacities;\nuniform bool sourceIndexed;\nuniform usampler2DArray sourceIndices;\n\nuniform int numSh;\nuniform usampler2DArray sh1Texture;\nuniform usampler2DArray sh2Texture;\nuniform usampler2DArray sh3TextureA;\nuniform usampler2DArray sh3TextureB;\n\nuniform mat3 objectBasis;\nuniform vec3 objectOffset;\nuniform vec3 objectLnScale;\nuniform vec4 objectQuaternion;\nuniform bool objectReflected;\nuniform vec4 recolor;\n\nuniform int numSdfs;\nuniform int numEdits;\nuniform usampler2D sdfTexture;\nuniform usampler2D editTexture;\n\nlayout(location = 0) out uvec4 target;\nlayout(location = 1) out uvec4 target2;\n#if GSL_STOCHASTIC_SEEDS\nlayout(location = 2) out uint targetSeed;\n#endif\n\n// Match WebGPU's finite sentinel for empty/unbounded SDFs. Smooth ALL shapes\n// must not evaluate exp(inf - inf).\nconst float SDF_DISTANCE_LIMIT = 1e20;\n\nfloat decodeSemanticOpacity(float alpha, float shapeAmount) {\n if (shapeAmount <= 0.0) return alpha;\n\n float kernelShape = 1.0 + 4.0 * min(shapeAmount, 1.0);\n float kernelOpacity = exp(\n (kernelShape * kernelShape - 1.0) / 2.718281828459045\n );\n return alpha * kernelOpacity;\n}\n\nfloat encodeWideSemanticOpacity(float opacity) {\n float kernelShape = sqrt(log(opacity) * 2.718281828459045 + 1.0);\n return min(1.0, 0.25 * (kernelShape - 1.0));\n}\n\nvec3 evaluateSH1(uvec4 data, vec3 direction) {\n return decodeSplatShRgb(data.x) * (-0.4886025 * direction.y)\n + decodeSplatShRgb(data.y) * (0.4886025 * direction.z)\n + decodeSplatShRgb(data.z) * (-0.4886025 * direction.x);\n}\n\nvec3 evaluateSH12(uvec4 first, uvec4 second, vec3 direction) {\n vec3 result = evaluateSH1(first, direction);\n result += decodeSplatShRgb(first.w) * (1.0925484 * direction.x * direction.y);\n result += decodeSplatShRgb(second.x) * (-1.0925484 * direction.y * direction.z);\n result += decodeSplatShRgb(second.y) * (0.3153915 * (2.0 * direction.z * direction.z - direction.x * direction.x - direction.y * direction.y));\n result += decodeSplatShRgb(second.z) * (-1.0925484 * direction.x * direction.z);\n result += decodeSplatShRgb(second.w) * (0.5462742 * (direction.x * direction.x - direction.y * direction.y));\n return result;\n}\n\nvec3 evaluateSH3(uvec4 first, uvec4 second, vec3 direction) {\n float xx = direction.x * direction.x;\n float yy = direction.y * direction.y;\n float zz = direction.z * direction.z;\n return decodeSplatShRgb(first.x) * (-0.5900436 * direction.y * (3.0 * xx - yy))\n + decodeSplatShRgb(first.y) * (2.8906114 * direction.x * direction.y * direction.z)\n + decodeSplatShRgb(first.z) * (-0.4570458 * direction.y * (4.0 * zz - xx - yy))\n + decodeSplatShRgb(first.w) * (0.3731763 * direction.z * (2.0 * zz - 3.0 * xx - 3.0 * yy))\n + decodeSplatShRgb(second.x) * (-0.4570458 * direction.x * (4.0 * zz - xx - yy))\n + decodeSplatShRgb(second.y) * (1.4453057 * direction.z * (xx - yy))\n + decodeSplatShRgb(second.z) * (-0.5900436 * direction.x * (xx - 3.0 * yy));\n}\n\nvec3 evaluateSH(ivec3 coord, vec3 direction) {\n vec3 result = vec3(0.0);\n if (numSh == 1) {\n result = evaluateSH1(texelFetch(sh1Texture, coord, 0), direction);\n } else if (numSh >= 2) {\n result = evaluateSH12(\n texelFetch(sh1Texture, coord, 0),\n texelFetch(sh2Texture, coord, 0),\n direction\n );\n if (numSh >= 3) {\n result += evaluateSH3(\n texelFetch(sh3TextureA, coord, 0),\n texelFetch(sh3TextureB, coord, 0),\n direction\n );\n }\n }\n return result;\n}\n\nvoid unpackSdf(\n int index,\n out uint flags,\n out vec3 center,\n out mat3 basis,\n out float distanceScale,\n out vec4 sizes,\n out vec4 sdfRgba\n) {\n uvec4 data = texelFetch(sdfTexture, ivec2(0, index), 0);\n center = vec3(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z));\n flags = data.w;\n uvec4 firstAxis = texelFetch(sdfTexture, ivec2(1, index), 0);\n uvec4 secondAxis = texelFetch(sdfTexture, ivec2(2, index), 0);\n uvec4 thirdAxis = texelFetch(sdfTexture, ivec2(5, index), 0);\n basis = mat3(uintBitsToFloat(firstAxis.xyz), uintBitsToFloat(secondAxis.xyz), uintBitsToFloat(thirdAxis.xyz));\n distanceScale = uintBitsToFloat(thirdAxis.w);\n data = texelFetch(sdfTexture, ivec2(3, index), 0);\n sizes = vec4(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z), uintBitsToFloat(data.w));\n data = texelFetch(sdfTexture, ivec2(4, index), 0);\n sdfRgba = vec4(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z), uintBitsToFloat(data.w));\n}\n\nfloat sdfDistance(uint type, vec3 position, vec4 sizes) {\n switch (type) {\n case 0u: return -SDF_DISTANCE_LIMIT;\n case 1u: return position.z;\n case 2u: return length(position) - sizes.w;\n case 3u: {\n vec3 q = abs(position) - sizes.xyz + sizes.w;\n return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0) - sizes.w;\n }\n case 4u: {\n vec3 radii = abs(sizes.xyz);\n if (any(lessThanEqual(radii, vec3(0.0)))) return SDF_DISTANCE_LIMIT;\n vec3 scaledPosition = position / radii;\n float k0 = length(scaledPosition);\n float k1 = length(scaledPosition / radii);\n // At the center, the exact signed distance is the shortest radius.\n if (k1 <= 0.0) return -min(radii.x, min(radii.y, radii.z));\n return k0 * (k0 - 1.0) / k1;\n }\n case 5u: {\n vec2 d = abs(vec2(length(position.xz), position.y)) - sizes.wy;\n return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));\n }\n case 6u: {\n position.y -= clamp(position.y, -0.5 * sizes.y, 0.5 * sizes.y);\n return length(position) - sizes.w;\n }\n case 7u: {\n float angle = 0.25 * PI * sizes.w;\n vec2 c = vec2(sin(angle), cos(angle));\n vec2 q = vec2(length(position.xy), -position.z);\n float distance = length(q - c * max(dot(q, c), 0.0));\n return distance * (((q.x * c.y - q.y * c.x) < 0.0) ? -1.0 : 1.0);\n }\n }\n return SDF_DISTANCE_LIMIT;\n}\n\nfloat evaluateSdfs(\n int sdfFirst,\n int sdfCount,\n vec3 position,\n float smoothAmount,\n out vec4 resultRgba,\n out vec4 resultRgbaMask\n) {\n float distanceAccum = smoothAmount == 0.0 ? SDF_DISTANCE_LIMIT : 0.0;\n float maxExponent = 0.0;\n resultRgba = vec4(0.0);\n resultRgbaMask = vec4(0.0);\n int sdfLast = min(sdfFirst + sdfCount, numSdfs);\n\n for (int index = sdfFirst; index < sdfLast; ++index) {\n uint flags;\n vec3 center;\n mat3 basis;\n float distanceScale;\n vec4 sizes;\n vec4 value;\n unpackSdf(index, flags, center, basis, distanceScale, sizes, value);\n if (distanceScale <= 0.0) continue;\n vec4 valueMask = vec4(\n (flags & 0x10000u) != 0u ? 1.0 : 0.0,\n (flags & 0x20000u) != 0u ? 1.0 : 0.0,\n (flags & 0x40000u) != 0u ? 1.0 : 0.0,\n (flags & 0x80000u) != 0u ? 1.0 : 0.0\n );\n vec3 sdfPosition = basis * position + center;\n float distance = sdfDistance(flags & 0xffu, sdfPosition, sizes) * distanceScale;\n if ((flags & 0x100u) != 0u) distance = -distance;\n\n if (smoothAmount == 0.0) {\n if (distance < distanceAccum) {\n distanceAccum = distance;\n resultRgba = value * valueMask;\n resultRgbaMask = valueMask;\n }\n } else {\n float exponent = -distance / smoothAmount;\n if (distanceAccum == 0.0) {\n maxExponent = exponent;\n } else if (exponent > maxExponent) {\n float rescale = exp(maxExponent - exponent);\n distanceAccum *= rescale;\n resultRgba *= rescale;\n resultRgbaMask *= rescale;\n maxExponent = exponent;\n }\n float weight = exp(exponent - maxExponent);\n distanceAccum += weight;\n resultRgba += weight * value * valueMask;\n resultRgbaMask += weight * valueMask;\n }\n }\n\n // A hard union can have distance zero on the surface; it is not empty.\n if (smoothAmount == 0.0) return distanceAccum;\n if (distanceAccum == 0.0) return SDF_DISTANCE_LIMIT;\n resultRgba /= distanceAccum;\n resultRgbaMask /= distanceAccum;\n return (-log(distanceAccum) - maxExponent) * smoothAmount;\n}\n\nbool applySdfEdits(\n vec3 position,\n inout vec4 rgba,\n float shapeAmount\n) {\n bool semanticOpacityDecoded = false;\n for (int editIndex = 0; editIndex < numEdits; ++editIndex) {\n uvec4 edit = texelFetch(editTexture, ivec2(0, editIndex), 0);\n uint blendMode = edit.x & 0xffu;\n bool invert = (edit.x & 0x100u) != 0u;\n int sdfFirst = int(edit.y & 0xffffu);\n int sdfCount = int(edit.y >> 16u);\n float softEdge = uintBitsToFloat(edit.z);\n float smoothAmount = uintBitsToFloat(edit.w);\n\n vec4 sdfRgba;\n vec4 sdfRgbaMask;\n float distance = evaluateSdfs(\n sdfFirst,\n sdfCount,\n position,\n smoothAmount,\n sdfRgba,\n sdfRgbaMask\n );\n if (invert) distance = -distance;\n float amount = softEdge == 0.0\n ? (distance < 0.0 ? 1.0 : 0.0)\n : clamp(-distance / softEdge + 0.5, 0.0, 1.0);\n bool editOpacity = amount > 0.0 && sdfRgbaMask.a > 0.0;\n if (editOpacity && !semanticOpacityDecoded) {\n // SDF opacity values operate on semantic opacity, not on the alpha\n // half of the nonlinear wide-kernel encoding.\n rgba.a = decodeSemanticOpacity(\n clamp(rgba.a, 0.0, 1.0),\n shapeAmount\n );\n semanticOpacityDecoded = true;\n }\n vec4 target = rgba;\n switch (blendMode) {\n case 0u:\n target = rgba * (vec4(1.0) + sdfRgba - sdfRgbaMask);\n break;\n case 1u:\n target = rgba * (vec4(1.0) - sdfRgbaMask) + sdfRgba;\n break;\n case 2u:\n target = rgba + sdfRgba;\n break;\n }\n rgba = mix(rgba, target, amount);\n }\n return semanticOpacityDecoded;\n}\n\nvoid produceSplat(int index) {\n uint sourceIndex = uint(index);\n if (sourceIndexed) {\n uvec4 indices = texelFetch(sourceIndices, splatTexCoord(index >> 2), 0);\n sourceIndex = indices[index & 3];\n }\n #if GSL_STOCHASTIC_SEEDS\n targetSeed = sourceIndex ^ stochasticSeedBase;\n #endif\n float blockOpacity = 1.0;\n if (sourceBlockBits < 32u) {\n // Group layers follow the source layers, at one texel per block.\n uint blockMask = sourceLayerMask >> sourceBlockBits;\n uint block = sourceIndex >> sourceBlockBits;\n uint group = texelFetch(sourceBlocks, ivec3(\n block & min(blockMask, SPLAT_TEX_WIDTH_MASK),\n (block & blockMask) >> SPLAT_TEX_WIDTH_BITS,\n sourceIndex >> sourceLayerBits\n ), 0).r;\n blockOpacity = uintBitsToFloat(texelFetch(sourceOpacities, splatTexCoord(int(group)), 0).r);\n }\n if (blockOpacity <= 0.0) return;\n ivec3 coord = ivec3(\n sourceIndex & SPLAT_TEX_WIDTH_MASK,\n (sourceIndex & sourceLayerMask) >> SPLAT_TEX_WIDTH_BITS,\n sourceIndex >> sourceLayerBits\n );\n uvec4 sourceSplat2 = texelFetch(sourceSplats2, coord, 0);\n // Detect the three packed -infinity scales before unpacking any floats.\n if ((sourceSplat2.y >> 16u) == 0xfc00u && sourceSplat2.z == 0xfc00fc00u) return;\n uvec4 sourceSplat = texelFetch(sourceSplats, coord, 0);\n vec2 alphaShapeAmount = decodeSplatAlphaShapeAmount(sourceSplat);\n vec3 center = decodeSplatCenter(sourceSplat);\n vec3 lnScales;\n vec4 quaternion;\n vec4 rgba;\n decodeSplatAttributesLnScale(\n sourceSplat2,\n alphaShapeAmount.x,\n lnScales,\n quaternion,\n rgba\n );\n float shapeAmount = alphaShapeAmount.y;\n\n // Match PlayCanvas' work-buffer transform. Centers retain the complete\n // affine transform, while Gaussian shape is approximated by composing the\n // model rotation and its positive per-axis scale with each splat.\n center = objectBasis * center;\n if (numSh > 0) {\n vec3 worldViewDirection = center + objectOffset;\n vec4 inverseObjectQuaternion = vec4(-objectQuaternion.xyz, objectQuaternion.w);\n vec3 sourceViewDirection = normalize(quatVec(inverseObjectQuaternion, worldViewDirection));\n if (objectReflected) sourceViewDirection.x = -sourceViewDirection.x;\n rgba.rgb += evaluateSH(coord, sourceViewDirection);\n }\n lnScales += objectLnScale;\n if (objectReflected) quaternion.yz = -quaternion.yz;\n quaternion = quatQuat(objectQuaternion, quaternion);\n\n vec3 editPosition = center;\n center += objectOffset;\n// The center is camera-relative while editPosition is mesh-origin-relative,\n// matching the rebased SDF transforms without reconstructing world position.\n // Opacity is clamped once on the CPU when preparing this mesh.\n float opacityScale = recolor.a * blockOpacity;\n bool semanticOpacityDecoded = applySdfEdits(\n editPosition,\n rgba,\n shapeAmount\n );\n rgba.rgb *= recolor.rgb;\n if (!semanticOpacityDecoded && opacityScale >= 1.0) {\n // Neither SDFs nor the mesh opacity changed opacity, so preserve the\n // source alpha/shape encoding without any transcendental operations.\n rgba.a = clamp(rgba.a, 0.0, 1.0);\n } else {\n if (!semanticOpacityDecoded) {\n rgba.a = decodeSemanticOpacity(\n clamp(rgba.a, 0.0, 1.0),\n shapeAmount\n );\n }\n float semanticOpacity = rgba.a * opacityScale;\n if (semanticOpacity <= 1.0) {\n rgba.a = clamp(semanticOpacity, 0.0, 1.0);\n shapeAmount = 0.0;\n } else {\n rgba.a = 1.0;\n shapeAmount = encodeWideSemanticOpacity(semanticOpacity);\n }\n }\n\n encodeSplatLnScale(\n target,\n target2,\n center,\n lnScales,\n quaternion,\n rgba,\n shapeAmount\n );\n}\n\nvoid main() {\n int targetIndex = int(targetLayer << SPLAT_TEX_LAYER_BITS)\n + int(uint(gl_FragCoord.y) << SPLAT_TEX_WIDTH_BITS)\n + int(gl_FragCoord.x);\n int index = targetIndex - targetBase;\n\n target = uvec4(0u);\n target2 = uvec4(0u);\n #if GSL_STOCHASTIC_SEEDS\n targetSeed = 0u;\n #endif\n if (index >= 0 && index < targetCount) {\n produceSplat(index);\n }\n}\n","import * as THREE from \"three\";\n\n// \"Identity\" vertex shader that just passes through the position.\nexport const IDENT_VERTEX_SHADER = `\nprecision highp float;\n\nin vec3 position;\n\nvoid main() {\n gl_Position = vec4(position.xy, 0.0, 1.0);\n}\n`;\n\n// Synchronous uploads share this CPU-only view; it has no GPU storage.\nconst uploadView = new THREE.DataTexture(\n null,\n 1,\n 1,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n);\n\nexport function uploadU32DataTextureRows(\n renderer: THREE.WebGLRenderer,\n texture: THREE.Texture,\n width: number,\n rows: number,\n data: Uint32Array,\n) {\n // Initialize before filling the shared view: onUpdate may trigger another upload.\n renderer.initTexture(texture);\n uploadView.image.data = data;\n uploadView.image.width = width;\n uploadView.image.height = rows;\n try {\n renderer.copyTextureToTexture(uploadView, texture);\n } finally {\n // Do not retain the sort buffer between uploads.\n uploadView.image.data = null;\n }\n}\n","import * as THREE from \"three\";\nimport { FullScreenQuad } from \"three/addons/postprocessing/Pass.js\";\nimport { SPLAT_TEX_HEIGHT, SPLAT_TEX_WIDTH } from \"../../data/defines\";\nimport {\n type GaussianSplatCompatibleRenderer,\n isWebGPURenderer,\n setRendererRenderTarget,\n} from \"../rendererUtils\";\nimport { type Uniforms, makeGenerateUniforms } from \"../uniforms\";\nimport { getShaders } from \"./shaders\";\nimport splatGenerate from \"./shaders/splatGenerate.glsl\";\nimport { IDENT_VERTEX_SHADER } from \"./textureUtils\";\n\n// Generate materials without and with the stochastic seed output.\nconst webGLMaterials: (THREE.RawShaderMaterial | undefined)[] = [];\nlet webGLUniforms: Uniforms | null = null;\nconst fullScreenQuad = new FullScreenQuad(\n new THREE.RawShaderMaterial({ visible: false }),\n);\n\n/** Sorted rendering needs no seed layer; stochastic draws read one per Splat. */\nexport function createWebGLAccumulatorTarget(\n width: number,\n height: number,\n depth: number,\n stochasticSeeds: boolean,\n) {\n const target = new THREE.WebGLArrayRenderTarget(width, height, depth, {\n depthBuffer: false,\n stencilBuffer: false,\n generateMipmaps: false,\n magFilter: THREE.NearestFilter,\n minFilter: THREE.NearestFilter,\n format: THREE.RGBAIntegerFormat,\n type: THREE.UnsignedIntType,\n });\n target.scissorTest = true;\n\n const second = target.texture.clone();\n target.textures = [target.texture, second];\n if (stochasticSeeds) {\n const seeds = target.texture.clone();\n seeds.format = THREE.RedIntegerFormat;\n seeds.name = \"SplatAccumulator.stochasticSeeds\";\n target.textures.push(seeds);\n }\n return target;\n}\n\n/** Whether an accumulator target stores stochastic sampling seeds. */\nexport function hasStochasticSeeds(target: THREE.WebGLArrayRenderTarget) {\n return target.textures.length > 2;\n}\n\nfunction getMaterial(stochasticSeeds: boolean) {\n const index = Number(stochasticSeeds);\n let material = webGLMaterials[index];\n if (!material) {\n getShaders();\n material = new THREE.RawShaderMaterial({\n glslVersion: THREE.GLSL3,\n vertexShader: IDENT_VERTEX_SHADER,\n fragmentShader: splatGenerate,\n // Both variants share one uniform set.\n uniforms: getWebGLGenerateUniforms(),\n defines: { GSL_STOCHASTIC_SEEDS: index },\n depthTest: false,\n depthWrite: false,\n });\n webGLMaterials[index] = material;\n }\n return material;\n}\n\nexport function getWebGLGenerateUniforms() {\n webGLUniforms ??= makeGenerateUniforms();\n return webGLUniforms;\n}\n\nexport function generateWebGLAccumulator(\n options: AccumulatorRenderOptions<THREE.WebGLRenderer>,\n) {\n const material = getMaterial(hasStochasticSeeds(options.target));\n fullScreenQuad.material = material;\n renderAccumulatorLayers(options, material.uniforms, () =>\n fullScreenQuad.render(options.renderer),\n );\n}\n\nexport type AccumulatorRenderOptions<\n Renderer extends\n GaussianSplatCompatibleRenderer = GaussianSplatCompatibleRenderer,\n> = {\n renderer: Renderer;\n target: THREE.WebGLArrayRenderTarget;\n base: number;\n count: number;\n};\n\n/** Draw row-aligned ranges into array layers with either WebGL renderer API. */\nexport function renderAccumulatorLayers(\n { renderer, target, base, count }: AccumulatorRenderOptions,\n uniforms: Uniforms,\n draw: () => void,\n) {\n const nodeRenderer = isWebGPURenderer(renderer) ? renderer : null;\n const previous = {\n target: renderer.getRenderTarget(),\n face: renderer.getActiveCubeFace(),\n level: renderer.getActiveMipmapLevel(),\n xr: renderer.xr.enabled,\n autoClear: renderer.autoClear,\n scissorTest: renderer.getScissorTest(),\n mrt: nodeRenderer?.getMRT() ?? null,\n };\n uniforms.targetBase.value = base;\n uniforms.targetCount.value = count;\n const nextBase =\n Math.ceil((base + count) / SPLAT_TEX_WIDTH) * SPLAT_TEX_WIDTH;\n const layerSize = SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT;\n\n try {\n renderer.xr.enabled = false;\n renderer.autoClear = false;\n nodeRenderer?.setScissorTest(true);\n nodeRenderer?.setMRT(null);\n while (base < nextBase) {\n const layer = Math.floor(base / layerSize);\n uniforms.targetLayer.value = layer;\n const layerBase = layer * layerSize;\n const yStart = Math.floor((base - layerBase) / SPLAT_TEX_WIDTH);\n const yEnd = Math.min(\n SPLAT_TEX_HEIGHT,\n Math.ceil((nextBase - layerBase) / SPLAT_TEX_WIDTH),\n );\n target.scissor.set(0, yStart, SPLAT_TEX_WIDTH, yEnd - yStart);\n renderer.setRenderTarget(target, layer);\n draw();\n base += SPLAT_TEX_WIDTH * (yEnd - yStart);\n }\n } finally {\n setRendererRenderTarget(\n renderer,\n previous.target,\n previous.face,\n previous.level,\n );\n nodeRenderer?.setMRT(previous.mrt);\n renderer.xr.enabled = previous.xr;\n renderer.autoClear = previous.autoClear;\n nodeRenderer?.setScissorTest(previous.scissorTest);\n }\n}\n","import * as THREE from \"three\";\nimport { NodeMaterial, QuadMesh, type WebGPURenderer } from \"three/webgpu\";\nimport { SPLAT_TEX_HEIGHT, SPLAT_TEX_WIDTH } from \"../../data/defines\";\nimport { createGenerateProgram } from \"../tsl/GenerateProgram\";\nimport { N, uniformBinding } from \"../tsl/shaderUtils\";\nimport { makeGenerateUniforms } from \"../uniforms\";\nimport {\n type AccumulatorRenderOptions,\n createWebGLAccumulatorTarget,\n renderAccumulatorLayers,\n} from \"../webgl/AccumulatorGenerator\";\n\nexport function createWebGLFallbackAccumulatorTarget(\n width: number,\n height: number,\n depth: number,\n stochasticSeeds: boolean,\n) {\n // The r186 fallback backend recognizes array attachments only at depth > 1.\n return createWebGLAccumulatorTarget(\n width,\n height,\n Math.max(2, depth),\n stochasticSeeds,\n );\n}\n\n/**\n * Rasterizes Splat records, and for stochastic targets stable sampling seeds,\n * into integer arrays.\n */\nexport class WebGLFallbackAccumulatorGenerator {\n readonly uniforms = makeGenerateUniforms();\n private readonly material = new NodeMaterial();\n private readonly quad = new QuadMesh(this.material);\n\n constructor(stochasticSeeds: boolean) {\n const targetBase = uniformBinding(this.uniforms, \"targetBase\", \"uint\");\n const targetLayer = uniformBinding(this.uniforms, \"targetLayer\", \"uint\");\n const generate = createGenerateProgram({ uniforms: this.uniforms });\n const second = N.property(\"uvec4\", \"gslAccumulatorB\");\n const seed = N.property(\"uint\", \"gslAccumulatorSeed\");\n const first = N.Fn(() => {\n // TSL texture loads and scissor rectangles use the same top-left origin.\n const pixel = N.uvec2(N.screenCoordinate.xy);\n const index = targetLayer\n .mul(SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT)\n .add(pixel.y.mul(SPLAT_TEX_WIDTH))\n .add(pixel.x)\n .sub(targetBase);\n const { accumulatorA, accumulatorB, stochasticSeed } = generate(index);\n second.assign(accumulatorB);\n if (stochasticSeeds) seed.assign(stochasticSeed);\n return accumulatorA;\n })();\n this.material.fragmentNode = stochasticSeeds\n ? N.outputStruct(first, second, seed)\n : N.outputStruct(first, second);\n this.material.depthTest = false;\n this.material.depthWrite = false;\n this.material.blending = THREE.NoBlending;\n this.material.toneMapped = false;\n }\n\n generate(options: AccumulatorRenderOptions<WebGPURenderer>) {\n if (options.count <= 0) return;\n renderAccumulatorLayers(options, this.uniforms, () =>\n this.quad.render(options.renderer),\n );\n }\n\n dispose() {\n this.material.dispose();\n }\n}\n","import * as THREE from \"three\";\n\nimport { SPLAT_TEX_WIDTH } from \"../data/defines\";\nimport { emptySplatTexture, getTextureSize } from \"../data/textureLayout\";\nimport { SplatEdit, SplatEdits } from \"../scene/SplatEdit\";\nimport { SplatMesh } from \"../scene/SplatMesh\";\nimport { threeRevision } from \"../utils/three\";\nimport { decomposeSplatTransform } from \"../utils/transforms\";\nimport {\n type GaussianSplatCompatibleRenderer,\n getViews,\n isWebGPURenderer,\n usesNativeWebGPU,\n} from \"./rendererUtils\";\nimport {\n WebGLFallbackAccumulatorGenerator,\n createWebGLFallbackAccumulatorTarget,\n} from \"./webgl-fallback/AccumulatorGenerator\";\nimport {\n createWebGLAccumulatorTarget,\n generateWebGLAccumulator,\n getWebGLGenerateUniforms,\n hasStochasticSeeds,\n} from \"./webgl/AccumulatorGenerator\";\n\nexport type SplatMapping = {\n node: SplatMesh;\n matrixWorld: THREE.Matrix4;\n source: SplatMesh[\"splats\"];\n version: number;\n sortVersion: number;\n centerVersion: number;\n mappingVersion: number;\n base: number;\n count: number;\n};\n\ntype GenerateUniforms = Record<string, THREE.IUniform>;\ntype SplatDataTextures = readonly [THREE.Texture, THREE.Texture];\n\nexport class SplatAccumulator {\n time = 0;\n deltaTime = 0;\n viewOrigin = new THREE.Vector3();\n private readonly previousOrigin = new THREE.Vector3();\n viewDirection = new THREE.Vector3();\n maxSplats = 0;\n numSplats = 0;\n target: THREE.WebGLArrayRenderTarget | null = null;\n mapping: SplatMapping[] = [];\n version = -1;\n mappingVersion = -1;\n\n private transformScale = new THREE.Vector3();\n private transformQuaternion = new THREE.Quaternion();\n private fallbackGenerator: WebGLFallbackAccumulatorGenerator | null = null;\n\n constructor() {\n if (threeRevision < 186) {\n throw new Error(\"Gaussian Splat Lite requires Three.js r186 or above\");\n }\n }\n\n dispose() {\n this.disposeStorage();\n this.mapping = [];\n this.numSplats = 0;\n this.version = -1;\n this.mappingVersion = -1;\n }\n\n private disposeStorage() {\n this.target?.dispose();\n this.target = null;\n this.fallbackGenerator?.dispose();\n this.fallbackGenerator = null;\n this.maxSplats = 0;\n }\n\n getTextures(): SplatDataTextures {\n const textures = this.target?.textures;\n return textures\n ? [textures[0], textures[1]]\n : SplatAccumulator.emptyTextures;\n }\n\n getStochasticSeeds(): THREE.Texture {\n return this.target?.textures[2] ?? SplatAccumulator.emptyTexture;\n }\n\n /** Whether this accumulator was generated for stochastic rendering. */\n get hasStochasticSeeds() {\n return this.target !== null && hasStochasticSeeds(this.target);\n }\n\n /**\n * Regenerate moved meshes in place, without changing the source ranges used\n * by an in-flight sort. WebGL backends only.\n */\n refreshTransforms(renderer: GaussianSplatCompatibleRenderer) {\n let changed = false;\n for (const entry of this.mapping) {\n const { node, source, base, count } = entry;\n if (entry.matrixWorld.equals(node.matrixWorld)) continue;\n // A new source/LOD mapping needs matching indices before it can be shown.\n if (\n !source ||\n source !== node.splats ||\n source.needsUpdate ||\n source.getNumSplats() !== count ||\n entry.centerVersion !== node.centerVersion ||\n entry.mappingVersion !== node.mappingVersion\n )\n continue;\n this.generate({ mesh: node, base, count, renderer });\n entry.matrixWorld.copy(node.matrixWorld);\n changed = true;\n }\n if (changed) this.version++;\n }\n\n generateMapping(splatCounts: number[], compact = false) {\n let maxSplats = 0;\n const mapping = splatCounts.map((count) => {\n const base = maxSplats;\n maxSplats += compact\n ? count\n : Math.ceil(count / SPLAT_TEX_WIDTH) * SPLAT_TEX_WIDTH;\n return { base, count };\n });\n return { maxSplats, mapping };\n }\n\n ensureGenerate({\n maxSplats,\n renderer,\n shrinkResources = false,\n stochasticSeeds = false,\n }: {\n maxSplats: number;\n renderer?: GaussianSplatCompatibleRenderer;\n shrinkResources?: boolean;\n stochasticSeeds?: boolean;\n }) {\n if (renderer && usesNativeWebGPU(renderer)) {\n throw new Error(\n \"Accumulator texture generation requires a WebGL backend\",\n );\n }\n const {\n width,\n height,\n depth,\n maxSplats: capacity,\n } = getTextureSize(Math.max(1, maxSplats), 1);\n const reusable = shrinkResources\n ? capacity === this.maxSplats\n : capacity <= this.maxSplats;\n\n const fallback = renderer !== undefined && isWebGPURenderer(renderer);\n if (\n this.target &&\n reusable &&\n fallback === (this.fallbackGenerator !== null) &&\n stochasticSeeds === hasStochasticSeeds(this.target)\n ) {\n return false;\n }\n // Keep the prepared mapping and versions while replacing only its GPU\n // storage. Full dispose() also severs references to source meshes.\n this.disposeStorage();\n\n this.maxSplats = capacity;\n this.target = fallback\n ? createWebGLFallbackAccumulatorTarget(\n width,\n height,\n depth,\n stochasticSeeds,\n )\n : createWebGLAccumulatorTarget(width, height, depth, stochasticSeeds);\n if (fallback)\n this.fallbackGenerator = new WebGLFallbackAccumulatorGenerator(\n stochasticSeeds,\n );\n return true;\n }\n\n prepareUniforms(\n mesh: SplatMesh,\n uniforms: GenerateUniforms,\n matrixWorld = mesh.matrixWorld,\n ) {\n const source = mesh.splats;\n if (!source) {\n throw new Error(\"SplatMesh has no source\");\n }\n source.setTextureUniforms(uniforms);\n // A mesh keeps its seed when other meshes enter/leave the packed mapping.\n // Combine it on the GPU with the physical source index, before LOD compaction.\n uniforms.stochasticSeedBase.value =\n Math.imul(mesh.id + 1, 0x9e3779b9) >>> 0;\n uniforms.numSh.value = Math.min(mesh.maxSh, source.getNumSh());\n\n uniforms.objectReflected.value = decomposeSplatTransform(\n matrixWorld,\n this.transformScale,\n this.transformQuaternion,\n );\n uniforms.objectBasis.value.setFromMatrix4(matrixWorld);\n uniforms.objectOffset.value.setFromMatrixPosition(matrixWorld);\n // THREE.Vector3 and Matrix4 use JS numbers, so this subtraction happens\n // before the value is narrowed to a float32 WebGL uniform.\n uniforms.objectOffset.value.sub(this.viewOrigin);\n // Match PlayCanvas' work-buffer transform: centers use the complete affine\n // basis, while splat shape uses the decomposed rotation and positive\n // per-axis scale. This is intentionally an approximation for non-uniform\n // transforms while preserving ordinary scale/quaternion storage and zero\n // scale axes.\n uniforms.objectLnScale.value.set(\n Math.log(this.transformScale.x),\n Math.log(this.transformScale.y),\n Math.log(this.transformScale.z),\n );\n uniforms.objectQuaternion.value.copy(this.transformQuaternion);\n uniforms.recolor.value.set(\n mesh.recolor.r,\n mesh.recolor.g,\n mesh.recolor.b,\n THREE.MathUtils.clamp(mesh.opacity, 0, 1),\n );\n\n const edits = mesh.sdfEdits;\n uniforms.numSdfs.value = edits?.numSdfs ?? 0;\n uniforms.numEdits.value = edits?.numEdits ?? 0;\n uniforms.sdfTexture.value = edits?.sdfTexture ?? SplatEdits.emptyTexture;\n uniforms.editTexture.value = edits?.editTexture ?? SplatEdits.emptyTexture;\n }\n\n generate({\n mesh,\n base,\n count,\n renderer,\n }: {\n mesh: SplatMesh;\n base: number;\n count: number;\n renderer: GaussianSplatCompatibleRenderer;\n }) {\n if (usesNativeWebGPU(renderer)) {\n throw new Error(\n \"Accumulator texture generation requires a WebGL backend\",\n );\n }\n if (base + count > this.maxSplats) {\n throw new Error(\"Splat generation range exceeds accumulator capacity\");\n }\n\n if (!this.target) throw new Error(\"Accumulator target is not initialized\");\n if (isWebGPURenderer(renderer)) {\n if (!this.fallbackGenerator)\n throw new Error(\"WebGL fallback accumulator is not initialized\");\n this.prepareUniforms(mesh, this.fallbackGenerator.uniforms);\n this.fallbackGenerator.generate({\n renderer,\n target: this.target,\n base,\n count,\n });\n return;\n }\n this.prepareUniforms(mesh, getWebGLGenerateUniforms());\n generateWebGLAccumulator({ renderer, target: this.target, base, count });\n }\n\n prepareGenerate({\n renderer,\n scene,\n timer,\n camera,\n layerCamera = camera,\n previous,\n }: {\n renderer: GaussianSplatCompatibleRenderer;\n scene: THREE.Scene;\n timer: THREE.Timer;\n camera: THREE.Camera;\n layerCamera?: THREE.Camera;\n previous: SplatAccumulator;\n }) {\n // Preserve the previous metadata before replacing this accumulator's\n // mapping. Native WebGPU prepares this metadata in place, so reading these\n // values later would compare the new mapping with itself and suppress\n // required updates.\n const previousMapping = previous.mapping;\n const previousVersion = previous.version;\n const previousMappingVersion = previous.mappingVersion;\n\n const previousOrigin = this.previousOrigin.copy(previous.viewOrigin);\n this.viewOrigin.setFromMatrixPosition(camera.matrixWorld);\n this.viewDirection\n .setFromMatrixColumn(camera.matrixWorld, 2)\n .normalize()\n .negate();\n this.time = timer.getElapsed();\n this.deltaTime = timer.getDelta();\n\n // Meshes on any eye's layers draw in both eyes; each eye's projection\n // still culls to its own view.\n const layerMask = getViews(layerCamera).reduce(\n (mask, view) => mask | view.layers.mask,\n 0,\n );\n\n const allMeshes: SplatMesh[] = [];\n scene.traverse((node) => {\n if (node instanceof SplatMesh && (layerMask & node.layers.mask) !== 0) {\n allMeshes.push(node);\n }\n });\n\n const globalEdits = new Set<SplatEdit>();\n scene.traverseVisible((node) => {\n if (!(node instanceof SplatEdit)) return;\n let ancestor = node.parent;\n while (ancestor && !(ancestor instanceof SplatMesh)) {\n ancestor = ancestor.parent;\n }\n if (!ancestor) globalEdits.add(node);\n });\n\n for (const mesh of allMeshes) {\n mesh.frameUpdate({\n time: this.time,\n deltaTime: this.deltaTime,\n globalEdits: Array.from(globalEdits),\n });\n }\n\n const visibleMeshes: SplatMesh[] = [];\n scene.traverseVisible((node) => {\n // Mesh opacity is the final multiplier after SDF opacity edits, so zero\n // remains fully transparent even when an SDF sets or adds opacity.\n // Meshes without data reserve no range: native sorting reads every\n // index below numSplats.\n if (\n node instanceof SplatMesh &&\n node.splats &&\n (layerMask & node.layers.mask) !== 0 &&\n node.opacity > 0\n ) {\n visibleMeshes.push(node);\n }\n });\n const { maxSplats, mapping: ranges } = this.generateMapping(\n visibleMeshes.map((mesh) => mesh.numSplats),\n usesNativeWebGPU(renderer),\n );\n\n // Native WebGPU rebuilds the mapping every frame. Reuse this accumulator's\n // pose snapshots; its previous mapping is only compared by version below.\n const poses = this.mapping.map(({ matrixWorld }) => matrixWorld);\n this.mapping = [];\n this.numSplats = 0;\n ranges.forEach(({ base, count }, index) => {\n const node = visibleMeshes[index];\n if (!node.splats || count <= 0) return;\n this.mapping.push({\n node,\n matrixWorld: (poses.pop() ?? new THREE.Matrix4()).copy(\n node.matrixWorld,\n ),\n source: node.splats,\n version: node.version,\n sortVersion: node.sortVersion,\n centerVersion: node.centerVersion,\n mappingVersion: node.mappingVersion,\n base,\n count,\n });\n this.numSplats = Math.max(this.numSplats, base + count);\n });\n\n const { splatsUpdated, mappingUpdated, sortUpdated } = checkMappingVersions(\n previousMapping,\n this.mapping,\n );\n const shViewChanged =\n !this.viewOrigin.equals(previousOrigin) &&\n this.mapping.some(\n ({ node, source }) => node.maxSh > 0 && (source?.getNumSh() ?? 0) > 0,\n );\n this.version = previousVersion + (splatsUpdated || shViewChanged ? 1 : 0);\n this.mappingVersion = previousMappingVersion + (mappingUpdated ? 1 : 0);\n\n return {\n version: this.version,\n sortUpdated,\n requiredMaxSplats: getTextureSize(\n Math.max(1, maxSplats),\n usesNativeWebGPU(renderer) ? 256 : 1,\n ).maxSplats,\n generate: (shrinkResources = false, stochasticSeeds = false) => {\n this.ensureGenerate({\n maxSplats,\n renderer,\n shrinkResources,\n stochasticSeeds,\n });\n for (const { node, base, count } of this.mapping) {\n this.generate({ mesh: node, base, count, renderer });\n }\n },\n };\n }\n\n checkVersions(other: SplatMapping[]) {\n return checkMappingVersions(this.mapping, other);\n }\n\n static emptyTexture = emptySplatTexture;\n\n static emptyTextures: SplatDataTextures = [\n SplatAccumulator.emptyTexture,\n SplatAccumulator.emptyTexture,\n ];\n}\n\nfunction checkMappingVersions(\n previousMapping: SplatMapping[],\n nextMapping: SplatMapping[],\n) {\n if (previousMapping.length !== nextMapping.length) {\n return { splatsUpdated: true, mappingUpdated: true, sortUpdated: true };\n }\n const mappingUpdated = previousMapping.some((item, index) => {\n const next = nextMapping[index];\n return (\n item.node !== next.node ||\n item.base !== next.base ||\n item.count !== next.count ||\n item.mappingVersion !== next.mappingVersion\n );\n });\n if (mappingUpdated) {\n return { splatsUpdated: true, mappingUpdated: true, sortUpdated: true };\n }\n return {\n splatsUpdated: previousMapping.some(\n (item, index) => item.version !== nextMapping[index].version,\n ),\n mappingUpdated: false,\n sortUpdated: previousMapping.some(\n (item, index) => item.sortVersion !== nextMapping[index].sortVersion,\n ),\n };\n}\n","import * as THREE from \"three\";\n\nexport const SPLATS_PER_INSTANCE = 128;\n\n/** Repeated quads; position.z identifies the Splat within each instance. */\nexport class SplatGeometry extends THREE.InstancedBufferGeometry {\n constructor() {\n super();\n const vertices = new Float32Array(SPLATS_PER_INSTANCE * 12);\n const indices = new Uint16Array(SPLATS_PER_INSTANCE * 6);\n for (let splat = 0; splat < SPLATS_PER_INSTANCE; splat++) {\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = splat * 12 + vertex * 3;\n vertices[offset] = QUAD_VERTICES[vertex * 3];\n vertices[offset + 1] = QUAD_VERTICES[vertex * 3 + 1];\n vertices[offset + 2] = splat;\n }\n for (let index = 0; index < 6; index++)\n indices[splat * 6 + index] = splat * 4 + QUAD_INDICES[index];\n }\n this.setAttribute(\"position\", new THREE.BufferAttribute(vertices, 3));\n this.setIndex(new THREE.BufferAttribute(indices, 1));\n }\n\n setSplatCount(count: number) {\n this.instanceCount = Math.ceil(count / SPLATS_PER_INSTANCE);\n }\n}\n\nconst QUAD_VERTICES = new Float32Array([\n -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0,\n]);\n\n// The projected covariance basis reverses handedness, so clockwise local\n// triangles become counter-clockwise screen-space faces for FrontSide culling.\nconst QUAD_INDICES = new Uint16Array([0, 2, 1, 0, 3, 2]);\n","import type { Node } from \"three/webgpu\";\nimport type { Uniforms } from \"../uniforms\";\nimport {\n E,\n N,\n decodeAlphaShape,\n decodeCenter,\n decodeLnScales,\n decodeQuaternion,\n decodeRgba,\n quatQuat,\n quatVec,\n uniformBinding,\n} from \"./shaderUtils\";\n\nexport type ProjectionView = {\n projectionMatrix: Node<\"mat4\">;\n renderToViewQuat: Node<\"vec4\">;\n renderToViewPos: Node<\"vec3\">;\n renderToViewScale: Node<\"float\">;\n near: Node<\"float\">;\n far: Node<\"float\">;\n renderSize: Node<\"vec2\">;\n};\n\ntype ProjectionInput =\n | { first: Node<\"uvec4\">; second: Node<\"uvec4\"> }\n | {\n valid: Node<\"bool\">;\n center: Node<\"vec3\">;\n lnScales: Node<\"vec3\">;\n quaternion: Node<\"vec4\">;\n rgba: Node<\"vec4\">;\n shapeAmount: Node<\"float\">;\n };\n\nexport type SplatProjection = {\n valid: Node<\"bool\">;\n clipCenter: Node<\"vec4\">;\n viewDepth: Node<\"float\">;\n /** NDC offsets for each +/-1 quad corner. */\n axis1: Node<\"vec2\">;\n axis2: Node<\"vec2\">;\n /** Source color space; the draw stage applies encodeLinear. */\n rgba: Node<\"vec4\">;\n supportRadius: Node<\"float\">;\n kernelPower: Node<\"float\">;\n};\n\nconst scaleQuaternionToMatrix = N.Fn(\n ([scale, quaternion]: [Node<\"vec3\">, Node<\"vec4\">]) => {\n const x = quaternion.x;\n const y = quaternion.y;\n const z = quaternion.z;\n const w = quaternion.w;\n return N.mat3(\n N.vec3(\n scale.x.mul(N.float(1).sub(y.mul(y).add(z.mul(z)).mul(2))),\n scale.x.mul(x.mul(y).add(w.mul(z)).mul(2)),\n scale.x.mul(x.mul(z).sub(w.mul(y)).mul(2)),\n ),\n N.vec3(\n scale.y.mul(x.mul(y).sub(w.mul(z)).mul(2)),\n scale.y.mul(N.float(1).sub(x.mul(x).add(z.mul(z)).mul(2))),\n scale.y.mul(y.mul(z).add(w.mul(x)).mul(2)),\n ),\n N.vec3(\n scale.z.mul(x.mul(z).add(w.mul(y)).mul(2)),\n scale.z.mul(y.mul(z).sub(w.mul(x)).mul(2)),\n scale.z.mul(N.float(1).sub(x.mul(x).add(y.mul(y)).mul(2))),\n ),\n );\n },\n);\n\nconst gaussianSupportRadius = N.Fn(\n ([alpha, maximumRadius, minimumAlpha]: [\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n ]) => {\n const radius = maximumRadius.toVar();\n N.If(minimumAlpha.greaterThan(0), () => {\n radius.assign(\n maximumRadius.min(alpha.div(minimumAlpha).log().mul(2).max(0).sqrt()),\n );\n });\n return radius;\n },\n);\n\nconst wideSupportRadius = N.Fn(\n ([alpha, power, maximumRadius, minimumAlpha]: [\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n ]) => {\n const radius = maximumRadius.toVar();\n N.If(minimumAlpha.greaterThan(0), () => {\n // 1 - (1 - x)^power <= power * x for power >= 1.\n radius.assign(\n maximumRadius.min(\n alpha.mul(power).div(minimumAlpha).log().mul(2).max(0).sqrt(),\n ),\n );\n });\n return radius;\n },\n);\n\n/** Shared projection for vertex and compute paths. Call inside a TSL Fn. */\nexport function createProjectionProgram(\n uniforms: Uniforms,\n view: ProjectionView,\n) {\n const {\n projectionMatrix,\n renderToViewQuat,\n renderToViewPos,\n renderToViewScale,\n near,\n far,\n renderSize,\n } = view;\n const maxStdDev = uniformBinding(uniforms, \"maxStdDev\", \"float\");\n const minPixelRadius = uniformBinding(uniforms, \"minPixelRadius\", \"float\");\n const maxPixelRadius = uniformBinding(uniforms, \"maxPixelRadius\", \"float\");\n const minAlpha = uniformBinding(uniforms, \"minAlpha\", \"float\");\n const preBlurAmount = uniformBinding(uniforms, \"preBlurAmount\", \"float\");\n const blurAmount = uniformBinding(uniforms, \"blurAmount\", \"float\");\n const clipXY = uniformBinding(uniforms, \"clipXY\", \"float\");\n const focalAdjustment = uniformBinding(uniforms, \"focalAdjustment\", \"float\");\n\n return (source: ProjectionInput, includeColor = true): SplatProjection => {\n // This is a JS-time choice, not a shader branch. WebGL still reads its\n // packed accumulator; native compute consumes transformed float32 values.\n const packed = \"first\" in source;\n const valid = N.bool(false).toVar();\n const projectedClipCenter = N.vec4(0, 0, 2, 1).toVar();\n const projectedViewDepth = N.float(0).toVar();\n const projectedAxis1 = N.vec2(0).toVar();\n const projectedAxis2 = N.vec2(0).toVar();\n const projectedRgba = N.vec4(0).toVar();\n const projectedSupportRadius = N.float(0).toVar();\n const projectedKernelPower = N.float(0).toVar();\n const alphaShape = packed\n ? decodeAlphaShape(source.first)\n : N.vec2(source.rgba.a, source.shapeAmount).clamp(0, 1);\n const alpha = alphaShape.x.toVar();\n const sourceValid = packed ? N.bool(true) : source.valid;\n\n const sourceVisible = sourceValid\n .and(alpha.greaterThanEqual(minAlpha))\n .and(alpha.greaterThan(0));\n N.If(sourceVisible, () => {\n const center = packed ? decodeCenter(source.first) : source.center;\n const viewCenter = quatVec(renderToViewQuat, center)\n .mul(renderToViewScale)\n .add(renderToViewPos);\n const clipCenter = N.vec4(0).toVar();\n const centerVisible = N.bool(false).toVar();\n const depthVisible = viewCenter.z\n .lessThan(near.negate())\n .and(viewCenter.z.greaterThan(far.negate()));\n N.If(depthVisible, () => {\n clipCenter.assign(projectionMatrix.mul(N.vec4(viewCenter, 1)));\n const clip = clipCenter.w.mul(clipXY);\n centerVisible.assign(\n clipCenter.x\n .abs()\n .lessThanEqual(clip)\n .and(clipCenter.y.abs().lessThanEqual(clip)),\n );\n });\n\n N.If(centerVisible, () => {\n const lnScales = packed\n ? decodeLnScales(source.second)\n : source.lnScales;\n const scales = lnScales.exp().mul(renderToViewScale).toVar();\n N.If(N.all(scales.equal(N.vec3(0))).not(), () => {\n const kernelShape = alphaShape.y.min(1).mul(4).add(1);\n const kernelPower = N.float(0).toVar();\n N.If(kernelShape.greaterThan(1), () => {\n kernelPower.assign(\n kernelShape.mul(kernelShape).sub(1).div(E).exp(),\n );\n });\n const maximumSupportRadius = maxStdDev.add(\n kernelShape.sub(1).max(0).mul(0.7),\n );\n const supportRadius = maximumSupportRadius.toVar();\n\n const viewQuaternion = quatQuat(\n renderToViewQuat,\n // Keep the unit-quaternion constraint without oct/angle quantization.\n packed\n ? decodeQuaternion(source.second.w)\n : source.quaternion.normalize(),\n );\n const rotationScale = scaleQuaternionToMatrix(scales, viewQuaternion);\n const scaledRenderSize = renderSize.mul(focalAdjustment).toVar();\n const focal = scaledRenderSize\n .mul(0.5)\n .mul(\n N.vec2(\n projectionMatrix.element(0).element(0),\n projectionMatrix.element(1).element(1),\n ),\n );\n const j0 = N.vec3(0).toVar();\n const j1 = N.vec3(0).toVar();\n const isOrthographic = projectionMatrix\n .element(2)\n .element(3)\n .equal(0);\n N.If(isOrthographic, () => {\n j0.assign(N.vec3(focal.x, 0, 0));\n j1.assign(N.vec3(0, focal.y, 0));\n }).Else(() => {\n const invZ = N.float(1).div(viewCenter.z);\n const firstJacobian = focal.mul(invZ);\n const secondJacobian = firstJacobian\n .mul(viewCenter.xy)\n .mul(invZ)\n .negate();\n j0.assign(N.vec3(firstJacobian.x, 0, secondJacobian.x));\n j1.assign(N.vec3(0, firstJacobian.y, secondJacobian.y));\n });\n\n const transposed = rotationScale.transpose();\n const p0 = transposed.mul(j0);\n const p1 = transposed.mul(j1);\n const a = p0.dot(p0).add(preBlurAmount).toVar();\n const b = p0.dot(p1);\n const d = p1.dot(p1).add(preBlurAmount).toVar();\n const detOrig = a.mul(d).sub(b.mul(b)).toVar();\n N.If(blurAmount.equal(0), () => {\n // No opacity compensation is needed, but reject degenerate covariance.\n N.If(detOrig.greaterThan(0).not(), () => {\n alpha.assign(0);\n });\n }).Else(() => {\n a.addAssign(blurAmount);\n d.addAssign(blurAmount);\n const det = a.mul(d).sub(b.mul(b)).toVar();\n N.If(det.greaterThan(0), () => {\n alpha.mulAssign(detOrig.div(det).max(0).sqrt());\n }).Else(() => {\n alpha.assign(0);\n });\n });\n\n const alphaVisible = alpha\n .greaterThanEqual(minAlpha)\n .and(alpha.greaterThan(0));\n N.If(alphaVisible, () => {\n N.If(kernelPower.equal(0), () => {\n supportRadius.assign(\n gaussianSupportRadius(alpha, supportRadius, minAlpha),\n );\n }).Else(() => {\n supportRadius.assign(\n wideSupportRadius(alpha, kernelPower, supportRadius, minAlpha),\n );\n });\n const eigenAverage = a.add(d).mul(0.5).toVar();\n const eigenDelta = N.vec2(a.sub(d).mul(0.5), b).length().toVar();\n const eigen1 = eigenAverage.add(eigenDelta).toVar();\n // Keep a small positive minor axis when subtraction rounds to zero.\n const eigen2 = eigenAverage.sub(eigenDelta).max(1e-4).toVar();\n const supportScale = N.select(\n maximumSupportRadius.greaterThan(0),\n supportRadius.div(maximumSupportRadius),\n 0,\n );\n const maxProjectedRadius = maxPixelRadius.mul(focalAdjustment);\n const fullScale1 = maxProjectedRadius.min(\n maximumSupportRadius.mul(eigen1.sqrt()),\n );\n const fullScale2 = maxProjectedRadius.min(\n maximumSupportRadius.mul(eigen2.sqrt()),\n );\n const scale1 = fullScale1.mul(supportScale);\n const scale2 = fullScale2.mul(supportScale);\n // Preserve the original wide-kernel minimum-size cutoff.\n const cullScale = N.select(kernelPower.equal(0), supportScale, 1);\n // Match the internal projection scale to keep the cutoff in screen pixels.\n const minProjectedRadius = minPixelRadius.mul(focalAdjustment);\n\n N.If(\n fullScale1\n .mul(cullScale)\n .greaterThanEqual(minProjectedRadius)\n .or(\n fullScale2\n .mul(cullScale)\n .greaterThanEqual(minProjectedRadius),\n ),\n () => {\n // Only surviving splats need an oriented covariance basis.\n const eigenVector1 = N.vec2(0).toVar();\n N.If(b.abs().greaterThan(0.001), () => {\n eigenVector1.assign(N.vec2(b, eigen1.sub(a)).normalize());\n }).Else(() => {\n eigenVector1.assign(\n N.select(a.greaterThanEqual(d), N.vec2(1, 0), N.vec2(0, 1)),\n );\n });\n const eigenVector2 = N.vec2(\n eigenVector1.y,\n eigenVector1.x.negate(),\n );\n projectedClipCenter.assign(clipCenter);\n projectedViewDepth.assign(viewCenter.z.negate());\n projectedAxis1.assign(\n eigenVector1.mul(scale1).mul(2).div(scaledRenderSize),\n );\n projectedAxis2.assign(\n eigenVector2.mul(scale2).mul(2).div(scaledRenderSize),\n );\n projectedRgba.assign(\n N.vec4(\n includeColor\n ? (packed\n ? decodeRgba(source.second, alpha).rgb\n : source.rgba.rgb\n ).max(0)\n : N.vec3(0),\n alpha,\n ),\n );\n projectedSupportRadius.assign(supportRadius);\n projectedKernelPower.assign(kernelPower);\n valid.assign(true);\n },\n );\n });\n });\n });\n });\n\n return {\n valid,\n clipCenter: projectedClipCenter,\n viewDepth: projectedViewDepth,\n axis1: projectedAxis1,\n axis2: projectedAxis2,\n rgba: projectedRgba,\n supportRadius: projectedSupportRadius,\n kernelPower: projectedKernelPower,\n };\n };\n}\n","import * as THREE from \"three\";\nimport type { Node } from \"three/webgpu\";\nimport { getViews } from \"../rendererUtils\";\nimport type { Uniforms } from \"../uniforms\";\nimport type { ProjectionView } from \"./ProjectionProgram\";\nimport { N, uniformBinding } from \"./shaderUtils\";\n\n/** Eye of the current WebXR draw; multiview draws both eyes at once. */\nexport function viewIndex(camera: THREE.Camera): Node<\"uint\"> {\n if (getViews(camera)[0] === camera) return N.uint(0);\n return (camera as { isMultiViewCamera?: boolean }).isMultiViewCamera\n ? N.builtin(\"gl_ViewID_OVR\")\n : N.cameraIndex;\n}\n\n/** Viewport data for drawing splats that have already been projected. */\nexport function splatViewportUniforms(\n uniforms: Uniforms,\n camera: THREE.Camera,\n) {\n const eyes = getViews(camera);\n if (eyes[0] === camera) {\n return {\n renderSize: uniformBinding(uniforms, \"renderSize\", \"vec2\"),\n viewportOrigin: uniformBinding(uniforms, \"viewportOrigin\", \"vec2\"),\n };\n }\n\n // WebXR eye viewports are physical pixels; Three draws them as given.\n const views = eyes.map(() => new THREE.Vector4());\n const viewData = N.uniformArray<\"vec4\">(views, \"vec4\").onObjectUpdate(\n ({ camera }) => {\n getViews(camera as THREE.Camera).forEach((eye, i) => {\n const size = uniforms.renderSize.value;\n views[i].set(\n eye.viewport?.z ?? size.x,\n eye.viewport?.w ?? size.y,\n eye.viewport?.x ?? 0,\n eye.viewport?.y ?? 0,\n );\n });\n },\n );\n const index = viewIndex(camera);\n const viewport = viewData.element(index);\n return { renderSize: viewport.xy, viewportOrigin: viewport.zw };\n}\n\nexport function splatViewUniforms(\n uniforms: Uniforms,\n camera: THREE.Camera,\n): Omit<ProjectionView, \"projectionMatrix\"> & { viewportOrigin: Node<\"vec2\"> } {\n const eyes = getViews(camera);\n if (eyes[0] === camera) {\n return {\n renderSize: uniformBinding(uniforms, \"renderSize\", \"vec2\"),\n viewportOrigin: uniformBinding(uniforms, \"viewportOrigin\", \"vec2\"),\n renderToViewQuat: uniformBinding(uniforms, \"renderToViewQuat\", \"vec4\"),\n renderToViewPos: uniformBinding(uniforms, \"renderToViewPos\", \"vec3\"),\n renderToViewScale: uniformBinding(uniforms, \"renderToViewScale\", \"float\"),\n near: uniformBinding(uniforms, \"near\", \"float\"),\n far: uniformBinding(uniforms, \"far\", \"float\"),\n };\n }\n\n // WebXR draws do not call onBeforeRender separately for each eye.\n // Pack rotation, position/scale, viewport/clipping and pixel origin per eye.\n const views = eyes.flatMap(() => [\n new THREE.Vector4(),\n new THREE.Vector4(),\n new THREE.Vector4(),\n new THREE.Vector4(),\n ]);\n const matrix = new THREE.Matrix4();\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n const viewData = N.uniformArray<\"vec4\">(views, \"vec4\").onObjectUpdate(\n ({ camera }) => {\n (getViews(camera as THREE.Camera) as THREE.PerspectiveCamera[]).forEach(\n (eye, i) => {\n // Subtract the world origin in CPU double precision before GPU upload.\n matrix.makeTranslation(uniforms.renderOrigin.value);\n matrix.premultiply(eye.matrixWorldInverse);\n matrix.decompose(position, rotation, scale);\n views[i * 4].set(rotation.x, rotation.y, rotation.z, rotation.w);\n views[i * 4 + 1].set(\n position.x,\n position.y,\n position.z,\n (scale.x + scale.y + scale.z) / 3,\n );\n const size = uniforms.renderSize.value;\n views[i * 4 + 2].set(\n eye.viewport?.z ?? size.x,\n eye.viewport?.w ?? size.y,\n eye.near,\n eye.far,\n );\n views[i * 4 + 3].set(\n eye.viewport?.x ?? 0,\n eye.viewport?.y ?? 0,\n 0,\n 0,\n );\n },\n );\n },\n );\n const index = viewIndex(camera);\n const offset = index.mul(4);\n const positionScale = viewData.element(offset.add(1));\n const viewportClip = viewData.element(offset.add(2));\n return {\n renderSize: viewportClip.xy,\n viewportOrigin: viewData.element(offset.add(3)).xy,\n renderToViewQuat: viewData.element(offset),\n renderToViewPos: positionScale.xyz,\n renderToViewScale: positionScale.w,\n near: viewportClip.z,\n far: viewportClip.w,\n };\n}\n","import * as THREE from \"three\";\nimport type { Node, NodeBuilder } from \"three/webgpu\";\nimport { NodeMaterial, type TextureNode } from \"three/webgpu\";\nimport { SPLATS_PER_INSTANCE } from \"../SplatGeometry\";\nimport { ORDERING_TEXTURE_WIDTH, type Uniforms } from \"../uniforms\";\nimport { createProjectionProgram } from \"./ProjectionProgram\";\nimport {\n N,\n load2D,\n loadArray,\n splatTexCoord,\n textureBinding,\n uniformBinding,\n} from \"./shaderUtils\";\nimport { materialCamera } from \"./tslCompat\";\nimport { splatViewUniforms } from \"./viewUniforms\";\n\nexport type ProjectedVertexData = {\n clipPosition: Node<\"vec4\">;\n /** Source color space; this material applies encodeLinear. */\n rgba: Node<\"vec4\">;\n splatUv: Node<\"vec2\">;\n /** Stochastic variant only. */\n stochasticSeed?: Node<\"uint\">;\n supportRadiusSquared: Node<\"float\">;\n kernelPower: Node<\"float\">;\n viewportOrigin: Node<\"vec2\">;\n};\n\nexport type SplatNodeMaterial = NodeMaterial & { uniforms: Uniforms };\n\nconst stochasticHash = N.Fn(([input]: [Node<\"uint\">]) => {\n const value = N.uint(input).toVar();\n value.bitXorAssign(value.shiftRight(16));\n value.mulAssign(N.uint(0x7feb352d));\n value.bitXorAssign(value.shiftRight(15));\n value.mulAssign(N.uint(0x846ca68b));\n value.bitXorAssign(value.shiftRight(16));\n return value;\n});\n\nfunction createSplatFragment(\n minAlpha: Node<\"float\">,\n stochasticNoise: TextureNode<\"uvec4\"> | null,\n) {\n // Per-Splat constants share one flat varying: RGB and kernel power as\n // halves, alpha and squared support radius as float32 bits. See packSplatVarying.\n const vSplat = N.varyingProperty(\"uvec4\", \"gslSplat\");\n const vSplatUv = N.varyingProperty(\"vec2\", \"gslSplatUv\");\n // Atlas offset: x in bits 0-4, y in 5-9, time in 10-14. See stochasticTileOffset.\n const vStochasticOffset = stochasticNoise\n ? N.varyingProperty(\"uint\", \"gslStochasticOffset\")\n : null;\n\n const fragmentNode = N.Fn(() => {\n const z2 = vSplatUv.dot(vSplatUv);\n z2.greaterThan(N.uintBitsToFloat(vSplat.w)).discard();\n const blueKernelPower = N.unpackHalf2x16(vSplat.y);\n const kernelPower = blueKernelPower.y;\n const kernelAlpha = z2.mul(-0.5).exp().toVar();\n N.If(kernelPower.notEqual(0), () => {\n kernelAlpha.assign(\n N.float(1).sub(N.float(1).sub(kernelAlpha).pow(kernelPower)),\n );\n });\n const alpha = N.uintBitsToFloat(vSplat.z).mul(kernelAlpha).toVar();\n alpha.lessThan(minAlpha).discard();\n if (stochasticNoise && vStochasticOffset) {\n const pixel = N.uvec2(N.screenCoordinate.xy);\n const coord = N.ivec2(\n pixel.x.add(vStochasticOffset).bitAnd(31),\n pixel.y\n .add(vStochasticOffset.shiftRight(5))\n .bitAnd(31)\n .add(vStochasticOffset.shiftRight(10).mul(32)),\n );\n const randomValue = N.float(load2D(stochasticNoise, coord).r)\n .add(0.5)\n .div(32768);\n randomValue.greaterThanEqual(alpha).discard();\n }\n // Decode color only after the fragment survives coverage tests.\n return N.vec4(\n N.unpackHalf2x16(vSplat.x),\n blueKernelPower.x,\n stochasticNoise ? 1 : alpha,\n );\n })();\n\n return {\n vSplat,\n vSplatUv,\n vStochasticOffset,\n fragmentNode,\n };\n}\n\n// Keep XY fixed while advancing the STBN time axis. Independent per-Splat XYZ\n// offsets decorrelate overlapping coverage tests without translating the field.\nfunction stochasticTileOffset(\n seed: Node<\"uint\">,\n sample: Node<\"uint\">,\n viewportOrigin: Node<\"vec2\">,\n) {\n const hash = stochasticHash(seed).toVar();\n const origin = N.uvec2(viewportOrigin);\n const x = hash.sub(origin.x);\n const y = hash.shiftRight(5).sub(origin.y);\n const phase = hash.shiftRight(10).add(sample).bitAnd(31);\n return x\n .bitAnd(31)\n .bitOr(y.bitAnd(31).shiftLeft(5))\n .bitOr(phase.shiftLeft(10));\n}\n\n// Half RGB saturates at its largest finite value instead of overflowing after\n// sRGB linearization. Source alpha keeps float32 bits, but half kernel power\n// can still change the final coverage of wide kernels.\nfunction packSplatVarying(\n rgba: Node<\"vec4\">,\n supportRadiusSquared: Node<\"float\">,\n kernelPower: Node<\"float\">,\n) {\n const rgb = rgba.rgb.min(65504);\n return N.uvec4(\n N.packHalf2x16(rgb.xy),\n N.packHalf2x16(N.vec2(rgb.z, kernelPower)),\n N.floatBitsToUint(rgba.a),\n N.floatBitsToUint(supportRadiusSquared),\n );\n}\n\n/**\n * Sorted and stochastic variants compile separate graphs, so sorted drawing\n * carries no coverage varyings, seed loads or mode branches.\n */\nexport function createSplatNodeMaterial({\n uniforms,\n orderingNode,\n vertexData,\n premultipliedAlpha,\n transparent,\n depthTest,\n depthWrite,\n stochastic,\n}: {\n uniforms: Uniforms;\n /** CPU ordering for drawing from accumulator textures. */\n orderingNode?: TextureNode<\"uvec4\">;\n /** Replaces accumulator projection, e.g. with a GPU projection cache. */\n vertexData?: (\n camera: THREE.Camera,\n stochastic: boolean,\n ) => ProjectedVertexData;\n premultipliedAlpha: boolean;\n transparent: boolean;\n depthTest: boolean;\n depthWrite: boolean;\n stochastic: boolean;\n}): SplatNodeMaterial {\n const minAlpha = uniformBinding(uniforms, \"minAlpha\", \"float\");\n const encodeLinear = uniformBinding(uniforms, \"encodeLinear\", \"bool\");\n const stochasticSample = stochastic\n ? uniformBinding(uniforms, \"stochasticSample\", \"uint\")\n : null;\n // Accumulator textures are only read without a projection cache.\n const accumulator = vertexData\n ? null\n : {\n splats: textureBinding(uniforms, \"splats\", true),\n splats2: textureBinding(uniforms, \"splats2\", true),\n seeds: stochastic\n ? textureBinding(uniforms, \"stochasticSeeds\", true)\n : null,\n };\n const { vSplat, vSplatUv, vStochasticOffset, fragmentNode } =\n createSplatFragment(\n minAlpha,\n stochastic ? textureBinding(uniforms, \"stochasticNoise\") : null,\n );\n\n function buildVertex(builder: NodeBuilder) {\n const camera = materialCamera(builder);\n const clipPosition = N.vec4(0, 0, 2, 1).toVar();\n vSplat.assign(N.uvec4(0));\n vSplatUv.assign(N.vec2(0));\n vStochasticOffset?.assign(N.uint(0));\n const assignVertexData = (data: ProjectedVertexData) => {\n const rgba = data.rgba.toVar();\n // RGB is constant across the quad; decode its color space once\n // per vertex rather than for every covered fragment.\n N.If(encodeLinear, () => {\n rgba.rgb.assign(N.sRGBTransferEOTF(rgba.rgb));\n });\n clipPosition.assign(data.clipPosition);\n vSplat.assign(\n packSplatVarying(rgba, data.supportRadiusSquared, data.kernelPower),\n );\n vSplatUv.assign(data.splatUv);\n if (vStochasticOffset && stochasticSample && data.stochasticSeed) {\n // Coverage uses the same offset across every fragment of this Splat.\n vStochasticOffset.assign(\n stochasticTileOffset(\n data.stochasticSeed,\n stochasticSample,\n data.viewportOrigin,\n ),\n );\n }\n };\n\n if (vertexData) {\n assignVertexData(vertexData(camera, stochastic));\n return clipPosition;\n }\n if (!accumulator || !orderingNode) {\n throw new Error(\"Accumulator splat drawing requires an ordering texture\");\n }\n\n const view = splatViewUniforms(uniforms, camera);\n const project = createProjectionProgram(uniforms, {\n ...view,\n projectionMatrix: N.cameraProjectionMatrix,\n });\n const index = N.uint(N.instanceIndex)\n .mul(SPLATS_PER_INSTANCE)\n .add(N.uint(N.positionGeometry.z))\n .toVar();\n const splatIndex = N.uint(0xffffffff).toVar();\n // Every view, including both WebXR eyes, draws the one shared order.\n const loadOrdered = () => {\n const texel = index.shiftRight(2);\n const coord = N.ivec2(\n texel.mod(ORDERING_TEXTURE_WIDTH),\n texel.div(N.uint(ORDERING_TEXTURE_WIDTH)),\n );\n splatIndex.assign(load2D(orderingNode, coord).element(index.bitAnd(3)));\n };\n N.If(index.lessThan(uniformBinding(uniforms, \"splatCount\", \"uint\")), () => {\n if (!stochastic) {\n loadOrdered();\n return;\n }\n // Unsorted stochastic draws use source indices directly.\n splatIndex.assign(index);\n N.If(uniformBinding(uniforms, \"stochasticOrdering\", \"bool\"), loadOrdered);\n });\n\n N.If(splatIndex.notEqual(N.uint(0xffffffff)), () => {\n const texCoord = splatTexCoord(splatIndex);\n const first = loadArray(accumulator.splats, texCoord);\n const projected = project({\n first,\n second: loadArray(accumulator.splats2, texCoord),\n });\n N.If(projected.valid, () => {\n const ndcOffset = projected.axis1\n .mul(N.positionGeometry.x)\n .add(projected.axis2.mul(N.positionGeometry.y));\n const ndcCenter = projected.clipCenter.xyz.div(projected.clipCenter.w);\n assignVertexData({\n clipPosition: N.vec4(\n ndcCenter.xy.add(ndcOffset).mul(projected.clipCenter.w),\n projected.clipCenter.zw,\n ),\n rgba: projected.rgba,\n splatUv: N.positionGeometry.xy.mul(projected.supportRadius),\n // Fetch stable coverage seeds only after all projection cutoffs.\n stochasticSeed: accumulator.seeds\n ? loadArray(accumulator.seeds, texCoord).r\n : undefined,\n supportRadiusSquared: projected.supportRadius.mul(\n projected.supportRadius,\n ),\n kernelPower: projected.kernelPower,\n viewportOrigin: view.viewportOrigin,\n });\n });\n });\n\n return clipPosition;\n }\n\n return Object.assign(new NodeMaterial(), {\n uniforms,\n vertexNode: N.Fn(buildVertex)(),\n colorNode: fragmentNode,\n premultipliedAlpha,\n transparent,\n depthTest,\n depthWrite,\n side: THREE.FrontSide,\n allowOverride: false,\n fog: false,\n toneMapped: false,\n });\n}\n","import type * as THREE from \"three\";\nimport type { TextureNode, WebGPURenderer } from \"three/webgpu\";\nimport type { SplatMaterialOptions } from \"../backend\";\nimport type { Uniforms } from \"../uniforms\";\nimport {\n type ProjectedVertexData,\n type SplatNodeMaterial,\n createSplatNodeMaterial,\n} from \"./SplatMaterial\";\n\n/** Drawing shared by both WebGPURenderer backends. */\nexport class NodeSplatBackend {\n readonly sortedMaterial: SplatNodeMaterial;\n readonly stochasticMaterial: SplatNodeMaterial;\n\n constructor(\n readonly renderer: WebGPURenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n orderingNode?: TextureNode<\"uvec4\">,\n vertexData?: (\n camera: THREE.Camera,\n stochastic: boolean,\n ) => ProjectedVertexData,\n ) {\n const create = (stochastic: boolean) =>\n createSplatNodeMaterial({\n uniforms,\n ...options,\n orderingNode,\n vertexData,\n stochastic,\n });\n this.sortedMaterial = create(false);\n this.stochasticMaterial = create(true);\n }\n\n selectMaterial(stochastic: boolean) {\n return stochastic ? this.stochasticMaterial : this.sortedMaterial;\n }\n\n dispose() {\n this.sortedMaterial.dispose();\n this.stochasticMaterial.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport type { CPUOrderingUpdate } from \"../backend\";\nimport { ORDERING_TEXTURE_WIDTH, SPLATS_PER_ORDERING_ROW } from \"../uniforms\";\n\n/** CPU ordering storage shared by both WebGL backends; uploads stay backend-specific. */\nexport class OrderingTexture {\n texture: THREE.DataTexture | null = null;\n\n getCapacity(count: number) {\n return (\n Math.max(1, Math.ceil(count / SPLATS_PER_ORDERING_ROW)) *\n SPLATS_PER_ORDERING_ROW\n );\n }\n\n get data(): Uint32Array | null {\n return (this.texture?.image.data as Uint32Array | null) ?? null;\n }\n\n update(\n { ordering, activeSplats, requiredCapacity, shrink }: CPUOrderingUpdate,\n uploadRows: (texture: THREE.DataTexture, rows: number) => void,\n ) {\n const rows = requiredCapacity / SPLATS_PER_ORDERING_ROW;\n if (\n this.texture &&\n (rows > this.texture.image.height ||\n (shrink && rows !== this.texture.image.height))\n )\n this.dispose();\n if (!this.texture) {\n this.texture = new THREE.DataTexture(\n ordering,\n ORDERING_TEXTURE_WIDTH,\n rows,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n );\n this.texture.needsUpdate = true;\n } else {\n this.texture.image.data = ordering;\n if (activeSplats > 0)\n uploadRows(\n this.texture,\n Math.ceil(activeSplats / SPLATS_PER_ORDERING_ROW),\n );\n }\n return this.texture;\n }\n\n dispose() {\n this.texture?.dispose();\n this.texture = null;\n }\n}\n","import type * as THREE from \"three\";\nimport type { TextureNode, WebGPURenderer } from \"three/webgpu\";\nimport type { CPUOrderingUpdate, SplatMaterialOptions } from \"../backend\";\nimport { NodeSplatBackend } from \"../tsl/SplatBackend\";\nimport { uintTexture } from \"../tsl/tslCompat\";\nimport { type Uniforms, emptyOrdering } from \"../uniforms\";\nimport { OrderingTexture } from \"../webgl/OrderingTexture\";\n\ntype TextureUploadBackend = {\n updateTexture(\n texture: THREE.DataTexture,\n options: {\n width: number;\n height: number;\n image: THREE.DataTexture[\"image\"];\n },\n ): void;\n};\n\n/** TSL drawing with CPU-sorted indices stored in an integer texture. */\nexport class WebGLFallbackSplatBackend extends NodeSplatBackend {\n readonly kind = \"webgl-fallback\";\n private readonly ordering = new OrderingTexture();\n // Shared by the sorted and stochastic materials.\n private readonly orderingNode: TextureNode<\"uvec4\">;\n\n constructor(\n renderer: WebGPURenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n ) {\n const orderingNode = uintTexture(emptyOrdering);\n super(renderer, uniforms, options, orderingNode);\n this.orderingNode = orderingNode;\n }\n\n getOrderingCapacity(count: number) {\n return this.ordering.getCapacity(count);\n }\n\n get cpuOrdering(): Uint32Array | null {\n return this.ordering.data;\n }\n\n setCPUOrdering(update: CPUOrderingUpdate) {\n this.orderingNode.value = this.ordering.update(update, (texture, rows) => {\n // Finish any pending allocation before uploading only active rows.\n this.renderer.initTexture(texture);\n // The r186 fallback's copyTextureToTexture allocates a GPU source;\n // update the destination directly to avoid that staging texture.\n const backend = this.renderer.backend as unknown as TextureUploadBackend;\n backend.updateTexture(texture, {\n width: texture.image.width,\n height: rows,\n image: texture.image,\n });\n });\n }\n\n /** Unsorted draws read no ordering; the next sort allocates it again. */\n releaseOrdering() {\n this.ordering.dispose();\n this.orderingNode.value = emptyOrdering;\n }\n\n dispose() {\n super.dispose();\n this.ordering.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport { SPLATS_PER_INSTANCE } from \"../SplatGeometry\";\nimport type { SplatMaterialOptions } from \"../backend\";\nimport type { Uniforms } from \"../uniforms\";\nimport { getShaders } from \"./shaders\";\n\nexport function createWebGLSplatMaterial(\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n) {\n const shaders = getShaders();\n return new THREE.ShaderMaterial({\n ...options,\n defines: {\n SPLATS_PER_INSTANCE,\n GSL_STOCHASTIC: 0,\n },\n glslVersion: THREE.GLSL3,\n vertexShader: shaders.splatVertex,\n fragmentShader: shaders.splatFragment,\n uniforms,\n side: THREE.FrontSide,\n allowOverride: false,\n });\n}\n","import type * as THREE from \"three\";\nimport type { CPUOrderingUpdate, SplatMaterialOptions } from \"../backend\";\nimport { type Uniforms, emptyOrdering } from \"../uniforms\";\nimport { OrderingTexture } from \"./OrderingTexture\";\nimport { createWebGLSplatMaterial } from \"./SplatMaterial\";\nimport { uploadU32DataTextureRows } from \"./textureUtils\";\n\n/** WebGL materials and ordering-texture uploads. */\nexport class WebGLSplatBackend {\n readonly kind = \"webgl\";\n readonly material: THREE.ShaderMaterial;\n private readonly ordering = new OrderingTexture();\n\n constructor(\n readonly renderer: THREE.WebGLRenderer,\n private readonly uniforms: Uniforms,\n options: SplatMaterialOptions,\n ) {\n this.material = createWebGLSplatMaterial(uniforms, options);\n const extension = renderer\n .getContext()\n .getExtension(\"WEBGL_provoking_vertex\");\n extension?.provokingVertexWEBGL(extension.FIRST_VERTEX_CONVENTION_WEBGL);\n }\n\n selectMaterial(stochastic: boolean) {\n const { material } = this;\n const value = Number(stochastic);\n if (material.defines.GSL_STOCHASTIC !== value) {\n material.defines.GSL_STOCHASTIC = value;\n material.needsUpdate = true;\n }\n return material;\n }\n\n getOrderingCapacity(count: number) {\n return this.ordering.getCapacity(count);\n }\n\n get cpuOrdering(): Uint32Array | null {\n return this.ordering.data;\n }\n\n setCPUOrdering(update: CPUOrderingUpdate) {\n this.uniforms.ordering.value = this.ordering.update(\n update,\n (texture, rows) => {\n uploadU32DataTextureRows(\n this.renderer,\n texture,\n texture.image.width,\n rows,\n update.ordering,\n );\n },\n );\n }\n\n /** Unsorted draws read no ordering; the next sort allocates it again. */\n releaseOrdering() {\n this.ordering.dispose();\n this.uniforms.ordering.value = emptyOrdering;\n }\n\n dispose() {\n this.ordering.dispose();\n this.material.dispose();\n }\n}\n","import {\n AlwaysDepth,\n type Camera,\n ColorManagement,\n Matrix4,\n NeverDepth,\n type OrthographicCamera,\n type PerspectiveCamera,\n type RenderTarget,\n Vector2,\n Vector3,\n} from \"three\";\n\ntype TAACamera = PerspectiveCamera | OrthographicCamera;\ntype TAAParameters = {\n depthThreshold: number;\n edgeDepthDiff: number;\n maxMotionLength: number;\n useSubpixelCorrection: boolean;\n};\n\nexport function createTAAState<\n FloatUniform extends { value: number },\n BoolUniform extends { value: boolean },\n Vec2Uniform extends { value: Vector2 },\n Vec3Uniform extends { value: Vector3 },\n Mat4Uniform extends { value: Matrix4 },\n>(\n makeUniform: {\n (value: number): FloatUniform;\n (value: boolean): BoolUniform;\n (value: Vector2): Vec2Uniform;\n (value: Vector3): Vec3Uniform;\n (value: Matrix4): Mat4Uniform;\n },\n targets: RenderTarget[],\n) {\n const uniforms = {\n renderSize: makeUniform(new Vector2(1, 1)),\n projection: makeUniform(new Matrix4()),\n unjitteredProjection: makeUniform(new Matrix4()),\n previousProjection: makeUniform(new Matrix4()),\n viewToPreviousClip: makeUniform(new Matrix4()),\n previousViewToView: makeUniform(new Matrix4()),\n valid: makeUniform(false),\n reversed: makeUniform(false),\n logarithmic: makeUniform(false),\n logFar: makeUniform(new Vector2()),\n // Parameters are copied from the owner before each resolve.\n depthThreshold: makeUniform(0),\n edgeDepthDiff: makeUniform(0),\n maxMotionLength: makeUniform(0),\n useSubpixelCorrection: makeUniform(false),\n luminanceCoefficients: makeUniform(new Vector3()),\n };\n const baseProjection = new Matrix4();\n const previousViewProjection = new Matrix4();\n const previousWorld = new Matrix4();\n const viewMatrix = new Matrix4();\n return {\n uniforms,\n historyIndex: 0,\n jitterIndex: 0,\n reset() {\n uniforms.valid.value = false;\n this.jitterIndex = 0;\n },\n setSize(width: number, height: number) {\n const w = Math.max(1, Math.floor(width));\n const h = Math.max(1, Math.floor(height));\n if (targets[0].width === w && targets[0].height === h) return;\n for (const target of targets) target.setSize(w, h);\n uniforms.renderSize.value.set(w, h);\n this.reset();\n },\n beginCapture(camera: TAACamera) {\n jitterProjection(\n camera,\n baseProjection,\n this.jitterIndex,\n uniforms.renderSize.value.x,\n uniforms.renderSize.value.y,\n );\n },\n endCapture(camera: TAACamera) {\n uniforms.projection.value.copy(camera.projectionMatrix);\n restoreProjection(camera, baseProjection);\n },\n prepareResolve(camera: TAACamera, parameters: TAAParameters) {\n uniforms.logFar.value.x = Math.log2(camera.far + 1);\n uniforms.unjitteredProjection.value.copy(camera.projectionMatrix);\n uniforms.viewToPreviousClip.value.multiplyMatrices(\n previousViewProjection,\n camera.matrixWorld,\n );\n uniforms.previousViewToView.value.multiplyMatrices(\n viewMatrix.copy(camera.matrixWorld).invert(),\n previousWorld,\n );\n uniforms.depthThreshold.value = parameters.depthThreshold;\n uniforms.edgeDepthDiff.value = parameters.edgeDepthDiff;\n uniforms.maxMotionLength.value = parameters.maxMotionLength;\n uniforms.useSubpixelCorrection.value = parameters.useSubpixelCorrection;\n ColorManagement.getLuminanceCoefficients(\n uniforms.luminanceCoefficients.value,\n );\n // Three r186 reverses AlwaysDepth/NeverDepth on both GPU backends.\n return uniforms.reversed.value ? NeverDepth : AlwaysDepth;\n },\n advance(camera: TAACamera) {\n previousViewProjection.multiplyMatrices(\n camera.projectionMatrix,\n viewMatrix,\n );\n previousWorld.copy(camera.matrixWorld);\n uniforms.previousProjection.value.copy(uniforms.projection.value);\n uniforms.logFar.value.y = uniforms.logFar.value.x;\n this.historyIndex = 1 - this.historyIndex;\n uniforms.valid.value = true;\n this.jitterIndex = (this.jitterIndex + 1) % taaJitterOffsets.length;\n },\n };\n}\n\nfunction halton(index: number, base: number) {\n let i = index;\n let fraction = 1;\n let result = 0;\n while (i > 0) {\n fraction /= base;\n result += fraction * (i % base);\n i = Math.floor(i / base);\n }\n return result;\n}\n\nconst taaJitterOffsets = Array.from({ length: 32 }, (_, i) => [\n halton(i + 1, 2) - 0.5,\n halton(i + 1, 3) - 0.5,\n]);\n\n// Native Splat projection uses the unjittered matrix for its compute cache.\nconst projections = new WeakMap<Camera, Matrix4>();\nexport const getTAAProjection = (camera: Camera) => projections.get(camera);\n\nfunction jitterProjection(\n camera: Camera,\n base: Matrix4,\n index: number,\n width: number,\n height: number,\n) {\n base.copy(camera.projectionMatrix);\n projections.set(camera, base);\n const [x, y] = taaJitterOffsets[index];\n const elements = camera.projectionMatrix.elements;\n for (let column = 0; column < 16; column += 4) {\n elements[column] -= ((2 * x) / width) * elements[column + 3];\n elements[column + 1] += ((2 * y) / height) * elements[column + 3];\n }\n camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();\n}\n\nfunction restoreProjection(camera: Camera, base: Matrix4) {\n projections.delete(camera);\n camera.projectionMatrix.copy(base);\n camera.projectionMatrixInverse.copy(base).invert();\n}\n","import * as THREE from \"three\";\nimport type { Node } from \"three/webgpu\";\nimport { StorageArrayTexture } from \"three/webgpu\";\nimport type { SplatProjection } from \"../tsl/ProjectionProgram\";\nimport { N, loadArray } from \"../tsl/shaderUtils\";\nimport { uintTexture } from \"../tsl/tslCompat\";\n\ntype TextureLimits = {\n maxTextureDimension2D: number;\n maxTextureArrayLayers: number;\n};\n\nfunction makeTexture() {\n const texture = new StorageArrayTexture(1, 1, 1);\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.minFilter = THREE.NearestFilter;\n texture.magFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n return texture;\n}\n\n// Round near-square caches to rows instead of source-data layers. Power-of-two\n// widths keep addressing cheap; balance array layers beyond a single plane.\nexport function getProjectionCacheSize(count: number, limits: TextureLimits) {\n if (!Number.isSafeInteger(count) || count > 0x1_0000_0000) {\n throw new RangeError(\"Projected Splat entries exceed uint32 addressing\");\n }\n const side = limits.maxTextureDimension2D;\n const maxWidth = 2 ** Math.floor(Math.log2(side));\n const depth = Math.ceil(count / (maxWidth * side));\n if (depth > limits.maxTextureArrayLayers) {\n throw new RangeError(\n \"Projected Splat textures exceed the WebGPU device texture limits\",\n );\n }\n const perLayer = Math.ceil(count / depth);\n const width = Math.min(\n maxWidth,\n 2 ** Math.ceil(Math.log2(Math.ceil(Math.sqrt(perLayer)))),\n );\n const height = Math.ceil(perLayer / width);\n return { width, height, depth };\n}\n\nconst cacheTexCoord = N.Fn(([index, size]: [Node<\"uint\">, Node<\"uvec4\">]) => {\n const value = N.uint(index);\n const row = value.shiftRight(size.w).toVar();\n const layer = N.uint(0).toVar();\n N.If(size.z.greaterThan(N.uint(1)), () => {\n layer.assign(row.div(size.y));\n });\n // Integer addressing stays exact above 2^24 entries; mono-layer caches need\n // no division. The fourth size component holds log2(width).\n return N.ivec3(\n value.bitAnd(size.x.sub(N.uint(1))),\n row.sub(layer.mul(size.y)),\n layer,\n );\n});\n\nfunction store(\n texture: StorageArrayTexture,\n coord: Node<\"ivec3\">,\n value: Node<\"uvec4\">,\n) {\n N.storageTexture(texture, coord.xy, value)\n .depth(coord.z)\n .toWriteOnly()\n .toStack();\n}\n\n/** Native projected records: compact layout, paired codec and texture ownership. */\nexport class ProjectionCache {\n // 32 bytes per compact slot and eye. RGB retains half precision; alpha,\n // support radius, kernel power and view depth retain their float32 bits.\n readonly textures = [makeTexture(), makeTexture()];\n readonly size = new THREE.Vector4(1, 1, 1, 0);\n private readonly dimensions = N.uniform(this.size, \"uvec4\").onObjectUpdate(\n () => this.size,\n );\n\n resize(size: ReturnType<typeof getProjectionCacheSize>) {\n for (const texture of this.textures)\n texture.setSize(size.width, size.height, size.depth);\n this.size.set(size.width, size.height, size.depth, Math.log2(size.width));\n }\n\n // Call after visibility and deferred color evaluation, inside the same guard.\n write(\n index: Node<\"uint\">,\n projection: SplatProjection,\n ndc: Node<\"vec2\">,\n pixelScale: Node<\"vec2\">,\n centerRange: Node<\"float\">,\n ) {\n const coord = cacheTexCoord(index, this.dimensions).toVar();\n // The axes are orthogonal before the per-component viewport division.\n const axis1 = projection.axis1.mul(pixelScale).toVar();\n const axis2 = projection.axis2.mul(pixelScale).toVar();\n const largest = axis1.abs().max(axis2.abs());\n // Scale only unusually large axes, per splat, so an unlimited radius\n // does not overflow half or reduce the precision of unrelated splats.\n const exponent = N.int(\n N.floatBitsToUint(largest.x.max(largest.y)).shiftRight(23),\n );\n const scaleCode = N.uint(exponent.sub(141).max(0).add(7).div(8)).toVar();\n // Construct the reciprocal power of two without division.\n const invAxisScale = N.uintBitsToFloat(\n N.uint(127).sub(scaleCode.mul(8)).shiftLeft(23),\n ).toVar();\n const packedAxis = N.packHalf2x16(axis1.mul(invAxisScale)).toVar();\n // Cache the ratio of the existing half-precision lengths once per splat.\n const minorLength = N.unpackHalf2x16(\n N.packHalf2x16(N.vec2(axis2.mul(invAxisScale).length(), 0)),\n ).x;\n const axisRatio = minorLength\n .div(N.unpackHalf2x16(packedAxis).length().max(1e-20))\n .min(65504); // Keep degenerate axes finite when packing to half.\n // RGB and axis ratio are nonnegative. Their four unused sign bits\n // hold the shared axis exponent; the float32 fields remain untouched.\n const ratioRed = N.packHalf2x16(N.vec2(axisRatio, projection.rgba.r))\n .bitAnd(N.uint(0x7fff7fff))\n .bitOr(scaleCode.bitAnd(1).shiftLeft(15))\n .bitOr(scaleCode.bitAnd(2).shiftLeft(30));\n const greenBlue = N.packHalf2x16(projection.rgba.gb)\n .bitAnd(N.uint(0x7fff7fff))\n .bitOr(scaleCode.bitAnd(4).shiftLeft(13))\n .bitOr(scaleCode.bitAnd(8).shiftLeft(28));\n store(\n this.textures[0],\n coord,\n N.uvec4(\n N.packSnorm2x16(ndc.div(centerRange)),\n N.floatBitsToUint(projection.viewDepth),\n packedAxis,\n ratioRed,\n ),\n );\n store(\n this.textures[1],\n coord,\n N.uvec4(\n greenBlue,\n N.floatBitsToUint(projection.rgba.a),\n N.floatBitsToUint(projection.supportRadius),\n N.floatBitsToUint(projection.kernelPower),\n ),\n );\n }\n\n /**\n * A shared WebXR slot another eye draws: a transparent record whose\n * corners collapse to one point, behind a perspective camera.\n */\n writeHidden(index: Node<\"uint\">) {\n const coord = cacheTexCoord(index, this.dimensions).toVar();\n store(\n this.textures[0],\n coord,\n N.uvec4(0, N.floatBitsToUint(N.float(-1)), 0, 0),\n );\n store(this.textures[1], coord, N.uvec4(0));\n }\n\n // Call inside the per-eye visible-count guard. No cache loads precede it.\n read(\n index: Node<\"uint\">,\n pixelScale: Node<\"vec2\">,\n centerRange: Node<\"float\">,\n /** NDC translation from the cached projection to the drawn one. */\n jitter: Node<\"vec2\">,\n ) {\n const coord = cacheTexCoord(index, this.dimensions).toVar();\n const first = loadArray(uintTexture(this.textures[0]), coord).toVar();\n const second = loadArray(uintTexture(this.textures[1]), coord).toVar();\n const ndc = N.unpackSnorm2x16(first.x).mul(centerRange).add(jitter);\n const viewZ = N.uintBitsToFloat(first.y).negate();\n const matrix = N.cameraProjectionMatrix;\n const col0 = matrix.element(0);\n const col1 = matrix.element(1);\n const col2 = matrix.element(2);\n const col3 = matrix.element(3);\n const clipW = col2.w.mul(viewZ).add(col3.w).toVar();\n const clipZ = col2.z.mul(viewZ).add(col3.z).toVar();\n // Standard perspective, orthographic and asymmetric XR projections take\n // the fast path. Oblique/custom depth rows also depend on view X/Y.\n N.If(\n N.any(col0.zw.notEqual(N.vec2(0))).or(N.any(col1.zw.notEqual(N.vec2(0)))),\n () => {\n const a = col0.xy.sub(ndc.mul(col0.w));\n const b = col1.xy.sub(ndc.mul(col1.w));\n const rhs = ndc.mul(clipW).sub(col2.xy.mul(viewZ).add(col3.xy));\n const determinant = a.x.mul(b.y).sub(b.x.mul(a.y));\n const xy = N.vec2(\n rhs.x.mul(b.y).sub(b.x.mul(rhs.y)),\n a.x.mul(rhs.y).sub(rhs.x.mul(a.y)),\n )\n .div(determinant)\n .toVar();\n clipW.addAssign(col0.w.mul(xy.x).add(col1.w.mul(xy.y)));\n clipZ.addAssign(col0.z.mul(xy.x).add(col1.z.mul(xy.y)));\n },\n );\n const scaleCode = first.w\n .shiftRight(15)\n .bitAnd(1)\n .bitOr(first.w.shiftRight(30).bitAnd(2))\n .bitOr(second.x.shiftRight(13).bitAnd(4))\n .bitOr(second.x.shiftRight(28).bitAnd(8));\n const axisScale = N.uintBitsToFloat(\n scaleCode.mul(8).add(127).shiftLeft(23),\n );\n const axis1 = N.unpackHalf2x16(first.z).toVar();\n const ratioRed = N.unpackHalf2x16(first.w.bitAnd(N.uint(0x7fff7fff)));\n const greenBlue = N.unpackHalf2x16(second.x.bitAnd(N.uint(0x7fff7fff)));\n const axis2 = N.vec2(axis1.y, axis1.x.negate()).mul(ratioRed.x);\n const offset = axis1\n .mul(N.positionGeometry.x)\n .add(axis2.mul(N.positionGeometry.y))\n .mul(axisScale.div(pixelScale));\n const supportRadius = N.uintBitsToFloat(second.z);\n return {\n clipPosition: N.vec4(ndc.add(offset).mul(clipW), clipZ, clipW),\n rgba: N.vec4(ratioRed.y, greenBlue, N.uintBitsToFloat(second.y)),\n splatUv: N.positionGeometry.xy.mul(supportRadius),\n supportRadiusSquared: supportRadius.mul(supportRadius),\n kernelPower: N.uintBitsToFloat(second.w),\n };\n }\n\n dispose() {\n for (const texture of this.textures) texture.dispose();\n }\n}\n","import {\n type ComputeNode,\n IndirectStorageBufferAttribute,\n type Node,\n StorageBufferAttribute,\n type StorageBufferNode,\n} from \"three/webgpu\";\n\nimport { N, setIndirectDispatch } from \"../tsl/tslCompat\";\n\n/**\n * Key layout of one sort: full 32-bit or fast 24-bit back-to-front keys, or\n * 16-bit front-to-back keys for stochastic ordering.\n */\nexport type RadixSortMode = \"full\" | \"fast\" | \"front\";\n/** Values of the GPU mode uniform. */\nexport const RADIX_SORT_MODE_IDS = {\n full: 0,\n fast: 1,\n front: 2,\n} as const satisfies Record<RadixSortMode, number>;\n/**\n * Input key of an absent record. The first pass drops these records and\n * compacts the rest in input order, so the output order is deterministic.\n */\nexport const INVALID_SORT_KEY = 0xffffffff;\n\nconst RADIX_BITS = 8;\nconst RADIX_BUCKETS = 1 << RADIX_BITS;\nconst RADIX_PASSES = 32 / RADIX_BITS;\nconst MODE_PASSES = {\n full: RADIX_PASSES,\n fast: 24 / RADIX_BITS,\n front: 16 / RADIX_BITS,\n} satisfies Record<RadixSortMode, number>;\nconst MODES = Object.keys(MODE_PASSES) as RadixSortMode[];\nconst WORKGROUP_SIZE = 256;\nconst ELEMENTS_PER_THREAD = 8;\nconst ELEMENTS_PER_WORKGROUP = WORKGROUP_SIZE * ELEMENTS_PER_THREAD;\nconst PREFIX_ITEMS_PER_WORKGROUP = WORKGROUP_SIZE * 2;\nconst PREFIX_LEVELS = 3;\n\ntype BufferRef = { value: StorageBufferAttribute };\n\ntype WebGPURadixSortOptions = {\n /** GPU count of input keys other than INVALID_SORT_KEY. */\n count: Node<\"uint\">;\n /** RADIX_SORT_MODE_IDS value matching the input key encoding. */\n mode: Node<\"uint\">;\n maxComputeWorkgroupsPerDimension: number;\n maxStorageBufferBindingSize: number;\n};\n\ntype PrefixLevel = {\n scan: ComputeNode;\n add: ComputeNode | null;\n dispatch: IndirectStorageBufferAttribute;\n blockSums: BufferRef;\n};\n\nfunction storage(buffer: BufferRef, name: string) {\n return N.storage(buffer.value, \"uint\")\n .setName(name)\n .onObjectUpdate(() => buffer.value);\n}\n\nfunction makeBuffer(count: number) {\n return new StorageBufferAttribute(new Uint32Array(count), 1);\n}\n\nfunction makeBufferRef(count: number): BufferRef {\n return { value: makeBuffer(count) };\n}\n\nfunction workgroupIndex() {\n return N.workgroupId.y.mul(N.numWorkgroups.x).add(N.workgroupId.x);\n}\n\nfunction makeHistogramTask({\n input,\n blockSums,\n elementCount,\n bitOffset,\n workgroupCount,\n}: {\n input: BufferRef;\n blockSums: BufferRef;\n elementCount: Node<\"uint\">;\n bitOffset: number;\n workgroupCount: Node<\"uint\">;\n}) {\n const inputKeys = storage(input, \"gslRadixInputKeys\").toReadOnly();\n const sums = storage(blockSums, \"gslRadixBlockSums\");\n const bit = N.uint(bitOffset);\n const histogram = N.workgroupArray(\"uint\", RADIX_BUCKETS)\n .toAtomic()\n .setName(\"gslRadixHistogram\");\n\n return N.Fn(() => {\n const tid = N.invocationLocalIndex;\n const workgroup = workgroupIndex();\n\n N.atomicStore(histogram.element(tid), N.uint(0));\n N.workgroupBarrier();\n\n N.Loop(\n {\n start: N.uint(0),\n end: N.uint(ELEMENTS_PER_THREAD),\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: round }) => {\n const index = workgroup\n .mul(ELEMENTS_PER_WORKGROUP)\n .add(round.mul(WORKGROUP_SIZE))\n .add(tid);\n N.If(index.lessThan(elementCount), () => {\n const key = inputKeys.element(index).toVar();\n const tally = () => {\n const digit = key.shiftRight(bit).bitAnd(RADIX_BUCKETS - 1);\n N.atomicAdd(histogram.element(digit), N.uint(1));\n };\n // The first pass drops absent records.\n if (bitOffset === 0)\n N.If(key.notEqual(N.uint(INVALID_SORT_KEY)), tally);\n else tally();\n });\n },\n );\n\n N.workgroupBarrier();\n sums\n .element(tid.mul(workgroupCount).add(workgroup))\n .assign(N.atomicLoad(histogram.element(tid)));\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix histogram\");\n}\n\nfunction makePrefixScanTask(\n itemsBuffer: BufferRef,\n blockSumsBuffer: BufferRef,\n elementCount: Node<\"uint\">,\n) {\n const items = storage(itemsBuffer, \"gslPrefixItems\");\n const blockSums = storage(blockSumsBuffer, \"gslPrefixBlockSums\");\n const temp = N.workgroupArray(\"uint\", PREFIX_ITEMS_PER_WORKGROUP).setName(\n \"gslPrefixTemp\",\n );\n\n return N.Fn(() => {\n const tid = N.invocationLocalIndex;\n const workgroup = workgroupIndex();\n const first = workgroup.mul(PREFIX_ITEMS_PER_WORKGROUP).add(tid.mul(2));\n const second = first.add(1);\n\n temp.element(tid.mul(2)).assign(0);\n temp.element(tid.mul(2).add(1)).assign(0);\n N.If(first.lessThan(elementCount), () => {\n temp.element(tid.mul(2)).assign(items.element(first));\n });\n N.If(second.lessThan(elementCount), () => {\n temp.element(tid.mul(2).add(1)).assign(items.element(second));\n });\n\n // Expand the fixed scan levels while building the shader.\n for (\n let distance = PREFIX_ITEMS_PER_WORKGROUP >> 1, offset = 1;\n distance > 0;\n distance >>= 1, offset <<= 1\n ) {\n N.workgroupBarrier();\n N.If(tid.lessThan(distance), () => {\n const a = tid.mul(2).add(1).mul(offset).sub(1);\n const b = tid.mul(2).add(2).mul(offset).sub(1);\n temp.element(b).addAssign(temp.element(a));\n });\n }\n N.workgroupBarrier();\n\n N.If(tid.equal(0), () => {\n blockSums\n .element(workgroup)\n .assign(temp.element(N.uint(PREFIX_ITEMS_PER_WORKGROUP - 1)));\n temp.element(N.uint(PREFIX_ITEMS_PER_WORKGROUP - 1)).assign(0);\n });\n\n for (\n let distance = 1, offset = PREFIX_ITEMS_PER_WORKGROUP >> 1;\n distance < PREFIX_ITEMS_PER_WORKGROUP;\n distance <<= 1, offset >>= 1\n ) {\n N.workgroupBarrier();\n N.If(tid.lessThan(distance), () => {\n const a = tid.mul(2).add(1).mul(offset).sub(1);\n const b = tid.mul(2).add(2).mul(offset).sub(1);\n const value = temp.element(a).toVar();\n temp.element(a).assign(temp.element(b));\n temp.element(b).addAssign(value);\n });\n }\n\n N.workgroupBarrier();\n N.If(first.lessThan(elementCount), () => {\n items.element(first).assign(temp.element(tid.mul(2)));\n });\n N.If(second.lessThan(elementCount), () => {\n items.element(second).assign(temp.element(tid.mul(2).add(1)));\n });\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix prefix scan\");\n}\n\nfunction makePrefixAddTask(\n itemsBuffer: BufferRef,\n blockSumsBuffer: BufferRef,\n elementCount: Node<\"uint\">,\n) {\n const items = storage(itemsBuffer, \"gslPrefixItems\");\n const blockSums = storage(blockSumsBuffer, \"gslPrefixBlockSums\").toReadOnly();\n\n return N.Fn(() => {\n const workgroup = workgroupIndex();\n const first = workgroup\n .mul(PREFIX_ITEMS_PER_WORKGROUP)\n .add(N.invocationLocalIndex.mul(2));\n const second = first.add(1);\n N.If(first.lessThan(elementCount), () => {\n const value = blockSums.element(workgroup);\n items.element(first).addAssign(value);\n N.If(second.lessThan(elementCount), () => {\n items.element(second).addAssign(value);\n });\n });\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix prefix add\");\n}\n\nfunction makeReorderTask({\n inputKeysAttribute,\n outputKeysAttribute,\n inputValuesAttribute,\n outputValuesAttribute,\n prefixAttribute,\n elementCount,\n bitOffset,\n lastPass,\n workgroupCount,\n}: {\n inputKeysAttribute: BufferRef;\n outputKeysAttribute: BufferRef;\n inputValuesAttribute: BufferRef;\n outputValuesAttribute: BufferRef;\n prefixAttribute: BufferRef;\n elementCount: Node<\"uint\">;\n bitOffset: number;\n lastPass: boolean | Node<\"bool\">;\n workgroupCount: Node<\"uint\">;\n}) {\n const inputKeys = storage(\n inputKeysAttribute,\n \"gslRadixInputKeys\",\n ).toReadOnly();\n const outputKeys = storage(outputKeysAttribute, \"gslRadixOutputKeys\");\n const inputValues = storage(\n inputValuesAttribute,\n \"gslRadixInputValues\",\n ).toReadOnly();\n const outputValues = storage(outputValuesAttribute, \"gslRadixOutputValues\");\n const prefix = storage(prefixAttribute, \"gslRadixPrefix\").toReadOnly();\n const bitOffsetNode = N.uint(bitOffset);\n // Shared masks use [word][bucket] for the parallel bucket scan.\n const digitMasks = N.workgroupArray(\"uint\", RADIX_BUCKETS * 8)\n .toAtomic()\n .setName(\"gslRadixDigitMasks\");\n const digitOffsets = N.workgroupArray(\"uint\", RADIX_BUCKETS).setName(\n \"gslRadixDigitOffsets\",\n );\n\n return N.Fn(() => {\n const tid = N.invocationLocalIndex;\n const workgroup = workgroupIndex();\n const word = tid.shiftRight(5);\n const bit = tid.bitAnd(31);\n\n digitOffsets\n .element(tid)\n .assign(prefix.element(tid.mul(workgroupCount).add(workgroup)));\n // Each thread clears one mask word per group of WORKGROUP_SIZE words.\n for (let offset = 0; offset < RADIX_BUCKETS * 8; offset += WORKGROUP_SIZE)\n N.atomicStore(digitMasks.element(tid.add(offset)), N.uint(0));\n N.workgroupBarrier();\n\n N.Loop(\n {\n start: N.uint(0),\n end: N.uint(ELEMENTS_PER_THREAD),\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: round }) => {\n const index = workgroup\n .mul(ELEMENTS_PER_WORKGROUP)\n .add(round.mul(WORKGROUP_SIZE))\n .add(tid);\n const valid = index.lessThan(elementCount).toVar();\n const key = N.uint(0).toVar();\n const digit = N.uint(0).toVar();\n const value = N.uint(0).toVar();\n N.If(valid, () => {\n key.assign(inputKeys.element(index));\n // Absent records take no rank or output slot.\n if (bitOffset === 0)\n valid.assign(key.notEqual(N.uint(INVALID_SORT_KEY)));\n });\n N.If(valid, () => {\n digit.assign(key.shiftRight(bitOffsetNode).bitAnd(RADIX_BUCKETS - 1));\n value.assign(inputValues.element(index));\n N.atomicOr(\n digitMasks.element(word.mul(RADIX_BUCKETS).add(digit)),\n N.uint(1).shiftLeft(bit),\n );\n });\n\n N.workgroupBarrier();\n N.If(valid, () => {\n const sortedIndex = digitOffsets.element(digit).toVar();\n N.Loop(\n {\n start: N.uint(0),\n end: word,\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: precedingWord }) => {\n sortedIndex.addAssign(\n N.countOneBits(\n N.atomicLoad(\n digitMasks.element(\n precedingWord.mul(RADIX_BUCKETS).add(digit),\n ),\n ),\n ),\n );\n },\n );\n const lowerBits = N.uint(1).shiftLeft(bit).sub(1);\n sortedIndex.addAssign(\n N.countOneBits(\n N.atomicLoad(\n digitMasks.element(word.mul(RADIX_BUCKETS).add(digit)),\n ).bitAnd(lowerBits),\n ),\n );\n // Boolean cases are resolved while building the shader.\n if (lastPass === false) {\n outputKeys.element(sortedIndex).assign(key);\n } else if (lastPass !== true) {\n N.If(lastPass.not(), () => {\n outputKeys.element(sortedIndex).assign(key);\n });\n }\n outputValues.element(sortedIndex).assign(value);\n });\n\n N.If(round.lessThan(ELEMENTS_PER_THREAD - 1), () => {\n // Finish all rank reads before updating offsets and clearing masks.\n N.workgroupBarrier();\n const count = N.uint(0).toVar();\n N.Loop(\n {\n start: N.uint(0),\n end: N.uint(8),\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: maskWord }) => {\n const maskIndex = maskWord.mul(RADIX_BUCKETS).add(tid);\n count.addAssign(\n N.countOneBits(\n N.atomicAnd(digitMasks.element(maskIndex), N.uint(0)),\n ),\n );\n },\n );\n digitOffsets.element(tid).addAssign(count);\n N.workgroupBarrier();\n });\n },\n );\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix reorder\");\n}\n\n/**\n * Stable 16-, 24- or 32-bit radix sort. The first pass compacts records whose\n * key is not INVALID_SORT_KEY, with the values the caller wrote to\n * `inputValues`. Borrows and overwrites input keys; their owner manages storage.\n */\nexport class WebGPURadixSort {\n capacity: number;\n readonly maxCapacity: number;\n readonly nodes: ComputeNode[];\n\n private readonly elementCount = N.uniform(0, \"uint\");\n private readonly keys: [BufferRef, BufferRef];\n private readonly values: [BufferRef, BufferRef];\n private readonly blockSums: BufferRef;\n // Count, padded histogram workgroups, and item count for each prefix level.\n private readonly counts = makeBufferRef(PREFIX_LEVELS + 2);\n private readonly sortDispatch = new IndirectStorageBufferAttribute(\n new Uint32Array(3),\n 1,\n );\n private readonly prefixLevels: PrefixLevel[] = [];\n // Mode of the last prepared sort; its pass count selects the output buffer.\n private mode: RadixSortMode = \"full\";\n private readonly maxWorkgroups: number;\n // Per mode, the dispatch list for each prefix depth.\n private readonly dispatchNodes: Record<RadixSortMode, ComputeNode[][]>;\n\n constructor(\n capacity: number,\n inputKeys: BufferRef,\n options: WebGPURadixSortOptions,\n ) {\n this.maxWorkgroups = options.maxComputeWorkgroupsPerDimension;\n this.maxCapacity = Math.min(\n 0xffffffff - ELEMENTS_PER_WORKGROUP + 1,\n Math.floor(options.maxStorageBufferBindingSize / 4),\n );\n const safeCapacity = this.validateCapacity(capacity);\n this.capacity = safeCapacity;\n // Projection fills the borrowed buffer before each sort. Reuse it for\n // ping-pong instead of allocating and copying another full set of keys.\n this.keys = [inputKeys, makeBufferRef(safeCapacity)];\n this.values = [makeBufferRef(safeCapacity), makeBufferRef(safeCapacity)];\n\n const histogramCount =\n RADIX_BUCKETS *\n this.paddedWorkgroups(safeCapacity, ELEMENTS_PER_WORKGROUP);\n this.blockSums = makeBufferRef(histogramCount);\n const counts = storage(this.counts, \"gslRadixCounts\").toReadOnly();\n this.createPrefixLevels(histogramCount, counts);\n // The first pass reads every input record; later passes read only the\n // valid records it compacted.\n const inputSetup = this.makeSetupTask(\n this.elementCount,\n \"Splat radix input setup\",\n );\n const compactSetup = this.makeSetupTask(\n options.count.min(this.elementCount),\n \"Splat radix compact setup\",\n );\n // Prebuild dispatch lists for every supported prefix depth. Choosing a\n // smaller list only omits work; it never creates or recompiles a node.\n const prefixNodes = this.prefixLevels.map((_, lastLevel) => {\n const nodes = this.prefixLevels\n .slice(0, lastLevel + 1)\n .map((level) => level.scan);\n for (let index = lastLevel - 1; index >= 0; index--) {\n const add = this.prefixLevels[index].add;\n if (add) nodes.push(add);\n }\n return nodes;\n });\n this.nodes = [inputSetup, compactSetup, ...prefixNodes[PREFIX_LEVELS - 1]];\n this.dispatchNodes = {\n full: prefixNodes.map(() => [inputSetup]),\n fast: prefixNodes.map(() => [inputSetup]),\n front: prefixNodes.map(() => [inputSetup]),\n };\n for (let pass = 0; pass < RADIX_PASSES; pass++) {\n const inputIndex = pass & 1;\n const outputIndex = inputIndex ^ 1;\n const histogram = makeHistogramTask({\n input: this.keys[inputIndex],\n blockSums: this.blockSums,\n elementCount: counts.element(0),\n workgroupCount: counts.element(1),\n bitOffset: pass * RADIX_BITS,\n });\n const reorder = makeReorderTask({\n inputKeysAttribute: this.keys[inputIndex],\n outputKeysAttribute: this.keys[outputIndex],\n inputValuesAttribute: this.values[inputIndex],\n outputValuesAttribute: this.values[outputIndex],\n prefixAttribute: this.blockSums,\n elementCount: counts.element(0),\n workgroupCount: counts.element(1),\n bitOffset: pass * RADIX_BITS,\n lastPass:\n pass === RADIX_PASSES - 1\n ? true\n : pass === MODE_PASSES.front - 1\n ? options.mode.equal(N.uint(RADIX_SORT_MODE_IDS.front))\n : pass === MODE_PASSES.fast - 1\n ? options.mode.equal(N.uint(RADIX_SORT_MODE_IDS.fast))\n : false,\n });\n setIndirectDispatch(histogram, this.sortDispatch);\n setIndirectDispatch(reorder, this.sortDispatch);\n this.nodes.push(histogram, reorder);\n for (let level = 0; level < PREFIX_LEVELS; level++) {\n const nodes = [histogram, ...prefixNodes[level], reorder];\n if (pass === 0) nodes.push(compactSetup);\n for (const mode of MODES)\n if (pass < MODE_PASSES[mode])\n this.dispatchNodes[mode][level].push(...nodes);\n }\n }\n }\n\n /** Values the caller writes for valid input records; sorting overwrites them. */\n get inputValues() {\n return this.values[0].value;\n }\n\n get ordering() {\n // Each pass writes the other value buffer.\n return this.values[MODE_PASSES[this.mode] & 1].value;\n }\n\n private validateCapacity(capacity: number) {\n const required = Math.max(1, capacity);\n if (!Number.isSafeInteger(required) || required > this.maxCapacity) {\n throw new RangeError(\n `GPU radix sort capacity ${capacity} exceeds the device's scalar storage buffer capacity (${this.maxCapacity} splats)`,\n );\n }\n return required;\n }\n\n private paddedWorkgroups(count: number, itemsPerWorkgroup: number) {\n const groups = Math.ceil(count / itemsPerWorkgroup);\n const width = Math.min(groups, this.maxWorkgroups);\n return width * Math.ceil(groups / this.maxWorkgroups);\n }\n\n private makeSetupTask(inputCount: Node<\"uint\">, name: string) {\n const counts = storage(this.counts, \"gslRadixCounts\");\n const dispatchBuffers = [\n this.sortDispatch,\n ...this.prefixLevels.map((level) => level.dispatch),\n ].map((value, index) => storage({ value }, `gslRadixDispatch${index}`));\n const maxWorkgroups = N.uint(this.maxWorkgroups);\n\n return N.Fn(() => {\n const count = inputCount.toVar();\n counts.element(0).assign(count);\n let itemCount = count;\n for (let index = 0; index < dispatchBuffers.length; index++) {\n const itemsPerWorkgroup =\n index === 0 ? ELEMENTS_PER_WORKGROUP : PREFIX_ITEMS_PER_WORKGROUP;\n const groups = itemCount\n .add(itemsPerWorkgroup - 1)\n .div(N.uint(itemsPerWorkgroup))\n .toVar();\n const width = groups.min(maxWorkgroups).toVar();\n const height = groups\n .add(this.maxWorkgroups - 1)\n .div(maxWorkgroups)\n .max(N.uint(1))\n .toVar();\n const dispatch = dispatchBuffers[index];\n dispatch.element(0).assign(width);\n dispatch.element(1).assign(height);\n dispatch.element(2).assign(1);\n // Include the empty tail of a 2D dispatch in the histogram/prefix\n // layout. Every workgroup can then execute barriers unconditionally.\n const paddedGroups = width.mul(height).toVar();\n if (index === 0) {\n counts.element(1).assign(paddedGroups);\n itemCount = paddedGroups.mul(RADIX_BUCKETS).toVar();\n } else {\n itemCount = paddedGroups;\n }\n if (index < PREFIX_LEVELS) counts.element(index + 2).assign(itemCount);\n }\n })()\n .compute(1, [1])\n .setName(name);\n }\n\n private replaceBuffer(buffer: BufferRef, count: number) {\n if (buffer.value.count === count) return;\n\n const previous = buffer.value;\n buffer.value = makeBuffer(count);\n previous.dispose();\n }\n\n private createPrefixLevels(\n itemCount: number,\n counts: StorageBufferNode<\"uint\">,\n ) {\n let items = this.blockSums;\n let currentCount = itemCount;\n\n for (let levelIndex = 0; levelIndex < PREFIX_LEVELS; levelIndex++) {\n const blockCount = this.paddedWorkgroups(\n currentCount,\n PREFIX_ITEMS_PER_WORKGROUP,\n );\n const blockSums = makeBufferRef(blockCount);\n const dispatch = new IndirectStorageBufferAttribute(\n new Uint32Array(3),\n 1,\n );\n const elementCount = counts.element(levelIndex + 2);\n const scan = makePrefixScanTask(items, blockSums, elementCount);\n const add =\n levelIndex < PREFIX_LEVELS - 1\n ? makePrefixAddTask(items, blockSums, elementCount)\n : null;\n setIndirectDispatch(scan, dispatch);\n if (add) setIndirectDispatch(add, dispatch);\n this.prefixLevels.push({ scan, add, dispatch, blockSums });\n items = blockSums;\n currentCount = blockCount;\n }\n }\n\n resize(capacity: number, shrinkResources = false) {\n const requiredCapacity = this.validateCapacity(capacity);\n if (!shrinkResources && requiredCapacity <= this.capacity) return;\n if (requiredCapacity === this.capacity) return;\n\n this.replaceBuffer(this.keys[1], requiredCapacity);\n for (const buffer of this.values)\n this.replaceBuffer(buffer, requiredCapacity);\n\n let itemCount =\n RADIX_BUCKETS *\n this.paddedWorkgroups(requiredCapacity, ELEMENTS_PER_WORKGROUP);\n this.replaceBuffer(this.blockSums, itemCount);\n for (const level of this.prefixLevels) {\n itemCount = this.paddedWorkgroups(itemCount, PREFIX_ITEMS_PER_WORKGROUP);\n this.replaceBuffer(level.blockSums, itemCount);\n }\n this.capacity = requiredCapacity;\n }\n\n /**\n * Prepare the persistent graph for this many input records. The GPU count\n * of valid records is clamped to it.\n */\n prepare(elementCount: number, mode: RadixSortMode): ComputeNode[] {\n if (\n !Number.isSafeInteger(elementCount) ||\n elementCount < 0 ||\n elementCount > this.capacity\n ) {\n throw new RangeError(\n \"Sort count must be an integer within buffer capacity\",\n );\n }\n this.mode = mode;\n if (elementCount === 0) return [];\n this.elementCount.value = elementCount;\n // The CPU knows an upper bound, while the live count stays on the GPU.\n // Include 2D dispatch padding just as the GPU setup does, so every possible\n // live count fits the selected hierarchy without a count readback.\n let items =\n RADIX_BUCKETS *\n this.paddedWorkgroups(elementCount, ELEMENTS_PER_WORKGROUP);\n let lastLevel = 0;\n while (lastLevel < PREFIX_LEVELS - 1) {\n items = this.paddedWorkgroups(items, PREFIX_ITEMS_PER_WORKGROUP);\n if (items === 1) break;\n lastLevel++;\n }\n return this.dispatchNodes[mode][lastLevel];\n }\n\n dispose() {\n for (const node of this.nodes) node.dispose();\n for (const level of this.prefixLevels) {\n level.blockSums.value.dispose();\n level.dispatch.dispose();\n }\n this.sortDispatch.dispose();\n this.counts.value.dispose();\n this.blockSums.value.dispose();\n this.keys[1].value.dispose();\n for (const buffer of this.values) buffer.value.dispose();\n this.capacity = 0;\n }\n}\n","import * as THREE from \"three\";\nimport type { ComputeNode } from \"three/webgpu\";\nimport {\n IndirectStorageBufferAttribute,\n StorageBufferAttribute,\n type WebGPURenderer,\n} from \"three/webgpu\";\nimport { getTAAProjection } from \"../../addons/taaShared\";\n\nimport type { SplatAccumulator } from \"../SplatAccumulator\";\nimport { SPLATS_PER_INSTANCE, type SplatGeometry } from \"../SplatGeometry\";\nimport { getMeanViewPose, getViews } from \"../rendererUtils\";\nimport { createGenerateProgram } from \"../tsl/GenerateProgram\";\nimport { createProjectionProgram } from \"../tsl/ProjectionProgram\";\nimport type { ProjectedVertexData } from \"../tsl/SplatMaterial\";\nimport { N, type UniformType, uniformBinding } from \"../tsl/shaderUtils\";\nimport { splatViewportUniforms } from \"../tsl/viewUniforms\";\nimport { type Uniforms, makeGenerateUniforms } from \"../uniforms\";\nimport { ProjectionCache, getProjectionCacheSize } from \"./ProjectionCache\";\nimport {\n INVALID_SORT_KEY,\n RADIX_SORT_MODE_IDS,\n type RadixSortMode,\n WebGPURadixSort,\n} from \"./RadixSort\";\n\nconst WORKGROUP_SIZE = 256;\nconst PROJECT_SLOTS = 8;\n\ntype BufferRef = { value: StorageBufferAttribute; name: string };\ntype ComputeSlot = { uniforms: Uniforms; node: ComputeNode };\ntype SlotSet = { slots: ComputeSlot[]; compiled: number };\ntype DeviceLimits = {\n maxStorageBufferBindingSize: number;\n maxBufferSize: number;\n maxTextureArrayLayers: number;\n maxTextureDimension2D: number;\n maxComputeWorkgroupsPerDimension: number;\n};\ntype ComputeRenderer = WebGPURenderer & {\n compileComputeAsync(nodes: ComputeNode[]): Promise<void>;\n backend: { device: { limits: DeviceLimits } };\n};\n\nfunction buffer(name: string): BufferRef {\n return { value: new StorageBufferAttribute(new Uint32Array(1), 1), name };\n}\n\n/**\n * Stores in `jitter` the NDC translation that `jittered` adds to `base`, as\n * TAA's sub-pixel view offsets do. Returns false for any other difference.\n */\nfunction getProjectionJitter(\n jittered: THREE.Matrix4,\n base: THREE.Matrix4,\n jitter: THREE.Vector2,\n) {\n const a = jittered.elements;\n const b = base.elements;\n for (let i = 0; i < 16; i++) {\n if (\n i !== 8 &&\n i !== 9 &&\n i !== 12 &&\n i !== 13 &&\n Math.abs(a[i] - b[i]) >\n 4 * Number.EPSILON * Math.max(1, Math.abs(a[i]), Math.abs(b[i]))\n ) {\n return false;\n }\n }\n // Perspective offsets scale with view depth (w = -z); orthographic ones\n // translate clip space directly (w = 1). Each projection uses only one.\n jitter.set(a[12] - b[12] - (a[8] - b[8]), a[13] - b[13] - (a[9] - b[9]));\n return true;\n}\n\nfunction bindBuffer(ref: BufferRef) {\n // Stable binding names let projection slots share the same WGSL program.\n return N.storage(ref.value, \"uint\")\n .setName(ref.name)\n .onObjectUpdate(() => ref.value);\n}\n\n/** Fixed compute graph. Source mappings and storage may change without rebuilding shaders. */\nexport class ProjectedSplats {\n // Only the instance count changes; the other indirect draw arguments are fixed.\n readonly indirect = new IndirectStorageBufferAttribute(\n new Uint32Array([SPLATS_PER_INSTANCE * 6, 0, 0, 0, 0]),\n 1,\n );\n /** Common kernels, the full sorter and the first slot are ready; remaining slots warm automatically. */\n readonly ready: Promise<void>;\n error: unknown = null;\n /**\n * Called when kernels for a new WebXR eye count can draw, or when a slot\n * fails to compile. Draws hide Splats until then, so on-demand hosts must\n * redraw.\n */\n onKernelsReady?: () => void;\n\n private readonly limits: DeviceLimits;\n private readonly cache = new ProjectionCache();\n private readonly visibleCount = new StorageBufferAttribute(\n new Uint32Array(1),\n 1,\n );\n private readonly keys = buffer(\"gslProjectionKeys\");\n private readonly seeds = buffer(\"gslProjectionSeeds\");\n private readonly sorter: WebGPURadixSort;\n // Slots for each eye count. One eye compiles at startup; WebXR eye counts\n // compile as a session starts or on first use, so other draws pay nothing.\n private readonly slotSets = new Map<number, SlotSet>();\n private readonly compilations: Promise<void>[] = [];\n private readonly onSessionStart = () => void this.getSlots(2);\n private shrinkViews = false;\n private readonly onSessionEnd = () => {\n this.shrinkViews = true;\n this.onKernelsReady?.();\n };\n private readonly resetCount: ComputeNode;\n private readonly finish: ComputeNode;\n private readonly state: Uniforms;\n private readonly matrix = new THREE.Matrix4();\n private readonly translation = new THREE.Matrix4();\n private readonly scale = new THREE.Vector3();\n private readonly viewPosition = new THREE.Vector3();\n private capacity = 0;\n private viewCapacity = 0;\n private disposed = false;\n private projectedInputs: unknown[] = [];\n\n constructor(\n private readonly renderer: WebGPURenderer,\n private readonly uniforms: Uniforms,\n ) {\n const computeRenderer = renderer as ComputeRenderer;\n this.limits = computeRenderer.backend.device.limits;\n this.state = {\n ...uniforms,\n projectionMatrix: { value: new THREE.Matrix4() },\n renderToViewQuat: { value: new THREE.Quaternion() },\n renderToViewPos: { value: new THREE.Vector3() },\n renderToViewScale: { value: 1 },\n near: { value: 0.1 },\n far: { value: 1000 },\n renderSize: { value: new THREE.Vector2() },\n // Projected records of each eye start one capacity after the last.\n viewStride: { value: 1 },\n sortDirection: { value: new THREE.Vector3() },\n sortOffset: { value: new THREE.Vector3() },\n sortRadial: { value: false },\n // RADIX_SORT_MODE_IDS value of the current key encoding.\n sortMode: { value: 0 },\n // NDC translation the draw applies to unjittered projections.\n projectionJitter: { value: new THREE.Vector2() },\n };\n // Every view, including each WebXR eye, draws one compact sorted order.\n const count = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toReadOnly()\n .element(0);\n this.sorter = new WebGPURadixSort(1, this.keys, {\n count,\n mode: uniformBinding(this.state, \"sortMode\", \"uint\"),\n maxComputeWorkgroupsPerDimension:\n this.limits.maxComputeWorkgroupsPerDimension,\n maxStorageBufferBindingSize: Math.min(\n this.limits.maxStorageBufferBindingSize,\n this.limits.maxBufferSize,\n ),\n });\n const drawCount = N.storage(this.indirect, \"uint\")\n .setName(\"gslDrawIndirect\")\n .element(1);\n const counter = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toAtomic();\n this.resetCount = N.Fn(() => {\n N.atomicStore(counter.element(0), N.uint(0));\n })()\n .compute(1, [1])\n .setName(\"Splat reset visible count\");\n this.finish = N.Fn(() => {\n drawCount.assign(\n count.add(SPLATS_PER_INSTANCE - 1).div(N.uint(SPLATS_PER_INSTANCE)),\n );\n })()\n .compute(1, [1])\n .setName(\"Splat visible draw arguments\");\n const mono = this.createSlotSet(1);\n this.ready = computeRenderer\n .compileComputeAsync([\n this.resetCount,\n this.finish,\n ...this.sorter.nodes,\n mono.slots[0].node,\n ])\n .then(() => {\n mono.compiled = 1;\n })\n .catch((error: unknown) => {\n this.error = error;\n });\n this.compilations.push(this.ready.then(() => this.compileSlots(mono)));\n renderer.xr.addEventListener(\"sessionstart\", this.onSessionStart);\n renderer.xr.addEventListener(\"sessionend\", this.onSessionEnd);\n }\n\n private createSlot(eyeCount = 1): ComputeSlot {\n this.ensureEyeUniforms(eyeCount);\n const uniforms = {\n ...this.state,\n ...makeGenerateUniforms(),\n };\n const u = <Type extends UniformType>(name: string, type: Type) =>\n uniformBinding(uniforms, name, type);\n const generate = createGenerateProgram({ uniforms });\n // Eye 0 reads the unsuffixed uniforms; later eyes append their index.\n const eyes = Array.from({ length: eyeCount }, (_, eye) =>\n eye ? `${eye}` : \"\",\n ).map((suffix) => ({\n project: createProjectionProgram(uniforms, {\n projectionMatrix: u(`projectionMatrix${suffix}`, \"mat4\"),\n renderToViewQuat: u(`renderToViewQuat${suffix}`, \"vec4\"),\n renderToViewPos: u(`renderToViewPos${suffix}`, \"vec3\"),\n renderToViewScale: u(`renderToViewScale${suffix}`, \"float\"),\n near: u(`near${suffix}`, \"float\"),\n far: u(`far${suffix}`, \"float\"),\n renderSize: u(`renderSize${suffix}`, \"vec2\"),\n }),\n pixelScale: u(`renderSize${suffix}`, \"vec2\")\n .mul(u(\"focalAdjustment\", \"float\"))\n .mul(0.5),\n }));\n const viewStride = u(\"viewStride\", \"uint\");\n const direction = u(\"sortDirection\", \"vec3\");\n const sortOffset = u(\"sortOffset\", \"vec3\");\n const radial = u(\"sortRadial\", \"bool\");\n const sortMode = u(\"sortMode\", \"uint\");\n const front = sortMode.equal(N.uint(RADIX_SORT_MODE_IDS.front));\n const stochastic = u(\"stochastic\", \"bool\");\n const centerRange = u(\"clipXY\", \"float\").abs().max(1).mul(1.000001);\n const keys = bindBuffer(this.keys);\n const seeds = bindBuffer(this.seeds);\n // Compact slot of each mapped Splat, read by the first sort pass.\n const sortValues = N.storage(this.sorter.inputValues, \"uint\")\n .setName(\"gslSortInputValues\")\n .onObjectUpdate(() => this.sorter.inputValues);\n const counter = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toAtomic();\n const node = N.Fn(() => {\n const index = N.uint(N.instanceIndex);\n // Sorted draws key each Splat at its mapping index, not its atomic slot.\n // The first radix pass compacts keys in mapping order, so equal keys\n // keep source order every frame.\n const sorted = stochastic\n .not()\n .or(u(\"stochasticOrdering\", \"bool\"))\n .toVar();\n const mappingIndex = u(\"targetBase\", \"uint\").add(index).toVar();\n // Decode, edit and evaluate color once, then project for each eye.\n const generated = generate.prepare(index);\n const projected = eyes.map(({ project }) => {\n const projection = project(generated, false);\n const extent = projection.axis1.abs().add(projection.axis2.abs());\n const ndc = projection.clipCenter.xy.div(projection.clipCenter.w);\n // Reject only quads wholly outside the viewport; clipXY and every\n // existing visual cutoff remain part of the shared projection math.\n const onscreen = N.all(ndc.abs().lessThanEqual(extent.add(1)));\n return { projection, ndc, visible: projection.valid.and(onscreen) };\n });\n // Shared culling keeps Splats any eye draws.\n const visible = projected\n .slice(1)\n .reduce((any, eye) => any.or(eye.visible), projected[0].visible);\n N.If(visible, () => {\n const rgb = generated.resolveRgb().toVar();\n // Compact survivors and their stable seeds into the same slots.\n const slot = N.atomicAdd(counter.element(0), N.uint(1)).toVar();\n projected.forEach(({ projection, ndc, visible: eyeVisible }, eye) => {\n const cacheIndex = viewStride.mul(eye).add(slot);\n const write = () => {\n projection.rgba.rgb.assign(rgb);\n this.cache.write(\n cacheIndex,\n projection,\n ndc,\n eyes[eye].pixelScale,\n centerRange,\n );\n };\n if (eyeCount > 1) {\n N.If(eyeVisible, write).Else(() => {\n this.cache.writeHidden(cacheIndex);\n });\n } else {\n write();\n }\n });\n N.If(stochastic, () => {\n seeds.element(slot).assign(generated.stochasticSeed);\n });\n // Sorted blending orders back to front by depth or distance;\n // stochastic ordering uses front-to-back depth.\n N.If(sorted, () => {\n const center = generated.center.add(sortOffset);\n const metric = N.select(\n radial.and(front.not()),\n center.dot(center),\n center.dot(direction),\n );\n const bits = N.floatBitsToUint(metric);\n // Non-finite metrics draw last; INVALID_SORT_KEY marks absence.\n const key = N.uint(INVALID_SORT_KEY - 1).toVar();\n N.If(\n bits.bitAnd(N.uint(0x7fffffff)).lessThan(N.uint(0x7f800000)),\n () => {\n // Signed float bits in ascending order, preserved across\n // negative view depths; inverted for back-to-front keys.\n const ascending = N.select(\n bits.bitAnd(N.uint(0x80000000)).notEqual(0),\n bits.bitXor(N.uint(0xffffffff)),\n bits.bitXor(N.uint(0x80000000)),\n );\n key.assign(\n ascending.bitXor(\n N.select(front, N.uint(0), N.uint(0xffffffff)),\n ),\n );\n },\n );\n // Discard low mantissa bits before storing the key: front keys keep\n // 16 bits and fast keys 24. Projection/depth cache precision is\n // independent of this sorting approximation.\n const shift = N.select(\n front,\n N.uint(16),\n N.select(\n sortMode.equal(N.uint(RADIX_SORT_MODE_IDS.fast)),\n N.uint(8),\n N.uint(0),\n ),\n );\n keys.element(mappingIndex).assign(key.shiftRight(shift));\n sortValues.element(mappingIndex).assign(slot);\n });\n }).Else(() => {\n N.If(sorted, () => {\n keys.element(mappingIndex).assign(N.uint(INVALID_SORT_KEY));\n });\n });\n })()\n .compute(1, [WORKGROUP_SIZE])\n .setName(\n eyeCount > 1\n ? `Splat generate project compact ${eyeCount} eyes`\n : \"Splat generate project compact\",\n );\n return { uniforms, node };\n }\n\n /** Projection uniforms of each eye after the first, created on demand. */\n private ensureEyeUniforms(eyeCount: number) {\n for (let eye = 1; eye < eyeCount; eye++) {\n if (this.state[`projectionMatrix${eye}`]) continue;\n Object.assign(this.state, {\n [`projectionMatrix${eye}`]: { value: new THREE.Matrix4() },\n [`renderToViewQuat${eye}`]: { value: new THREE.Quaternion() },\n [`renderToViewPos${eye}`]: { value: new THREE.Vector3() },\n [`renderToViewScale${eye}`]: { value: 1 },\n [`near${eye}`]: { value: 0.1 },\n [`far${eye}`]: { value: 1000 },\n [`renderSize${eye}`]: { value: new THREE.Vector2() },\n });\n }\n }\n\n private createSlotSet(eyeCount: number): SlotSet {\n const set: SlotSet = {\n slots: Array.from({ length: PROJECT_SLOTS }, () =>\n this.createSlot(eyeCount),\n ),\n compiled: 0,\n };\n this.slotSets.set(eyeCount, set);\n return set;\n }\n\n /**\n * Compiled slots that project this many eyes. One eye uses the startup\n * slots; WebXR eye counts build theirs on first request.\n */\n private getSlots(eyeCount: number) {\n let set = this.slotSets.get(eyeCount);\n if (!set) {\n set = this.createSlotSet(eyeCount);\n this.compilations.push(this.compileSlots(set));\n }\n return set.slots.slice(0, set.compiled);\n }\n\n private async compileSlots(set: SlotSet) {\n try {\n // A drawable set yields first, so readiness callbacks run before the\n // slots that only batch more meshes.\n if (set.compiled > 0)\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n while (!this.disposed && !this.error && set.compiled < set.slots.length) {\n await (this.renderer as ComputeRenderer).compileComputeAsync([\n set.slots[set.compiled].node,\n ]);\n set.compiled++;\n // The first slot is enough to draw; later ones only batch more meshes.\n if (set.compiled === 1 && !this.disposed) this.onKernelsReady?.();\n }\n } catch (error) {\n this.error = error;\n // The next draw throws the compilation error.\n if (!this.disposed) this.onKernelsReady?.();\n }\n }\n\n vertexData(camera: THREE.Camera, stochastic: boolean): ProjectedVertexData {\n const multiView = getViews(camera)[0] !== camera;\n const eye = multiView ? N.cameraIndex : N.uint(0);\n const stride = uniformBinding(this.state, \"viewStride\", \"uint\");\n // Compute the eye offset before looking up its order.\n const base = eye.mul(stride).toVar();\n const i = N.uint(N.instanceIndex)\n .mul(SPLATS_PER_INSTANCE)\n .add(N.uint(N.positionGeometry.z));\n const count = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toReadOnly()\n .element(0);\n const clipPosition = N.vec4(0, 0, 2, 1).toVar();\n const rgba = N.vec4(0).toVar();\n const splatUv = N.vec2(0).toVar();\n const stochasticSeed = stochastic ? N.uint(0).toVar() : undefined;\n const supportRadiusSquared = N.float(0).toVar();\n const kernelPower = N.float(0).toVar();\n const view = splatViewportUniforms(this.uniforms, camera);\n const centerRange = uniformBinding(this.uniforms, \"clipXY\", \"float\")\n .abs()\n .max(1)\n .mul(1.000001);\n const renderSize = multiView\n ? view.renderSize\n : uniformBinding(this.state, \"renderSize\", \"vec2\");\n const pixelScale = renderSize\n .mul(uniformBinding(this.uniforms, \"focalAdjustment\", \"float\"))\n .mul(0.5);\n\n // Indirect draws round up to whole quad groups; trim before any index or\n // cache load, including the unused tail of the final instance.\n N.If(i.lessThan(count), () => {\n // Every eye draws the one shared order of compact slots.\n const cacheIndex = i.toVar();\n const loadOrdered = () => {\n cacheIndex.assign(\n N.storage(this.sorter.ordering, \"uint\")\n .onObjectUpdate(() => this.sorter.ordering)\n .toReadOnly()\n .element(i),\n );\n };\n if (stochastic) {\n // Unsorted stochastic draws read compacted slots directly.\n N.If(\n uniformBinding(this.uniforms, \"stochasticOrdering\", \"bool\"),\n loadOrdered,\n );\n } else {\n loadOrdered();\n }\n stochasticSeed?.assign(\n bindBuffer(this.seeds).toReadOnly().element(cacheIndex),\n );\n const projected = this.cache.read(\n base.add(cacheIndex),\n pixelScale,\n centerRange,\n uniformBinding(this.state, \"projectionJitter\", \"vec2\"),\n );\n clipPosition.assign(projected.clipPosition);\n rgba.assign(projected.rgba);\n splatUv.assign(projected.splatUv);\n supportRadiusSquared.assign(projected.supportRadiusSquared);\n kernelPower.assign(projected.kernelPower);\n });\n return {\n clipPosition,\n rgba,\n splatUv,\n stochasticSeed,\n supportRadiusSquared,\n kernelPower,\n viewportOrigin: view.viewportOrigin,\n };\n }\n\n private resizeBuffer(ref: BufferRef, count: number) {\n if (ref.value.count === count) return;\n const old = ref.value;\n ref.value = new StorageBufferAttribute(new Uint32Array(count), 1);\n old.dispose();\n }\n\n private resize(count: number, views: number, shrink = false) {\n const required = Math.max(1, count);\n const bytes = required * 4;\n const byteLimit = Math.min(\n this.limits.maxStorageBufferBindingSize,\n this.limits.maxBufferSize,\n );\n if (bytes > byteLimit) {\n throw new RangeError(\n `WebGPU sort requires ${bytes} bytes per index buffer; device binding limit is ${this.limits.maxStorageBufferBindingSize}. Request higher requiredLimits when creating WebGPURenderer or reduce resident Splats.`,\n );\n }\n const limit = Math.floor(byteLimit / 4);\n // Amortize small mapping changes without tying shader graphs to capacity.\n const capacity = shrink\n ? required\n : required <= this.capacity\n ? this.capacity\n : Math.min(\n limit,\n Math.max(\n required,\n 2048,\n Math.ceil((this.capacity * 1.5) / 2048) * 2048,\n ),\n );\n const viewCapacity =\n shrink || this.shrinkViews ? views : Math.max(views, this.viewCapacity);\n this.shrinkViews = false;\n if (capacity === this.capacity && viewCapacity === this.viewCapacity)\n return;\n const size = getProjectionCacheSize(capacity * viewCapacity, this.limits);\n this.resizeBuffer(this.keys, capacity);\n this.sorter.resize(capacity, shrink);\n this.cache.resize(size);\n this.capacity = capacity;\n this.viewCapacity = viewCapacity;\n this.state.viewStride.value = capacity;\n }\n\n render(\n accumulator: SplatAccumulator,\n camera: THREE.Camera,\n geometry: SplatGeometry,\n radial: boolean,\n fastSort: boolean,\n shrink = false,\n ) {\n if (this.error) throw this.error;\n const cameras = getViews(camera) as THREE.PerspectiveCamera[];\n const multiView = cameras[0] !== camera;\n // WebXR eyes share one generated, culled, compacted and sorted set, like\n // one head; each eye still gets its exact projection.\n const slots = this.disposed ? [] : this.getSlots(cameras.length);\n if (slots.length === 0) {\n // Draw nothing until the kernels for this eye count compile.\n geometry.setIndirect(null);\n geometry.instanceCount = 0;\n return false;\n }\n this.resize(accumulator.numSplats, cameras.length, shrink);\n const { uniforms } = this;\n const stochastic = uniforms.stochastic.value;\n // Only stochastic draws read seeds; sorted rendering keeps one entry.\n this.resizeBuffer(this.seeds, stochastic ? this.capacity : 1);\n // Unsorted stochastic draws need no keys or sort.\n const sortMode: RadixSortMode | null = !stochastic\n ? fastSort\n ? \"fast\"\n : \"full\"\n : uniforms.stochasticOrdering.value\n ? \"front\"\n : null;\n if (sortMode) this.state.sortMode.value = RADIX_SORT_MODE_IDS[sortMode];\n this.state.sortRadial.value = radial;\n // TAA exposes its unjittered projection during scene capture. Project and\n // sort without the jitter so a still view reuses the compute results;\n // drawing applies the jitter as an NDC translation.\n const jitter = this.state.projectionJitter.value as THREE.Vector2;\n jitter.set(0, 0);\n const unjittered = getTAAProjection(camera);\n const monoProjection =\n !multiView &&\n unjittered &&\n getProjectionJitter(camera.projectionMatrix, unjittered, jitter)\n ? unjittered\n : null;\n geometry.setIndirect(this.indirect);\n geometry.setSplatCount(Math.max(1, accumulator.numSplats));\n // The accumulator version covers source, mapping, transform, animation and\n // edit changes. Output color settings are draw-only.\n const inputs = [\n accumulator,\n accumulator.version,\n ...accumulator.viewOrigin.toArray(),\n cameras.length,\n stochastic,\n // Each mode keys only the sort options it reads.\n !stochastic && radial,\n sortMode,\n uniforms.maxStdDev.value,\n uniforms.minPixelRadius.value,\n uniforms.maxPixelRadius.value,\n uniforms.minAlpha.value,\n uniforms.preBlurAmount.value,\n uniforms.blurAmount.value,\n uniforms.clipXY.value,\n uniforms.focalAdjustment.value,\n ];\n for (const { node } of accumulator.mapping) inputs.push(node.layers.mask);\n for (const view of cameras) {\n inputs.push(\n ...view.matrixWorld.elements,\n ...(monoProjection ?? view.projectionMatrix).elements,\n view.near,\n view.far,\n view.layers.mask,\n view.viewport?.z ?? uniforms.renderSize.value.x,\n view.viewport?.w ?? uniforms.renderSize.value.y,\n );\n }\n if (\n !shrink &&\n inputs.length === this.projectedInputs.length &&\n inputs.every((value, index) => value === this.projectedInputs[index])\n )\n return true;\n // A failed or partially submitted update must not reuse the old snapshot.\n this.projectedInputs = [];\n cameras.forEach((view, eye) => {\n this.setEye(eye, view, monoProjection, accumulator);\n });\n this.setSortPose(cameras, accumulator);\n this.dispatch(slots, cameras, accumulator, sortMode);\n this.projectedInputs = inputs;\n return true;\n }\n\n /** Projection uniforms for one eye; eye 0 also serves mono draws. */\n private setEye(\n eye: number,\n view: THREE.PerspectiveCamera,\n projection: THREE.Matrix4 | null,\n accumulator: SplatAccumulator,\n ) {\n const state = this.state;\n const suffix = eye ? `${eye}` : \"\";\n // WebXR eye viewports are physical pixels; Three draws them as given.\n const viewport = view.viewport;\n state[`projectionMatrix${suffix}`].value.copy(\n projection ?? view.projectionMatrix,\n );\n state[`near${suffix}`].value = view.near;\n state[`far${suffix}`].value = view.far;\n const renderSize = state[`renderSize${suffix}`].value as THREE.Vector2;\n renderSize.copy(this.uniforms.renderSize.value);\n if (viewport) renderSize.set(viewport.z, viewport.w);\n this.matrix\n .copy(view.matrixWorld)\n .invert()\n .multiply(this.translation.makeTranslation(accumulator.viewOrigin))\n .decompose(\n state[`renderToViewPos${suffix}`].value,\n state[`renderToViewQuat${suffix}`].value,\n this.scale,\n );\n state[`renderToViewScale${suffix}`].value =\n (this.scale.x + this.scale.y + this.scale.z) / 3;\n }\n\n /** Sort from the views' mean pose: the camera, or the WebXR head. */\n private setSortPose(\n views: THREE.PerspectiveCamera[],\n accumulator: SplatAccumulator,\n ) {\n // Read the views at each draw: after a manual update, the accumulator's\n // pose may be stale and only places the render origin.\n getMeanViewPose(\n views,\n this.viewPosition,\n this.state.sortDirection.value as THREE.Vector3,\n );\n (this.state.sortOffset.value as THREE.Vector3).subVectors(\n accumulator.viewOrigin,\n this.viewPosition,\n );\n }\n\n /**\n * Generates, projects, compacts and sorts the meshes any view draws. Sorted\n * modes also visit hidden meshes, which only mark their keys absent.\n */\n private dispatch(\n slots: ComputeSlot[],\n views: THREE.Camera[],\n accumulator: SplatAccumulator,\n sortMode: RadixSortMode | null,\n ) {\n const pending: ComputeNode[] = [this.resetCount];\n let slotCount = 0;\n for (const { node, base, count, matrixWorld } of accumulator.mapping) {\n const drawn = views.some((view) => view.layers.test(node.layers));\n // Sorting reads a key for every mapped Splat, including hidden meshes.\n if (!drawn && !sortMode) continue;\n // A slot's uniforms can only be changed after its preceding batch has\n // been submitted. Keep the last batch open for draw arguments and sorting.\n if (slotCount === slots.length) {\n this.renderer.compute(pending);\n pending.length = 0;\n slotCount = 0;\n }\n const slot = slots[slotCount++];\n if (drawn) accumulator.prepareUniforms(node, slot.uniforms, matrixWorld);\n slot.uniforms.targetBase.value = base;\n // Hidden meshes read no source data; each Splat fails visibility.\n slot.uniforms.targetCount.value = drawn ? count : 0;\n slot.node.count = count;\n pending.push(slot.node);\n }\n pending.push(this.finish);\n if (sortMode)\n pending.push(...this.sorter.prepare(accumulator.numSplats, sortMode));\n this.renderer.compute(pending);\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.projectedInputs = [];\n this.renderer.xr.removeEventListener(\"sessionstart\", this.onSessionStart);\n this.renderer.xr.removeEventListener(\"sessionend\", this.onSessionEnd);\n void Promise.all(this.compilations).then(() => this.disposeResources());\n }\n\n private disposeResources() {\n for (const { slots } of this.slotSets.values())\n for (const slot of slots) slot.node.dispose();\n for (const node of [this.resetCount, this.finish]) node.dispose();\n this.sorter.dispose();\n this.cache.dispose();\n this.visibleCount.dispose();\n this.keys.value.dispose();\n this.seeds.value.dispose();\n this.indirect.dispose();\n }\n}\n","import type { WebGPURenderer } from \"three/webgpu\";\nimport type { SplatMaterialOptions } from \"../backend\";\nimport { NodeSplatBackend } from \"../tsl/SplatBackend\";\nimport type { Uniforms } from \"../uniforms\";\nimport { ProjectedSplats } from \"./ProjectedSplats\";\n\n/** Native WebGPU: fixed compute projection, visible compaction, GPU sort and indirect draw. */\nexport class WebGPUSplatBackend extends NodeSplatBackend {\n readonly kind = \"webgpu\";\n readonly projection: ProjectedSplats;\n precompile: Promise<void> | null;\n\n constructor(\n renderer: WebGPURenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n ) {\n const projection = new ProjectedSplats(renderer, uniforms);\n super(renderer, uniforms, options, undefined, (camera, stochastic) =>\n projection.vertexData(camera, stochastic),\n );\n this.projection = projection;\n this.precompile = projection.ready.finally(() => {\n this.precompile = null;\n });\n }\n\n get sortError() {\n return this.projection.error;\n }\n getOrderingCapacity(count: number) {\n return Math.max(1, count);\n }\n\n dispose() {\n super.dispose();\n this.projection.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport {\n type GaussianSplatCompatibleRenderer,\n isWebGPURenderer,\n isXRRenderTarget,\n usesNativeWebGPU,\n} from \"./rendererUtils\";\nimport type { SplatNodeMaterial } from \"./tsl/SplatMaterial\";\nimport type { Uniforms } from \"./uniforms\";\nimport { WebGLFallbackSplatBackend } from \"./webgl-fallback/SplatBackend\";\nimport { WebGLSplatBackend } from \"./webgl/SplatBackend\";\nimport { WebGPUSplatBackend } from \"./webgpu/SplatBackend\";\n\nexport type SplatBackend =\n | WebGLSplatBackend\n | WebGPUSplatBackend\n | WebGLFallbackSplatBackend;\n\nexport function createSplatBackend(\n renderer: GaussianSplatCompatibleRenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n): SplatBackend {\n if (!isWebGPURenderer(renderer)) {\n return new WebGLSplatBackend(renderer, uniforms, options);\n }\n return usesNativeWebGPU(renderer)\n ? new WebGPUSplatBackend(renderer, uniforms, options)\n : new WebGLFallbackSplatBackend(renderer, uniforms, options);\n}\n\nexport function configureSplatOutput(\n renderer: GaussianSplatCompatibleRenderer,\n target: THREE.RenderTarget | null,\n uniforms: Uniforms,\n) {\n let blendSpace = THREE.ColorManagement.workingColorSpace;\n if (!isWebGPURenderer(renderer)) {\n if (target === null) blendSpace = renderer.outputColorSpace;\n else if (isXRRenderTarget(target)) blendSpace = target.texture.colorSpace;\n }\n uniforms.encodeLinear.value = blendSpace !== THREE.SRGBColorSpace;\n}\n\nexport type CPUOrderingUpdate = {\n ordering: Uint32Array;\n activeSplats: number;\n requiredCapacity: number;\n shrink: boolean;\n};\n\nexport type SplatMaterial = THREE.ShaderMaterial | SplatNodeMaterial;\n\nexport type SplatMaterialOptions = {\n premultipliedAlpha: boolean;\n transparent: boolean;\n depthTest: boolean;\n depthWrite: boolean;\n};\n","import * as THREE from \"three\";\nimport { SplatWorker } from \"../runtime/SplatWorker\";\nimport { resolveTimer } from \"../utils/three\";\nimport { SortCenterCache } from \"./SortCenterCache\";\nimport { SplatAccumulator } from \"./SplatAccumulator\";\nimport { SplatGeometry } from \"./SplatGeometry\";\nimport {\n type SplatBackend,\n type SplatMaterial,\n configureSplatOutput,\n createSplatBackend,\n} from \"./backend\";\nimport {\n type GaussianSplatCompatibleRenderer,\n assertSupportedRenderer,\n getMeanViewPose,\n getRenderFrame,\n getViews,\n} from \"./rendererUtils\";\nimport { DEFAULT_MIN_ALPHA, makeSplatUniforms } from \"./uniforms\";\n\nconst renderToViewScaleTmp = new THREE.Vector3();\nconst renderToViewMatrixTmp = new THREE.Matrix4();\nconst renderTranslationTmp = new THREE.Matrix4();\nconst headPositionTmp = new THREE.Vector3();\nconst headTargetTmp = new THREE.Vector3();\ntype UpdateRequest = {\n scene: THREE.Scene;\n camera: THREE.Camera;\n shrinkResources: boolean;\n};\n\n// Back-to-front for blending, front-to-back for stochastic overdraw, or\n// source order for unsorted stochastic draws.\ntype SortMode = \"back\" | \"front\" | \"identity\";\n\nconst UNSUPPORTED_CAMERA =\n \"GaussianSplatRenderer draws ArrayCamera only for WebXR; render other views with separate cameras\";\n\n/**\n * Whether the camera is the WebXR camera or one of its eyes. Presenting alone\n * is not enough: Three draws render targets with the caller's camera when\n * xr.enabled is off, and WebGPURenderer whenever the target is not its output.\n */\nfunction isXRCamera(\n camera: THREE.Camera,\n renderer: GaussianSplatCompatibleRenderer,\n) {\n if (!renderer.xr.isPresenting) return false;\n const xrCamera = renderer.xr.getCamera();\n return (\n camera === xrCamera || (xrCamera.cameras as THREE.Camera[]).includes(camera)\n );\n}\n\n/**\n * Multiple views are drawn only as WebXR eyes. Classic WebGL draws each view\n * of an ArrayCamera separately, as a camera with a viewport.\n */\nfunction isSupportedCamera(\n camera: THREE.Camera,\n renderer: GaussianSplatCompatibleRenderer,\n) {\n return (\n isXRCamera(camera, renderer) ||\n (!(camera as THREE.ArrayCamera).isArrayCamera &&\n (camera as THREE.PerspectiveCamera).viewport === undefined)\n );\n}\n\nfunction assertSupportedCamera(\n camera: THREE.Camera,\n renderer: GaussianSplatCompatibleRenderer,\n) {\n if (!isSupportedCamera(camera, renderer)) throw new Error(UNSUPPORTED_CAMERA);\n}\n\n// Average (uniform) world scale of a camera, read without updating it.\nfunction getCameraWorldScale(camera: THREE.Camera): number {\n const scale = renderToViewScaleTmp.setFromMatrixScale(camera.matrixWorld);\n return (scale.x + scale.y + scale.z) / 3;\n}\n\nexport interface GaussianSplatRendererOptions {\n /**\n * Pass in a THREE.WebGLRenderer or an initialized THREE.WebGPURenderer so\n * Gaussian Splat Lite can perform work outside the usual render loop. Both\n * native WebGPU and the WebGL2 fallback are supported. The renderer\n * should be created with antialias: false (the default) because MSAA does not\n * improve Gaussian Splatting and significantly reduces performance.\n */\n renderer: GaussianSplatCompatibleRenderer;\n /**\n * Callback function to be called when GaussianSplatRenderer needs to re-render,\n * for example when a splat sort completes.\n */\n onDirty?: () => void;\n /**\n * Whether to use premultiplied alpha when accumulating splat RGB\n * @default true\n */\n premultipliedAlpha?: boolean;\n /**\n * Pass in a THREE.Timer to synchronize time-based effects across different\n * systems. A supplied timer remains owned and updated by the caller.\n * @default new THREE.Timer()\n */\n timer?: THREE.Timer;\n /**\n * Controls whether to check and automatically update Gsplat collection\n * each frame render.\n * @default true\n */\n autoUpdate?: boolean;\n /**\n * Controls whether to update the Gsplats before or after rendering. For WebXR\n * this is set to false in order to complete rendering as soon as possible.\n * @default true (if not WebXR)\n */\n preUpdate?: boolean;\n /**\n * Maximum standard deviations from the center to render Gaussians. Values\n * Math.sqrt(4)..Math.sqrt(9) produce acceptable results and can be tweaked for\n * performance.\n * @default Math.sqrt(8)\n */\n maxStdDev?: number;\n /**\n * Minimum screen-pixel radius for splat rendering, independent of the\n * internal projection scale used by focalAdjustment.\n * @default 1.0\n */\n minPixelRadius?: number;\n /**\n * Maximum screen-pixel radius for splat rendering, independent of the\n * internal projection scale used by focalAdjustment.\n * @default 256.0\n */\n maxPixelRadius?: number;\n /**\n * Minimum alpha value for splat rendering.\n * @default 0.5 / 255\n */\n minAlpha?: number;\n /**\n * Scalar value to add to 2D splat covariance diagonal, effectively blurring +\n * enlarging splats. In scenes trained without the Gsplat anti-aliasing tweak\n * this value was typically 0.3, but with anti-aliasing it is 0.0\n * @default 0.3\n */\n preBlurAmount?: number;\n /**\n * Scalar value to add to the projected 2D splat covariance diagonal, with\n * opacity adjustment for anti-aliasing. Set to 0.3 with preBlurAmount = 0\n * to enable compensated blur. Its screen-space scale depends on focalAdjustment.\n * @default 0.0\n */\n blurAmount?: number;\n /**\n * X/Y clipping boundary factor for Gsplat centers against view frustum.\n * 1.0 clips any centers that are exactly out of bounds, while 1.25 clips\n * centers that are 25% beyond the bounds.\n * @default 1.25\n */\n clipXY?: number;\n /**\n * Parameter to adjust projected splat scale calculation to match other renderers,\n * similar to the same parameter in the MKellogg 3DGS renderer. Higher values will\n * tend to sharpen the splats. A value 2.0 can be used to match the behavior of\n * the PlayCanvas renderer.\n * @default 2.0\n */\n focalAdjustment?: number;\n /**\n * Whether to sort splats radially (geometric distance) from the viewpoint (true)\n * or by Z-depth (false). Most scenes are trained with the Z-depth sort metric\n * and will render more accurately at certain viewpoints. However, radial sorting\n * is more stable under viewpoint rotations.\n * @default false\n */\n sortRadial?: boolean;\n /**\n * Lower-precision sorting for faster sorted rendering.\n * Has no effect on stochastic rendering.\n * @default true\n */\n fastSort?: boolean;\n /**\n * Minimum interval between WebGL sort calls in milliseconds. Native WebGPU\n * projects and sorts each draw without CPU throttling.\n * @default 0\n */\n minSortIntervalMs?: number;\n /**\n * Enables stochastic transparency. Also applies to WebXR.\n * @default false\n */\n stochastic?: boolean;\n /**\n * Increment stochasticSample once per scene render while stochastic\n * coverage is active, including WebXR. All views in that render share the\n * same sample.\n * @default true\n */\n autoAdvanceStochasticSample?: boolean;\n /**\n * 16-bit front-to-back ordering for stochastic frames.\n * WebXR eyes share one order based on their mean position and direction.\n * WebGL and WebGL fallback sort asynchronously; native WebGPU sorts on the GPU.\n * Disable to draw in source/compacted order.\n * @default true\n */\n stochasticSort?: boolean;\n /**\n * Set the splat shader material to be transparent which determines if the\n * splats are rendered during the first opaque THREE.js render pass or the\n * second transparent render pass. Stochastic rendering keeps the\n * material in the opaque list, with depth testing and writing enabled.\n * @default undefined = true\n */\n transparent?: boolean;\n /**\n * Set the splat shader material to enable depth testing which determines if the\n * splats respect the Z depth buffer and blend with other opaque objects in the scene.\n * @default undefined = true\n */\n depthTest?: boolean;\n /**\n * Set the splat shader material to enable depth writing which determines if the\n * splats write to the Z depth buffer. Note that enabling this may produce\n * undesirable results because most of the Gsplat is transparent.\n * @default undefined = false\n */\n depthWrite?: boolean;\n}\n\nexport class GaussianSplatRenderer extends THREE.Mesh<\n SplatGeometry,\n SplatMaterial\n> {\n readonly renderer: GaussianSplatCompatibleRenderer;\n readonly uniforms: ReturnType<typeof GaussianSplatRenderer.makeUniforms>;\n\n autoUpdate: boolean;\n preUpdate: boolean;\n\n renderSize = new THREE.Vector2();\n maxStdDev: number;\n minPixelRadius: number;\n maxPixelRadius: number;\n minAlpha: number;\n preBlurAmount: number;\n blurAmount: number;\n clipXY: number;\n focalAdjustment: number;\n sortRadial: boolean;\n private _fastSort: boolean;\n minSortIntervalMs: number;\n /**\n * Noise pattern index, wrapped to uint32. Each value selects an independent\n * pattern. Disable autoAdvanceStochasticSample for manual control.\n */\n stochasticSample = 0;\n autoAdvanceStochasticSample: boolean;\n private _stochastic: boolean;\n private stochasticFrame: boolean;\n private _stochasticSort: boolean;\n private _premultipliedAlpha: boolean;\n private _transparent: boolean;\n private readonly sortedBlending: THREE.Blending;\n private _depthTest: boolean;\n private _depthWrite: boolean;\n\n readonly timer: THREE.Timer;\n private readonly ownsTimer: boolean;\n lastFrame = -1;\n updateTimeoutId = -1;\n onDirty?: () => void;\n dirty: boolean;\n\n private readonly backend: SplatBackend;\n private orderingBuffer: Uint32Array = new Uint32Array(0);\n // A CPU ordering matching the displayed accumulator; unsorted stochastic\n // updates display without one.\n private orderingReady = false;\n // Mean pose of the WebXR eyes; see getGenerationCamera().\n private readonly headCamera = new THREE.PerspectiveCamera();\n maxSplats = 0;\n activeSplats = 0;\n\n display: SplatAccumulator;\n current: SplatAccumulator;\n accumulators: SplatAccumulator[] = [];\n\n sorting = false;\n sortDirty = false;\n lastSortTime = 0;\n sortWorker: SplatWorker | null = null;\n sortedCenter = new THREE.Vector3().setScalar(Number.NEGATIVE_INFINITY);\n sortedDir = new THREE.Vector3().setScalar(0);\n private sortedRadial: boolean | undefined;\n private sortedFastSort: boolean | undefined;\n private sortedMode: SortMode | undefined;\n private sortCenterCache = new SortCenterCache();\n private sortStateRevision = 0;\n private uploadedSortStateRevision = -1;\n private updateRunning = false;\n private updatePromise: Promise<void> = Promise.resolve();\n private queuedUpdate: UpdateRequest | null = null;\n private disposed = false;\n private pendingProjectionShrink = false;\n private unsupportedCameraReported = false;\n\n constructor(options: GaussianSplatRendererOptions) {\n if (!options?.renderer) {\n throw new Error(\"renderer is required in GaussianSplatRenderer options\");\n }\n assertSupportedRenderer(options.renderer);\n\n const uniforms = GaussianSplatRenderer.makeUniforms();\n\n const premultipliedAlpha = options.premultipliedAlpha ?? true;\n const stochastic = options.stochastic ?? false;\n const backend = createSplatBackend(options.renderer, uniforms, {\n premultipliedAlpha,\n transparent: options.transparent ?? true,\n depthTest: options.depthTest ?? true,\n depthWrite: options.depthWrite ?? false,\n });\n const geometry = new SplatGeometry();\n const material = backend.selectMaterial(stochastic);\n\n super(geometry, material);\n this.renderer = options.renderer;\n this.backend = backend;\n this.uniforms = uniforms;\n this.sortedBlending = material.blending;\n this._depthTest = options.depthTest ?? true;\n this._depthWrite = options.depthWrite ?? false;\n this._premultipliedAlpha = premultipliedAlpha;\n this._transparent = options.transparent ?? true;\n this._stochastic = stochastic;\n this.autoAdvanceStochasticSample =\n options.autoAdvanceStochasticSample ?? true;\n this._stochasticSort = options.stochasticSort ?? true;\n this.stochasticFrame = stochastic;\n this.applyMaterialState(this.stochasticFrame);\n // Disable frustum culling because we want to always draw them all\n // and cull Gsplats individually in the shader\n this.frustumCulled = false;\n\n // By default GaussianSplatRenderer will only render for layer 0\n // this.layers.enableAll();\n\n // gaussianSplatRendererInstance = this;\n this.onDirty = options.onDirty;\n this.dirty = true;\n this.autoUpdate = options.autoUpdate ?? true;\n this.preUpdate = options.preUpdate ?? true;\n\n this.maxStdDev = options.maxStdDev ?? Math.sqrt(8.0);\n this.minPixelRadius = options.minPixelRadius ?? 1.0;\n this.maxPixelRadius = options.maxPixelRadius ?? 256.0;\n this.minAlpha = options.minAlpha ?? DEFAULT_MIN_ALPHA;\n this.preBlurAmount = options.preBlurAmount ?? 0.3;\n this.blurAmount = options.blurAmount ?? 0.0;\n this.clipXY = options.clipXY ?? 1.25;\n this.focalAdjustment = options.focalAdjustment ?? 2.0;\n this.sortRadial = options.sortRadial ?? false;\n this._fastSort = options.fastSort ?? true;\n this.minSortIntervalMs = options.minSortIntervalMs ?? 0;\n\n const { timer, ownsTimer } = resolveTimer(options.timer);\n this.timer = timer;\n this.ownsTimer = ownsTimer;\n\n this.display = new SplatAccumulator();\n this.current = this.display;\n if (backend.kind !== \"webgpu\") {\n this.accumulators.push(new SplatAccumulator());\n }\n\n if (backend.kind === \"webgpu\") {\n backend.precompile?.then(() => {\n if (!this.disposed) this.setDirty();\n });\n // WebXR eye kernels compile on first use or session start; draws hide\n // Splats until they are ready, so request a redraw.\n backend.projection.onKernelsReady = () => {\n if (!this.disposed) this.setDirty();\n };\n }\n }\n\n raycast(_raycaster: THREE.Raycaster, _intersects: THREE.Intersection[]) {}\n\n static makeUniforms() {\n return makeSplatUniforms();\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.queuedUpdate = null;\n clearTimeout(this.updateTimeoutId);\n this.updateTimeoutId = -1;\n\n super.dispose();\n\n this.backend.dispose();\n this.uniforms.stochasticNoise.value.dispose();\n\n const accumulators = new Set<SplatAccumulator>();\n accumulators.add(this.display);\n accumulators.add(this.current);\n for (const accumulator of this.accumulators) {\n accumulators.add(accumulator);\n }\n for (const accumulator of accumulators) {\n accumulator.dispose();\n }\n this.accumulators.length = 0;\n\n this.resetSortWorker();\n this.orderingBuffer = new Uint32Array(0);\n this.orderingReady = false;\n this.maxSplats = 0;\n this.activeSplats = 0;\n\n this.geometry.dispose();\n }\n\n /** Native WebGPU sorts on the GPU before drawing; WebGL sorts in a worker. */\n get synchronousSort() {\n return this.backend.kind === \"webgpu\";\n }\n\n setDirty() {\n if (!this.dirty) {\n this.dirty = true;\n this.onDirty?.();\n }\n }\n\n private resetSortWorker() {\n this.sortWorker?.dispose();\n this.sortWorker = null;\n this.sortCenterCache.dispose();\n this.uploadedSortStateRevision = -1;\n }\n\n /**\n * Frees the worker, its sort state and the ordering, which unsorted draws\n * never read. Re-enabling sorting reallocates them and uploads centers.\n */\n private releaseOrdering() {\n this.resetSortWorker();\n if (this.backend.kind !== \"webgpu\") this.backend.releaseOrdering();\n this.orderingBuffer = new Uint32Array(0);\n this.maxSplats = 0;\n }\n\n private takeAccumulator() {\n return this.accumulators.pop() ?? new SplatAccumulator();\n }\n\n private releaseAccumulator(accumulator: SplatAccumulator) {\n this.accumulators.push(accumulator);\n }\n\n private disposeOversizedAccumulators(maxSplats: number) {\n for (const accumulator of this.accumulators) {\n if (accumulator.maxSplats > maxSplats) accumulator.dispose();\n }\n }\n\n /**\n * Draw stochastically exactly while the displayed accumulator was generated\n * for it: only stochastic accumulators carry sampling seeds, and only\n * sorted ones a back-to-front order. WebGL backends therefore switch modes\n * once an update for the new mode is displayed. Native WebGPU switches at\n * the update boundary too, keeping mode changes outside an active draw.\n */\n private syncStochasticFrame() {\n const active =\n this.backend.kind === \"webgpu\" || this.display.numSplats === 0\n ? this._stochastic\n : this.display.hasStochasticSeeds;\n if (active === this.stochasticFrame) return;\n this.stochasticFrame = active;\n this.material = this.backend.selectMaterial(active);\n this.applyMaterialState(active);\n this.setDirty();\n }\n\n private applyMaterialState(stochasticActive: boolean) {\n const { material } = this;\n const wasOpaque = isOpaqueMaterial(material);\n material.transparent = stochasticActive ? false : this._transparent;\n material.blending = stochasticActive\n ? THREE.NoBlending\n : this.sortedBlending;\n material.depthTest = stochasticActive ? true : this._depthTest;\n material.depthWrite = stochasticActive ? true : this._depthWrite;\n if (\n material.premultipliedAlpha !== this._premultipliedAlpha ||\n wasOpaque !== isOpaqueMaterial(material)\n ) {\n material.premultipliedAlpha = this._premultipliedAlpha;\n material.needsUpdate = true;\n }\n }\n\n private reportedRenderError = \"\";\n private runAutomaticUpdate(request: UpdateRequest) {\n try {\n void this.updateInternal(request).catch((error) =>\n this.reportRenderError(error),\n );\n } catch (error) {\n this.reportRenderError(error);\n }\n }\n private readonly viewportSize = new THREE.Vector4();\n\n private reportRenderError(error: unknown) {\n const message = String(error);\n if (message !== this.reportedRenderError) {\n this.reportedRenderError = message;\n console.error(\"Gaussian Splat render failed\", error);\n }\n }\n\n onBeforeRender(\n renderer: GaussianSplatCompatibleRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n ) {\n try {\n this.prepareDraw(renderer, scene, camera);\n } catch (error) {\n this.reportRenderError(error);\n this.geometry.setIndirect(null);\n this.geometry.instanceCount = 0;\n } finally {\n // Generation can render nested quads, advancing Three's render counter.\n this.lastFrame = getRenderFrame(renderer);\n }\n }\n\n private prepareDraw(\n renderer: GaussianSplatCompatibleRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n ) {\n if (!isSupportedCamera(camera, renderer)) {\n // Throwing here would leave Three.js mid-render; skip this draw instead.\n if (!this.unsupportedCameraReported) {\n this.unsupportedCameraReported = true;\n console.error(UNSUPPORTED_CAMERA);\n }\n this.geometry.setIndirect(null);\n this.geometry.instanceCount = 0;\n return;\n }\n const frame = getRenderFrame(renderer);\n const isNewFrame = frame !== this.lastFrame;\n this.lastFrame = frame;\n if (isNewFrame) {\n if (this.autoAdvanceStochasticSample && this.stochasticFrame) {\n this.stochasticSample = (this.stochasticSample + 1) >>> 0;\n }\n }\n\n const currentRenderTarget = renderer.getRenderTarget();\n if (currentRenderTarget) {\n this.renderSize.set(\n currentRenderTarget.viewport.z,\n currentRenderTarget.viewport.w,\n );\n } else {\n renderer.getViewport(this.viewportSize);\n this.renderSize\n .set(this.viewportSize.z, this.viewportSize.w)\n .multiplyScalar(renderer.getPixelRatio());\n }\n\n const xrView = isXRCamera(camera, renderer);\n const updateCamera = xrView ? renderer.xr.getCamera() : camera;\n // Classic WebGL draws each eye separately; node backends select viewport\n // uniforms per eye in the shader. XR preparation uses the first eye's size.\n const viewport =\n (camera as THREE.PerspectiveCamera).viewport ??\n (xrView\n ? (getViews(updateCamera)[0] as THREE.PerspectiveCamera).viewport\n : undefined);\n this.uniforms.viewportOrigin.value.set(viewport?.x ?? 0, viewport?.y ?? 0);\n if (viewport) this.renderSize.set(viewport.z, viewport.w);\n this.uniforms.renderSize.value.copy(this.renderSize);\n // Accumulator generation inside this draw would reset a classic WebGL\n // eye viewport and must not delay XR frames.\n const renderNested =\n this.backend.kind !== \"webgpu\" && this.preUpdate && !xrView && !viewport;\n\n // Trigger update after refreshing renderSize but before any uniforms that\n // depend on the active accumulator, avoiding both size and display latency.\n if (this.autoUpdate && isNewFrame) {\n // Native preparation only updates mappings and edit metadata. Its GPU\n // projection runs below, so it can prepare before XR draws as well.\n // Three has already selected this draw's material and render list.\n // Mode changes must finish outside the draw; onDirty then requests\n // a frame with the matching material, ordering and accumulator.\n const preUpdate =\n this.stochasticFrame === this._stochastic &&\n (this.backend.kind === \"webgpu\" || renderNested);\n const updateRequest = {\n scene,\n camera: updateCamera,\n shrinkResources: false,\n };\n if (preUpdate) {\n this.runAutomaticUpdate(updateRequest);\n } else if (this.updateTimeoutId === -1) {\n this.updateTimeoutId = setTimeout(() => {\n this.updateTimeoutId = -1;\n this.runAutomaticUpdate(updateRequest);\n }, 0);\n }\n }\n\n const typedCamera = camera as\n | THREE.PerspectiveCamera\n | THREE.OrthographicCamera;\n\n this.uniforms.near.value = typedCamera.near;\n this.uniforms.far.value = typedCamera.far;\n\n const display = this.display;\n // Native WebGPU prepares current poses before every draw.\n if (this.autoUpdate && renderNested) {\n display.refreshTransforms(renderer);\n }\n this.uniforms.renderOrigin.value.copy(display.viewOrigin);\n const geometry = this.geometry;\n // CPU orderings exist only while they match the displayed accumulator.\n this.uniforms.stochasticOrdering.value =\n this.stochasticSort &&\n (this.backend.kind === \"webgpu\" || this.orderingReady);\n const splatCount =\n this.stochasticFrame && !this.uniforms.stochasticOrdering.value\n ? display.numSplats\n : this.activeSplats;\n geometry.setSplatCount(splatCount);\n this.uniforms.splatCount.value = splatCount;\n\n // Keep rig scale: Camera.matrixWorldInverse can strip it in Three.js.\n renderToViewMatrixTmp\n .copy(camera.matrixWorld)\n .invert()\n .multiply(renderTranslationTmp.makeTranslation(display.viewOrigin))\n .decompose(\n this.uniforms.renderToViewPos.value,\n this.uniforms.renderToViewQuat.value,\n renderToViewScaleTmp,\n );\n this.uniforms.renderToViewScale.value =\n (renderToViewScaleTmp.x +\n renderToViewScaleTmp.y +\n renderToViewScaleTmp.z) /\n 3;\n this.uniforms.maxStdDev.value = this.maxStdDev;\n this.uniforms.minPixelRadius.value = this.minPixelRadius;\n this.uniforms.maxPixelRadius.value = this.maxPixelRadius;\n this.uniforms.minAlpha.value = this.minAlpha;\n this.uniforms.preBlurAmount.value = this.preBlurAmount;\n this.uniforms.blurAmount.value = this.blurAmount;\n this.uniforms.clipXY.value = this.clipXY;\n this.uniforms.focalAdjustment.value = this.focalAdjustment;\n this.uniforms.stochastic.value = this.stochasticFrame;\n this.uniforms.stochasticSample.value = this.stochasticSample >>> 0;\n configureSplatOutput(renderer, currentRenderTarget, this.uniforms);\n\n if (this.backend.kind === \"webgpu\") {\n if (this.backend.sortError) throw this.backend.sortError;\n if (this.backend.precompile) {\n geometry.instanceCount = 0;\n } else {\n const projected = this.backend.projection.render(\n display,\n camera,\n geometry,\n this.sortRadial,\n this.fastSort,\n this.pendingProjectionShrink,\n );\n if (projected) this.pendingProjectionShrink = false;\n }\n } else {\n const splatTextures = display.getTextures();\n this.uniforms.splats.value = splatTextures[0];\n this.uniforms.splats2.value = splatTextures[1];\n this.uniforms.stochasticSeeds.value = display.getStochasticSeeds();\n }\n\n this.dirty = false;\n }\n\n clearSplats() {\n this.activeSplats = 0;\n this.display.numSplats = 0;\n this.display.mapping = [];\n this.syncStochasticFrame();\n this.setDirty();\n }\n\n async update({\n scene,\n camera,\n }: {\n scene: THREE.Scene;\n camera: THREE.Camera;\n }) {\n assertSupportedCamera(camera, this.renderer);\n this.reportedRenderError = \"\";\n if (this.backend.kind === \"webgpu\") {\n await this.backend.precompile;\n if (this.backend.sortError) throw this.backend.sortError;\n }\n await this.updateInternal({\n scene,\n camera,\n shrinkResources: false,\n });\n }\n\n /** Updates the current scene and shrinks renderer work resources to their current allocation tiers. */\n async shrinkResources({\n scene,\n camera,\n }: {\n scene: THREE.Scene;\n camera: THREE.Camera;\n }) {\n assertSupportedCamera(camera, this.renderer);\n this.reportedRenderError = \"\";\n await this.updateInternal({\n scene,\n camera,\n shrinkResources: true,\n });\n }\n\n private updateInternal(request: UpdateRequest): Promise<void> {\n if (this.disposed) return Promise.resolve();\n\n if (this.backend.kind === \"webgpu\") {\n const { scene, shrinkResources } = request;\n if (scene.matrixWorldAutoUpdate) scene.updateMatrixWorld();\n if (!(request.camera as THREE.ArrayCamera).isArrayCamera)\n request.camera.updateWorldMatrix(true, false);\n const camera = this.getGenerationCamera(request.camera);\n if (this.ownsTimer) this.timer.update();\n if (shrinkResources) this.pendingProjectionShrink = true;\n const previousVersion = this.current.version;\n const viewChanged =\n !this.current.viewOrigin.equals(\n renderToViewScaleTmp.setFromMatrixPosition(camera.matrixWorld),\n ) ||\n !this.current.viewDirection.equals(\n renderToViewScaleTmp\n .setFromMatrixColumn(camera.matrixWorld, 2)\n .normalize()\n .negate(),\n );\n const { requiredMaxSplats } = this.current.prepareGenerate({\n renderer: this.renderer,\n scene,\n timer: this.timer,\n camera,\n layerCamera: request.camera,\n previous: this.current,\n });\n // The accumulator only carries source mappings and the camera-relative\n // origin here. Projection, compaction and ordering happen on the GPU\n // immediately before each draw.\n this.display = this.current;\n this.activeSplats = this.current.numSplats;\n this.maxSplats = requiredMaxSplats;\n this.sortDirty = false;\n this.syncStochasticFrame();\n if (\n shrinkResources ||\n viewChanged ||\n previousVersion !== this.current.version\n ) {\n this.setDirty();\n }\n return Promise.resolve();\n }\n\n const pending = this.queuedUpdate;\n const shrinkResources =\n request.shrinkResources || (pending?.shrinkResources ?? false);\n this.queuedUpdate = {\n scene: request.scene,\n camera: request.camera,\n shrinkResources,\n };\n\n if (!this.updateRunning) {\n this.updateRunning = true;\n this.updatePromise = this.drainUpdates();\n }\n return this.updatePromise;\n }\n\n private async drainUpdates() {\n try {\n while (this.queuedUpdate) {\n const request = this.queuedUpdate;\n this.queuedUpdate = null;\n await this.performUpdate(request);\n }\n } finally {\n this.queuedUpdate = null;\n this.updateRunning = false;\n }\n }\n\n private async performUpdate({\n scene,\n camera: updateCamera,\n shrinkResources,\n }: UpdateRequest) {\n const next = this.takeAccumulator();\n\n const renderer = this.renderer;\n if (scene.matrixWorldAutoUpdate) scene.updateMatrixWorld();\n if (!(updateCamera as THREE.ArrayCamera).isArrayCamera)\n updateCamera.updateWorldMatrix(true, false);\n if (this.ownsTimer) {\n this.timer.update();\n }\n\n // Read the mode when the update runs; queued requests may predate a switch.\n const mode: SortMode = !this._stochastic\n ? \"back\"\n : this.stochasticSort\n ? \"front\"\n : \"identity\";\n // One viewpoint generates and sorts: the camera, or the WebXR head.\n const camera = this.getGenerationCamera(updateCamera);\n const center = new THREE.Vector3().setFromMatrixPosition(\n camera.matrixWorld,\n );\n const direction = new THREE.Vector3()\n .setFromMatrixColumn(camera.matrixWorld, 2)\n .normalize()\n .negate();\n const moveTolerance =\n 0.001 * getCameraWorldScale(getViews(updateCamera)[0]);\n const viewChanged =\n mode !== this.sortedMode ||\n (mode === \"back\" &&\n (this.sortRadial !== this.sortedRadial ||\n this.fastSort !== this.sortedFastSort)) ||\n center.distanceTo(this.sortedCenter) > moveTolerance ||\n (mode !== \"identity\" &&\n (mode === \"front\" || !this.sortRadial) &&\n direction.dot(this.sortedDir) < 0.999);\n\n const previousVersion = this.current.version;\n let preparation: ReturnType<SplatAccumulator[\"prepareGenerate\"]>;\n try {\n preparation = next.prepareGenerate({\n renderer,\n scene,\n timer: this.timer,\n camera,\n layerCamera: updateCamera,\n previous: this.current,\n });\n } catch (error) {\n this.releaseAccumulator(next);\n throw error;\n }\n const { version, sortUpdated, requiredMaxSplats, generate } = preparation;\n const orderingNeedsShrink =\n shrinkResources &&\n this.backend.getOrderingCapacity(requiredMaxSplats) < this.maxSplats;\n const doUpdate =\n shrinkResources ||\n mode !== this.sortedMode ||\n center.distanceTo(this.current.viewOrigin) > moveTolerance ||\n version !== previousVersion;\n const needsSort = orderingNeedsShrink || viewChanged || sortUpdated;\n // Unsorted stochastic draws read source indices directly.\n const skipSort = mode === \"identity\";\n\n if (!doUpdate) {\n this.current.viewDirection.copy(direction);\n this.sortDirty ||= needsSort;\n this.releaseAccumulator(next);\n } else {\n try {\n generate(shrinkResources, mode !== \"back\");\n } catch (error) {\n this.releaseAccumulator(next);\n throw error;\n }\n\n if (sortUpdated) {\n this.sortStateRevision += 1;\n }\n\n if (skipSort) {\n this.releaseAccumulator(this.display);\n if (this.current !== this.display) {\n this.releaseAccumulator(this.current);\n }\n // The stochastic shader reads identity indices, so the latest generated\n // accumulator is immediately displayable without a matching ordering.\n this.display = next;\n } else if (\n this.display.mappingVersion === next.mappingVersion &&\n !needsSort\n ) {\n // Appearance-only update: the mapping and existing sort order are\n // still valid, so display the new accumulator immediately.\n this.releaseAccumulator(this.display);\n this.display = next;\n } else {\n if (this.display !== this.current) {\n // The previous current is not being displayed, so replace it\n this.releaseAccumulator(this.current);\n }\n }\n\n this.current = next;\n // Appearance-only updates can reuse the current ordering. Preserve an\n // already pending sort, but do not enqueue a new one unless depth or the\n // mapping may have changed.\n this.sortDirty ||= needsSort;\n this.setDirty();\n }\n\n if (skipSort) {\n // No ordering matches the displayed accumulator. Record the view it\n // was generated for, so later frames compare against it as they do\n // against a sort and only real view or mode changes regenerate it.\n this.sortDirty = false;\n this.activeSplats = this.display.numSplats;\n this.orderingReady = false;\n if (doUpdate) {\n this.sortedMode = mode;\n this.sortedCenter.copy(center);\n this.sortedDir.copy(direction);\n }\n if (shrinkResources) {\n this.releaseOrdering();\n this.disposeOversizedAccumulators(this.current.maxSplats);\n }\n this.syncStochasticFrame();\n return;\n }\n\n await this.driveSort(\n orderingNeedsShrink,\n // Switch modes without waiting for the sort interval.\n shrinkResources || this.stochasticFrame !== this._stochastic,\n mode,\n );\n\n this.syncStochasticFrame();\n if (shrinkResources) {\n this.disposeOversizedAccumulators(this.current.maxSplats);\n }\n }\n\n /**\n * Viewpoint for generation, spherical harmonics, the render origin and\n * sorting: the camera, or for WebXR eyes their mean pose, the shared head.\n */\n private getGenerationCamera(camera: THREE.Camera) {\n const views = getViews(camera);\n if (views.length < 2 || !isXRCamera(camera, this.renderer)) return views[0];\n const position = headPositionTmp;\n const target = headTargetTmp;\n getMeanViewPose(views, position, target);\n target.add(position);\n const head = this.headCamera;\n head.matrixAutoUpdate = false;\n head.matrix\n .lookAt(\n position,\n target,\n renderToViewScaleTmp.setFromMatrixColumn(views[0].matrixWorld, 1),\n )\n .setPosition(position);\n head.updateMatrixWorld(true);\n return head;\n }\n\n private async driveSort(\n shrinkOrdering: boolean,\n forceSort: boolean,\n mode: SortMode,\n ) {\n // WebGL updates await each sort before draining the next queued update.\n if (this.disposed || this.backend.kind === \"webgpu\" || !this.sortDirty)\n return;\n\n const now = performance.now();\n const nextSortTime = this.lastSortTime\n ? this.lastSortTime + this.minSortIntervalMs\n : now;\n\n this.sorting = true;\n this.sortDirty = false;\n this.lastSortTime = performance.now();\n const current = this.current;\n const previousActiveSplats = this.activeSplats;\n\n try {\n const sortRadial = this.sortRadial;\n const fastSort = this.fastSort;\n if (shrinkOrdering || this.sortWorker?.disposed) this.resetSortWorker();\n this.sortWorker ??= new SplatWorker();\n const sortWorker = this.sortWorker;\n\n const { numSplats, maxSplats } = current;\n const orderingMaxSplats = this.backend.getOrderingCapacity(maxSplats);\n this.maxSplats = shrinkOrdering\n ? orderingMaxSplats\n : Math.max(this.maxSplats, orderingMaxSplats);\n\n if (this.orderingBuffer.length !== this.maxSplats) {\n this.orderingBuffer = new Uint32Array(this.maxSplats);\n }\n\n const stateRevision = this.sortStateRevision;\n const stateUpdate =\n this.uploadedSortStateRevision !== stateRevision\n ? this.sortCenterCache.prepare(current)\n : undefined;\n const cameraPosition = current.viewOrigin.toArray() as [\n number,\n number,\n number,\n ];\n const direction = current.viewDirection.toArray() as [\n number,\n number,\n number,\n ];\n if (!forceSort && now < nextSortTime) {\n await new Promise((resolve) => setTimeout(resolve, nextSortTime - now));\n if (this.disposed) return;\n }\n this.lastSortTime = performance.now();\n if (stateUpdate) {\n const { payload, commit } = stateUpdate;\n await sortWorker.call(\"setSortCenterState\", payload);\n if (this.disposed) return;\n commit();\n this.uploadedSortStateRevision = stateRevision;\n }\n\n // Every view, including both WebXR eyes, draws this one order.\n const { ordering, activeSplats } = await sortWorker.call(\n \"sortCenters32\",\n {\n numSplats,\n cameraPosition,\n direction,\n radial: sortRadial,\n fastSort,\n frontSort: mode !== \"back\",\n ordering: this.orderingBuffer,\n },\n );\n if (this.disposed) return;\n\n this.activeSplats = activeSplats;\n const previousOrdering = this.backend.cpuOrdering;\n this.backend.setCPUOrdering({\n ordering,\n activeSplats,\n requiredCapacity: this.maxSplats,\n shrink: shrinkOrdering,\n });\n\n // Keep the displayed texture's CPU source attached while transferring\n // the other buffer to the worker for the next sort.\n this.orderingBuffer =\n previousOrdering?.length === this.maxSplats\n ? previousOrdering\n : new Uint32Array(this.maxSplats);\n\n this.sortedCenter.fromArray(cameraPosition);\n this.sortedDir.fromArray(direction);\n this.sortedRadial = sortRadial;\n this.sortedFastSort = fastSort;\n this.sortedMode = mode;\n this.orderingReady = true;\n if (this.display !== current) {\n this.releaseAccumulator(this.display);\n this.display = current;\n }\n this.setDirty();\n } catch (error) {\n if (this.disposed) return;\n this.sortDirty = true;\n if (current !== this.display && this.accumulators.length === 0) {\n // A candidate waiting on a new ordering cannot be displayed. Roll back\n // to the still-valid display accumulator and free the failed one.\n this.current = this.display;\n this.releaseAccumulator(current);\n this.activeSplats = previousActiveSplats;\n this.sortDirty = false;\n this.uploadedSortStateRevision = -1;\n }\n throw error;\n } finally {\n this.sorting = false;\n }\n }\n\n get premultipliedAlpha(): boolean {\n return this._premultipliedAlpha;\n }\n\n set premultipliedAlpha(value: boolean) {\n const nextValue = Boolean(value);\n if (this._premultipliedAlpha !== nextValue) {\n this._premultipliedAlpha = nextValue;\n this.applyMaterialState(this.stochasticFrame);\n }\n }\n\n get transparent(): boolean {\n return this._transparent;\n }\n\n set transparent(value: boolean) {\n const nextValue = Boolean(value);\n if (this._transparent !== nextValue) {\n this._transparent = nextValue;\n this.applyMaterialState(this.stochasticFrame);\n }\n }\n\n get fastSort(): boolean {\n return this._fastSort;\n }\n\n set fastSort(value: boolean) {\n const nextValue = Boolean(value);\n if (nextValue === this._fastSort) return;\n this._fastSort = nextValue;\n // Stochastic orderings sort front to back and ignore it.\n if (!this._stochastic && this.backend.kind !== \"webgpu\") {\n this.sortDirty = true;\n }\n this.setDirty();\n }\n\n get stochasticSort(): boolean {\n return this._stochasticSort;\n }\n\n set stochasticSort(value: boolean) {\n const nextValue = Boolean(value);\n if (nextValue === this._stochasticSort) return;\n this._stochasticSort = nextValue;\n if (this._stochastic && this.backend.kind !== \"webgpu\") {\n this.sortDirty = true;\n }\n this.setDirty();\n }\n\n get stochastic(): boolean {\n return this._stochastic;\n }\n\n /**\n * Whether Splats currently draw stochastically. It follows `stochastic`\n * once an update for the new mode is displayed.\n */\n get stochasticActive(): boolean {\n return this.stochasticFrame;\n }\n\n set stochastic(value: boolean) {\n const nextValue = Boolean(value);\n if (nextValue === this._stochastic) return;\n this._stochastic = nextValue;\n if (this.display.numSplats === 0) this.syncStochasticFrame();\n this.sortDirty = true;\n this.setDirty();\n }\n\n get depthTest(): boolean {\n return this._depthTest;\n }\n\n set depthTest(value: boolean) {\n this._depthTest = Boolean(value);\n this.applyMaterialState(this.stochasticFrame);\n }\n\n get depthWrite(): boolean {\n return this._depthWrite;\n }\n\n set depthWrite(value: boolean) {\n this._depthWrite = Boolean(value);\n this.applyMaterialState(this.stochasticFrame);\n }\n}\n\nfunction isOpaqueMaterial(material: THREE.Material) {\n return (\n material.transparent === false &&\n material.blending === THREE.NormalBlending &&\n material.alphaToCoverage === false\n );\n}\n","import {\n Color,\n ColorManagement,\n DepthTexture,\n FloatType,\n GLSL3,\n HalfFloatType,\n type Matrix4,\n NoBlending,\n NoToneMapping,\n type OrthographicCamera,\n type PerspectiveCamera,\n type Scene,\n ShaderMaterial,\n type ToneMapping,\n Vector2,\n WebGLRenderTarget,\n type WebGLRenderer,\n} from \"three\";\nimport { FullScreenQuad, Pass } from \"three/addons/postprocessing/Pass.js\";\nimport { createTAAState } from \"./taaShared\";\n\nconst vertexShader = /* glsl */ `\nout vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = vec4(position.xy, 0.0, 1.0);\n}\n`;\n\n// TRAANode's resolve, with camera/depth reprojection in place of velocity.\nconst fragmentShader = /* glsl */ `\nprecision highp float;\nprecision highp int;\nuniform sampler2D source;\nuniform sampler2D sourceDepth;\nuniform sampler2D history;\nuniform sampler2D historyDepth;\nuniform vec2 renderSize;\nuniform mat4 projection;\nuniform mat4 unjitteredProjection;\nuniform mat4 previousProjection;\nuniform mat4 viewToPreviousClip;\nuniform mat4 previousViewToView;\nuniform bool valid;\nuniform bool reversed;\nuniform bool logarithmic;\nuniform vec2 logFar;\nuniform float depthThreshold;\nuniform float edgeDepthDiff;\nuniform float maxMotionLength;\nuniform bool useSubpixelCorrection;\nuniform vec3 luminanceCoefficients;\nin vec2 vUv;\nout vec4 fragColor;\n\nivec2 bounded(ivec2 p) {\n return clamp(p, ivec2(0), ivec2(renderSize) - 1);\n}\n\n// Homogeneous view coordinates retain far-depth precision and avoid a\n// world-space round trip.\nvec4 viewPosition(vec2 uv, float depth, mat4 p, float logFarValue) {\n float z = reversed ? depth : depth * 2.0 - 1.0;\n float orientation = reversed ? -1.0 : 1.0;\n float viewZ = (p[3][2] - z * p[3][3]) * orientation;\n float viewW = (z * p[2][3] - p[2][2]) * orientation;\n if (logarithmic) {\n viewZ = 1.0 - exp2(depth * logFarValue);\n viewW = 1.0;\n }\n float clipW = p[2][3] * viewZ + p[3][3] * viewW;\n vec2 viewXY = ((uv * 2.0 - 1.0) * clipW - p[2].xy * viewZ\n - p[3].xy * viewW) / vec2(p[0][0], p[1][1]);\n return vec4(viewXY, viewZ, viewW);\n}\n\nfloat forwardDepth(vec4 positionView) {\n vec4 clip = projection * positionView;\n float depth = clip.z / clip.w;\n return reversed ? 1.0 - depth : depth * 0.5 + 0.5;\n}\n\nvec4 clipAABB(vec4 center, vec4 historyColor, vec4 extent) {\n vec4 delta = historyColor - center;\n vec3 unit = abs(delta.rgb / (extent.rgb + 1e-7));\n float maxUnit = max(unit.r, max(unit.g, unit.b));\n return maxUnit > 1.0 ? center + delta / maxUnit : historyColor;\n}\n\nvec4 flickerReduction(vec4 currentColor, vec4 historyColor, float currentWeight) {\n vec3 compressedCurrent = currentColor.rgb / (max(currentColor.r, max(currentColor.g, currentColor.b)) + 1.0);\n vec3 compressedHistory = historyColor.rgb / (max(historyColor.r, max(historyColor.g, historyColor.b)) + 1.0);\n float weightCurrent = currentWeight / (dot(compressedCurrent, luminanceCoefficients) + 1.0);\n float weightHistory = (1.0 - currentWeight) / (dot(compressedHistory, luminanceCoefficients) + 1.0);\n return (currentColor * weightCurrent + historyColor * weightHistory)\n / max(weightCurrent + weightHistory, 0.00001);\n}\n\nvoid main() {\n ivec2 pixel = ivec2(gl_FragCoord.xy);\n vec4 currentColor = texelFetch(source, pixel, 0);\n fragColor = currentColor;\n gl_FragDepth = texelFetch(sourceDepth, pixel, 0).r;\n if (!valid) return;\n\n float closestDepth = 2.0;\n float farthestDepth = -1.0;\n float closestRawDepth = gl_FragDepth;\n ivec2 closestPixel = pixel;\n vec4 moment1 = currentColor;\n vec4 moment2 = currentColor * currentColor;\n for (int x = -1; x <= 1; ++x) {\n for (int y = -1; y <= 1; ++y) {\n ivec2 p = bounded(pixel + ivec2(x, y));\n float rawDepth = texelFetch(sourceDepth, p, 0).r;\n float depth = reversed && !logarithmic ? 1.0 - rawDepth : rawDepth;\n if (depth < closestDepth) {\n closestDepth = depth;\n closestRawDepth = rawDepth;\n closestPixel = p;\n }\n farthestDepth = max(farthestDepth, depth);\n if (x != 0 || y != 0) {\n vec4 neighbor = max(texelFetch(source, p, 0), vec4(0.0));\n moment1 += neighbor;\n moment2 += neighbor * neighbor;\n }\n }\n }\n\n vec2 closestUV = (vec2(closestPixel) + 0.5) / renderSize;\n vec4 positionView = viewPosition(closestUV, closestRawDepth, projection, logFar.x);\n vec4 previousClip = viewToPreviousClip * positionView;\n if (previousClip.w <= 0.0) return;\n vec4 currentClip = unjitteredProjection * positionView;\n // Exclude projection jitter from camera motion.\n vec2 offsetUV = (currentClip.xy / currentClip.w - previousClip.xy / previousClip.w) * 0.5;\n vec2 historyUV = vUv - offsetUV;\n if (any(lessThan(historyUV, vec2(0.0))) || any(greaterThanEqual(historyUV, vec2(1.0)))) return;\n\n float oldDepth = texture(historyDepth, historyUV).r;\n vec4 previousView = viewPosition(historyUV, oldDepth, previousProjection, logFar.y);\n float previousDepth = forwardDepth(previousViewToView * previousView);\n if (logarithmic) {\n // Log depth is monotonic; convert only the extrema for depth thresholds.\n closestDepth = forwardDepth(positionView);\n float farthestZ = 1.0 - exp2(farthestDepth * logFar.x);\n farthestDepth = forwardDepth(vec4(0.0, 0.0, farthestZ, 1.0));\n }\n bool isEdge = farthestDepth - closestDepth > edgeDepthDiff;\n bool isDisocclusion = closestDepth - previousDepth > depthThreshold;\n if (!isEdge && isDisocclusion) return;\n\n float motionFactor = clamp(length(offsetUV * renderSize) / maxMotionLength, 0.0, 1.0);\n float currentWeight = 0.05;\n if (useSubpixelCorrection) {\n vec2 phase = fract(offsetUV * renderSize);\n vec2 weight = max(phase, 1.0 - phase);\n currentWeight += (1.0 - weight.x * weight.y) / 0.75 * 0.25;\n }\n currentWeight = clamp(currentWeight + motionFactor, 0.0, 1.0);\n float gamma = mix(0.5, 1.0, pow(1.0 - motionFactor, 2.0));\n vec4 mean = moment1 / 9.0;\n vec4 extent = sqrt(max(moment2 / 9.0 - mean * mean, vec4(0.0))) * gamma;\n vec4 historyColor = clipAABB(mean, texture(history, historyUV), extent);\n fragColor = flickerReduction(currentColor, historyColor, currentWeight);\n}\n`;\n\nfunction makeTarget(name: string) {\n const target = new WebGLRenderTarget(1, 1, {\n type: HalfFloatType,\n depthTexture: new DepthTexture(1, 1, FloatType),\n });\n target.texture.name = name;\n return target;\n}\n\n/**\n * Temporal reprojection for WebGLRenderer, using depth and camera motion.\n * Object motion is not tracked; no velocity texture is required.\n * Owns scene capture, camera jitter, and history. By default it blends and\n * accumulates in the output color space, like direct canvas rendering, and\n * presents the result without OutputPass.\n */\nexport class TAAPass extends Pass {\n /** Depth difference above which non-edge history is rejected. */\n depthThreshold = 0.0005;\n /** Depth range within the 3x3 neighborhood that identifies an edge. */\n edgeDepthDiff = 0.001;\n /** Camera motion in pixels at which history loses all weight. */\n maxMotionLength = 128;\n /** Increase current-frame weight for subpixel camera motion. */\n useSubpixelCorrection = true;\n /**\n * Capture and accumulate in the renderer's output color space, ready for\n * presentation. Set false to stay in the working color space for linear\n * effects, followed by OutputPass.\n */\n accumulateInOutputSpace = true;\n\n // Three uses this flag to honor the target's output color space for both\n // ordinary materials and splats, matching direct canvas blending.\n private readonly _source = Object.assign(makeTarget(\"TAAPass.scene\"), {\n isXRRenderTarget: false,\n });\n private readonly _history = [\n makeTarget(\"TAAPass.history0\"),\n makeTarget(\"TAAPass.history1\"),\n ];\n private readonly _size = new Vector2();\n private readonly _clearColor = new Color();\n private readonly _state = createTAAState(\n <T>(value: T) => ({ value }),\n [this._source, ...this._history],\n );\n private _workingColorSpace = ColorManagement.workingColorSpace;\n private _toneMapping: ToneMapping = NoToneMapping;\n private _toneMappingExposure = 1;\n private readonly _uniforms;\n private readonly _resolveMaterial: ShaderMaterial;\n private readonly _copyMaterial: ShaderMaterial;\n private readonly _quad: FullScreenQuad;\n\n constructor(\n public scene: Scene,\n public camera: PerspectiveCamera | OrthographicCamera,\n ) {\n super();\n\n this._uniforms = {\n source: { value: this._source.texture },\n sourceDepth: { value: this._source.depthTexture },\n history: { value: this._history[0].texture },\n historyDepth: { value: this._history[0].depthTexture },\n ...this._state.uniforms,\n };\n this._resolveMaterial = new ShaderMaterial({\n name: \"TAAPass.resolve\",\n uniforms: this._uniforms,\n vertexShader,\n fragmentShader,\n glslVersion: GLSL3,\n blending: NoBlending,\n depthTest: true,\n depthWrite: true,\n toneMapped: false,\n });\n this._copyMaterial = new ShaderMaterial({\n name: \"TAAPass.copy\",\n uniforms: { source: { value: null } },\n vertexShader,\n fragmentShader: /* glsl */ `\n uniform sampler2D source;\n in vec2 vUv;\n out vec4 fragColor;\n void main() { fragColor = texture(source, vUv); }\n `,\n glslVersion: GLSL3,\n blending: NoBlending,\n depthTest: false,\n depthWrite: false,\n toneMapped: false,\n });\n this._quad = new FullScreenQuad(this._resolveMaterial);\n }\n\n /** Current scene depth, before temporal accumulation. Owned by this pass. */\n get depthTexture(): DepthTexture {\n return this._source.depthTexture as DepthTexture;\n }\n\n /** Jittered projection used to capture depthTexture. Treat as read-only. */\n get projectionMatrix(): Matrix4 {\n return this._uniforms.projection.value;\n }\n\n /** Resize all internal targets in physical pixels; a size change clears history. */\n override setSize(width: number, height: number): void {\n this._state.setSize(width, height);\n }\n\n /** Discard history after a camera cut, scene replacement, or color-space change. */\n reset(): void {\n this._state.reset();\n }\n\n /** Render the scene and TAA to the canvas, a target, or the composer's buffer. */\n override render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget | null = null,\n ): void {\n const { camera, _state: state, _uniforms: uniforms } = this;\n if (writeBuffer) {\n this.setSize(writeBuffer.width, writeBuffer.height);\n } else {\n renderer.getDrawingBufferSize(this._size);\n this.setSize(this._size.x, this._size.y);\n }\n const workingColorSpace = ColorManagement.workingColorSpace;\n const colorSpace = this.accumulateInOutputSpace\n ? renderer.outputColorSpace\n : workingColorSpace;\n // Only transforms applied during capture affect accumulated history.\n const toneMapping = this.accumulateInOutputSpace\n ? renderer.toneMapping\n : NoToneMapping;\n const exposure =\n toneMapping === NoToneMapping ? 1 : renderer.toneMappingExposure;\n if (\n this._source.texture.colorSpace !== colorSpace ||\n this._source.isXRRenderTarget !== this.accumulateInOutputSpace ||\n this._workingColorSpace !== workingColorSpace ||\n this._toneMapping !== toneMapping ||\n this._toneMappingExposure !== exposure\n ) {\n this._source.texture.colorSpace = colorSpace;\n this._source.isXRRenderTarget = this.accumulateInOutputSpace;\n this._workingColorSpace = workingColorSpace;\n this._toneMapping = toneMapping;\n this._toneMappingExposure = exposure;\n this.reset();\n }\n const previousTarget = renderer.getRenderTarget();\n const autoClear = renderer.autoClear;\n const xrEnabled = renderer.xr.enabled;\n try {\n renderer.xr.enabled = false;\n renderer.autoClear = false;\n const reversedDepth = camera.reversedDepth;\n state.beginCapture(camera);\n try {\n renderer.setRenderTarget(this._source);\n // Refresh the clear color in the capture target's color space.\n renderer.setClearColor(\n renderer.getClearColor(this._clearColor),\n renderer.getClearAlpha(),\n );\n renderer.clear();\n renderer.render(this.scene, camera);\n } finally {\n state.endCapture(camera);\n // Three may initialize reversed depth during the first draw. Keep its\n // new depth convention when restoring the unjittered projection.\n if (camera.reversedDepth !== reversedDepth)\n camera.updateProjectionMatrix();\n }\n\n const input = this._history[state.historyIndex];\n const output = this._history[1 - state.historyIndex];\n if (!uniforms.valid.value) {\n // Allocate depth attachments before either is bound as a sampler.\n for (const target of this._history) renderer.initRenderTarget(target);\n }\n uniforms.history.value = input.texture;\n uniforms.historyDepth.value = input.depthTexture;\n uniforms.reversed.value = renderer.capabilities.reversedDepthBuffer;\n uniforms.logarithmic.value =\n renderer.capabilities.logarithmicDepthBuffer &&\n \"isPerspectiveCamera\" in camera &&\n camera.isPerspectiveCamera;\n this._resolveMaterial.depthFunc = state.prepareResolve(camera, this);\n renderer.setRenderTarget(output);\n this._quad.material = this._resolveMaterial;\n this._quad.render(renderer);\n\n this._copyMaterial.uniforms.source.value = output.texture;\n renderer.setRenderTarget(this.renderToScreen ? null : writeBuffer);\n this._quad.material = this._copyMaterial;\n this._quad.render(renderer);\n\n state.advance(camera);\n } finally {\n renderer.setRenderTarget(previousTarget);\n renderer.autoClear = autoClear;\n renderer.xr.enabled = xrEnabled;\n }\n }\n\n override dispose(): void {\n this._source.dispose();\n for (const target of this._history) target.dispose();\n this._resolveMaterial.dispose();\n this._copyMaterial.dispose();\n this._quad.dispose();\n }\n}\n","import {\n ColorManagement,\n DepthTexture,\n FloatType,\n HalfFloatType,\n type Matrix4,\n NoBlending,\n type OrthographicCamera,\n type PerspectiveCamera,\n type Scene,\n type Texture,\n Vector2,\n type Vector3,\n WebGLCoordinateSystem,\n} from \"three\";\nimport {\n type Node,\n type NodeBuilder,\n type NodeFrame,\n NodeMaterial,\n NodeUpdateType,\n QuadMesh,\n RenderTarget,\n RendererUtils,\n TempNode,\n type TextureNode,\n type UniformNode,\n type WebGPURenderer,\n} from \"three/webgpu\";\nimport { N } from \"../rendering/tsl/tslCompat\";\nimport { createTAAState } from \"./taaShared\";\n\n/** Camera/depth TAA for WebGPURenderer, including its WebGL2 fallback. */\nexport class TAANode extends TempNode<\"vec4\"> {\n static get type() {\n return \"TAANode\";\n }\n\n depthThreshold = 0.0005;\n edgeDepthDiff = 0.001;\n maxMotionLength = 128;\n useSubpixelCorrection = true;\n\n private readonly source = this.makeTarget(\"TAA.scene\");\n private readonly history = [\n this.makeTarget(\"TAA.history0\"),\n this.makeTarget(\"TAA.history1\"),\n ];\n private readonly textureNode = (\n N.passTexture as unknown as (pass: TAANode, texture: Texture) => TextureNode\n )(this, this.history[0].texture);\n private readonly material = new NodeMaterial();\n private readonly quad = new QuadMesh(this.material);\n private readonly state = createTAAState<\n UniformNode<\"float\", number>,\n UniformNode<\"bool\", boolean>,\n UniformNode<\"vec2\", Vector2>,\n UniformNode<\"vec3\", Vector3>,\n UniformNode<\"mat4\", Matrix4>\n >(N.uniform, [this.source, ...this.history]);\n private readonly zeroToOne = N.uniform(true);\n private readonly drawingSize = new Vector2();\n private workingColorSpace = ColorManagement.workingColorSpace;\n private readonly pipelineStates = new WeakSet<object>();\n private pipelineRendering = false;\n private capturePending = true;\n\n constructor(\n public scene: Scene,\n public camera: PerspectiveCamera | OrthographicCamera,\n ) {\n super(\"vec4\");\n this.updateBeforeType = NodeUpdateType.RENDER;\n this.material.name = \"TAA.resolve\";\n this.material.blending = NoBlending;\n this.material.depthTest = true;\n this.material.depthWrite = true;\n this.material.toneMapped = false;\n this.quad.name = \"TAA.resolve\";\n }\n\n private makeTarget(name: string) {\n const target = new RenderTarget(1, 1, {\n type: HalfFloatType,\n depthTexture: new DepthTexture(1, 1, FloatType),\n samples: 0,\n });\n target.texture.name = name;\n return target as RenderTarget & { depthTexture: DepthTexture };\n }\n\n get depthTexture(): DepthTexture {\n return this.source.depthTexture;\n }\n\n get projectionMatrix(): Matrix4 {\n return this.state.uniforms.projection.value;\n }\n\n getTextureNode() {\n return this.textureNode;\n }\n\n setSize(width: number, height: number) {\n this.state.setSize(width, height);\n }\n\n reset() {\n this.state.reset();\n }\n\n override updateBefore(frame: NodeFrame) {\n if (this.pipelineRendering && !this.capturePending) return;\n const renderer = frame.renderer as WebGPURenderer;\n if (this.workingColorSpace !== ColorManagement.workingColorSpace) {\n this.workingColorSpace = ColorManagement.workingColorSpace;\n this.reset();\n }\n const rendererState = RendererUtils.saveRendererState(renderer);\n const xrEnabled = renderer.xr.enabled;\n const { camera, state } = this;\n const { uniforms } = state;\n if (this.pipelineRendering) {\n this.setSize(this.drawingSize.x, this.drawingSize.y);\n } else if (rendererState.renderTarget) {\n this.setSize(\n rendererState.renderTarget.width,\n rendererState.renderTarget.height,\n );\n } else {\n renderer.getDrawingBufferSize(this.drawingSize);\n this.setSize(this.drawingSize.x, this.drawingSize.y);\n }\n try {\n renderer.xr.enabled = false;\n renderer.setMRT(null);\n renderer.setScissorTest(false);\n renderer.autoClear = true;\n const reversedDepth = camera.reversedDepth;\n const coordinateSystem = camera.coordinateSystem;\n state.beginCapture(camera);\n try {\n renderer.setRenderTarget(this.source);\n renderer.render(this.scene, camera);\n } finally {\n state.endCapture(camera);\n // Three may initialize the camera's depth convention on its first draw.\n if (\n camera.reversedDepth !== reversedDepth ||\n camera.coordinateSystem !== coordinateSystem\n )\n camera.updateProjectionMatrix();\n }\n uniforms.reversed.value = renderer.reversedDepthBuffer;\n this.zeroToOne.value =\n renderer.coordinateSystem !== WebGLCoordinateSystem ||\n renderer.reversedDepthBuffer;\n uniforms.logarithmic.value =\n renderer.logarithmicDepthBuffer &&\n \"isPerspectiveCamera\" in camera &&\n camera.isPerspectiveCamera;\n this.material.depthFunc = state.prepareResolve(camera, this);\n if (!uniforms.valid.value)\n for (const target of this.history) renderer.initRenderTarget(target);\n const output = this.history[1 - state.historyIndex];\n renderer.setRenderObjectFunction(null);\n renderer.setRenderTarget(output);\n this.quad.render(renderer);\n this.textureNode.value = output.texture;\n state.advance(camera);\n this.capturePending = false;\n } finally {\n RendererUtils.restoreRendererState(renderer, rendererState);\n renderer.xr.enabled = xrEnabled;\n }\n return undefined;\n }\n\n override setup(builder: NodeBuilder) {\n const pipelineState = (builder.context as { renderPipelineState?: object })\n .renderPipelineState;\n if (pipelineState && !this.pipelineStates.has(pipelineState)) {\n this.pipelineStates.add(pipelineState);\n const begin = () => {\n this.pipelineRendering = true;\n this.capturePending = true;\n const renderer = builder.renderer;\n const target =\n renderer.getRenderTarget() ?? renderer.getOutputRenderTarget();\n if (target) this.drawingSize.set(target.width, target.height);\n else renderer.getDrawingBufferSize(this.drawingSize);\n };\n // The first pipeline render builds its callbacks after the before phase.\n begin();\n N.OnBeforeRenderPipeline(begin);\n N.OnAfterRenderPipeline(() => {\n this.pipelineRendering = false;\n });\n }\n const u = this.state.uniforms;\n const source = N.texture(this.source.texture);\n const sourceDepth = N.texture(this.depthTexture);\n const history = N.texture(this.history[0].texture).onObjectUpdate(\n () => this.history[this.state.historyIndex].texture,\n );\n const historyDepth = N.texture(this.history[0].depthTexture).onObjectUpdate(\n () => this.history[this.state.historyIndex].depthTexture,\n );\n const bounded = (p: Node<\"ivec2\">) =>\n p.clamp(N.ivec2(0), N.ivec2(u.renderSize).sub(1));\n // TSL texture coordinates have a top-left origin on both backends.\n const viewPosition = (\n uv: Node<\"vec2\">,\n depth: Node<\"float\">,\n p: Node<\"mat4\">,\n far: Node<\"float\">,\n ) => {\n const z = N.select(this.zeroToOne, depth, depth.mul(2).sub(1));\n const orientation = N.select(u.reversed, -1, 1);\n const viewZ = p\n .element(3)\n .z.sub(z.mul(p.element(3).w))\n .mul(orientation)\n .toVar();\n const viewW = z\n .mul(p.element(2).w)\n .sub(p.element(2).z)\n .mul(orientation)\n .toVar();\n N.If(u.logarithmic, () => {\n viewZ.assign(N.float(1).sub(depth.mul(far).exp2()));\n viewW.assign(1);\n });\n const clipW = p.element(2).w.mul(viewZ).add(p.element(3).w.mul(viewW));\n const xy = uv\n .mul(2)\n .sub(1)\n .mul(N.vec2(1, -1))\n .mul(clipW)\n .sub(p.element(2).xy.mul(viewZ))\n .sub(p.element(3).xy.mul(viewW))\n .div(N.vec2(p.element(0).x, p.element(1).y));\n return N.vec4(xy, viewZ, viewW);\n };\n const forwardDepth = (position: Node<\"vec4\">) => {\n const clip = u.projection.mul(position).toVar();\n const depth = clip.z.div(clip.w);\n return N.select(\n u.reversed,\n N.float(1).sub(depth),\n N.select(this.zeroToOne, depth, depth.mul(0.5).add(0.5)),\n );\n };\n const pixel = N.ivec2(N.screenCoordinate.xy);\n this.material.depthNode = sourceDepth.load(pixel).r;\n this.material.colorNode = N.Fn(() => {\n const currentColor = source.load(pixel).toVar();\n const result = currentColor.toVar();\n N.If(u.valid, () => {\n const closestDepth = N.float(2).toVar();\n const farthestDepth = N.float(-1).toVar();\n const closestRawDepth = sourceDepth.load(pixel).r.toVar();\n const closestPixel = pixel.toVar();\n const moment1 = currentColor.toVar();\n const moment2 = currentColor.mul(currentColor).toVar();\n for (let x = -1; x <= 1; x++) {\n for (let y = -1; y <= 1; y++) {\n const p = bounded(pixel.add(N.ivec2(x, y))).toVar();\n const rawDepth = sourceDepth.load(p).r.toVar();\n const depth = N.select(\n u.reversed.and(u.logarithmic.not()),\n N.float(1).sub(rawDepth),\n rawDepth,\n ).toVar();\n N.If(depth.lessThan(closestDepth), () => {\n closestDepth.assign(depth);\n closestRawDepth.assign(rawDepth);\n closestPixel.assign(p);\n });\n farthestDepth.assign(farthestDepth.max(depth));\n if (x !== 0 || y !== 0) {\n const neighbor = source.load(p).max(0).toVar();\n moment1.addAssign(neighbor);\n moment2.addAssign(neighbor.mul(neighbor));\n }\n }\n }\n const closestUV = N.vec2(closestPixel).add(0.5).div(u.renderSize);\n const positionView = viewPosition(\n closestUV,\n closestRawDepth,\n u.projection,\n u.logFar.x,\n );\n const previousClip = u.viewToPreviousClip.mul(positionView).toVar();\n N.If(previousClip.w.greaterThan(0), () => {\n const currentClip = u.unjitteredProjection.mul(positionView).toVar();\n const offsetUV = currentClip.xy\n .div(currentClip.w)\n .sub(previousClip.xy.div(previousClip.w))\n .mul(N.vec2(0.5, -0.5))\n .toVar();\n const historyUV = N.screenUV.sub(offsetUV).toVar();\n N.If(\n historyUV\n .greaterThanEqual(0)\n .all()\n .and(historyUV.lessThan(1).all()),\n () => {\n const oldDepth = historyDepth.sample(historyUV).r;\n const previousView = viewPosition(\n historyUV,\n oldDepth,\n u.previousProjection,\n u.logFar.y,\n );\n const previousDepth = forwardDepth(\n u.previousViewToView.mul(previousView),\n );\n N.If(u.logarithmic, () => {\n closestDepth.assign(forwardDepth(positionView));\n const farthestZ = N.float(1).sub(\n farthestDepth.mul(u.logFar.x).exp2(),\n );\n farthestDepth.assign(forwardDepth(N.vec4(0, 0, farthestZ, 1)));\n });\n const isEdge = farthestDepth\n .sub(closestDepth)\n .greaterThan(u.edgeDepthDiff);\n const isDisocclusion = closestDepth\n .sub(previousDepth)\n .greaterThan(u.depthThreshold);\n N.If(isEdge.or(isDisocclusion.not()), () => {\n const motionFactor = offsetUV\n .mul(u.renderSize)\n .length()\n .div(u.maxMotionLength)\n .clamp(0, 1)\n .toVar();\n const currentWeight = N.float(0.05).toVar();\n N.If(u.useSubpixelCorrection, () => {\n const phase = offsetUV.mul(u.renderSize).fract();\n const weight = phase.max(N.vec2(1).sub(phase));\n currentWeight.addAssign(\n N.float(1).sub(weight.x.mul(weight.y)).div(0.75).mul(0.25),\n );\n });\n currentWeight.assign(\n currentWeight.add(motionFactor).clamp(0, 1),\n );\n const gamma = N.mix(\n 0.5,\n 1,\n N.float(1).sub(motionFactor).pow(2),\n );\n const mean = moment1.div(9).toVar();\n const extent = moment2\n .div(9)\n .sub(mean.mul(mean))\n .max(0)\n .sqrt()\n .mul(gamma);\n const historyColor = history.sample(historyUV).toVar();\n const delta = historyColor.sub(mean).toVar();\n const unit = delta.rgb.div(extent.rgb.add(1e-7)).abs();\n const maxUnit = unit.x.max(unit.y).max(unit.z);\n N.If(maxUnit.greaterThan(1), () => {\n historyColor.assign(mean.add(delta.div(maxUnit)));\n });\n const compressedCurrent = currentColor.rgb.div(\n currentColor.r.max(currentColor.g).max(currentColor.b).add(1),\n );\n const compressedHistory = historyColor.rgb.div(\n historyColor.r.max(historyColor.g).max(historyColor.b).add(1),\n );\n const weightCurrent = currentWeight.div(\n compressedCurrent.dot(u.luminanceCoefficients).add(1),\n );\n const weightHistory = N.float(1)\n .sub(currentWeight)\n .div(compressedHistory.dot(u.luminanceCoefficients).add(1));\n result.assign(\n currentColor\n .mul(weightCurrent)\n .add(historyColor.mul(weightHistory))\n .div(weightCurrent.add(weightHistory).max(0.00001)),\n );\n });\n },\n );\n });\n });\n return result;\n })();\n return this.textureNode;\n }\n\n override dispose() {\n super.dispose();\n this.source.dispose();\n for (const target of this.history) target.dispose();\n this.material.dispose();\n }\n}\n","/** Response URLs such as blob: and data: cannot resolve relative assets. */\nexport function getAssetBaseUrl(url?: string): string | undefined {\n if (!url) return undefined;\n try {\n new URL(\".\", url);\n return url;\n } catch {\n return undefined;\n }\n}\n","/** @internal */\nexport enum Opcode {\n Constant = 1,\n InputField = 2,\n InputAttribute = 3,\n Negate = 10,\n Abs = 11,\n Sqrt = 12,\n Log = 13,\n Exp = 14,\n Floor = 15,\n Ceil = 16,\n Round = 17,\n Normalize = 18,\n Length = 19,\n IsFinite = 20,\n Not = 22,\n Sin = 23,\n Cos = 24,\n Acos = 25,\n Tan = 26,\n Asin = 27,\n Atan = 28,\n Add = 30,\n Subtract = 31,\n Multiply = 32,\n Divide = 33,\n Min = 34,\n Max = 35,\n Pow = 36,\n Dot = 37,\n Cross = 38,\n Equal = 39,\n NotEqual = 40,\n Less = 41,\n LessEqual = 42,\n Greater = 43,\n GreaterEqual = 44,\n And = 45,\n Or = 46,\n QuaternionMultiply = 47,\n RotateVector = 48,\n Atan2 = 49,\n Select = 60,\n Clamp = 61,\n Mix = 62,\n // Preserve float32 rounding between the two operations (not hardware FMA).\n MultiplyAdd = 63,\n AddMultiply = 64,\n Vec2 = 70,\n Vec3 = 71,\n Vec4 = 72,\n Component = 74,\n MaxComponentIndex = 75,\n}\n\n/** @internal */\nexport enum InputField {\n Position = 1,\n Scale = 2,\n Quaternion = 3,\n Opacity = 4,\n Alpha = 5,\n Color = 6,\n Sh0 = 7,\n}\n\n/** @internal */\nexport const SH_COEFFICIENT_COUNT = 15;\n\n/** @internal */\nexport type SplatPostDecodeValueType =\n | \"float\"\n | \"bool\"\n | \"vec2\"\n | \"vec3\"\n | \"vec4\"\n | \"quaternion\";\n\n/** @internal */\nexport const TYPE_WIDTHS: Record<SplatPostDecodeValueType, number> = {\n float: 1,\n bool: 1,\n vec2: 2,\n vec3: 3,\n vec4: 4,\n quaternion: 4,\n};\n\n/** @internal */\nexport type SplatPostDecodeInstruction = {\n opcode: Opcode;\n type: SplatPostDecodeValueType;\n args: readonly number[];\n immediate: number;\n};\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_OPCODE = 0;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_WIDTH = 1;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE = 2;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 = 3;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT = 4;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_STRIDE = 7;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_MISSING_ARGUMENT = 0xffff;\n\n/** @internal */\nexport type SplatPostDecodeAttributeFormat =\n | \"f32\"\n | \"f16\"\n | \"u8\"\n | \"unorm8\"\n | \"i8\"\n | \"snorm8\"\n | \"u16\"\n | \"unorm16\"\n | \"i16\"\n | \"snorm16\"\n | \"u32\"\n | \"i32\";\n\n/** @internal */\nexport const ATTRIBUTE_FORMAT_BYTES: Record<\n SplatPostDecodeAttributeFormat,\n number\n> = {\n f32: 4,\n f16: 2,\n u8: 1,\n unorm8: 1,\n i8: 1,\n snorm8: 1,\n u16: 2,\n unorm16: 2,\n i16: 2,\n snorm16: 2,\n u32: 4,\n i32: 4,\n};\n\nexport type AttributeComponents = 1 | 2 | 3 | 4;\n\nexport type AttributeBinding = {\n data: ArrayBufferView;\n format: SplatPostDecodeAttributeFormat;\n count: number;\n components: AttributeComponents;\n byteOffset: number;\n byteStride: number;\n};\n\n/** @internal */\nexport type SerializedSplatPostDecodeAttribute = {\n format: SplatPostDecodeAttributeFormat;\n components: AttributeComponents;\n byteOffset: number;\n byteStride: number;\n count: number;\n};\n\n/** @internal */\nexport type SplatPostDecodeOutputs = {\n when?: number;\n position?: number;\n scale?: number;\n quaternion?: number;\n opacity?: number;\n alpha?: number;\n color?: number;\n sh?: readonly number[];\n};\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_START = 0;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION = 1;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_REGISTER = 2;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE = 3;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE = 4;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_STRIDE = 5;\n\n/** @internal */\nexport type SerializedSplatPostDecodeCondition = {\n /** Packed start/instruction/register/onTrue/onFalse Uint16 records. */\n stages: Uint16Array;\n};\n\n/** @internal */\nexport type SerializedSplatPostDecode = {\n /** Packed opcode/width/immediate/arg0/arg1/arg2/arg3 Uint16 records. */\n instructions: Uint16Array;\n constants: Float32Array;\n outputs: Omit<SplatPostDecodeOutputs, \"when\">;\n condition?: SerializedSplatPostDecodeCondition;\n attributeData: Uint8Array;\n attributes: readonly SerializedSplatPostDecodeAttribute[];\n};\n\nexport type PostDecodeSource = {\n instructions: readonly SplatPostDecodeInstruction[];\n constants: readonly number[];\n attributes: readonly AttributeBinding[];\n};\n\nexport type PostDecodeSplatData = {\n numSplats: number;\n splat0: Uint32Array;\n splat1: Uint32Array;\n sortCenters: Float32Array;\n sourceIds?: Uint32Array;\n sh1?: Uint32Array;\n sh2?: Uint32Array;\n sh3a?: Uint32Array;\n sh3b?: Uint32Array;\n};\n","import {\n ATTRIBUTE_FORMAT_BYTES,\n type AttributeBinding,\n type AttributeComponents,\n InputField,\n Opcode,\n SH_COEFFICIENT_COUNT,\n type SplatPostDecodeAttributeFormat,\n type SplatPostDecodeInstruction,\n type SplatPostDecodeOutputs,\n type SplatPostDecodeValueType,\n TYPE_WIDTHS,\n} from \"./protocol\";\n\ntype NumericValueType = \"float\" | \"vec2\" | \"vec3\" | \"vec4\";\n\ntype VectorValueType = \"vec2\" | \"vec3\" | \"vec4\";\n\nclass SplatPostDecodeValue<T extends SplatPostDecodeValueType> {\n /** @internal */\n constructor(\n readonly type: T,\n /** @internal */ readonly register: number,\n /** @internal */ readonly owner: ProgramBuilder,\n ) {}\n}\n\ntype FloatValue = SplatPostDecodeValue<\"float\">;\n\ntype BoolValue = SplatPostDecodeValue<\"bool\">;\n\ntype Vec2Value = SplatPostDecodeValue<\"vec2\">;\n\ntype Vec3Value = SplatPostDecodeValue<\"vec3\">;\n\ntype Vec4Value = SplatPostDecodeValue<\"vec4\">;\n\ntype QuaternionValue = SplatPostDecodeValue<\"quaternion\">;\n\ntype FloatLike = number | FloatValue;\n\ntype BoolLike = boolean | BoolValue;\n\ntype Vec2Literal = readonly [number, number];\n\ntype Vec3Literal = readonly [number, number, number];\n\ntype Vec4Literal = readonly [number, number, number, number];\n\ntype Vec2Like = Vec2Literal | Vec2Value;\n\ntype Vec3Like = Vec3Literal | Vec3Value;\n\ntype Vec4Like = Vec4Literal | Vec4Value;\n\ntype QuaternionLike = Vec4Literal | QuaternionValue;\n\ntype LiteralFor<T extends SplatPostDecodeValueType> = T extends \"float\"\n ? number\n : T extends \"bool\"\n ? boolean\n : T extends \"vec2\"\n ? Vec2Literal\n : T extends \"vec3\"\n ? Vec3Literal\n : Vec4Literal;\n\ntype ValueLike<T extends SplatPostDecodeValueType> =\n | LiteralFor<T>\n | SplatPostDecodeValue<T>;\n\ntype AnyValueLike = ValueLike<SplatPostDecodeValueType>;\n\ntype BroadcastLike<T extends NumericValueType> = ValueLike<T> | FloatLike;\n\ntype SplatPostDecodeAttributeOptions<\n Components extends AttributeComponents = 1,\n> = {\n data: ArrayBufferView;\n format: SplatPostDecodeAttributeFormat;\n count: number;\n components?: Components;\n /** Byte offset relative to the supplied data view. */\n byteOffset?: number;\n byteStride?: number;\n};\n\ntype AttributeValue<Components extends AttributeComponents> =\n Components extends 1\n ? FloatValue\n : Components extends 2\n ? Vec2Value\n : Components extends 3\n ? Vec3Value\n : Vec4Value;\n\ntype SplatShCoefficientContext = {\n index: number;\n degree: 1 | 2 | 3;\n order: number;\n};\n\nclass SplatPostDecodeShPatch {\n /** @internal */\n constructor(\n /** @internal */ readonly owner: ProgramBuilder,\n /** @internal */ readonly coefficients: readonly Vec3Value[],\n ) {}\n}\n\nclass SplatPostDecodeShValue {\n /** @internal */\n constructor(private readonly owner: ProgramBuilder) {}\n\n coefficient(index: number): Vec3Value {\n if (\n !Number.isInteger(index) ||\n index < 0 ||\n index >= SH_COEFFICIENT_COUNT\n ) {\n throw new Error(\"SH coefficient index must be between 0 and 14\");\n }\n return this.owner.inputField(\"vec3\", InputField.Sh0 + index);\n }\n\n map(\n transform: (\n coefficient: Vec3Value,\n context: SplatShCoefficientContext,\n ) => Vec3Like,\n ): SplatPostDecodeShPatch {\n const coefficients: Vec3Value[] = [];\n let index = 0;\n for (let degree = 1 as 1 | 2 | 3; degree <= 3; degree += 1) {\n for (let order = -degree; order <= degree; order += 1) {\n coefficients.push(\n this.owner.coerce(\n transform(this.coefficient(index), { index, degree, order }),\n \"vec3\",\n ),\n );\n index += 1;\n }\n }\n return new SplatPostDecodeShPatch(this.owner, coefficients);\n }\n}\n\ntype SplatPostDecodeInput = {\n readonly position: Vec3Value;\n readonly scale: Vec3Value;\n readonly quaternion: QuaternionValue;\n /** Semantic opacity in [0, exp(24/e)] (approximately 6830.182). */\n readonly opacity: FloatValue;\n /** Standard alpha in the [0, 1] range. */\n readonly alpha: FloatValue;\n readonly color: Vec3Value;\n readonly sh: SplatPostDecodeShValue;\n};\n\nexport type SplatPostDecodePatch = {\n /** If false, this splat's packed values are left byte-for-byte unchanged. */\n when?: BoolLike;\n position?: Vec3Like;\n scale?: Vec3Like;\n quaternion?: QuaternionLike;\n /** Semantic opacity, encoded within the renderer's shape range [0, 1]. */\n opacity?: FloatLike;\n /**\n * Standard alpha, clamped to [0, 1] and independent from semantic opacity.\n * Cannot be output with opacity in the same patch.\n */\n alpha?: FloatLike;\n color?: Vec3Like;\n sh?: SplatPostDecodeShPatch;\n};\n\ntype VariadicNumericOperation = <T extends NumericValueType>(\n first: ValueLike<T>,\n ...rest: BroadcastLike<T>[]\n) => SplatPostDecodeValue<T>;\n\ntype BinaryNumericOperation = <T extends NumericValueType>(\n left: ValueLike<T>,\n right: BroadcastLike<T>,\n) => SplatPostDecodeValue<T>;\n\ntype UnaryNumericOperation = <T extends NumericValueType>(\n value: ValueLike<T>,\n) => SplatPostDecodeValue<T>;\n\ntype SplatPostDecodeOperations = {\n add: VariadicNumericOperation;\n sub: BinaryNumericOperation;\n mul: VariadicNumericOperation;\n div: BinaryNumericOperation;\n min: BinaryNumericOperation;\n max: BinaryNumericOperation;\n pow: BinaryNumericOperation;\n clamp<T extends NumericValueType>(\n value: ValueLike<T>,\n min: BroadcastLike<T>,\n max: BroadcastLike<T>,\n ): SplatPostDecodeValue<T>;\n mix<T extends NumericValueType>(\n left: ValueLike<T>,\n right: ValueLike<T>,\n amount: BroadcastLike<T>,\n ): SplatPostDecodeValue<T>;\n neg: UnaryNumericOperation;\n abs: UnaryNumericOperation;\n sqrt: UnaryNumericOperation;\n log: UnaryNumericOperation;\n exp: UnaryNumericOperation;\n floor: UnaryNumericOperation;\n ceil: UnaryNumericOperation;\n round: UnaryNumericOperation;\n sin: UnaryNumericOperation;\n cos: UnaryNumericOperation;\n acos: UnaryNumericOperation;\n tan: UnaryNumericOperation;\n asin: UnaryNumericOperation;\n atan: UnaryNumericOperation;\n atan2: BinaryNumericOperation;\n normalize<T extends VectorValueType | \"quaternion\">(\n value: ValueLike<T>,\n ): SplatPostDecodeValue<T>;\n length(value: Vec2Like | Vec3Like | Vec4Like): FloatValue;\n isFinite(\n value: FloatLike | Vec2Like | Vec3Like | Vec4Like | QuaternionLike,\n ): BoolValue;\n not(value: BoolLike): BoolValue;\n eq<T extends SplatPostDecodeValueType>(\n left: ValueLike<T>,\n right: ValueLike<T>,\n ): BoolValue;\n ne<T extends SplatPostDecodeValueType>(\n left: ValueLike<T>,\n right: ValueLike<T>,\n ): BoolValue;\n lt(left: FloatLike, right: FloatLike): BoolValue;\n lte(left: FloatLike, right: FloatLike): BoolValue;\n gt(left: FloatLike, right: FloatLike): BoolValue;\n gte(left: FloatLike, right: FloatLike): BoolValue;\n and(first: BoolLike, ...rest: BoolLike[]): BoolValue;\n or(first: BoolLike, ...rest: BoolLike[]): BoolValue;\n select<T extends SplatPostDecodeValueType>(\n condition: BoolLike,\n whenTrue: ValueLike<T>,\n whenFalse: ValueLike<T>,\n ): SplatPostDecodeValue<T>;\n dot(\n left: Vec2Like | Vec3Like | Vec4Like,\n right: Vec2Like | Vec3Like | Vec4Like,\n ): FloatValue;\n cross(left: Vec3Like, right: Vec3Like): Vec3Value;\n vec2(x: FloatLike, y: FloatLike): Vec2Value;\n vec3(x: FloatLike, y: FloatLike, z: FloatLike): Vec3Value;\n vec4(x: FloatLike, y: FloatLike, z: FloatLike, w: FloatLike): Vec4Value;\n quaternion(\n x: FloatLike,\n y: FloatLike,\n z: FloatLike,\n w: FloatLike,\n ): QuaternionValue;\n component(\n value: Vec2Like | Vec3Like | Vec4Like | QuaternionLike,\n index: number,\n ): FloatValue;\n maxComponentIndex(value: Vec2Like | Vec3Like | Vec4Like): FloatValue;\n quatMul(left: QuaternionLike, right: QuaternionLike): QuaternionValue;\n rotateVector(quaternion: QuaternionLike, vector: Vec3Like): Vec3Value;\n};\n\nexport type SplatPostDecodeContext = {\n splat: SplatPostDecodeInput;\n op: SplatPostDecodeOperations;\n attribute<Components extends AttributeComponents = 1>(\n options: SplatPostDecodeAttributeOptions<Components>,\n ): AttributeValue<Components>;\n};\n\nconst COMPONENT_TYPES = [\"float\", \"vec2\", \"vec3\", \"vec4\"] as const;\n\nfunction inferLiteralType(value: unknown): SplatPostDecodeValueType {\n if (typeof value === \"boolean\") return \"bool\";\n if (typeof value === \"number\") return \"float\";\n if (Array.isArray(value) && value.length >= 2 && value.length <= 4) {\n return COMPONENT_TYPES[value.length - 1];\n }\n throw new Error(\"Unsupported postDecode literal\");\n}\n\nfunction constantKey(\n type: SplatPostDecodeValueType,\n values: readonly number[],\n) {\n return `${type}:${values\n .map((value) => (Object.is(value, -0) ? \"-0\" : value))\n .join(\":\")}`;\n}\n\nexport class ProgramBuilder {\n readonly instructions: SplatPostDecodeInstruction[] = [];\n readonly constants: number[] = [];\n readonly attributes: AttributeBinding[] = [];\n readonly op: SplatPostDecodeOperations;\n readonly splat: SplatPostDecodeInput;\n\n readonly constantRegisters = new Map<\n string,\n SplatPostDecodeValue<SplatPostDecodeValueType>\n >();\n readonly inputRegisters = new Map<\n number,\n SplatPostDecodeValue<SplatPostDecodeValueType>\n >();\n\n constructor() {\n this.op = this.createOperations();\n const builder = this;\n const sh = new SplatPostDecodeShValue(this);\n this.splat = {\n get position() {\n return builder.inputField(\"vec3\", InputField.Position);\n },\n get scale() {\n return builder.inputField(\"vec3\", InputField.Scale);\n },\n get quaternion() {\n return builder.inputField(\"quaternion\", InputField.Quaternion);\n },\n get opacity() {\n return builder.inputField(\"float\", InputField.Opacity);\n },\n get alpha() {\n return builder.inputField(\"float\", InputField.Alpha);\n },\n get color() {\n return builder.inputField(\"vec3\", InputField.Color);\n },\n sh,\n };\n }\n\n private instruction<T extends SplatPostDecodeValueType>(\n type: T,\n opcode: Opcode,\n args: readonly number[] = [],\n immediate = 0,\n ): SplatPostDecodeValue<T> {\n if (this.instructions.length >= 4096) {\n throw new Error(\"postDecode program exceeds 4096 instructions\");\n }\n const register = this.instructions.length;\n this.instructions.push({ opcode, type, args, immediate });\n return new SplatPostDecodeValue(type, register, this);\n }\n\n inputField<T extends SplatPostDecodeValueType>(\n type: T,\n field: InputField,\n ): SplatPostDecodeValue<T> {\n const existing = this.inputRegisters.get(field);\n if (existing) return existing as SplatPostDecodeValue<T>;\n const value = this.instruction(type, Opcode.InputField, [], field);\n this.inputRegisters.set(field, value);\n return value;\n }\n\n attribute<Components extends AttributeComponents = 1>(\n options: SplatPostDecodeAttributeOptions<Components>,\n ): AttributeValue<Components> {\n if (!ArrayBuffer.isView(options.data)) {\n throw new Error(\"postDecode attribute data must be an ArrayBuffer view\");\n }\n const componentBytes = ATTRIBUTE_FORMAT_BYTES[options.format];\n if (!componentBytes) {\n throw new Error(`Unknown postDecode format: ${options.format}`);\n }\n const count = options.count;\n const components = options.components ?? 1;\n const byteOffset = options.byteOffset ?? 0;\n const packedBytes = componentBytes * components;\n const byteStride = options.byteStride ?? packedBytes;\n if (!Number.isSafeInteger(count) || count < 0) {\n throw new Error(\"postDecode attribute count must be non-negative\");\n }\n if (!Number.isInteger(components) || components < 1 || components > 4) {\n throw new Error(\n \"postDecode attribute components must be between 1 and 4\",\n );\n }\n if (\n !Number.isSafeInteger(byteOffset) ||\n byteOffset < 0 ||\n !Number.isSafeInteger(byteStride) ||\n byteStride < packedBytes\n ) {\n throw new Error(\"Invalid postDecode attribute byteOffset or byteStride\");\n }\n const requiredBytes =\n count === 0\n ? byteOffset\n : byteOffset + (count - 1) * byteStride + packedBytes;\n if (\n !Number.isSafeInteger(requiredBytes) ||\n requiredBytes > options.data.byteLength\n ) {\n throw new Error(\"postDecode attribute data is too small\");\n }\n\n const index = this.attributes.length;\n this.attributes.push({\n data: options.data,\n format: options.format,\n count,\n components,\n byteOffset,\n byteStride,\n });\n return this.instruction(\n COMPONENT_TYPES[components - 1],\n Opcode.InputAttribute,\n [],\n index,\n ) as AttributeValue<Components>;\n }\n\n coerce<T extends SplatPostDecodeValueType>(\n value: ValueLike<T>,\n expectedType?: T,\n ): SplatPostDecodeValue<T> {\n if (value instanceof SplatPostDecodeValue) {\n if (value.owner !== this) {\n throw new Error(\n \"Cannot combine values from different postDecode programs\",\n );\n }\n if (expectedType && value.type !== expectedType) {\n const vec4Quaternion =\n (expectedType === \"quaternion\" && value.type === \"vec4\") ||\n (expectedType === \"vec4\" && value.type === \"quaternion\");\n if (!vec4Quaternion) {\n throw new Error(`Expected ${expectedType}, received ${value.type}`);\n }\n }\n return value as SplatPostDecodeValue<T>;\n }\n\n const type = expectedType ?? inferLiteralType(value);\n const numeric =\n typeof value === \"boolean\"\n ? [value ? 1 : 0]\n : typeof value === \"number\"\n ? [value]\n : [...(value as readonly number[])];\n const width = TYPE_WIDTHS[type];\n if (numeric.length !== width) {\n throw new Error(`Expected ${width} values for ${type}`);\n }\n const values = numeric.map(Math.fround);\n if (!values.every(Number.isFinite)) {\n throw new Error(\"postDecode constants must be finite\");\n }\n const key = constantKey(type, values);\n const existing = this.constantRegisters.get(key);\n if (existing) return existing as SplatPostDecodeValue<T>;\n\n const immediate = this.constants.length;\n this.constants.push(...values);\n const result = this.instruction(type as T, Opcode.Constant, [], immediate);\n this.constantRegisters.set(key, result);\n return result;\n }\n\n private unary(\n opcode: Opcode,\n value: AnyValueLike,\n outputType?: SplatPostDecodeValueType,\n ) {\n const input = this.coerce(value);\n return this.instruction(outputType ?? input.type, opcode, [input.register]);\n }\n\n private binary(\n opcode: Opcode,\n leftValue: AnyValueLike,\n rightValue: AnyValueLike,\n outputType?: SplatPostDecodeValueType,\n ) {\n const left = this.coerce(leftValue);\n const right = this.coerceForBinary(rightValue, left.type);\n return this.instruction(outputType ?? left.type, opcode, [\n left.register,\n right.register,\n ]);\n }\n\n private ternary(\n opcode: Opcode,\n firstValue: AnyValueLike,\n secondValue: AnyValueLike,\n thirdValue: AnyValueLike,\n ) {\n const first = this.coerce(firstValue);\n const second = this.coerceForBinary(secondValue, first.type);\n const third = this.coerceForBinary(thirdValue, first.type);\n return this.instruction(first.type, opcode, [\n first.register,\n second.register,\n third.register,\n ]);\n }\n\n private coerceForBinary(\n value: AnyValueLike,\n targetType: SplatPostDecodeValueType,\n ) {\n if (value instanceof SplatPostDecodeValue) {\n return value.type === \"float\" && TYPE_WIDTHS[targetType] > 1\n ? this.coerce(value)\n : this.coerce(value, targetType);\n }\n return this.coerce(\n value,\n typeof value === \"number\" && TYPE_WIDTHS[targetType] > 1\n ? \"float\"\n : targetType,\n );\n }\n\n private createOperations(): SplatPostDecodeOperations {\n const reduceNumeric =\n (opcode: Opcode): VariadicNumericOperation =>\n <T extends NumericValueType>(\n first: ValueLike<T>,\n ...rest: BroadcastLike<T>[]\n ) => {\n let result = this.coerce(first);\n for (const right of rest) {\n result = this.binary(\n opcode,\n result,\n right,\n ) as SplatPostDecodeValue<T>;\n }\n return result;\n };\n const binaryNumeric =\n (opcode: Opcode): BinaryNumericOperation =>\n <T extends NumericValueType>(\n left: ValueLike<T>,\n right: BroadcastLike<T>,\n ) =>\n this.binary(opcode, left, right) as SplatPostDecodeValue<T>;\n const unaryNumeric =\n (opcode: Opcode): UnaryNumericOperation =>\n <T extends NumericValueType>(value: ValueLike<T>) =>\n this.unary(opcode, value) as SplatPostDecodeValue<T>;\n const compare =\n (opcode: Opcode) => (left: AnyValueLike, right: AnyValueLike) => {\n const a = this.coerce(left);\n const scalar = opcode !== Opcode.Equal && opcode !== Opcode.NotEqual;\n if (scalar && a.type !== \"float\")\n throw new Error(\"Ordered comparisons require scalars\");\n const b = this.coerce(right, a.type);\n return this.instruction(\"bool\", opcode, [\n a.register,\n b.register,\n ]) as BoolValue;\n };\n const vectorBinary = (\n opcode: Opcode,\n left: AnyValueLike,\n right: AnyValueLike,\n ) => {\n const a = this.coerce(left);\n if (\n !(a.type === \"vec2\" || a.type === \"vec3\" || a.type === \"vec4\") ||\n (opcode === Opcode.Cross && a.type !== \"vec3\")\n )\n throw new Error(\"dot/cross require matching vectors\");\n const b = this.coerce(right, a.type);\n return this.instruction(\n opcode === Opcode.Dot ? \"float\" : a.type,\n opcode,\n [a.register, b.register],\n );\n };\n const reduceBoolean =\n (opcode: Opcode) =>\n (first: BoolLike, ...rest: BoolLike[]): BoolValue => {\n let result = this.coerce(first, \"bool\");\n for (const right of rest) {\n result = this.binary(opcode, result, right, \"bool\") as BoolValue;\n }\n return result;\n };\n const construct = <T extends VectorValueType | \"quaternion\">(\n opcode: Opcode,\n type: T,\n values: FloatLike[],\n ) =>\n this.instruction(\n type,\n opcode,\n values.map((value) => this.coerce(value, \"float\").register),\n );\n\n return {\n add: reduceNumeric(Opcode.Add),\n sub: binaryNumeric(Opcode.Subtract),\n mul: reduceNumeric(Opcode.Multiply),\n div: binaryNumeric(Opcode.Divide),\n min: binaryNumeric(Opcode.Min),\n max: binaryNumeric(Opcode.Max),\n pow: binaryNumeric(Opcode.Pow),\n clamp: (value, min, max) =>\n this.ternary(Opcode.Clamp, value, min, max) as never,\n mix: (left, right, amount) =>\n this.ternary(Opcode.Mix, left, right, amount) as never,\n neg: unaryNumeric(Opcode.Negate),\n abs: unaryNumeric(Opcode.Abs),\n sqrt: unaryNumeric(Opcode.Sqrt),\n log: unaryNumeric(Opcode.Log),\n exp: unaryNumeric(Opcode.Exp),\n floor: unaryNumeric(Opcode.Floor),\n ceil: unaryNumeric(Opcode.Ceil),\n round: unaryNumeric(Opcode.Round),\n sin: unaryNumeric(Opcode.Sin),\n cos: unaryNumeric(Opcode.Cos),\n acos: unaryNumeric(Opcode.Acos),\n tan: unaryNumeric(Opcode.Tan),\n asin: unaryNumeric(Opcode.Asin),\n atan: unaryNumeric(Opcode.Atan),\n atan2: binaryNumeric(Opcode.Atan2),\n normalize: (value) => this.unary(Opcode.Normalize, value) as never,\n length: (value) =>\n this.unary(Opcode.Length, value, \"float\") as FloatValue,\n isFinite: (value) =>\n this.unary(Opcode.IsFinite, value, \"bool\") as BoolValue,\n not: (value) =>\n this.unary(Opcode.Not, this.coerce(value, \"bool\"), \"bool\") as BoolValue,\n eq: compare(Opcode.Equal),\n ne: compare(Opcode.NotEqual),\n lt: compare(Opcode.Less),\n lte: compare(Opcode.LessEqual),\n gt: compare(Opcode.Greater),\n gte: compare(Opcode.GreaterEqual),\n and: reduceBoolean(Opcode.And),\n or: reduceBoolean(Opcode.Or),\n select: (condition, whenTrue, whenFalse) => {\n const trueValue = this.coerce(whenTrue);\n const falseValue = this.coerce(whenFalse, trueValue.type);\n return this.instruction(trueValue.type, Opcode.Select, [\n this.coerce(condition, \"bool\").register,\n trueValue.register,\n falseValue.register,\n ]) as never;\n },\n dot: (left, right) => vectorBinary(Opcode.Dot, left, right) as FloatValue,\n cross: (left, right) =>\n vectorBinary(Opcode.Cross, left, right) as Vec3Value,\n vec2: (x, y) => construct(Opcode.Vec2, \"vec2\", [x, y]),\n vec3: (x, y, z) => construct(Opcode.Vec3, \"vec3\", [x, y, z]),\n vec4: (x, y, z, w) => construct(Opcode.Vec4, \"vec4\", [x, y, z, w]),\n quaternion: (x, y, z, w) =>\n construct(Opcode.Vec4, \"quaternion\", [x, y, z, w]),\n component: (value, index) => {\n const input = this.coerce(value as AnyValueLike);\n if (\n !Number.isInteger(index) ||\n index < 0 ||\n index >= TYPE_WIDTHS[input.type]\n ) {\n throw new Error(\"postDecode component index is out of bounds\");\n }\n return this.instruction(\n \"float\",\n Opcode.Component,\n [input.register],\n index,\n );\n },\n maxComponentIndex: (value) =>\n this.unary(Opcode.MaxComponentIndex, value, \"float\") as FloatValue,\n quatMul: (left, right) => {\n const a = this.coerce(left, \"quaternion\");\n const b = this.coerce(right, \"quaternion\");\n return this.instruction(\"quaternion\", Opcode.QuaternionMultiply, [\n a.register,\n b.register,\n ]);\n },\n rotateVector: (quaternion, vector) => {\n const q = this.coerce(quaternion, \"quaternion\");\n const v = this.coerce(vector, \"vec3\");\n return this.instruction(\"vec3\", Opcode.RotateVector, [\n q.register,\n v.register,\n ]);\n },\n };\n }\n}\n\nexport function buildOutputs(\n builder: ProgramBuilder,\n patch: SplatPostDecodePatch,\n) {\n if (patch.opacity !== undefined && patch.alpha !== undefined) {\n throw new Error(\"postDecode opacity cannot be combined with alpha\");\n }\n const output = <T extends SplatPostDecodeValueType>(\n value: ValueLike<T> | undefined,\n type: T,\n ) => (value === undefined ? undefined : builder.coerce(value, type).register);\n const outputs: SplatPostDecodeOutputs = {\n when: output(patch.when, \"bool\"),\n position: output(patch.position, \"vec3\"),\n scale: output(patch.scale, \"vec3\"),\n quaternion: output(patch.quaternion, \"quaternion\"),\n opacity: output(patch.opacity, \"float\"),\n alpha: output(patch.alpha, \"float\"),\n color: output(patch.color, \"vec3\"),\n };\n if (patch.sh !== undefined) {\n if (\n !(patch.sh instanceof SplatPostDecodeShPatch) ||\n patch.sh.owner !== builder\n ) {\n throw new Error(\n \"postDecode SH output must be created from splat.sh.map()\",\n );\n }\n outputs.sh = patch.sh.coefficients.map((value) => value.register);\n }\n return outputs;\n}\n","import {\n Opcode,\n type PostDecodeSource,\n type SplatPostDecodeOutputs,\n} from \"./protocol\";\n\n/** Fuse only single-use intermediates; shared values must still run once. */\nexport function fuseArithmetic(\n source: PostDecodeSource,\n outputs: SplatPostDecodeOutputs,\n): PostDecodeSource {\n const uses = new Uint32Array(source.instructions.length);\n for (const instruction of source.instructions) {\n for (const argument of instruction.args) uses[argument] += 1;\n }\n for (const register of [\n outputs.when,\n outputs.position,\n outputs.scale,\n outputs.quaternion,\n outputs.opacity,\n outputs.alpha,\n outputs.color,\n ...(outputs.sh ?? []),\n ]) {\n if (register !== undefined) uses[register] += 1;\n }\n\n const instructions = source.instructions.slice();\n for (let index = 0; index < instructions.length; index += 1) {\n const outer = instructions[index];\n if (outer.opcode !== Opcode.Add && outer.opcode !== Opcode.Multiply) {\n continue;\n }\n const innerOpcode =\n outer.opcode === Opcode.Add ? Opcode.Multiply : Opcode.Add;\n for (let side = 0; side < 2; side += 1) {\n const register = outer.args[side];\n const inner = instructions[register];\n if (uses[register] !== 1 || inner.opcode !== innerOpcode) continue;\n instructions[index] = {\n ...outer,\n opcode:\n outer.opcode === Opcode.Add ? Opcode.MultiplyAdd : Opcode.AddMultiply,\n args: [...inner.args, outer.args[1 - side]],\n // Keep the outer operand order as well as its rounding boundary.\n immediate: side,\n };\n break;\n }\n }\n // The compiler's dependency walk removes the bypassed intermediates.\n return { ...source, instructions };\n}\n","import { fuseArithmetic } from \"./optimizer\";\nimport {\n ATTRIBUTE_FORMAT_BYTES,\n type AttributeBinding,\n Opcode,\n type PostDecodeSource,\n SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION,\n SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE,\n SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE,\n SPLAT_POST_DECODE_FLOW_STAGE_REGISTER,\n SPLAT_POST_DECODE_FLOW_STAGE_START,\n SPLAT_POST_DECODE_FLOW_STAGE_STRIDE,\n SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0,\n SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE,\n SPLAT_POST_DECODE_INSTRUCTION_OPCODE,\n SPLAT_POST_DECODE_INSTRUCTION_STRIDE,\n SPLAT_POST_DECODE_INSTRUCTION_WIDTH,\n SPLAT_POST_DECODE_MISSING_ARGUMENT,\n type SerializedSplatPostDecodeAttribute,\n type SerializedSplatPostDecodeCondition,\n type SplatPostDecodeInstruction,\n type SplatPostDecodeOutputs,\n TYPE_WIDTHS,\n} from \"./protocol\";\n\nclass GenerationRegisterMap {\n private readonly values: Int32Array;\n private readonly generations: Uint32Array;\n private generation = 1;\n\n constructor(size: number) {\n this.values = new Int32Array(size);\n this.generations = new Uint32Array(size);\n }\n\n clear() {\n // A map lives for one compilation, capped at 4096 condition stages.\n this.generation += 1;\n }\n\n has(source: number) {\n return this.generations[source] === this.generation;\n }\n\n get(source: number) {\n return this.values[source];\n }\n\n set(source: number, target: number) {\n this.generations[source] = this.generation;\n this.values[source] = target;\n }\n\n delete(source: number) {\n this.generations[source] = 0;\n }\n}\n\ntype CompiledProgram = {\n instructions: SplatPostDecodeInstruction[];\n constants: number[];\n outputs: Omit<SplatPostDecodeOutputs, \"when\">;\n condition?: SerializedSplatPostDecodeCondition;\n attributes: AttributeBinding[];\n};\n\nfunction markDependencies(\n builder: PostDecodeSource,\n roots: readonly (number | undefined)[],\n marked: Uint8Array,\n) {\n const pending: number[] = [];\n for (const root of roots) {\n if (root === undefined || marked[root]) continue;\n marked[root] = 1;\n pending.push(root);\n }\n while (pending.length !== 0) {\n const register = pending.pop() as number;\n for (const argument of builder.instructions[register].args) {\n if (marked[argument]) continue;\n marked[argument] = 1;\n pending.push(argument);\n }\n }\n}\n\n/**\n * Serializes source instructions while remapping only live registers. A\n * generation map represents the current straight-line path. Branch merges\n * advance its generation in O(1), while unique predecessors reuse it. One\n * generation array is also shared by every dependency walk.\n */\nclass InstructionSerializer {\n readonly instructions: SplatPostDecodeInstruction[] = [];\n readonly constants: number[] = [];\n readonly attributes: AttributeBinding[] = [];\n\n private readonly constantMap = new Map<number, number>();\n private readonly attributeMap = new Map<number, number>();\n private readonly dependencyMarks: Uint32Array;\n private dependencyGeneration = 0;\n\n constructor(private readonly builder: PostDecodeSource) {\n this.dependencyMarks = new Uint32Array(builder.instructions.length);\n }\n\n appendDependencies(\n roots: readonly (number | undefined)[],\n registers: GenerationRegisterMap,\n forceRoots = false,\n ) {\n if (forceRoots) {\n for (const root of roots) {\n if (\n root !== undefined &&\n this.builder.instructions[root].opcode !== Opcode.Constant\n ) {\n registers.delete(root);\n }\n }\n }\n\n this.dependencyGeneration += 1;\n const generation = this.dependencyGeneration;\n const pending: number[] = [];\n const sourceOrder: number[] = [];\n for (const root of roots) {\n if (root !== undefined && !registers.has(root)) pending.push(root);\n }\n while (pending.length !== 0) {\n const source = pending.pop() as number;\n if (\n registers.has(source) ||\n this.dependencyMarks[source] === generation\n ) {\n continue;\n }\n this.dependencyMarks[source] = generation;\n sourceOrder.push(source);\n for (const argument of this.builder.instructions[source].args) {\n if (!registers.has(argument)) pending.push(argument);\n }\n }\n\n sourceOrder.sort((left, right) => left - right);\n this.append(sourceOrder, registers);\n return registers;\n }\n\n append(sourceOrder: readonly number[], registers: GenerationRegisterMap) {\n for (const sourceIndex of sourceOrder) {\n const source = this.builder.instructions[sourceIndex];\n if (source.opcode === Opcode.Constant) {\n let target = this.constantMap.get(sourceIndex);\n if (target === undefined) {\n this.reserveInstruction();\n target = this.instructions.length;\n this.constantMap.set(sourceIndex, target);\n const immediate = this.constants.length;\n this.constants.push(\n ...this.builder.constants.slice(\n source.immediate,\n source.immediate + TYPE_WIDTHS[source.type],\n ),\n );\n this.instructions.push({ ...source, immediate });\n }\n registers.set(sourceIndex, target);\n continue;\n }\n\n this.reserveInstruction();\n let immediate = source.immediate;\n if (source.opcode === Opcode.InputAttribute) {\n let target = this.attributeMap.get(immediate);\n if (target === undefined) {\n target = this.attributes.length;\n this.attributeMap.set(immediate, target);\n this.attributes.push(this.builder.attributes[immediate]);\n }\n immediate = target;\n }\n const args = source.args.map((argument) => registers.get(argument));\n registers.set(sourceIndex, this.instructions.length);\n this.instructions.push({ ...source, args, immediate });\n }\n }\n\n private reserveInstruction() {\n if (this.instructions.length >= 4096) {\n throw new Error(\"postDecode compiled program exceeds 4096 instructions\");\n }\n }\n}\n\nfunction emptyCompiledProgram(): CompiledProgram {\n return {\n instructions: [],\n constants: [],\n outputs: {},\n condition: undefined,\n attributes: [],\n };\n}\n\nfunction remapOutputs(\n outputs: SplatPostDecodeOutputs,\n registers: GenerationRegisterMap,\n): Omit<SplatPostDecodeOutputs, \"when\"> {\n const remap = (register: number | undefined) =>\n register === undefined ? undefined : registers.get(register);\n return {\n position: remap(outputs.position),\n scale: remap(outputs.scale),\n quaternion: remap(outputs.quaternion),\n opacity: remap(outputs.opacity),\n alpha: remap(outputs.alpha),\n color: remap(outputs.color),\n sh: outputs.sh?.map((register) => registers.get(register)),\n };\n}\n\ntype FlowNode = {\n register: number;\n onTrue: number;\n onFalse: number;\n};\n\nfunction compileConditionFlow(\n builder: PostDecodeSource,\n outputs: SplatPostDecodeOutputs,\n outputRoots: readonly (number | undefined)[],\n whenRegister: number,\n): CompiledProgram | undefined {\n const FLOW_ACCEPT = -1;\n const FLOW_REJECT = -2;\n const FLOW_DYNAMIC = 0;\n const FLOW_CONSTANT_FALSE = 1;\n const FLOW_CONSTANT_TRUE = 2;\n const constantValues = new Uint8Array(whenRegister + 1);\n for (let register = 0; register <= whenRegister; register += 1) {\n const instruction = builder.instructions[register];\n if (instruction.opcode === Opcode.Constant && instruction.type === \"bool\") {\n constantValues[register] = builder.constants[instruction.immediate]\n ? FLOW_CONSTANT_TRUE\n : FLOW_CONSTANT_FALSE;\n continue;\n }\n const left = constantValues[instruction.args[0]];\n if (instruction.opcode === Opcode.Not) {\n constantValues[register] =\n left === FLOW_CONSTANT_TRUE\n ? FLOW_CONSTANT_FALSE\n : left === FLOW_CONSTANT_FALSE\n ? FLOW_CONSTANT_TRUE\n : FLOW_DYNAMIC;\n } else if (instruction.opcode === Opcode.And) {\n const right = constantValues[instruction.args[1]];\n constantValues[register] =\n left === FLOW_CONSTANT_FALSE || right === FLOW_CONSTANT_FALSE\n ? FLOW_CONSTANT_FALSE\n : left === FLOW_CONSTANT_TRUE && right === FLOW_CONSTANT_TRUE\n ? FLOW_CONSTANT_TRUE\n : FLOW_DYNAMIC;\n } else if (instruction.opcode === Opcode.Or) {\n const right = constantValues[instruction.args[1]];\n constantValues[register] =\n left === FLOW_CONSTANT_TRUE || right === FLOW_CONSTANT_TRUE\n ? FLOW_CONSTANT_TRUE\n : left === FLOW_CONSTANT_FALSE && right === FLOW_CONSTANT_FALSE\n ? FLOW_CONSTANT_FALSE\n : FLOW_DYNAMIC;\n }\n }\n\n const reverseNodes: FlowNode[] = [];\n const FLOW_AND_LEFT = 0;\n const FLOW_OR_LEFT = 1;\n const FLOW_CONTINUATION_SIZE = 3;\n const continuations = new Int32Array(\n (whenRegister + 1) * FLOW_CONTINUATION_SIZE,\n );\n let continuationEnd = 0;\n let register = whenRegister;\n let onTrue = FLOW_ACCEPT;\n let onFalse = FLOW_REJECT;\n let compiledTarget = FLOW_REJECT;\n while (true) {\n const constant = constantValues[register];\n if (constant !== FLOW_DYNAMIC) {\n compiledTarget = constant === FLOW_CONSTANT_TRUE ? onTrue : onFalse;\n } else {\n const instruction = builder.instructions[register];\n if (instruction.opcode === Opcode.Not) {\n register = instruction.args[0];\n const target = onTrue;\n onTrue = onFalse;\n onFalse = target;\n continue;\n }\n if (\n instruction.opcode === Opcode.And ||\n instruction.opcode === Opcode.Or\n ) {\n const isAnd = instruction.opcode === Opcode.And;\n continuations[continuationEnd] = isAnd ? FLOW_AND_LEFT : FLOW_OR_LEFT;\n continuations[continuationEnd + 1] = instruction.args[0];\n continuations[continuationEnd + 2] = isAnd ? onFalse : onTrue;\n continuationEnd += FLOW_CONTINUATION_SIZE;\n register = instruction.args[1];\n continue;\n }\n if (reverseNodes.length >= 4096) {\n throw new Error(\"postDecode condition exceeds 4096 flow nodes\");\n }\n compiledTarget = reverseNodes.length;\n reverseNodes.push({ register, onTrue, onFalse });\n }\n\n if (continuationEnd === 0) break;\n continuationEnd -= FLOW_CONTINUATION_SIZE;\n const type = continuations[continuationEnd];\n register = continuations[continuationEnd + 1];\n const target = continuations[continuationEnd + 2];\n if (type === FLOW_AND_LEFT) {\n onTrue = compiledTarget;\n onFalse = target;\n } else {\n onTrue = target;\n onFalse = compiledTarget;\n }\n }\n\n const entry = compiledTarget;\n if (entry === FLOW_REJECT) return emptyCompiledProgram();\n if (entry === FLOW_ACCEPT) {\n outputs.when = undefined;\n return undefined;\n }\n\n const stageCount = reverseNodes.length;\n\n const acceptTarget = stageCount;\n const rejectTarget = acceptTarget + 1;\n const stages = new Uint16Array(\n stageCount * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE,\n );\n const predecessors = new Int32Array(stageCount).fill(-1);\n let acceptPredecessor = -1;\n const recordPredecessor = (target: number, predecessor: number) => {\n if (target === rejectTarget) return;\n if (target === acceptTarget) {\n acceptPredecessor =\n acceptPredecessor === -1\n ? predecessor\n : acceptPredecessor === predecessor\n ? predecessor\n : -2;\n return;\n }\n predecessors[target] =\n predecessors[target] === -1\n ? predecessor\n : predecessors[target] === predecessor\n ? predecessor\n : -2;\n };\n const remapTarget = (target: number) =>\n target === FLOW_ACCEPT\n ? acceptTarget\n : target === FLOW_REJECT\n ? rejectTarget\n : stageCount - 1 - target;\n\n for (let stage = 0; stage < stageCount; stage += 1) {\n const node = reverseNodes[stageCount - 1 - stage];\n const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;\n const onTrue = remapTarget(node.onTrue);\n const onFalse = remapTarget(node.onFalse);\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE] = onTrue;\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE] = onFalse;\n recordPredecessor(onTrue, stage);\n recordPredecessor(onFalse, stage);\n }\n\n const serializer = new InstructionSerializer(builder);\n const pathRegisters = new GenerationRegisterMap(builder.instructions.length);\n for (let stage = 0; stage < stageCount; stage += 1) {\n if (stage === 0 || predecessors[stage] !== stage - 1) {\n pathRegisters.clear();\n }\n const node = reverseNodes[stageCount - 1 - stage];\n const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_START] =\n serializer.instructions.length;\n serializer.appendDependencies([node.register], pathRegisters, true);\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION] =\n serializer.instructions.length - 1;\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_REGISTER] = pathRegisters.get(\n node.register,\n );\n }\n\n if (acceptPredecessor !== stageCount - 1) pathRegisters.clear();\n serializer.appendDependencies(outputRoots, pathRegisters);\n return {\n instructions: serializer.instructions,\n constants: serializer.constants,\n outputs: remapOutputs(outputs, pathRegisters),\n condition: { stages },\n attributes: serializer.attributes,\n };\n}\n\nexport function compileProgram(\n builder: PostDecodeSource,\n sourceOutputs: SplatPostDecodeOutputs,\n): CompiledProgram {\n return compileSource(fuseArithmetic(builder, sourceOutputs), sourceOutputs);\n}\n\nfunction compileSource(\n builder: PostDecodeSource,\n sourceOutputs: SplatPostDecodeOutputs,\n): CompiledProgram {\n const outputs = { ...sourceOutputs };\n if (outputs.when !== undefined) {\n const condition = builder.instructions[outputs.when];\n if (condition.opcode === Opcode.Constant) {\n if (builder.constants[condition.immediate] === 0) {\n return emptyCompiledProgram();\n }\n outputs.when = undefined;\n }\n }\n\n const outputRoots = [\n outputs.position,\n outputs.scale,\n outputs.quaternion,\n outputs.opacity,\n outputs.alpha,\n outputs.color,\n ...(outputs.sh ?? []),\n ];\n if (outputs.when !== undefined) {\n const flow = compileConditionFlow(\n builder,\n outputs,\n outputRoots,\n outputs.when,\n );\n if (flow) return flow;\n }\n\n const live = new Uint8Array(builder.instructions.length);\n markDependencies(builder, outputRoots, live);\n const instructionOrder: number[] = [];\n for (let register = 0; register < live.length; register += 1) {\n if (live[register]) instructionOrder.push(register);\n }\n\n const serializer = new InstructionSerializer(builder);\n const registers = new GenerationRegisterMap(builder.instructions.length);\n serializer.append(instructionOrder, registers);\n return {\n instructions: serializer.instructions,\n constants: serializer.constants,\n outputs: remapOutputs(outputs, registers),\n attributes: serializer.attributes,\n };\n}\n\nexport function packInstructions(\n instructions: readonly SplatPostDecodeInstruction[],\n): Uint16Array {\n // The builder and compiler cap programs at 4096 instructions with at most\n // four arguments/components each, so registers and immediates fit Uint16.\n const packed = new Uint16Array(\n instructions.length * SPLAT_POST_DECODE_INSTRUCTION_STRIDE,\n );\n packed.fill(SPLAT_POST_DECODE_MISSING_ARGUMENT);\n for (let index = 0; index < instructions.length; index += 1) {\n const instruction = instructions[index];\n const offset = index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_OPCODE] = instruction.opcode;\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_WIDTH] =\n TYPE_WIDTHS[instruction.type];\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE] =\n instruction.immediate;\n for (let argument = 0; argument < instruction.args.length; argument += 1) {\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 + argument] =\n instruction.args[argument];\n }\n }\n return packed;\n}\n\ntype AttributeRegion = {\n buffer: ArrayBufferLike;\n start: number;\n end: number;\n outputOffset: number;\n};\n\nexport function snapshotAttributes(bindings: readonly AttributeBinding[]) {\n const attributes: SerializedSplatPostDecodeAttribute[] = bindings.map(\n ({ format, components, byteStride, count }) => ({\n format,\n components,\n byteOffset: 0,\n byteStride,\n count,\n }),\n );\n const rangesByBuffer = new Map<\n ArrayBufferLike,\n {\n start: number;\n end: number;\n attribute: SerializedSplatPostDecodeAttribute;\n }[]\n >();\n for (const [index, binding] of bindings.entries()) {\n if (binding.count === 0) continue;\n const packedBytes =\n ATTRIBUTE_FORMAT_BYTES[binding.format] * binding.components;\n const start = binding.data.byteOffset + binding.byteOffset;\n const end = start + (binding.count - 1) * binding.byteStride + packedBytes;\n const ranges = rangesByBuffer.get(binding.data.buffer) ?? [];\n ranges.push({ start, end, attribute: attributes[index] });\n rangesByBuffer.set(binding.data.buffer, ranges);\n }\n\n const regions: AttributeRegion[] = [];\n let byteLength = 0;\n for (const [buffer, ranges] of rangesByBuffer) {\n ranges.sort((left, right) => left.start - right.start);\n let region: AttributeRegion | undefined;\n for (const { start, end, attribute } of ranges) {\n if (region && start <= region.end) {\n byteLength += Math.max(0, end - region.end);\n region.end = Math.max(region.end, end);\n } else {\n region = { buffer, start, end, outputOffset: byteLength };\n regions.push(region);\n byteLength += end - start;\n }\n attribute.byteOffset = region.outputOffset + start - region.start;\n }\n }\n\n const data = new Uint8Array(byteLength);\n for (const region of regions) {\n data.set(\n new Uint8Array(region.buffer, region.start, region.end - region.start),\n region.outputOffset,\n );\n }\n\n return { data, attributes };\n}\n","import {\n ProgramBuilder,\n type SplatPostDecodeContext,\n type SplatPostDecodePatch,\n buildOutputs,\n} from \"./builder\";\nimport {\n compileProgram,\n packInstructions,\n snapshotAttributes,\n} from \"./compiler\";\nimport type {\n SerializedSplatPostDecode,\n SplatPostDecodeOutputs,\n} from \"./protocol\";\n\nconst SPLAT_POST_DECODE_PROGRAM = Symbol(\"SplatPostDecodeProgram\");\n\nexport type SplatPostDecodeProgram = {\n readonly [SPLAT_POST_DECODE_PROGRAM]: true;\n};\n\nclass SplatPostDecodeProgramImpl implements SplatPostDecodeProgram {\n readonly [SPLAT_POST_DECODE_PROGRAM] = true as const;\n\n private readonly compiled: ReturnType<typeof compileProgram>;\n\n constructor(builder: ProgramBuilder, outputs: SplatPostDecodeOutputs) {\n this.compiled = compileProgram(builder, outputs);\n }\n\n static serialize(program: SplatPostDecodeProgram): SerializedSplatPostDecode {\n if (!(program instanceof SplatPostDecodeProgramImpl)) {\n throw new Error(\"Invalid postDecode program\");\n }\n const compiled = program.compiled;\n const snapshot = snapshotAttributes(compiled.attributes);\n return {\n instructions: packInstructions(compiled.instructions),\n constants: new Float32Array(compiled.constants),\n outputs: compiled.outputs,\n condition: compiled.condition,\n attributeData: snapshot.data,\n attributes: snapshot.attributes,\n };\n }\n}\n\n/** @internal */\nexport function serializeSplatPostDecode(\n program: SplatPostDecodeProgram,\n): SerializedSplatPostDecode {\n return SplatPostDecodeProgramImpl.serialize(program);\n}\n\nfunction defineSplatPostDecode(\n build: (context: SplatPostDecodeContext) => SplatPostDecodePatch,\n): SplatPostDecodeProgram {\n const builder = new ProgramBuilder();\n const patch = build({\n splat: builder.splat,\n op: builder.op,\n attribute: (options) => builder.attribute(options),\n });\n if (!patch || typeof patch !== \"object\") {\n throw new Error(\"postDecode builder must return a splat patch object\");\n }\n return new SplatPostDecodeProgramImpl(builder, buildOutputs(builder, patch));\n}\n\nexport const postDecode = {\n define: defineSplatPostDecode,\n};\n","import { DefaultLoadingManager, type Loader } from \"three\";\nimport type { ReorderedSplatResult, SplatFileType } from \"../data/defines\";\nimport { workerPool } from \"../runtime/SplatWorker\";\nimport { abortable, linkedAbortController } from \"../runtime/abort\";\nimport { getAssetBaseUrl } from \"./assetUrl\";\nimport type {\n SplatFileResolver,\n SplatLoadStatus,\n SplatProgressEvent,\n} from \"./loadTypes\";\nimport {\n type SplatPostDecodeProgram,\n serializeSplatPostDecode,\n} from \"./postDecode/program\";\n\nexport type SplatDataLoadOptions = {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n resolveFile?: SplatFileResolver;\n postDecode?: SplatPostDecodeProgram;\n signal?: AbortSignal;\n onProgress?: (event: SplatProgressEvent) => void;\n onLoad?: (decoded: ReorderedSplatResult) => void;\n onError?: (error: unknown) => void;\n};\n\ntype SplatLoadContext = Pick<\n Loader,\n \"manager\" | \"path\" | \"requestHeader\" | \"withCredentials\"\n>;\n\n/** Loads packed data without constructing scene objects or GPU textures. */\nexport async function loadSplatData(\n {\n url,\n file,\n fileBytes,\n fileType,\n fileName,\n resolveFile,\n postDecode,\n signal,\n onLoad,\n onProgress,\n onError,\n }: SplatDataLoadOptions,\n context: SplatLoadContext = {\n manager: DefaultLoadingManager,\n path: \"\",\n requestHeader: {},\n withCredentials: false,\n },\n): Promise<ReorderedSplatResult> {\n let resolvedURL: string | undefined;\n let started = false;\n const request = linkedAbortController(signal);\n const { controller } = request;\n try {\n signal?.throwIfAborted();\n // Snapshot application attributes at the load call, before waiting for a worker.\n const serializedPostDecode = postDecode\n ? serializeSplatPostDecode(postDecode)\n : undefined;\n if (\n [url, file, fileBytes].filter((input) => input !== undefined).length !== 1\n ) {\n throw new Error(\"Provide exactly one of url, file, or fileBytes\");\n }\n fileName ??= (file as File | undefined)?.name;\n const byteArray =\n fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;\n const resourcePath = url === undefined ? undefined : context.path + url;\n resolvedURL =\n resourcePath === undefined\n ? undefined\n : context.manager.resolveURL(resourcePath);\n started = true;\n context.manager.itemStart(resolvedURL ?? \"\");\n\n const pathName = resolvedURL || fileName;\n const requestUrl = new URL(pathName || \"\", window.location.href).href;\n const resourceUrl = new URL(\n resourcePath || fileName || \"\",\n window.location.href,\n ).href;\n const memoryHeavy =\n fileType === \"sog\" ||\n (!fileType && !/\\.(ply|spz)(?:[?#]|$)/i.test(pathName ?? \"\"));\n const decoded = await workerPool.withWorker(\n (worker) =>\n worker.call(\n \"loadSplats\",\n {\n url: resolvedURL ? requestUrl : undefined,\n requestHeader: context.requestHeader,\n withCredentials: context.withCredentials,\n file,\n fileBytes: byteArray?.slice(),\n fileType,\n pathName,\n hasFileResolver: resolveFile !== undefined,\n reportProcessingProgress: onProgress !== undefined,\n baseUrl: getAssetBaseUrl(requestUrl) ?? resourceUrl,\n postDecode: serializedPostDecode,\n },\n {\n signal: controller.signal,\n onStatus: async (data) => {\n const status = data as SplatLoadStatus;\n if (\"assetRequest\" in status) {\n return worker.call(\"resolveAsset\", {\n requestId: status.assetRequest,\n url: new URL(\n context.manager.resolveURL(status.url),\n window.location.href,\n ).href,\n });\n }\n if (\"fileRequest\" in status) {\n if (!resolveFile) throw new Error(\"No external file resolver\");\n const input = await abortable(\n Promise.resolve(\n resolveFile(status.filename, controller.signal),\n ),\n controller.signal,\n );\n controller.signal.throwIfAborted();\n return worker.call(\"resolveFile\", {\n requestId: status.fileRequest,\n input:\n input instanceof Uint8Array\n ? input.slice()\n : input instanceof ArrayBuffer\n ? input.slice(0)\n : input,\n });\n }\n if (onProgress) {\n try {\n onProgress(\n Object.assign(\n new ProgressEvent(\"progress\", {\n lengthComputable: status.total !== 0,\n loaded: status.loaded,\n total: status.total,\n }),\n { stage: status.stage ?? \"download\" },\n ),\n );\n } catch (error) {\n console.error(\"Progress callback failed\", error);\n }\n }\n },\n },\n ),\n memoryHeavy,\n controller.signal,\n );\n signal?.throwIfAborted();\n onLoad?.(decoded);\n return decoded;\n } catch (error) {\n if (started) context.manager.itemError(resolvedURL ?? \"\");\n onError?.(error);\n throw error;\n } finally {\n request.cleanup();\n controller.abort();\n if (started) context.manager.itemEnd(resolvedURL ?? \"\");\n }\n}\n","import { Loader } from \"three\";\nimport { Splats } from \"../data/Splats\";\nimport { linkedAbortController } from \"../runtime/abort\";\nimport { SplatMesh } from \"../scene/SplatMesh\";\nimport { type SplatDataLoadOptions, loadSplatData } from \"./loadSplatData\";\nimport type { SplatProgressEvent } from \"./loadTypes\";\n\ntype SplatLoadOptions = Omit<SplatDataLoadOptions, \"onLoad\"> & {\n splats?: Splats;\n onLoad?: (decoded: Splats) => void;\n};\n\n// SplatLoader implements the THREE.Loader interface for PLY, SPZ, SOG and RAD.\nexport class SplatLoader extends Loader {\n private readonly requests = new Set<AbortController>();\n\n override abort() {\n for (const request of this.requests)\n request.abort(new DOMException(\"Splat load aborted\", \"AbortError\"));\n return this;\n }\n\n load(\n url: string,\n onLoad?: (decoded: Splats) => void,\n onProgress?: (event: SplatProgressEvent) => void,\n onError?: (error: unknown) => void,\n ) {\n return this.loadInternal({ url, onLoad, onProgress, onError });\n }\n\n loadAsync(\n url: string,\n onProgress?: (event: SplatProgressEvent) => void,\n signal?: AbortSignal,\n ): Promise<Splats> {\n return this.loadInternalAsync({ url, onProgress, signal });\n }\n\n parse(splats: Splats): SplatMesh {\n return new SplatMesh({ splats });\n }\n\n loadInternal(options: SplatLoadOptions) {\n void this.loadInternalAsync(options).catch(() => {});\n }\n\n async loadInternalAsync({\n splats,\n onLoad,\n ...options\n }: SplatLoadOptions): Promise<Splats> {\n const request = linkedAbortController(options.signal);\n this.requests.add(request.controller);\n try {\n let result!: Splats;\n await loadSplatData(\n {\n ...options,\n signal: request.signal,\n onLoad: (decoded) => {\n result = splats ?? new Splats();\n result.initializeDecoded(decoded);\n onLoad?.(result);\n },\n },\n this,\n );\n return result;\n } finally {\n this.requests.delete(request.controller);\n request.cleanup();\n }\n }\n}\n","import * as THREE from \"three\";\nimport { SPLAT_TEX_HEIGHT, SPLAT_TEX_WIDTH } from \"./defines\";\n\nconst GROUP_LAYER_SIZE = SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT;\n\ntype OpacityRange = { first: number; last: number; refs: number };\n\n/** Source blocks hold group IDs; a small float32 table holds their opacities. */\nexport class SplatOpacityTable {\n private blocks: Uint32Array;\n private readonly blockSize: number;\n private readonly blocksPerLayer: number;\n private readonly blockTexture: THREE.DataArrayTexture;\n private dirtyLayers: Uint8Array;\n private dirty = false;\n // Transparent, stable, RAD incoming and RAD outgoing groups.\n private values = new Float32Array([0, 1, 0, 1]);\n private valueTexture = this.createValueTexture();\n private valuesDirty = false;\n private readonly ranges = new Map<number, OpacityRange>();\n private readonly freeGroups: number[] = [];\n private nextGroup = 4;\n\n constructor(capacity: number, layerSize: number, blockBits: number) {\n this.blockSize = 2 ** blockBits;\n this.blocksPerLayer = layerSize / this.blockSize;\n this.blocks = new Uint32Array(capacity / this.blockSize);\n const width = Math.min(SPLAT_TEX_WIDTH, this.blocksPerLayer);\n this.blockTexture = this.createTexture(\n this.blocks,\n width,\n this.blocksPerLayer / width,\n capacity / layerSize,\n );\n this.dirtyLayers = new Uint8Array(capacity / layerSize);\n }\n\n private createTexture(\n data: Uint32Array,\n width: number,\n height: number,\n depth: number,\n ) {\n const texture = new THREE.DataArrayTexture(data, width, height, depth);\n texture.format = THREE.RedIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n }\n\n private createValueTexture() {\n const count = this.values.length;\n return this.createTexture(\n new Uint32Array(this.values.buffer),\n Math.min(SPLAT_TEX_WIDTH, count),\n Math.min(SPLAT_TEX_HEIGHT, Math.ceil(count / SPLAT_TEX_WIDTH)),\n Math.ceil(count / GROUP_LAYER_SIZE),\n );\n }\n\n /** CPU arrays and GPU storage each occupy this many bytes. */\n get byteLength() {\n return this.blocks.byteLength + this.values.byteLength;\n }\n\n getOpacity(source: number) {\n return this.values[this.blocks[Math.floor(source / this.blockSize)]];\n }\n\n setGroupOpacity(group: number, opacity: number) {\n const value = Math.fround(opacity);\n if (this.values[group] === value) return false;\n this.values[group] = value;\n this.valuesDirty = true;\n return true;\n }\n\n private releaseBlock(group: number) {\n if (group < 4) return;\n const range = this.ranges.get(group) as OpacityRange;\n if (--range.refs === 0) {\n this.ranges.delete(group);\n this.freeGroups.push(group);\n }\n }\n\n /** Validated ranges retain their group while only its coefficient changes. */\n setOpacity(start: number, count: number, opacity: number) {\n const first = Math.floor(start / this.blockSize);\n const last = Math.ceil((start + count) / this.blockSize);\n const previous = this.blocks[first];\n const range = this.ranges.get(previous);\n if (\n range?.first === first &&\n range.last === last &&\n range.refs === last - first\n )\n return this.setGroupOpacity(previous, opacity);\n\n const value = Math.fround(opacity);\n let block = first;\n while (block < last && this.values[this.blocks[block]] === value) block++;\n if (block === last) return false;\n const group = this.freeGroups.pop() ?? this.nextGroup++;\n if (group >= this.values.length) {\n const values = new Float32Array(this.values.length * 2);\n values.set(this.values);\n this.values = values;\n this.valueTexture.dispose();\n this.valueTexture = this.createValueTexture();\n }\n this.ranges.set(group, { first, last, refs: last - first });\n this.values[group] = value;\n this.valuesDirty = true;\n for (let index = first; index < last; index++) {\n this.releaseBlock(this.blocks[index]);\n this.blocks[index] = group;\n }\n this.dirtyLayers.fill(\n 1,\n Math.floor(first / this.blocksPerLayer),\n Math.ceil(last / this.blocksPerLayer),\n );\n this.dirty = true;\n return true;\n }\n\n copyBlocks() {\n return this.blocks.slice();\n }\n\n /** Adopt a prepared RAD table, retaining any uploads still pending. */\n commitBlocks(blocks: Uint32Array, dirtyLayers: Uint8Array) {\n this.blocks = blocks;\n this.blockTexture.image.data = blocks;\n for (let layer = 0; layer < dirtyLayers.length; layer++) {\n if (!dirtyLayers[layer]) continue;\n this.dirtyLayers[layer] = 1;\n this.dirty = true;\n }\n }\n\n get texture() {\n if (this.dirty) {\n for (let layer = 0; layer < this.dirtyLayers.length; layer++) {\n if (!this.dirtyLayers[layer]) continue;\n this.blockTexture.addLayerUpdate(layer);\n this.dirtyLayers[layer] = 0;\n }\n this.blockTexture.needsUpdate = true;\n this.dirty = false;\n }\n return this.blockTexture;\n }\n\n get opacityTexture() {\n if (this.valuesDirty) {\n this.valueTexture.needsUpdate = true;\n this.valuesDirty = false;\n }\n return this.valueTexture;\n }\n\n dispose() {\n this.blockTexture.dispose();\n this.valueTexture.dispose();\n this.blockTexture.image.data = new Uint32Array(0);\n this.valueTexture.image.data = new Uint32Array(0);\n this.blocks = new Uint32Array(0);\n this.values = new Float32Array(0);\n this.dirtyLayers = new Uint8Array(0);\n this.ranges.clear();\n this.freeGroups.length = 0;\n this.dirty = this.valuesDirty = false;\n }\n}\n","import * as THREE from \"three\";\nimport { SplatOpacityTable } from \"./SplatOpacityTable\";\nimport { Splats, type SplatsOptions } from \"./Splats\";\nimport {\n type ReorderedSplatResult,\n SPLAT_BOUNDS_BLOCK_SIZE,\n SPLAT_TEX_WIDTH,\n type SplatResult,\n} from \"./defines\";\nimport type { RaycastRangeCallback, SplatRaycastQuery } from \"./raycast\";\nimport { decodeShRgbToArray } from \"./splatCodec\";\nimport { SH_ARRAY_COUNTS, SH_KEYS } from \"./splatData\";\nimport { getTextureSize } from \"./textureLayout\";\nimport { decodeSplat } from \"./unpack\";\n\ntype IndexedSplatsOptions = {\n capacity: number;\n layerSize: number;\n numSh: number;\n blockBits: number;\n};\n\nfunction makeTexture(\n data: Uint32Array,\n width: number,\n height: number,\n depth: number,\n) {\n const texture = new THREE.DataArrayTexture(data, width, height, depth);\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n return texture;\n}\n\ntype DecodedSplat = ReturnType<typeof decodeSplat>;\ntype DecodedSplatWithSh = DecodedSplat & { sh: THREE.Color[] };\n\n/** Fixed packed storage with one visible-index contract for rendering and CPU reads.\n * Fades affect display only: records returned to picking retain their source opacity. */\nexport abstract class IndexedSplats extends Splats {\n readonly layerSize: number;\n readonly numSh: 0 | 1 | 2 | 3;\n protected readonly opacities: SplatOpacityTable;\n protected sourceIndices = new Uint32Array(0);\n protected visibleIndices: Uint32Array;\n private sourceArrays: Uint32Array[];\n private sourceCenters: Float32Array;\n private sourceTextures: THREE.DataArrayTexture[];\n private indexTexture = Splats.emptyTexture;\n private readonly blockBits: number;\n private disposed = false;\n private readonly spatialChunks = new Map<\n number,\n { count: number; bounds: Float32Array }\n >();\n private spatialBoundsBytes = 0;\n\n constructor({ capacity, layerSize, numSh, blockBits }: IndexedSplatsOptions) {\n // RAD and SOG layout helpers supply aligned power-of-two layers.\n if (capacity > 0x1_0000_0000)\n throw new Error(\"Indexed Splat capacity exceeds 32-bit addressing\");\n super();\n this.maxSplats = capacity;\n this.layerSize = layerSize;\n this.numSh = numSh as 0 | 1 | 2 | 3;\n this.blockBits = blockBits;\n this.opacities = new SplatOpacityTable(capacity, layerSize, blockBits);\n this.sourceArrays = Array.from(\n { length: 2 + SH_ARRAY_COUNTS[numSh] },\n () => new Uint32Array(capacity * 4),\n );\n this.sourceCenters = new Float32Array(this.sourceArrays[0].buffer);\n this.sourceIds = new Uint32Array(capacity);\n this.visibleIndices = new Uint32Array(capacity);\n this.sourceTextures = this.sourceArrays.map((array) =>\n makeTexture(\n array,\n SPLAT_TEX_WIDTH,\n layerSize / SPLAT_TEX_WIDTH,\n capacity / layerSize,\n ),\n );\n }\n\n protected assertLive() {\n if (this.disposed) throw new Error(\"Streaming Splat source is disposed\");\n }\n\n override initialize(options: SplatsOptions = {}) {\n // Splats calls initialize once during super(); fixed storage is installed next.\n if (this.sourceArrays !== undefined)\n throw new Error(\"Streaming sources cannot be reinitialized\");\n return super.initialize(options);\n }\n\n /** Range-based sources can materialize their visible map lazily. */\n protected ensureIndices() {}\n\n /** Each source updates its bounds independently of the visible-index map. */\n protected commitIndices(indices: Uint32Array) {\n const target = this.prepareIndices(indices.length);\n for (let index = 0; index < indices.length; index++) {\n const source = indices[index];\n target[index] = source;\n this.visibleIndices[source] = index;\n }\n }\n\n /** Reserve index storage and mark it for upload; fill the first count entries synchronously. */\n protected prepareIndices(count: number) {\n this.assertLive();\n if (\n count > this.sourceIndices.length ||\n count < this.sourceIndices.length / 4\n ) {\n const layout = getTextureSize(Math.max(1, Math.ceil(count / 4)), 1);\n const capacity = layout.maxSplats * 4;\n if (capacity !== this.sourceIndices.length) {\n if (this.indexTexture !== Splats.emptyTexture)\n this.indexTexture.dispose();\n this.sourceIndices = new Uint32Array(capacity);\n this.indexTexture = makeTexture(\n this.sourceIndices,\n layout.width,\n layout.height,\n layout.depth,\n );\n }\n }\n this.numSplats = count;\n if (this.indexTexture !== Splats.emptyTexture)\n this.indexTexture.needsUpdate = true;\n this.needsUpdate = true;\n return this.sourceIndices;\n }\n\n /** Copies packed records. Input buffers remain caller-owned for both formats. */\n protected writeRecords(\n start: number,\n data: ReorderedSplatResult,\n allocation: number,\n ) {\n this.assertLive();\n const count = data.numSplats;\n if (\n !Number.isSafeInteger(start) ||\n start < 0 ||\n !Number.isSafeInteger(count) ||\n count < 0 ||\n !Number.isSafeInteger(allocation) ||\n allocation < count ||\n start + allocation > this.maxSplats\n )\n throw new Error(\"Invalid streaming Splat write range\");\n const arrays = [\n ...data.splatArrays,\n ...SH_KEYS.slice(0, SH_ARRAY_COUNTS[this.numSh]).map(\n (key) => data.extra[key],\n ),\n ];\n if (\n arrays.length !== this.sourceArrays.length ||\n data.sourceIds.length < count ||\n arrays.some(\n (array) =>\n count > 0 &&\n (!(array instanceof Uint32Array) || array.length < count * 4),\n )\n )\n throw new Error(\"Incomplete packed Splat or SH records\");\n if (\n data.spatialBounds?.length !==\n Math.ceil(count / SPLAT_BOUNDS_BLOCK_SIZE) * 6\n )\n throw new Error(\"Incorrect spatial bounds block length\");\n this.releaseSpatialBounds(start);\n // Packed data remains caller-owned, as do its spatial bounds.\n const bounds = data.spatialBounds.slice();\n this.spatialChunks.set(start, { count, bounds });\n this.spatialBoundsBytes += bounds.byteLength;\n this.sourceIds.set(data.sourceIds.subarray(0, count), start);\n this.sourceIds.fill(0, start + count, start + allocation);\n const firstLayer = Math.floor(start / this.layerSize);\n const lastLayer = Math.ceil((start + allocation) / this.layerSize);\n for (let index = 0; index < this.sourceArrays.length; index++) {\n const target = this.sourceArrays[index];\n const source = arrays[index];\n if (source) target.set(source.subarray(0, count * 4), start * 4);\n target.fill(0, (start + count) * 4, (start + allocation) * 4);\n for (let layer = firstLayer; layer < lastLayer; layer++)\n this.sourceTextures[index].addLayerUpdate(layer);\n this.sourceTextures[index].needsUpdate = true;\n }\n this.needsUpdate = true;\n }\n\n private getStorageIndex(index: number) {\n this.assertLive();\n this.ensureIndices();\n this.checkVisibleRange(index, 1);\n return this.sourceIndices[index];\n }\n\n override getSourceIndex(index: number) {\n return this.sourceIds[this.getStorageIndex(index)];\n }\n\n private checkVisibleRange(start: number, count: number) {\n if (\n !Number.isSafeInteger(start) ||\n start < 0 ||\n !Number.isSafeInteger(count) ||\n count < 0 ||\n start + count > this.numSplats\n )\n throw new Error(\"Invalid visible Splat range\");\n }\n\n override getNumSh() {\n return this.numSh;\n }\n\n private get textureByteLength() {\n return (\n this.sourceArrays.reduce((bytes, array) => bytes + array.byteLength, 0) +\n this.sourceIndices.byteLength +\n this.opacities.byteLength\n );\n }\n\n override getByteLength() {\n return (\n this.textureByteLength +\n this.sourceIds.byteLength +\n this.centerOnlyBounds.byteLength +\n this.bounds.byteLength +\n this.spatialBoundsBytes +\n this.visibleIndices.byteLength\n );\n }\n\n get residentBytes() {\n return this.getByteLength() + this.textureByteLength;\n }\n\n private center(source: number, axis: number) {\n const second = this.sourceArrays[1];\n const base = source * 4;\n return second[base + 1] >>> 16 === 0xfc00 && second[base + 2] === 0xfc00fc00\n ? Number.NaN\n : this.sourceCenters[base + axis];\n }\n\n override copySortCenters(\n target: Float32Array,\n targetStart: number,\n count: number,\n ) {\n this.assertLive();\n this.ensureIndices();\n this.checkVisibleRange(0, count);\n if (\n !Number.isSafeInteger(targetStart) ||\n targetStart < 0 ||\n targetStart + count * 3 > target.length\n )\n throw new Error(\"Invalid sort center target range\");\n for (let index = 0; index < count; index++)\n for (let axis = 0; axis < 3; axis++)\n target[targetStart + index * 3 + axis] = this.center(\n this.sourceIndices[index],\n axis,\n );\n }\n\n protected releaseSpatialBounds(start: number) {\n const chunk = this.spatialChunks.get(start);\n if (chunk) {\n this.spatialBoundsBytes -= chunk.bounds.byteLength;\n this.spatialChunks.delete(start);\n }\n }\n\n override forEachRaycastRange(\n query: SplatRaycastQuery,\n callback: RaycastRangeCallback,\n ) {\n this.assertLive();\n this.ensureIndices();\n let rangeStart = -1;\n let rangeEnd = -1;\n for (const [start, { count, bounds }] of this.spatialChunks) {\n query.forEachRange(bounds, count, (base, length) => {\n for (\n let source = start + base;\n source < start + base + length;\n source++\n ) {\n const index = this.visibleIndices[source];\n // Validate against the current cut so hidden slots need no clearing.\n if (index >= this.numSplats || this.sourceIndices[index] !== source)\n continue;\n if (index !== rangeEnd) {\n if (rangeStart >= 0) callback(rangeStart, rangeEnd - rangeStart);\n rangeStart = index;\n }\n rangeEnd = index + 1;\n }\n });\n }\n if (rangeStart >= 0) callback(rangeStart, rangeEnd - rangeStart);\n }\n\n override copySplatRecords(\n firstTarget: Uint32Array,\n secondTarget: Uint32Array,\n sourceStart: number,\n count: number,\n ) {\n this.assertLive();\n this.ensureIndices();\n this.checkVisibleRange(sourceStart, count);\n if (firstTarget.length < count * 4 || secondTarget.length < count * 4)\n throw new Error(\"Splat record target is too small\");\n for (let index = 0; index < count; index++) {\n const source = this.sourceIndices[sourceStart + index] * 4;\n for (let word = 0; word < 4; word++) {\n firstTarget[index * 4 + word] = this.sourceArrays[0][source + word];\n secondTarget[index * 4 + word] = this.sourceArrays[1][source + word];\n }\n }\n }\n\n override getSplat(index: number): DecodedSplatWithSh;\n override getSplat(index: number, includeSh: true): DecodedSplatWithSh;\n override getSplat(index: number, includeSh: false): DecodedSplat;\n override getSplat(index: number, includeSh: boolean): DecodedSplat;\n override getSplat(index: number, includeSh = true) {\n const source = this.getStorageIndex(index);\n const splat = decodeSplat(\n [this.sourceArrays[0], this.sourceArrays[1]],\n source,\n );\n if (!includeSh) return splat;\n const rgb = [0, 0, 0];\n const sh = Array.from(\n { length: [0, 3, 8, 15][this.numSh] },\n (_, coefficient) => {\n const word =\n this.sourceArrays[2 + (coefficient >> 2)][\n source * 4 + (coefficient & 3)\n ];\n decodeShRgbToArray(word, rgb);\n return new THREE.Color(rgb[0], rgb[1], rgb[2]);\n },\n );\n return { ...splat, sh };\n }\n\n override forEachCenter(\n callback: (index: number, x: number, y: number, z: number) => void,\n ) {\n this.assertLive();\n this.ensureIndices();\n for (let index = 0; index < this.numSplats; index++) {\n const source = this.sourceIndices[index];\n callback(\n index,\n this.center(source, 0),\n this.center(source, 1),\n this.center(source, 2),\n );\n }\n }\n\n override forEachSplat(callback: Parameters<Splats[\"forEachSplat\"]>[0]) {\n this.assertLive();\n this.ensureIndices();\n let splat: ReturnType<typeof decodeSplat> | undefined;\n const records: [Uint32Array, Uint32Array] = [\n this.sourceArrays[0],\n this.sourceArrays[1],\n ];\n for (let index = 0; index < this.numSplats; index++) {\n splat = decodeSplat(records, this.sourceIndices[index], splat);\n callback(\n index,\n splat.center,\n splat.scales,\n splat.quaternion,\n splat.opacity,\n splat.color,\n );\n }\n }\n\n override takeData(): SplatResult & { sourceIds: Uint32Array } {\n this.assertLive();\n this.ensureIndices();\n const count = this.numSplats;\n const sourceIds = new Uint32Array(count);\n for (let i = 0; i < count; i++)\n sourceIds[i] = this.sourceIds[this.sourceIndices[i]];\n const arrays = this.sourceArrays.map((source) => {\n const target = new Uint32Array(count * 4);\n for (let index = 0; index < count; index++) {\n const offset = this.sourceIndices[index] * 4;\n for (let word = 0; word < 4; word++)\n target[index * 4 + word] = source[offset + word];\n }\n return target;\n });\n const data = {\n numSplats: count,\n splatArrays: [arrays[0], arrays[1]],\n sourceIds,\n extra: Object.fromEntries(\n arrays.slice(2).map((array, index) => [SH_KEYS[index], array]),\n ),\n } satisfies SplatResult;\n this.dispose();\n return data;\n }\n\n override setTextureUniforms(uniforms: Record<string, THREE.IUniform>) {\n this.assertLive();\n this.ensureIndices();\n uniforms.sourceSplats.value = this.sourceTextures[0];\n uniforms.sourceSplats2.value = this.sourceTextures[1];\n uniforms.sh1Texture.value = this.sourceTextures[2] ?? Splats.emptyTexture;\n uniforms.sh2Texture.value = this.sourceTextures[3] ?? Splats.emptyTexture;\n uniforms.sh3TextureA.value = this.sourceTextures[4] ?? Splats.emptyTexture;\n uniforms.sh3TextureB.value = this.sourceTextures[5] ?? Splats.emptyTexture;\n uniforms.sourceLayerBits.value = Math.log2(this.layerSize);\n uniforms.sourceLayerMask.value = this.layerSize - 1;\n uniforms.sourceBlockBits.value = this.blockBits;\n uniforms.sourceBlocks.value = this.opacities.texture;\n uniforms.sourceOpacities.value = this.opacities.opacityTexture;\n uniforms.sourceIndexed.value = true;\n uniforms.sourceIndices.value = this.indexTexture;\n this.needsUpdate = false;\n }\n\n override dispose() {\n if (this.disposed) return;\n super.dispose();\n for (const texture of this.sourceTextures) texture.dispose();\n if (this.indexTexture !== Splats.emptyTexture) this.indexTexture.dispose();\n this.opacities.dispose();\n this.sourceArrays = [];\n this.sourceTextures = [];\n this.sourceCenters = new Float32Array(0);\n this.sourceIndices = new Uint32Array(0);\n this.visibleIndices = new Uint32Array(0);\n this.indexTexture = Splats.emptyTexture;\n this.spatialChunks.clear();\n this.spatialBoundsBytes = 0;\n this.disposed = true;\n }\n}\n","import { IndexedSplats } from \"./IndexedSplats\";\nimport {\n type ReorderedSplatResult,\n SPLAT_TEX_HEIGHT,\n SPLAT_TEX_WIDTH,\n} from \"./defines\";\nimport { resetSplatBounds } from \"./splatData\";\n\nexport type RadPagedSplatsOptions = {\n /** Maximum records in one decoded chunk. Defaults to Spark's 65,536. */\n pageSize?: number;\n pageCount: number;\n numSh: number;\n /** Pass the device limit when known. WebGL2 guarantees at least 256. */\n maxArrayLayers?: number;\n};\n\n/** Page ranges in a sorted, file-global cut; used only by RAD streaming. */\nexport type RadSelectionRange = {\n start: number;\n end: number;\n slot: number;\n pageStart: number;\n chunkIndex: number;\n sourceBase: number;\n};\n\nexport type RadSelectionSnapshot = {\n pageCount: number;\n opacityBlocks: Uint32Array;\n ranges: RadSelectionRange[];\n};\n\ntype RadPreparedCut = {\n indices: Uint32Array;\n selectedPages: Uint32Array;\n centerOnlyBoundingBox: Float32Array;\n boundingBox: Float32Array;\n};\n\nexport type RadPreparedSelection = RadPreparedCut & {\n opacityBlocks: Uint32Array;\n dirtyLayers: Uint8Array;\n fadeKinds: number;\n final?: RadPreparedCut;\n};\n\nconst EMPTY_INDICES = new Uint32Array(0);\n\n/** One power-of-two texture layer per page, with no shared upload layers. */\nexport function radPageTextureLayout({\n pageSize = 65_536,\n pageCount,\n maxArrayLayers = 256,\n}: Omit<RadPagedSplatsOptions, \"numSh\">) {\n if (\n !Number.isSafeInteger(pageSize) ||\n pageSize < 1 ||\n pageSize > SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT\n )\n throw new Error(\"RAD pageSize must be between 1 and 4,194,304\");\n if (\n !Number.isSafeInteger(maxArrayLayers) ||\n maxArrayLayers < 1 ||\n !Number.isSafeInteger(pageCount) ||\n pageCount < 1 ||\n pageCount > maxArrayLayers\n )\n throw new Error(\"RAD pageCount exceeds the texture array layer limit\");\n const pageStride =\n 2 ** Math.ceil(Math.log2(Math.max(SPLAT_TEX_WIDTH, pageSize)));\n const capacity = pageStride * pageCount;\n if (capacity > 0x1_0000_0000)\n throw new Error(\"RAD page pool exceeds the 32-bit source index limit\");\n return {\n pageSize,\n pageStride,\n pageCount,\n capacity,\n width: SPLAT_TEX_WIDTH,\n height: pageStride / SPLAT_TEX_WIDTH,\n depth: pageCount,\n };\n}\n\n/** Fixed RAD page slots; shared IndexedSplats owns rendering and CPU access. */\nexport class RadPagedSplats extends IndexedSplats {\n readonly pageSize: number;\n readonly pageStride: number;\n readonly pageCount: number;\n private selectedPages: Uint32Array;\n private finalSelection?: RadPreparedCut;\n private fadeProgress = 1;\n private fadeKinds = 0;\n\n constructor(options: RadPagedSplatsOptions) {\n const layout = radPageTextureLayout(options);\n super({\n capacity: layout.capacity,\n layerSize: layout.pageStride,\n numSh: options.numSh,\n blockBits: 0,\n });\n this.pageSize = layout.pageSize;\n this.pageStride = layout.pageStride;\n this.pageCount = layout.pageCount;\n this.selectedPages = new Uint32Array(this.pageCount);\n }\n\n pageStart(slot: number) {\n return slot * this.pageStride;\n }\n\n /** Copies data; callers retain ownership of the packed buffers. */\n writePage(slot: number, data: ReorderedSplatResult) {\n const start = this.pageStart(slot);\n if (data.numSplats > this.pageSize)\n throw new Error(\"RAD chunk does not fit its page slot\");\n this.writeRecords(start, data, this.pageStride);\n }\n\n /** Remove the displayed cut when its scheduler becomes hidden. */\n clearSelection() {\n this.assertLive();\n if (!this.numSplats) return false;\n this.commitIndices(EMPTY_INDICES);\n this.selectedPages.fill(0);\n resetSplatBounds(this.centerOnlyBounds);\n resetSplatBounds(this.bounds);\n this.finalSelection = undefined;\n this.fadeKinds = 0;\n this.fadeProgress = 1;\n this.opacities.setGroupOpacity(2, 1);\n this.opacities.setGroupOpacity(3, 1);\n return true;\n }\n\n /** Snapshot only changed pools; never transfer live texture storage. */\n snapshotSelection(ranges: RadSelectionRange[]): RadSelectionSnapshot {\n this.assertLive();\n return {\n pageCount: this.pageCount,\n opacityBlocks: this.opacities.copyBlocks(),\n ranges,\n };\n }\n\n /** Internal commit of worker-prepared data; the caller gives up the arrays. */\n commitSelection(prepared: RadPreparedSelection) {\n this.commitCut(prepared);\n this.finalSelection = prepared.final;\n this.fadeKinds = prepared.fadeKinds;\n this.fadeProgress = this.fadeKinds ? 0 : 1;\n this.opacities.setGroupOpacity(2, this.fadeKinds ? 0 : 1);\n this.opacities.setGroupOpacity(3, 1);\n this.opacities.commitBlocks(prepared.opacityBlocks, prepared.dirtyLayers);\n }\n\n /** Keep record indices, page occupancy and bounds on the same cut. */\n private commitCut(cut: RadPreparedCut) {\n this.commitIndices(cut.indices);\n this.selectedPages = cut.selectedPages;\n this.centerOnlyBounds = cut.centerOnlyBoundingBox;\n this.bounds = cut.boundingBox;\n }\n\n /** A normal streaming fade changes only two group coefficients. */\n setFadeProgress(progress: number) {\n this.assertLive();\n if (progress === this.fadeProgress) return false;\n this.fadeProgress = progress;\n if (!this.fadeKinds) return false;\n const fadeIn = this.opacities.setGroupOpacity(2, progress);\n const fadeOut = this.opacities.setGroupOpacity(3, 1 - progress);\n return (\n (!!(this.fadeKinds & 1) && fadeIn) || (!!(this.fadeKinds & 2) && fadeOut)\n );\n }\n\n isPageSelected(slot: number) {\n return this.selectedPages[slot] > 0;\n }\n\n /** Complete opacity changes without removing outgoing records. */\n finishFadeIn() {\n const changed = this.setFadeProgress(1);\n this.finalSelection = undefined;\n this.fadeKinds = 0;\n return changed;\n }\n\n /** The worker already removed outgoing records from the final cut. */\n finishFade() {\n if (!this.finalSelection) return this.finishFadeIn();\n this.commitCut(this.finalSelection);\n this.finishFadeIn();\n return true;\n }\n\n override getByteLength() {\n return (\n super.getByteLength() +\n (this.finalSelection?.indices.byteLength ?? 0) +\n (this.finalSelection?.selectedPages.byteLength ?? 0) +\n (this.finalSelection?.centerOnlyBoundingBox.byteLength ?? 0) +\n (this.finalSelection?.boundingBox.byteLength ?? 0) +\n this.selectedPages.byteLength\n );\n }\n\n override dispose() {\n super.dispose();\n this.selectedPages = new Uint32Array(0);\n this.finalSelection = undefined;\n }\n}\n","/** Exponential backoff for temporary streaming failures. */\nexport function retryDelay(failures: number) {\n return Math.min(30_000, 1000 * 2 ** failures);\n}\n\n/** Wake on-demand render loops at the next retry, without polling idle scenes. */\nexport class RetryTimer {\n private timer?: ReturnType<typeof setTimeout>;\n private deadline = Number.POSITIVE_INFINITY;\n\n constructor(private readonly wake: () => void) {}\n\n update(deadlines: Iterable<number>) {\n const now = performance.now();\n let next = Number.POSITIVE_INFINITY;\n for (const at of deadlines) if (at > now) next = Math.min(next, at);\n if (next === this.deadline) return;\n this.dispose();\n this.deadline = next;\n if (Number.isFinite(next))\n this.timer = setTimeout(() => {\n this.dispose();\n this.wake();\n }, next - now);\n }\n\n dispose() {\n clearTimeout(this.timer);\n this.timer = undefined;\n this.deadline = Number.POSITIVE_INFINITY;\n }\n}\n","import type { ReorderedSplatResult, SplatResult } from \"../../data/defines\";\nimport type { PostDecodeSplatData } from \"../postDecode/protocol\";\n\nexport type RadChunkRange = {\n offset: number;\n bytes: number;\n base?: number;\n count?: number;\n filename?: string;\n};\n\n/** Spark RAD version 1 directory. Child references use file-global indices. */\nexport type RadMeta = {\n version: number;\n type: \"gsplat\";\n count: number;\n maxSh?: number;\n lodTree?: boolean;\n chunkSize?: number;\n allChunkBytes: number;\n chunks: RadChunkRange[];\n shCodeCount?: number;\n splatEncoding?: Record<string, unknown>;\n comment?: string;\n};\n\nexport type RadHeader = { meta: RadMeta; chunksStart: number };\n\nexport type RadChunkData = SplatResult & {\n base: number;\n childStart?: Uint32Array;\n childCount?: Uint16Array;\n lodRadii?: Float32Array;\n};\n\n/** Render records for streaming; tree arrays are transferred to the LOD worker. */\nexport type RadStreamChunk = Omit<ReorderedSplatResult, \"sortCenters\"> & {\n /** Root-page radius used when its initial bounds collapse to one point. */\n rootRadius?: number;\n};\n\nexport type RadDecodedChunk = PostDecodeSplatData & {\n base: number;\n childStart?: Uint32Array;\n childCount?: Uint16Array;\n lodRadii?: Float32Array;\n};\n\nexport function unpackRadChunk(decoded: RadDecodedChunk): RadChunkData {\n return {\n base: decoded.base,\n numSplats: decoded.numSplats,\n splatArrays: [decoded.splat0, decoded.splat1],\n sortCenters: decoded.sortCenters,\n extra: {\n sh1: decoded.sh1,\n sh2: decoded.sh2,\n sh3a: decoded.sh3a,\n sh3b: decoded.sh3b,\n },\n childStart: decoded.childStart,\n childCount: decoded.childCount,\n lodRadii: decoded.lodRadii,\n };\n}\n\n/** Without chunkSize, Spark treats the dataset as one chunk. */\nexport function getRadChunkSpan(meta: RadMeta, index: number) {\n const chunk = meta.chunks[index];\n const base = chunk.base ?? index * (meta.chunkSize ?? meta.count);\n const count =\n chunk.count ?? Math.min(meta.chunkSize ?? meta.count, meta.count - base);\n return { base, count };\n}\n\nexport function isRadPrefix(bytes: Uint8Array) {\n return (\n bytes[0] === 0x52 &&\n bytes[1] === 0x41 &&\n bytes[2] === 0x44 &&\n bytes[3] === 0x30\n );\n}\n\nexport function getRadHeaderSize(prefix: Uint8Array) {\n if (!isRadPrefix(prefix)) throw new Error(\"RAD: missing RAD0 magic\");\n const jsonLength = new DataView(\n prefix.buffer,\n prefix.byteOffset,\n prefix.byteLength,\n ).getUint32(4, true);\n return { jsonLength, headerLength: 8 + Math.ceil(jsonLength / 8) * 8 };\n}\n\n/** Validate the header as soon as a full-response fallback supplies it. */\nexport function collectRadHeader(complete: (bytes: Uint8Array) => void) {\n let header = new Uint8Array(8);\n let received = 0;\n let done = false;\n return (bytes: Uint8Array) => {\n if (done) return;\n let offset = 0;\n if (received < 8) {\n const count = Math.min(bytes.length, 8 - received);\n header.set(bytes.subarray(0, count), received);\n received += count;\n offset += count;\n }\n if (received === 8 && header.length === 8) {\n const expanded = new Uint8Array(getRadHeaderSize(header).headerLength);\n expanded.set(header);\n header = expanded;\n }\n if (received >= 8) {\n const count = Math.min(bytes.length - offset, header.length - received);\n header.set(bytes.subarray(offset, offset + count), received);\n received += count;\n if (received === header.length) {\n done = true;\n complete(header);\n }\n }\n };\n}\n","/** Bound pending copies while allowing one oversized item to make progress. */\nexport class StreamByteBudget {\n constructor(\n readonly limit: number,\n public used = 0,\n ) {}\n\n reserve(bytes: number) {\n if (bytes === 0) return true;\n if (this.used > 0 && this.used + bytes > this.limit) return false;\n this.used += bytes;\n return true;\n }\n}\n","import * as THREE from \"three\";\n\n/** A renderer whose size, in CSS pixels, sets a camera's resolution. */\nexport type StreamResolutionSource = {\n getSize(target: THREE.Vector2): THREE.Vector2;\n};\n\nconst size = new THREE.Vector2();\nconst identity = new THREE.Matrix4();\n\n/**\n * Bring a registered camera's world matrices up to date and report whether it\n * can select detail. WebXR uses the eye matrices supplied by Three, preserving\n * their rig transforms. Wait until the eyes have a projection and viewport.\n */\nfunction prepareStreamCamera(camera: THREE.Camera) {\n const array = camera as THREE.ArrayCamera;\n if (array.isArrayCamera) {\n return (\n array.cameras.length > 0 &&\n array.cameras.every(\n (eye) =>\n (eye.viewport?.z ?? 0) > 0 &&\n (eye.viewport?.w ?? 0) > 0 &&\n !eye.projectionMatrix.equals(identity) &&\n !(eye.matrixWorld.equals(identity) && !eye.matrix.equals(identity)),\n )\n );\n }\n camera.updateWorldMatrix(true, false);\n return true;\n}\n\n/** Capture actual eye poses; the ArrayCamera rig can be unset on its first frame. */\nexport function streamViews(cameras: readonly THREE.Camera[]) {\n const views: THREE.Camera[] = [];\n for (const camera of cameras) {\n if (!prepareStreamCamera(camera)) continue;\n const array = camera as THREE.ArrayCamera;\n if (array.isArrayCamera) views.push(...array.cameras);\n else views.push(camera);\n }\n return views;\n}\n\n/** Cameras that select a streamed model's detail, with their resolutions. */\nexport class StreamCameras {\n // Keys keep registration order.\n private readonly resolutions = new Map<THREE.Camera, THREE.Vector2>();\n\n /** Registered cameras, in registration order. */\n get cameras() {\n return [...this.resolutions.keys()];\n }\n\n has(camera: THREE.Camera) {\n return this.resolutions.has(camera);\n }\n\n add(camera: THREE.Camera) {\n if (this.resolutions.has(camera)) return false;\n this.resolutions.set(camera, new THREE.Vector2());\n return true;\n }\n\n delete(camera: THREE.Camera) {\n return this.resolutions.delete(camera);\n }\n\n setResolution(\n camera: THREE.Camera,\n xOrVec: number | THREE.Vector2,\n y?: number,\n ) {\n const resolution = this.resolutions.get(camera);\n if (!resolution) return false;\n const width = typeof xOrVec === \"number\" ? xOrVec : xOrVec.x;\n const height = typeof xOrVec === \"number\" ? (y ?? Number.NaN) : xOrVec.y;\n if (!(width > 0 && height > 0) || !Number.isFinite(width + height))\n throw new Error(\"Camera resolution must be positive and finite\");\n resolution.set(width, height);\n return true;\n }\n\n setResolutionFromRenderer(\n camera: THREE.Camera,\n renderer: StreamResolutionSource,\n ) {\n return this.setResolution(camera, renderer.getSize(size));\n }\n\n /** The camera's resolution, or undefined until one is set. */\n getResolution(camera: THREE.Camera) {\n const resolution = this.resolutions.get(camera);\n return resolution && resolution.x > 0 ? resolution : undefined;\n }\n\n /**\n * Registered cameras that see `layers`. Throws when none are registered,\n * since nothing could select detail.\n */\n seeing(layers: THREE.Layers) {\n if (!this.resolutions.size)\n throw new Error(\"Register a camera with setCamera() before update()\");\n const cameras: THREE.Camera[] = [];\n for (const camera of this.resolutions.keys())\n if (camera.layers.test(layers)) cameras.push(camera);\n return cameras;\n }\n}\n","import type { Group, LoadingManager } from \"three\";\nimport { retryDelay } from \"../../runtime/retry\";\nimport type { SplatRequestOptions } from \"../loadTypes\";\n\nexport type StreamRequestOptions = SplatRequestOptions & {\n manager?: LoadingManager;\n};\n\nexport type StreamSchedulerOptions = {\n group?: Group;\n /** Initial Splat budget; update scheduler.splatBudget to change it at runtime. */\n splatBudget?: number;\n /** Milliseconds to retain unused data after fade-out; defaults to 2000. */\n cooldownMs?: number;\n fadeDurationMs?: number;\n /** Active downloads/decodes. Ready copies use a separate bounded byte queue. */\n maxConcurrentLoads?: number;\n onChange?: () => void;\n onError?: (error: unknown, url: string) => void;\n};\n\nexport type StreamStats = {\n visibleSplats: number;\n visibleMeshes: number;\n residentMeshes: number;\n /** Decoded chunks, including cached chunks that are not currently drawn. */\n residentChunks: number;\n /** Retained CPU and estimated GPU bytes, excluding pending copies and WASM. */\n residentBytes: number;\n /** Reserved or ready copies awaiting publication into source storage. */\n pendingBytes: number;\n loadingChunks: number;\n downloadedBytes: number;\n peakWasmMemoryBytes: number;\n};\n\nexport function positiveInteger(value: number, name: string) {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new Error(`${name} must be a positive safe integer`);\n return value;\n}\n\nexport function streamSettings(options: StreamSchedulerOptions) {\n const splatBudget = positiveInteger(\n options.splatBudget ?? 3_000_000,\n \"splatBudget\",\n );\n const cooldownMs = options.cooldownMs ?? 2000;\n if (!Number.isFinite(cooldownMs) || cooldownMs < 0)\n throw new Error(\"cooldownMs must be finite and nonnegative\");\n const fadeDurationMs = options.fadeDurationMs ?? 200;\n if (!Number.isFinite(fadeDurationMs) || fadeDurationMs < 0)\n throw new Error(\"fadeDurationMs must be finite and nonnegative\");\n const maxConcurrentLoads = positiveInteger(\n options.maxConcurrentLoads ?? 4,\n \"maxConcurrentLoads\",\n );\n return {\n splatBudget,\n cooldownMs,\n fadeDurationMs,\n maxConcurrentLoads,\n };\n}\n\n/** Bound queued decode/extraction copies independently of per-update publication. */\nexport function streamPendingLimit(concurrency: number, unitBytes = 0) {\n const pendingBytesPerLoad = 8 * 1024 * 1024;\n return concurrency * Math.max(pendingBytesPerLoad, unitBytes);\n}\n\n/** Format errors are permanent; transient failures retry with capped backoff. */\nexport function streamRetryAt(error: unknown, failures: number) {\n const failure = error as { fatal?: boolean } | undefined;\n if (failure?.fatal) return Number.POSITIVE_INFINITY;\n const message = error instanceof Error ? error.message : String(error);\n const status = /\\bHTTP (\\d{3})\\b/.exec(message)?.[1];\n const retryable = status\n ? [408, 425, 429].includes(Number(status)) || Number(status) >= 500\n : error instanceof TypeError ||\n (error instanceof Error && error.name === \"NetworkError\");\n const workerLost =\n error instanceof Error && error.name === \"WorkerTerminatedError\";\n return retryable || workerLost\n ? performance.now() + retryDelay(failures)\n : Number.POSITIVE_INFINITY;\n}\n\nexport function notifyStreamChange(options: StreamSchedulerOptions) {\n try {\n options.onChange?.();\n } catch (error) {\n console.error(\"Stream onChange failed\", error);\n }\n}\n\nexport function notifyStreamError(\n options: StreamSchedulerOptions,\n error: unknown,\n url: string,\n) {\n try {\n if (options.onError) options.onError(error, url);\n else console.error(\"Streaming load failed\", url, error);\n } catch (callbackError) {\n console.error(\"Stream onError failed\", callbackError);\n }\n}\n","import {\n RadPagedSplats,\n type RadPagedSplatsOptions,\n type RadPreparedSelection,\n} from \"../../../data/RadPagedSplats\";\nimport { SplatMesh } from \"../../../scene/SplatMesh\";\n\n/** A fixed pool of RAD pages sharing one scene node and accumulator call. */\nexport class RadStreamBatch extends SplatMesh {\n readonly source: RadPagedSplats;\n\n constructor(options: RadPagedSplatsOptions) {\n const source = new RadPagedSplats(options);\n super({ splats: source });\n this.source = source;\n this.name = \"rad-batch\";\n this.maxSh = source.numSh;\n }\n\n clearSelection() {\n if (!this.source.clearSelection()) return false;\n this.numSplats = 0;\n this.updateMappingVersion();\n return true;\n }\n\n setFadeProgress(progress: number) {\n if (!this.source.setFadeProgress(progress)) return false;\n this.updateVersion({ sort: false });\n return true;\n }\n\n commitSelection(prepared: RadPreparedSelection) {\n this.source.commitSelection(prepared);\n this.numSplats = this.source.getNumSplats();\n this.updateMappingVersion();\n }\n\n finishFade() {\n if (!this.source.finishFade()) return false;\n if (this.numSplats !== this.source.getNumSplats()) {\n this.numSplats = this.source.getNumSplats();\n this.updateMappingVersion();\n } else this.updateVersion({ sort: false });\n return true;\n }\n\n override dispose() {\n this.removeFromParent();\n super.dispose();\n this.numSplats = 0;\n }\n}\n","import { abortable } from \"../runtime/abort\";\nimport type { SplatRequestOptions } from \"./loadTypes\";\n\nexport type ByteSource = {\n size: number;\n url?: string;\n read(offset: number, length: number, retain?: boolean): Promise<Uint8Array>;\n};\n\nexport function checkRange(offset: number, length: number, size?: number) {\n if (\n !Number.isSafeInteger(offset) ||\n !Number.isSafeInteger(length) ||\n !Number.isSafeInteger(offset + length) ||\n offset < 0 ||\n length < 0 ||\n (size !== undefined && offset + length > size)\n )\n throw new Error(\"Source byte range is out of bounds\");\n}\n\nexport function joinBytes(chunks: Uint8Array[], length: number) {\n if (chunks.length === 1) return chunks[0];\n const bytes = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n}\n\nexport async function collectBytes(\n read: () => Promise<Uint8Array | undefined>,\n maxBytes: number,\n progress: (bytes: number) => void,\n signal?: AbortSignal,\n validateChunk?: (chunk: Uint8Array, size: number) => void,\n) {\n const chunks: Uint8Array[] = [];\n let size = 0;\n for (;;) {\n signal?.throwIfAborted();\n const bytes = await abortable(read(), signal);\n if (bytes === undefined) break;\n size += bytes.byteLength;\n if (size > maxBytes)\n throw new Error(\"Source response exceeds its byte limit\");\n validateChunk?.(bytes, size);\n if (bytes.byteLength) chunks.push(bytes);\n progress(bytes.byteLength);\n }\n return { chunks, size };\n}\n\nexport async function readResponse(\n response: Response,\n maxBytes: number,\n progress: (bytes: number) => void,\n signal?: AbortSignal,\n validateChunk?: (chunk: Uint8Array, size: number) => void,\n) {\n const reader = response.body?.getReader();\n try {\n if (!response.ok)\n throw new Error(`HTTP ${response.status} loading ${response.url}`);\n const announced = Number(response.headers.get(\"Content-Length\"));\n if (Number.isFinite(announced) && announced > maxBytes)\n throw new Error(\"Source response exceeds its byte limit\");\n return await collectBytes(\n async () => {\n const chunk = await reader?.read();\n return chunk?.done ? undefined : chunk?.value;\n },\n maxBytes,\n progress,\n signal,\n validateChunk,\n );\n } catch (error) {\n await reader?.cancel(error).catch(() => {});\n throw error;\n } finally {\n reader?.releaseLock();\n }\n}\n\n/** Each reader owns its Range header. Credentials only follow the original origin. */\nexport function requestOptions(\n args: SplatRequestOptions,\n url: string,\n base?: string,\n): RequestInit & { headers: Headers } {\n const sameOrigin = !base || new URL(url).origin === new URL(base).origin;\n const headers = new Headers(sameOrigin ? args.requestHeader : undefined);\n headers.delete(\"Range\");\n headers.delete(\"If-Range\");\n return {\n headers,\n credentials: sameOrigin && args.withCredentials ? \"include\" : \"same-origin\",\n };\n}\n\n/** Bounded ordered prefetch: consume in decoder order while later reads overlap. */\nexport async function* prefetchOrdered<T>(\n count: number,\n concurrency: number,\n read: (index: number) => Promise<T>,\n signal?: AbortSignal,\n) {\n signal?.throwIfAborted();\n const pending = new Map<number, Promise<T>>();\n let next = 0;\n const fill = () => {\n while (next < count && pending.size < concurrency) {\n const index = next++;\n const task = Promise.resolve().then(() => read(index));\n void task.catch(() => {});\n pending.set(index, task);\n }\n };\n fill();\n try {\n for (let index = 0; index < count; index++) {\n signal?.throwIfAborted();\n const value = await abortable(pending.get(index) as Promise<T>, signal);\n pending.delete(index);\n fill();\n yield value;\n }\n } finally {\n pending.clear();\n }\n}\n","import type { LoadingManager } from \"three\";\nimport { abortable, linkedAbortController } from \"../../runtime/abort\";\nimport { getAssetBaseUrl } from \"../assetUrl\";\nimport type {\n SplatFileInput,\n SplatFileResolver,\n SplatRequestOptions,\n} from \"../loadTypes\";\nimport { checkRange, joinBytes, readResponse, requestOptions } from \"../source\";\nimport {\n type RadHeader,\n collectRadHeader,\n getRadHeaderSize,\n} from \"./radFormat\";\n\nexport type RadSourceOptions = SplatRequestOptions & {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n baseUrl?: string;\n manager?: LoadingManager;\n resolveFile?: SplatFileResolver;\n /** Internal bridge for LoadingManager URL modifiers in a decode worker. */\n resolveAsset?: (url: string) => Promise<string>;\n onProgress?: (downloadedBytes: number) => void;\n /** Validate ordinary metadata as soon as the full-response header arrives. */\n validateHeader?: (bytes: Uint8Array) => void;\n};\n\ntype Remote = {\n url: string;\n resolved?: string;\n responseUrl?: string;\n total?: number;\n validator?: string;\n validatorHeader?: \"ETag\" | \"Last-Modified\";\n full?: Blob;\n};\n\n/** Small response snapshot shared across a dataset's download workers. */\nexport type RadResourceState = Pick<\n Remote,\n \"responseUrl\" | \"total\" | \"validator\" | \"validatorHeader\"\n>;\n\n/** Resolved page input. Local inputs contain only the requested Blob slice. */\nexport type RadReadRequest = {\n input: string | Blob;\n offset: number;\n length: number;\n wholeFile: boolean;\n resourceUrl?: string;\n state?: RadResourceState;\n requestHeader?: Record<string, string>;\n withCredentials?: boolean;\n};\n\nfunction baseUrl() {\n return typeof document === \"undefined\" ? undefined : document.baseURI;\n}\n\n/** Slice without copying; callers choose how to take ownership of page bytes. */\nfunction sliceLocalInput(\n input: Exclude<SplatFileInput, string>,\n offset: number,\n length: number,\n) {\n if (input instanceof Blob) {\n checkRange(offset, length, input.size);\n return input.slice(offset, offset + length);\n }\n const bytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\n if (!(bytes instanceof Uint8Array))\n throw new Error(\"RAD: chunk resolver returned an unsupported input\");\n checkRange(offset, length, bytes.length);\n return bytes.subarray(offset, offset + length);\n}\n\n/** Validated byte reads shared by ordinary RAD loading and paged loading. */\nexport class RadSource {\n readonly stats = { downloadedBytes: 0, activeRequests: 0, cachedBytes: 0 };\n private readonly controller = new AbortController();\n private readonly remotes = new Map<string, Remote>();\n private readonly root: SplatFileInput;\n private readonly origin?: string;\n\n constructor(\n readonly options: RadSourceOptions,\n private readonly allowFullDownload = false,\n ) {\n const inputs = [options.url, options.file, options.fileBytes].filter(\n (input) => input !== undefined,\n );\n if (inputs.length !== 1)\n throw new Error(\"RAD: provide exactly one of url, file, or fileBytes\");\n this.root = inputs[0];\n const initialUrl = options.url ?? options.baseUrl;\n if (initialUrl) this.origin = new URL(initialUrl, baseUrl()).origin;\n }\n\n get url() {\n if (typeof this.root !== \"string\") return this.options.baseUrl;\n return this.remotes.get(this.root)?.responseUrl ?? this.root;\n }\n\n async readHeader(signal?: AbortSignal) {\n const prefix = await this.read(this.root, 0, 8, signal);\n const { headerLength } = getRadHeaderSize(prefix);\n const tail = await this.read(this.root, 8, headerLength - 8, signal);\n const bytes = new Uint8Array(headerLength);\n bytes.set(prefix);\n bytes.set(tail, 8);\n return bytes;\n }\n\n async readChunk(header: RadHeader, index: number, signal?: AbortSignal) {\n const { input, offset, length, wholeFile } = await this.chunkRead(\n header,\n index,\n signal,\n );\n return this.read(input, offset, length, signal, wholeFile);\n }\n\n private async chunkRead(\n header: RadHeader,\n index: number,\n signal?: AbortSignal,\n ) {\n signal?.throwIfAborted();\n this.controller.signal.throwIfAborted();\n const chunk = header.meta.chunks[index];\n if (!chunk) throw new Error(`RAD: missing chunk ${index}`);\n let input = this.root;\n let offset = header.chunksStart + chunk.offset;\n if (chunk.filename !== undefined) {\n offset = chunk.offset;\n if (this.options.resolveFile) {\n const controller = this.requestController(signal);\n try {\n input = await abortable(\n Promise.resolve(\n this.options.resolveFile(chunk.filename, controller.signal),\n ),\n controller.signal,\n );\n } finally {\n controller.cleanup();\n }\n } else {\n const sourceBase = getAssetBaseUrl(this.url) ?? this.options.baseUrl;\n if (!sourceBase)\n throw new Error(\n `RAD: external chunk \"${chunk.filename}\" requires resolveFile or baseUrl`,\n );\n input = new URL(chunk.filename, sourceBase).href;\n }\n if (typeof input === \"string\")\n input = new URL(\n input,\n getAssetBaseUrl(this.url) ?? this.options.baseUrl ?? baseUrl(),\n ).href;\n }\n return {\n input,\n offset,\n length: chunk.bytes,\n wholeFile: chunk.filename !== undefined && offset === 0,\n };\n }\n\n /** Resolve callbacks on their owning thread; workers read and validate bodies. */\n async prepareChunk(\n header: RadHeader,\n index: number,\n signal?: AbortSignal,\n ): Promise<RadReadRequest> {\n const read = await this.chunkRead(header, index, signal);\n signal?.throwIfAborted();\n this.controller.signal.throwIfAborted();\n const { input, offset, length } = read;\n if (typeof input === \"string\") {\n const remote = this.remote(input);\n const controller = this.requestController(signal);\n try {\n const url = await this.resolveRemote(remote, controller.signal);\n controller.signal.throwIfAborted();\n checkRange(offset, length, remote.total);\n const options = requestOptions(this.options, url, this.origin);\n const requestHeader: Record<string, string> = {};\n options.headers.forEach((value, name) => {\n requestHeader[name] = value;\n });\n return {\n ...read,\n input: url,\n resourceUrl: input,\n state: this.resourceState(remote),\n requestHeader,\n withCredentials: options.credentials === \"include\",\n };\n } finally {\n controller.cleanup();\n }\n }\n const slice = sliceLocalInput(input, offset, length);\n // Snapshot only this page, never copy/detach the full file per worker.\n const file = slice instanceof Blob ? slice : new Blob([slice as BlobPart]);\n return { input: file, offset: 0, length, wholeFile: true };\n }\n\n /** Worker transport reuses all ordinary Range, size and encoding validation. */\n static async readPreparedChunk(\n request: RadReadRequest,\n signal: AbortSignal,\n onProgress?: (downloadedBytes: number) => void,\n ) {\n const { input, offset, length, wholeFile } = request;\n const source = new RadSource({\n ...(typeof input === \"string\" ? { url: input } : { file: input }),\n requestHeader: request.requestHeader,\n withCredentials: request.withCredentials,\n onProgress,\n });\n try {\n if (typeof input === \"string\")\n Object.assign(source.remote(input), request.state, { resolved: input });\n const bytes = await source.read(input, offset, length, signal, wholeFile);\n const state =\n typeof input === \"string\"\n ? source.resourceState(source.remote(input))\n : undefined;\n return { bytes, state };\n } finally {\n source.dispose();\n }\n }\n\n /** Reconcile parallel responses before publishing a decoded page. */\n acceptChunkResponse(request: RadReadRequest, state?: RadResourceState) {\n this.controller.signal.throwIfAborted();\n if (request.resourceUrl === undefined) return;\n if (!state) throw new Error(\"RAD: missing worker response metadata\");\n const remote = this.remote(request.resourceUrl);\n if (\n remote.validator &&\n (state.validator !== remote.validator ||\n state.validatorHeader !== remote.validatorHeader)\n )\n throw new Error(\"RAD: resource version changed during loading\");\n if (\n remote.total !== undefined &&\n state.total !== undefined &&\n remote.total !== state.total\n )\n throw new Error(\"RAD: resource length changed during loading\");\n remote.responseUrl = state.responseUrl ?? remote.responseUrl;\n remote.total ??= state.total;\n if (!remote.validator && state.validator) {\n remote.validator = state.validator;\n remote.validatorHeader = state.validatorHeader;\n }\n }\n\n private resourceState(remote: Remote): RadResourceState {\n const { responseUrl, total, validator, validatorHeader } = remote;\n return { responseUrl, total, validator, validatorHeader };\n }\n\n private remote(url: string) {\n let remote = this.remotes.get(url);\n if (!remote) {\n remote = { url };\n this.remotes.set(url, remote);\n }\n return remote;\n }\n\n private async resolveRemote(remote: Remote, signal: AbortSignal) {\n remote.resolved ??= new URL(\n this.options.resolveAsset\n ? await abortable(this.options.resolveAsset(remote.url), signal)\n : (this.options.manager?.resolveURL(remote.url) ?? remote.url),\n this.options.baseUrl ?? baseUrl(),\n ).href;\n return remote.resolved;\n }\n\n private requestController(signal?: AbortSignal) {\n return linkedAbortController(this.controller.signal, signal);\n }\n\n private async read(\n input: SplatFileInput,\n offset: number,\n length: number,\n signal?: AbortSignal,\n wholeFile = false,\n ): Promise<Uint8Array> {\n signal?.throwIfAborted();\n this.controller.signal.throwIfAborted();\n if (typeof input === \"string\") {\n return this.readRemote(\n this.remote(input),\n offset,\n length,\n signal,\n wholeFile,\n );\n }\n const slice = sliceLocalInput(input, offset, length);\n if (slice instanceof Blob) {\n return new Uint8Array(await abortable(slice.arrayBuffer(), signal));\n }\n // Workers transfer buffers; never detach the caller's source bytes.\n return new Uint8Array(slice);\n }\n\n private async readRemote(\n remote: Remote,\n offset: number,\n length: number,\n signal?: AbortSignal,\n wholeFile = false,\n ): Promise<Uint8Array> {\n checkRange(offset, length, remote.total);\n if (!length) return new Uint8Array();\n if (remote.full)\n return new Uint8Array(\n await abortable(\n remote.full.slice(offset, offset + length).arrayBuffer(),\n signal,\n ),\n );\n const controller = this.requestController(signal);\n const manager = this.options.manager;\n let started = false;\n let response: Response | undefined;\n try {\n const resolved = await this.resolveRemote(remote, controller.signal);\n controller.signal.throwIfAborted();\n const options = requestOptions(this.options, resolved, this.origin);\n const { headers } = options;\n if (!wholeFile)\n headers.set(\"Range\", `bytes=${offset}-${offset + length - 1}`);\n // A single byte range can be fetched without a CORS preflight. Adding\n // If-Range would require server opt-in even when Range itself works.\n // Compare response validators below to detect resource changes instead.\n manager?.itemStart(resolved);\n started = true;\n this.stats.activeRequests++;\n response = await fetch(resolved, {\n headers,\n credentials: options.credentials,\n signal: controller.signal,\n });\n remote.responseUrl = response.url || remote.resolved;\n const encoding = response.headers.get(\"Content-Encoding\");\n if (\n encoding &&\n encoding.toLowerCase() !== \"identity\" &&\n response.status === 206\n )\n throw new Error(\n \"RAD: byte-range resources must use identity Content-Encoding\",\n );\n const etag = response.headers.get(\"ETag\");\n const modified = response.headers.get(\"Last-Modified\");\n const validatorHeader =\n etag && !etag.startsWith(\"W/\")\n ? \"ETag\"\n : modified\n ? \"Last-Modified\"\n : undefined;\n const validator = validatorHeader\n ? (response.headers.get(validatorHeader) ?? undefined)\n : undefined;\n if (\n remote.validator &&\n response.headers.get(remote.validatorHeader ?? \"ETag\") !==\n remote.validator\n )\n throw new Error(\"RAD: resource version changed during loading\");\n if (!remote.validator && validator) {\n remote.validator = validator;\n remote.validatorHeader = validatorHeader;\n }\n if (response.status === 206) {\n const contentRange = response.headers.get(\"Content-Range\");\n // Some public storage hosts serve correct ranges but do not expose\n // Content-Range to browser JavaScript. In that case the bounded body\n // and RAD/RADC container checks still validate the returned data.\n if (contentRange !== null) {\n const range = /^bytes (\\d+)-(\\d+)\\/(\\d+)$/.exec(contentRange);\n if (!range) throw new Error(\"RAD: invalid Content-Range header\");\n const [start, end, total] = range.slice(1).map(Number);\n if (\n !Number.isSafeInteger(total) ||\n start !== offset ||\n end !== offset + length - 1 ||\n end >= total ||\n (remote.total !== undefined && remote.total !== total)\n )\n throw new Error(\n \"RAD: Content-Range does not match the requested bytes\",\n );\n remote.total = total;\n }\n const bytes = await this.readResponse(\n response,\n length,\n controller.signal,\n );\n if (bytes.length !== length)\n throw new Error(\"RAD: truncated range response\");\n return bytes;\n }\n if (response.status !== 200)\n throw new Error(\n `RAD: HTTP ${response.status} loading ${remote.resolved}`,\n );\n if (\n this.allowFullDownload &&\n remote.url === this.root &&\n offset === 0 &&\n length === 8\n ) {\n const { chunks, size } = await readResponse(\n response,\n Number.POSITIVE_INFINITY,\n (bytes) => this.progress(bytes),\n controller.signal,\n collectRadHeader((bytes) => this.options.validateHeader?.(bytes)),\n );\n const full = new Blob(chunks as BlobPart[]);\n remote.total = size;\n checkRange(offset, length, size);\n this.cacheFullResponse(remote, full);\n return new Uint8Array(await full.slice(0, 8).arrayBuffer());\n }\n const limit = wholeFile\n ? length\n : this.allowFullDownload\n ? Number.POSITIVE_INFINITY\n : 0;\n if (!limit && offset === 0 && length === 8) {\n // A split dataset's .rad contains only its bounded header. Allow that\n // complete response even when its server cannot serve byte ranges.\n const bytes = await this.readHeaderOnlyResponse(\n response,\n controller.signal,\n );\n remote.total = bytes.length;\n this.cacheFullResponse(remote, bytes);\n return bytes.slice(0, 8);\n }\n if (!limit)\n throw new Error(\n \"RAD: server ignored Range; streaming requires byte-range support\",\n );\n if (remote.total !== undefined && remote.total > limit)\n throw new Error(\"RAD: full response exceeds its byte limit\");\n const bytes = await this.readResponse(response, limit, controller.signal);\n if (wholeFile && bytes.length !== length)\n throw new Error(\n \"RAD: external chunk length does not match its directory entry\",\n );\n if (remote.total !== undefined && remote.total !== bytes.length)\n throw new Error(\"RAD: resource length changed during loading\");\n remote.total = bytes.length;\n checkRange(offset, length, bytes.length);\n return bytes.slice(offset, offset + length);\n } catch (error) {\n await response?.body?.cancel().catch(() => {});\n if (started) manager?.itemError(remote.resolved ?? remote.url);\n throw error;\n } finally {\n controller.cleanup();\n if (started) {\n this.stats.activeRequests--;\n manager?.itemEnd(remote.resolved ?? remote.url);\n }\n }\n }\n\n private cacheFullResponse(remote: Remote, bytes: Uint8Array | Blob) {\n remote.full = bytes instanceof Blob ? bytes : new Blob([bytes as BlobPart]);\n this.stats.cachedBytes = [...this.remotes.values()].reduce(\n (sum, entry) => sum + (entry.full?.size ?? 0),\n 0,\n );\n }\n\n private async readHeaderOnlyResponse(\n response: Response,\n signal: AbortSignal,\n ) {\n const failure = () =>\n new Error(\n \"RAD: server ignored Range for a monolithic file; streaming requires byte-range support\",\n );\n const prefix = new Uint8Array(8);\n let headerLength: number | undefined;\n let jsonLength = 0;\n // The prefix establishes the byte limit before response chunks are retained.\n const bytes = await this.readResponse(\n response,\n Number.POSITIVE_INFINITY,\n signal,\n (chunk, size) => {\n const offset = size - chunk.length;\n if (offset < 8) prefix.set(chunk.subarray(0, 8 - offset), offset);\n if (size >= 8 && headerLength === undefined)\n ({ jsonLength, headerLength } = getRadHeaderSize(prefix));\n if (size > (headerLength ?? 8)) throw failure();\n },\n );\n if (bytes.length !== headerLength)\n throw new Error(\"RAD: truncated header-only response\");\n const meta = JSON.parse(\n new TextDecoder(\"utf-8\", { fatal: true }).decode(\n bytes.subarray(8, 8 + jsonLength),\n ),\n ) as { chunks?: unknown };\n if (\n !Array.isArray(meta.chunks) ||\n !meta.chunks.every(\n (chunk) =>\n chunk &&\n typeof chunk.filename === \"string\" &&\n chunk.filename.length > 0,\n )\n )\n throw failure();\n return bytes;\n }\n\n private async readResponse(\n response: Response,\n limit: number,\n signal: AbortSignal,\n validateChunk?: (chunk: Uint8Array, size: number) => void,\n ) {\n const { chunks, size } = await readResponse(\n response,\n limit,\n (bytes) => this.progress(bytes),\n signal,\n validateChunk,\n );\n return joinBytes(chunks, size);\n }\n\n private progress(bytes: number) {\n this.stats.downloadedBytes += bytes;\n this.options.onProgress?.(this.stats.downloadedBytes);\n }\n\n dispose() {\n this.controller.abort(\n new DOMException(\"RAD source disposed\", \"AbortError\"),\n );\n this.remotes.clear();\n this.stats.cachedBytes = 0;\n }\n}\n","import type { LoadingManager } from \"three\";\nimport { abortable, linkedAbortController } from \"../../runtime/abort\";\n\ntype StreamWorker = {\n disposed: boolean;\n peakWasmMemoryBytes: number;\n dispose(reason?: unknown): void;\n};\ntype Slot<W> = {\n worker: W;\n busy: boolean;\n references: number;\n};\n\ntype WorkerLease<W> = {\n worker: W;\n /** The retained cache handle releases this reference once on disposal. */\n retain: () => () => void;\n release: () => void;\n};\n\ntype LoadTask<W> = WorkerLease<W> & {\n id: number;\n signal: AbortSignal;\n start: (url: string) => void;\n progress: (loaded: number) => void;\n};\n\n/** Bounded worker leases. Cache handles retain slots; cancellation never kills unrelated work. */\nexport class StreamWorkerPool<W extends StreamWorker> {\n private readonly slots: Slot<W>[] = [];\n private readonly waiters = new Set<() => void>();\n private readonly controller = new AbortController();\n private peakBytes = 0;\n private nextTaskId = 0;\n downloadedBytes = 0;\n\n constructor(\n private readonly createWorker: () => W,\n readonly concurrency: number,\n private readonly retainIdle = false,\n ) {}\n\n get workers() {\n return this.slots.map(({ worker }) => worker);\n }\n\n get peakWasmMemoryBytes() {\n this.peakBytes = Math.max(\n this.peakBytes,\n this.slots.reduce(\n (bytes, { worker }) => bytes + worker.peakWasmMemoryBytes,\n 0,\n ),\n );\n return this.peakBytes;\n }\n\n private retire(slot: Slot<W>) {\n this.peakBytes = this.peakWasmMemoryBytes;\n if (!this.retainIdle && !slot.busy && !slot.references)\n slot.worker.dispose();\n }\n\n /** Shared RAD/SOG task lifecycle; format RPCs and cache ownership stay local. */\n async run<T>(\n options: {\n signal?: AbortSignal;\n manager: LoadingManager;\n cancel: (worker: W, id: number) => Promise<unknown>;\n },\n load: (task: LoadTask<W>) => Promise<T>,\n ): Promise<T> {\n const id = ++this.nextTaskId;\n const request = linkedAbortController(\n this.controller.signal,\n options.signal,\n );\n let lease: WorkerLease<W> | undefined;\n let cancel: (() => void) | undefined;\n let url: string | undefined;\n let loaded = 0;\n try {\n lease = await this.acquire(request.signal);\n const { worker } = lease;\n cancel = () => {\n if (!worker.disposed) void options.cancel(worker, id).catch(() => {});\n };\n request.signal.addEventListener(\"abort\", cancel, { once: true });\n request.signal.throwIfAborted();\n // Do not race load() against abort: synchronous decoding keeps its slot\n // until the worker replies. The format also checks before publishing.\n return await load({\n ...lease,\n id,\n signal: request.signal,\n start: (value) => {\n url = value;\n options.manager.itemStart(value);\n request.signal.throwIfAborted();\n },\n progress: (next) => {\n this.downloadedBytes += next - loaded;\n loaded = next;\n },\n });\n } catch (error) {\n cancel?.();\n if (url !== undefined) options.manager.itemError(url);\n throw error;\n } finally {\n if (cancel) request.signal.removeEventListener(\"abort\", cancel);\n request.cleanup();\n lease?.release();\n if (url !== undefined) options.manager.itemEnd(url);\n }\n }\n\n private async acquire(signal: AbortSignal): Promise<WorkerLease<W>> {\n for (;;) {\n signal.throwIfAborted();\n let slot = this.slots.find((candidate) => !candidate.busy);\n if (!slot && this.slots.length < this.concurrency) {\n slot = {\n worker: this.createWorker(),\n busy: false,\n references: 0,\n };\n this.slots.push(slot);\n }\n if (slot) {\n if (slot.worker.disposed) {\n this.peakBytes = this.peakWasmMemoryBytes;\n slot.worker = this.createWorker();\n slot.references = 0;\n }\n const owner = slot;\n const worker = owner.worker;\n owner.busy = true;\n let released = false;\n return {\n worker,\n retain: () => {\n owner.references++;\n return () => {\n if (owner.worker === worker) {\n owner.references--;\n this.retire(owner);\n }\n };\n },\n release: () => {\n if (released) return;\n released = true;\n owner.busy = false;\n this.retire(owner);\n this.wake();\n },\n };\n }\n let wake!: () => void;\n const available = new Promise<void>((resolve) => {\n wake = resolve;\n this.waiters.add(wake);\n });\n try {\n await abortable(available, signal);\n } finally {\n this.waiters.delete(wake);\n }\n }\n }\n\n private wake() {\n for (const wake of this.waiters) wake();\n this.waiters.clear();\n }\n\n dispose(\n reason: unknown = new DOMException(\n \"Streaming worker pool disposed\",\n \"AbortError\",\n ),\n ) {\n if (this.controller.signal.aborted) return;\n this.controller.abort(reason);\n this.peakBytes = this.peakWasmMemoryBytes;\n for (const { worker } of this.slots) worker.dispose(reason);\n this.wake();\n }\n}\n","import { WorkerRpc } from \"../../../runtime/WorkerRpc\";\nimport type { RadStreamRpcHandlers } from \"./worker\";\nimport BundledWorker from \"./worker?worker&inline\";\n\n/** Worker assigned either LOD ownership or a persistent page decoder. */\nexport class RadStreamWorker extends WorkerRpc<RadStreamRpcHandlers> {\n constructor(onDispose?: () => void) {\n super(new BundledWorker(), onDispose);\n }\n}\n","import { DefaultLoadingManager } from \"three\";\nimport { abortable } from \"../../../runtime/abort\";\nimport { RadSource, type RadSourceOptions } from \"../../rad/RadSource\";\nimport type { RadHeader, RadStreamChunk } from \"../../rad/radFormat\";\nimport { StreamWorkerPool } from \"../StreamWorkerPool\";\nimport type { RadSelectionRequest } from \"./RadSelectionState\";\nimport { RadStreamWorker } from \"./RadStreamWorker\";\nimport type { prepareRadSelection } from \"./prepareRadSelection\";\nimport type { RadStreamSelection } from \"./radFade\";\n\nexport type RadStreamLoaderOptions = Pick<\n RadSourceOptions,\n | \"url\"\n | \"file\"\n | \"fileBytes\"\n | \"resolveFile\"\n | \"manager\"\n | \"requestHeader\"\n | \"withCredentials\"\n>;\n\n/** Dedicated LOD traversal with a separate bounded pool of parallel decoders. */\nexport class RadStreamLoader {\n readonly source: RadSource;\n private readonly lodWorker: RadStreamWorker;\n private readonly pool: StreamWorkerPool<RadStreamWorker>;\n private readonly decoderReady = new WeakMap<RadStreamWorker, Promise<void>>();\n private readonly controller = new AbortController();\n private initialization?: Promise<RadHeader>;\n private header?: RadHeader;\n private rootReady?: Promise<void>;\n private initialRoot?: RadStreamChunk;\n private rootBytes?: Uint8Array;\n private pending = new Map<\n number,\n { task: Promise<RadStreamChunk>; signal?: AbortSignal }\n >();\n private estimatedCodebookBytes = 0;\n private selectionBytes = 0;\n\n constructor(\n private readonly options: RadStreamLoaderOptions,\n maxConcurrentLoads = 4,\n ) {\n this.source = new RadSource({\n ...options,\n manager: options.manager ?? DefaultLoadingManager,\n });\n this.lodWorker = new RadStreamWorker();\n this.pool = new StreamWorkerPool(\n () => new RadStreamWorker(),\n maxConcurrentLoads,\n true,\n );\n }\n\n get stats() {\n return {\n cachedBytes: this.source.stats.cachedBytes,\n downloadedBytes:\n this.source.stats.downloadedBytes + this.pool.downloadedBytes,\n peakWasmMemoryBytes:\n this.pool.peakWasmMemoryBytes + this.lodWorker.peakWasmMemoryBytes,\n estimatedCodebookBytes:\n this.estimatedCodebookBytes *\n this.pool.workers.filter((worker) => !worker.disposed).length,\n bootstrapBytes: this.rootBytes?.byteLength ?? 0,\n selectionBytes: this.selectionBytes,\n };\n }\n\n get lodWorkerLost() {\n return this.lodWorker.disposed && !this.controller.signal.aborted;\n }\n\n private assertActive() {\n this.controller.signal.throwIfAborted();\n if (this.lodWorker.disposed) throw new Error(\"RAD LOD worker terminated\");\n }\n\n initialize(signal?: AbortSignal) {\n signal?.throwIfAborted();\n this.assertActive();\n this.initialization ??= this.source\n .readHeader(this.controller.signal)\n .then(async (bytes) => {\n const header = await this.lodWorker.call(\"initializeRad\", {\n bytes,\n });\n this.assertActive();\n this.header = header;\n const degree = header.meta.maxSh ?? 0;\n // Float codebooks plus packed caches for every degree up to maxSh.\n this.estimatedCodebookBytes =\n (header.meta.shCodeCount ?? 0) * [0, 52, 144, 292][degree];\n return header;\n });\n return abortable(this.initialization, signal);\n }\n\n async loadChunk(\n index: number,\n signal?: AbortSignal,\n onDecoded?: () => void,\n ): Promise<RadStreamChunk> {\n signal?.throwIfAborted();\n this.assertActive();\n let pending = this.pending.get(index);\n if (!pending || pending.signal?.aborted) {\n const task = this.loadChunkInternal(index, signal, onDecoded).finally(\n () => {\n if (this.pending.get(index) === pending) this.pending.delete(index);\n },\n );\n pending = { task, signal };\n this.pending.set(index, pending);\n }\n // Keep cancelled synchronous work reserved until its worker reply arrives.\n return pending.task;\n }\n\n private async loadChunkInternal(\n index: number,\n signal?: AbortSignal,\n onDecoded?: () => void,\n ): Promise<RadStreamChunk> {\n const header = await this.initialize(signal);\n // Codebooks live in chunk zero. Its initial geometry is held only until the\n // caller requests that page, avoiding a duplicate fetch during races.\n this.rootReady ??= this.decode(\n 0,\n header,\n this.controller.signal,\n index === 0 ? onDecoded : undefined,\n )\n .then((data) => {\n this.initialRoot = data;\n })\n .catch((error) => {\n this.rootReady = undefined;\n throw error;\n });\n await abortable(this.rootReady, signal);\n if (index === 0 && this.initialRoot) {\n const root = this.initialRoot;\n this.initialRoot = undefined;\n return root;\n }\n return this.decode(index, header, signal, onDecoded);\n }\n\n private async decode(\n index: number,\n header: RadHeader,\n signal?: AbortSignal,\n onDecoded?: () => void,\n ) {\n this.assertActive();\n return this.pool.run(\n {\n signal,\n manager: this.options.manager ?? DefaultLoadingManager,\n cancel: (worker, generation) =>\n worker.call(\"cancelRadLoad\", { generation }),\n },\n async ({ worker, id: generation, signal, release, start, progress }) => {\n this.assertActive();\n let ready = this.decoderReady.get(worker);\n if (!ready) {\n ready = worker\n .call(\"initializeRadDecoder\", {\n header,\n rootBytes: this.rootBytes?.slice(),\n })\n .catch((error) => {\n worker.dispose(error);\n throw error;\n });\n this.decoderReady.set(worker, ready);\n }\n // Resolve application callbacks here; page bodies stay inside the worker.\n const [request] = await Promise.all([\n this.source.prepareChunk(header, index, signal),\n ready,\n ]);\n signal.throwIfAborted();\n this.assertActive();\n if (typeof request.input === \"string\") start(request.input);\n const result = await worker.call(\n \"loadRadChunk\",\n { index, generation, request },\n {\n onStatus: (status) =>\n progress((status as { loaded: number }).loaded),\n },\n );\n this.assertActive();\n signal.throwIfAborted();\n try {\n this.source.acceptChunkResponse(request, result.state);\n } catch (error) {\n // A response rejected against another worker must not seed future jobs.\n worker.dispose(error);\n throw error;\n }\n const registration = this.lodWorker.call(\"retainRadChunk\", {\n index,\n generation,\n tree: result.tree,\n });\n // Registration owns no decoder state; release the slot before awaiting it.\n release();\n try {\n onDecoded?.();\n await registration;\n this.assertActive();\n signal.throwIfAborted();\n if (result.rootBytes) this.rootBytes = result.rootBytes;\n return result.data;\n } catch (error) {\n // A throwing callback must still observe registration before rollback.\n await registration.catch(() => {});\n this.releaseChunk(index, generation);\n throw error;\n }\n },\n );\n }\n\n getChunkUrl(index: number) {\n const filename = this.header?.meta.chunks[index]?.filename;\n const root = this.source.url;\n if (filename) return root ? new URL(filename, root).href : filename;\n return root ?? (this.options.file as File | undefined)?.name ?? \"RAD\";\n }\n\n async selectLod(request: RadSelectionRequest): Promise<RadStreamSelection> {\n this.assertActive();\n const { retainedBytes, ...selection } = await this.lodWorker.call(\n \"selectRadLod\",\n request,\n );\n this.assertActive();\n this.selectionBytes = retainedBytes;\n return selection;\n }\n\n async prepareSelection(request: Parameters<typeof prepareRadSelection>[0]) {\n this.assertActive();\n const result = await this.lodWorker.call(\"prepareRadSelection\", request);\n this.assertActive();\n return result;\n }\n\n releaseChunk(index: number, generation?: number) {\n if (index === 0 && generation === undefined) this.initialRoot = undefined;\n if (!this.lodWorker.disposed)\n void this.lodWorker\n .call(\"releaseRadChunk\", { index, generation })\n .catch(() => {});\n }\n\n dispose() {\n if (this.controller.signal.aborted) return;\n this.controller.abort(\n new DOMException(\"RAD loader disposed\", \"AbortError\"),\n );\n this.source.dispose();\n this.pool.dispose(this.controller.signal.reason);\n this.lodWorker.dispose(this.controller.signal.reason);\n this.pending.clear();\n this.initialRoot = undefined;\n this.rootBytes = undefined;\n this.estimatedCodebookBytes = 0;\n this.selectionBytes = 0;\n this.header = undefined;\n }\n}\n","import type { RadMeta } from \"../../rad/radFormat\";\nimport { getRadChunkSpan } from \"../../rad/radFormat\";\n\n/** CPU-only data retained in the dataset worker, never GPU source storage. */\nexport type RadLodChunk = {\n centers: Float32Array;\n radii: Float32Array;\n childStart: Uint32Array;\n childCount: Uint16Array;\n /** Original page index to Morton storage; tree arrays keep file order. */\n sourceToStorage: Uint32Array;\n /** Center and scale/rotation bounds per Morton storage block. */\n boundsBlocks: Float32Array;\n};\n\nexport type RadLodView = {\n /** Object-to-camera transform; doubles preserve large scene translations. */\n viewFromObject: number[];\n /** Camera projection's X/Y rows (8 values), including zoom and view offsets. */\n projectionRows: number[];\n /** Pixels per camera-space unit at depth 1, including projection zoom. */\n pixelScale: number;\n orthographic: boolean;\n};\n\nexport type RadLodRequest = {\n views: RadLodView[];\n splatBudget: number;\n pixelThreshold: number;\n residentChunks: number[];\n hysteresis?: number;\n};\n\nexport type RadLodSelection = {\n /** Stable file indices. The scheduler maps these to occupied GPU slots. */\n indices: Uint32Array;\n wantedChunks: Uint32Array;\n /** Ancestor and selected pages required by this cut. */\n touchedChunks: Uint32Array;\n};\n\n/** Resolve validated LOD indices without assuming that chunks are 64K records. */\nexport function radChunkIndex(meta: RadMeta, index: number): number {\n const size = meta.chunkSize ?? meta.count;\n const candidate = Math.floor(index / size);\n if (candidate < meta.chunks.length) {\n const range = getRadChunkSpan(meta, candidate);\n if (index >= range.base && index < range.base + range.count)\n return candidate;\n }\n // Header validation guarantees contiguous, ordered spans covering every index.\n let low = 0;\n let high = meta.chunks.length;\n while (low < high) {\n const middle = (low + high) >>> 1;\n if (getRadChunkSpan(meta, middle).base <= index) low = middle + 1;\n else high = middle;\n }\n return low - 1;\n}\n","import * as THREE from \"three\";\nimport {\n type RadSelectionRange,\n radPageTextureLayout,\n} from \"../../../data/RadPagedSplats\";\nimport { SPLAT_BOUNDS_BLOCK_SIZE } from \"../../../data/defines\";\nimport {\n getSplatByteLength,\n getSplatTextureBytes,\n} from \"../../../data/splatData\";\nimport { RetryTimer } from \"../../../runtime/retry\";\nimport type { RadMeta, RadStreamChunk } from \"../../rad/radFormat\";\nimport { getRadChunkSpan } from \"../../rad/radFormat\";\nimport { StreamByteBudget } from \"../StreamByteBudget\";\nimport {\n StreamCameras,\n type StreamResolutionSource,\n streamViews,\n} from \"../StreamCameras\";\nimport {\n type StreamSchedulerOptions,\n type StreamStats,\n notifyStreamChange,\n notifyStreamError,\n positiveInteger,\n streamPendingLimit,\n streamRetryAt,\n streamSettings,\n} from \"../streamOptions\";\nimport { RadStreamBatch } from \"./RadStreamBatch\";\nimport {\n RadStreamLoader,\n type RadStreamLoaderOptions,\n} from \"./RadStreamLoader\";\nimport type { RadSelectionPreparation } from \"./prepareRadSelection\";\nimport type { RadStreamSelection, RadVersionedSelection } from \"./radFade\";\nimport { type RadLodView, radChunkIndex } from \"./radLod\";\n\nexport type RadStreamSchedulerOptions = RadStreamLoaderOptions &\n StreamSchedulerOptions;\nexport type RadStreamStats = StreamStats & {\n pageBudget: number;\n lodTimeMs: number;\n};\n\ntype Pool = {\n batch: RadStreamBatch;\n /** The scheduler owns slot allocation and retirement. */\n slots: (Page | undefined)[];\n};\ntype PageSlot = { pool: Pool; slot: number };\ntype PageLoad = {\n controller: AbortController;\n phase: \"decoding\" | \"registering\";\n /** Kept until tree registration settles, including after cancellation. */\n reservedBytes: number;\n};\ntype PageStorage =\n | { phase: \"decoded\"; data: RadStreamChunk; allocation?: PageSlot }\n | { phase: \"resident\"; allocation: PageSlot };\n\ntype Page = {\n index: number;\n base: number;\n count: number;\n load?: PageLoad;\n /** Decoded buffers stay owned here until written to the reserved slot. */\n storage?: PageStorage;\n failures: number;\n retryAt: number;\n expiresAt?: number;\n};\n\ntype DisplayedCut = {\n selection: RadVersionedSelection;\n pages: Set<number>;\n transition?: { startedAt: number; pools: Pool[] };\n};\n\ntype ReadyCut = {\n selection: RadStreamSelection;\n pages: Set<number>;\n reselect: boolean;\n};\n\ntype Traversal = {\n pages: Set<number>;\n previous?: RadVersionedSelection;\n splatBudget: number;\n};\n\ntype Preparation = {\n /** Same order as the worker's pool snapshots and results. */\n pools: Pool[];\n pages: Set<number>;\n cancelled: boolean;\n bytes: number;\n result?: RadSelectionPreparation;\n};\n\nfunction pendingPageBytes(page: Page) {\n return page.storage?.phase === \"decoded\"\n ? getSplatByteLength(page.storage.data)\n : (page.load?.reservedBytes ?? 0);\n}\n\n/** Camera-driven RAD tree cuts with crossfades, on-demand pages and cooldown. */\nexport class RadStreamScheduler {\n readonly group: THREE.Group;\n readonly initialized: Promise<this>;\n readonly firstRenderable: Promise<this>;\n readonly cooldownMs: number;\n readonly fadeDurationMs: number;\n readonly maxConcurrentLoads: number;\n private _splatBudget: number;\n private readonly loader: RadStreamLoader;\n private readonly abort = new AbortController();\n private readonly streamCameras = new StreamCameras();\n private readonly pages = new Map<number, Page>();\n private readonly pools: Pool[] = [];\n private readonly bounds = new THREE.Box3();\n private readonly matrix = new THREE.Matrix4();\n private meta?: RadMeta;\n private pageSize = 0;\n private pageBudget = 0;\n private numSh = 0;\n private maxPagePendingBytes = 0;\n private disposed = false;\n private shown = true;\n private displayed?: DisplayedCut;\n private ready?: ReadyCut;\n private traversal?: Traversal;\n private preparation?: Preparation;\n private wanted = new Set<number>();\n private revision = 0;\n private lastRequestedRevision = -1;\n private refinementStopped = false;\n private lastViewKey = \"\";\n private views: RadLodView[] = [];\n private lodTimeMs = 0;\n private resolveFirst!: (value: this) => void;\n private rejectFirst!: (error: unknown) => void;\n\n constructor(private readonly options: RadStreamSchedulerOptions) {\n this.group = options.group ?? new THREE.Group();\n const settings = streamSettings(options);\n this._splatBudget = settings.splatBudget;\n this.cooldownMs = settings.cooldownMs;\n this.fadeDurationMs = settings.fadeDurationMs;\n this.maxConcurrentLoads = settings.maxConcurrentLoads;\n this.loader = new RadStreamLoader(options, this.maxConcurrentLoads);\n this.firstRenderable = new Promise((resolve, reject) => {\n this.resolveFirst = resolve;\n this.rejectFirst = reject;\n });\n this.initialized = this.initialize().catch((error) => {\n this.rejectFirst(error);\n this.loader.dispose();\n throw error;\n });\n void this.initialized.catch(() => {});\n void this.firstRenderable.catch(() => {});\n }\n\n /** Selected-node budget. Assigning a new value requests LOD selection. */\n get splatBudget(): number {\n return this._splatBudget;\n }\n\n set splatBudget(value: number) {\n if (value === this._splatBudget) return;\n this._splatBudget = positiveInteger(value, \"splatBudget\");\n this.invalidatePendingSelection();\n this.revision++;\n void this.requestSelection();\n }\n\n /** Cameras that select detail, in registration order. */\n get cameras(): readonly THREE.Camera[] {\n return this.streamCameras.cameras;\n }\n\n hasCamera(camera: THREE.Camera) {\n return this.streamCameras.has(camera);\n }\n\n /**\n * Select detail for this camera on each update; set its resolution too. For\n * WebXR register renderer.xr.getCamera(): it selects with its eyes' combined\n * frustum, sized by an eye's viewport. Returns whether the camera was newly\n * added.\n */\n setCamera(camera: THREE.Camera) {\n return this.streamCameras.add(camera);\n }\n\n /** Stop selecting detail for this camera. Returns whether it was registered. */\n deleteCamera(camera: THREE.Camera) {\n return this.streamCameras.delete(camera);\n }\n\n /**\n * Set a registered camera's render size in CSS pixels, without the device\n * pixel ratio. Returns whether the camera is registered.\n */\n setResolution(\n camera: THREE.Camera,\n xOrVec: number | THREE.Vector2,\n y?: number,\n ) {\n return this.streamCameras.setResolution(camera, xOrVec, y);\n }\n\n /** Set a registered camera's resolution from renderer.getSize(). */\n setResolutionFromRenderer(\n camera: THREE.Camera,\n renderer: StreamResolutionSource,\n ) {\n return this.streamCameras.setResolutionFromRenderer(camera, renderer);\n }\n\n get stats(): RadStreamStats {\n const loader = this.loader.stats;\n let pendingBytes = 0;\n let residentChunks = 0;\n let loadingChunks = 0;\n for (const page of this.pages.values()) {\n if (page.storage?.phase === \"resident\") residentChunks++;\n if (page.load?.phase === \"decoding\") loadingChunks++;\n pendingBytes += pendingPageBytes(page);\n }\n return {\n visibleSplats: this.shown\n ? this.pools.reduce((sum, { batch }) => sum + batch.numSplats, 0)\n : 0,\n visibleMeshes: this.shown\n ? this.pools.filter(({ batch }) => batch.numSplats > 0).length\n : 0,\n residentChunks,\n residentMeshes: this.pools.length,\n residentBytes:\n this.pools.reduce(\n (sum, { batch }) => sum + batch.source.residentBytes,\n 0,\n ) +\n loader.estimatedCodebookBytes +\n loader.bootstrapBytes +\n loader.cachedBytes +\n loader.selectionBytes +\n (this.displayed?.selection.indices.byteLength ?? 0),\n pendingBytes: pendingBytes + (this.preparation?.bytes ?? 0),\n loadingChunks,\n downloadedBytes: loader.downloadedBytes,\n peakWasmMemoryBytes: loader.peakWasmMemoryBytes,\n pageBudget: this.pageBudget,\n lodTimeMs: this.lodTimeMs,\n };\n }\n\n /** Group-local root bounds plus selected Gaussian extents; approximate while streaming. */\n getBoundingBox(): THREE.Box3 {\n const box = this.bounds.clone();\n // Coarse centers can cluster inside large Gaussians. Include their extent\n // here so callers can frame the scene without inspecting owned batches.\n for (const { batch } of this.pools) {\n if (!batch.numSplats) continue;\n if (batch.matrixAutoUpdate) batch.updateMatrix();\n box.union(batch.getBoundingBox(false).applyMatrix4(batch.matrix));\n }\n return box;\n }\n\n private async initialize() {\n const { meta } = await this.loader.initialize(this.abort.signal);\n this.abort.signal.throwIfAborted();\n if (meta.count && !meta.lodTree) {\n const error = new Error(\n \"RAD streaming requires a LOD tree; load this file with SplatMesh instead\",\n );\n error.name = \"RadLodRequiredError\";\n throw error;\n }\n this.meta = meta;\n this.numSh = meta.maxSh ?? 0;\n if (!meta.count) {\n this.resolveFirst(this);\n this.changed();\n return this;\n }\n this.pageSize = getRadChunkSpan(meta, 0).count;\n for (let index = 1; index < meta.chunks.length; index++)\n this.pageSize = Math.max(\n this.pageSize,\n getRadChunkSpan(meta, index).count,\n );\n // Validate the largest page against the texture layout limits.\n radPageTextureLayout({\n pageSize: this.pageSize,\n pageCount: 1,\n });\n const paddedCount = Math.ceil(this.pageSize / 2048) * 2048;\n this.maxPagePendingBytes =\n getSplatTextureBytes(paddedCount, this.numSh) +\n // Tree data, source IDs, Morton order and bounds awaiting LOD registration.\n this.pageSize * 30 +\n Math.ceil(this.pageSize / SPLAT_BOUNDS_BLOCK_SIZE) * (48 + 32);\n this.pageBudget = meta.chunks.length;\n this.wanted.add(0);\n this.pump();\n this.changed();\n return this;\n }\n\n /**\n * Call before rendering. Registered cameras share one cut at the greatest\n * detail any of them needs.\n */\n update(): boolean {\n if (this.disposed) return false;\n const cameras = this.streamCameras.seeing(this.group.layers);\n if (!this.meta) return false;\n const now = performance.now();\n if (this.refinementStopped) {\n for (const { batch } of this.pools)\n batch.layers.mask = this.group.layers.mask;\n let changed = this.updateFade(now);\n changed = this.releaseUnused(now, true) || changed;\n if (changed) this.changed();\n return changed;\n }\n this.group.updateWorldMatrix(true, false);\n let shown = cameras.length > 0;\n for (\n let object: THREE.Object3D | null = this.group;\n object;\n object = object.parent\n )\n shown &&= object.visible;\n let changed = false;\n if (shown !== this.shown) {\n this.shown = shown;\n this.revision++;\n if (!shown) {\n this.clearSelectionState();\n for (const { batch } of this.pools)\n changed = batch.clearSelection() || changed;\n this.cancelUnusedLoads();\n }\n }\n for (const { batch } of this.pools)\n batch.layers.mask = this.group.layers.mask;\n this.views = [];\n for (const camera of streamViews(cameras)) {\n // A WebXR camera is sized by an eye's viewport: a headset has only\n // physical pixels.\n const viewport = (camera as THREE.PerspectiveCamera).viewport;\n const resolution = this.streamCameras.getResolution(camera);\n const width = viewport?.z ?? resolution?.x;\n const height = viewport?.w ?? resolution?.y;\n if (width === undefined || height === undefined)\n throw new Error(\n \"RAD camera has no resolution; call setResolution() or setResolutionFromRenderer()\",\n );\n this.matrix\n .copy(camera.matrixWorld)\n .invert()\n .multiply(this.group.matrixWorld);\n const p = camera.projectionMatrix.elements;\n this.views.push({\n viewFromObject: this.matrix.elements.slice(),\n projectionRows: [p[0], p[4], p[8], p[12], p[1], p[5], p[9], p[13]],\n pixelScale:\n Math.max(Math.abs(p[0]) * width, Math.abs(p[5]) * height) / 2,\n orthographic:\n (camera as THREE.OrthographicCamera).isOrthographicCamera === true,\n });\n }\n const key = this.views\n .map(\n (view) =>\n `${view.viewFromObject.join(\",\")}/${view.projectionRows.join(\",\")}/${view.pixelScale}/${view.orthographic}`,\n )\n .join(\";\");\n if (key !== this.lastViewKey) {\n this.lastViewKey = key;\n this.revision++;\n }\n if (shown && this.meta.count && !this.pages.get(0)?.storage?.allocation)\n this.wanted.add(0);\n changed = this.updateFade(now) || changed;\n if (shown) {\n this.reservePages();\n changed = this.uploadPages() || changed;\n }\n const preparation = this.preparation;\n if (preparation?.result && !this.displayed?.transition) {\n this.preparation = undefined;\n if (!preparation.cancelled && shown)\n changed =\n this.applySelection(preparation.result, preparation.pools, now) ||\n changed;\n // Apply the latest view after publishing or discarding this snapshot.\n this.revision++;\n }\n // Keep drawing the old cut until its replacement is prepared.\n if (\n this.ready &&\n !this.preparation &&\n !this.displayed?.transition &&\n this.selectionPagesReady(this.ready.selection)\n ) {\n const { selection: selected, reselect } = this.ready;\n this.ready = undefined;\n if (selected.changedChunks.length) void this.prepareSelection(selected);\n else\n changed =\n this.applySelection(\n { selection: selected, fade: false, pools: [] },\n [],\n now,\n ) || changed;\n if (reselect) this.revision++;\n }\n // Keep expired caches until a pending view/budget decision can reuse them.\n const allowRelease = !shown || this.lastRequestedRevision === this.revision;\n changed = this.releaseUnused(now, allowRelease) || changed;\n if (shown) {\n void this.requestSelection();\n this.pump();\n }\n if (changed) this.changed();\n return changed;\n }\n\n private async requestSelection() {\n if (\n this.disposed ||\n this.refinementStopped ||\n !this.shown ||\n this.traversal ||\n this.preparation ||\n !this.meta?.count ||\n !this.views.length ||\n this.lastRequestedRevision === this.revision ||\n !this.pages.get(0)?.storage?.allocation\n )\n return;\n const residentChunks = [...this.pages.values()]\n .filter((page) => page.storage?.allocation)\n .map((page) => page.index);\n const traversal: Traversal = {\n pages: new Set(residentChunks),\n previous: this.displayed?.selection,\n splatBudget: this.splatBudget,\n };\n this.traversal = traversal;\n this.lastRequestedRevision = this.revision;\n const { previous, splatBudget } = traversal;\n const started = performance.now();\n let accepted = false;\n try {\n const selection = await this.loader.selectLod({\n views: this.views,\n splatBudget,\n pixelThreshold: 1,\n residentChunks,\n previousId: previous?.selectionId,\n readyId: this.ready?.selection.selectionId,\n fade: this.fadeDurationMs > 0,\n });\n if (this.disposed || !this.shown || splatBudget !== this.splatBudget)\n return;\n this.lodTimeMs = performance.now() - started;\n // Keep the selected tree path while its reserved pages await writing.\n this.wanted = new Set(selection.wantedChunks);\n for (const index of selection.touchedChunks) this.wanted.add(index);\n accepted = true;\n this.cancelUnusedLoads();\n this.pump();\n // A completed cut may be applied or hidden during traversal. Recompute\n // against its new fade baseline, but accept camera lag to avoid starvation.\n if (this.displayed?.selection !== previous || this.preparation) {\n this.lastRequestedRevision = -1;\n this.changed();\n return;\n }\n if (\n this.ready &&\n !this.displayed?.transition &&\n !this.selectionPagesReady(selection)\n ) {\n // Finish the waiting cut instead of chasing newly decoded pages forever.\n // Loading still follows the latest result; refresh after publication.\n this.ready.reselect = true;\n } else {\n this.ready = {\n selection,\n pages: new Set(selection.touchedChunks),\n reselect: false,\n };\n }\n this.changed();\n } catch (error) {\n if (!this.disposed) {\n this.stopRefinement(error);\n }\n } finally {\n if (this.traversal === traversal) this.traversal = undefined;\n // Each accepted decision retires unused caches before the next snapshot,\n // even if the camera kept moving while the worker was selecting.\n if (!this.disposed) {\n const revision = this.revision;\n this.cancelUnusedLoads();\n const released = this.releaseUnused(\n performance.now(),\n accepted || !this.shown,\n );\n if (released || revision !== this.revision) {\n this.changed();\n this.pump();\n }\n }\n // Updates overwrite views/revision while this task runs. Dispatch their\n // latest snapshot immediately; ready results never block the next task.\n void this.requestSelection();\n }\n }\n\n private selectionPagesReady(selection: RadStreamSelection) {\n // Shared and outgoing nodes are already displayed; only changed pages may\n // still be unwritten. Ancestors need not delay publishing the selected cut.\n return selection.changedChunks.every((index) => {\n const page = this.pages.get(index);\n return page?.storage?.phase === \"resident\";\n });\n }\n\n private async prepareSelection(selection: RadStreamSelection) {\n let preparation: Preparation | undefined;\n try {\n const rangesByPool = new Map<Pool, RadSelectionRange[]>();\n for (const index of selection.changedChunks) {\n const pool = this.pages.get(index)?.storage?.allocation?.pool;\n if (!pool) throw new Error(\"RAD transition references a retired page\");\n if (!rangesByPool.has(pool)) rangesByPool.set(pool, []);\n }\n const indices = selection.fade?.indices ?? selection.indices;\n const meta = this.meta as RadMeta;\n let selectedCount = 0;\n // Sorted file indices let us resolve each page once, without a per-node\n // scan on the main thread. Only changed pools need replacement data.\n for (let start = 0; start < indices.length; ) {\n const page = this.pages.get(radChunkIndex(meta, indices[start]));\n const allocation = page?.storage?.allocation;\n if (!page || !allocation)\n throw new Error(\"RAD cut references a retired page\");\n const { pool, slot } = allocation;\n const pageEnd = page.base + page.count;\n let end = start + 1;\n let high = indices.length;\n while (end < high) {\n const middle = Math.floor((end + high) / 2);\n if (indices[middle] < pageEnd) end = middle + 1;\n else high = middle;\n }\n const ranges = rangesByPool.get(pool);\n if (ranges) {\n ranges.push({\n start,\n end,\n slot,\n pageStart: pool.batch.source.pageStart(slot),\n chunkIndex: page.index,\n sourceBase: page.base,\n });\n selectedCount += end - start;\n }\n start = end;\n }\n const pools = Array.from(rangesByPool, ([pool, ranges]) =>\n pool.batch.source.snapshotSelection(ranges),\n );\n // Pin physical slots until the reply, even when cancelled or hidden.\n const pages = new Set<number>();\n for (const page of this.pages.values())\n if (page.storage?.allocation) pages.add(page.index);\n preparation = {\n pools: Array.from(rangesByPool.keys()),\n pages,\n cancelled: false,\n bytes:\n selection.indices.byteLength +\n (selection.fade?.indices.byteLength ?? 0) +\n (selection.fade?.fades.byteLength ?? 0) +\n selection.changedChunks.byteLength +\n selection.touchedChunks.byteLength +\n selection.wantedChunks.byteLength +\n selectedCount * 8 + // Render indices and post-fade indices.\n // Opacity tables, current/post-fade page counts and bounds, dirty flags.\n pools.reduce(\n (bytes, pool) =>\n bytes + pool.opacityBlocks.byteLength + pool.pageCount * 9 + 96,\n 0,\n ),\n };\n this.preparation = preparation;\n const result = await this.loader.prepareSelection({ selection, pools });\n if (this.preparation !== preparation) return;\n preparation.result = result;\n } catch (error) {\n if (this.disposed || this.preparation !== preparation) return;\n this.preparation = undefined;\n this.lastRequestedRevision = -1;\n if (!preparation?.cancelled) {\n this.stopRefinement(error);\n }\n }\n this.changed();\n }\n\n private applySelection(\n prepared: RadSelectionPreparation,\n affected: Pool[],\n now: number,\n ) {\n const { selection, fade } = prepared;\n const changed = affected.length > 0;\n let index = 0;\n for (const pool of affected) {\n pool.batch.commitSelection(prepared.pools[index++]);\n if (pool.batch.numSplats > 0 && pool.batch.parent !== this.group)\n this.group.add(pool.batch);\n else if (pool.batch.numSplats === 0) pool.batch.removeFromParent();\n }\n // Unchanged nodes keep the fade baseline valid for an in-flight decision.\n let displayedSelection: RadVersionedSelection = selection;\n if (this.displayed && !selection.changedChunks.length) {\n const previous = this.displayed.selection;\n previous.touchedChunks = selection.touchedChunks;\n previous.wantedChunks = selection.wantedChunks;\n displayedSelection = previous;\n }\n this.displayed = {\n selection: displayedSelection,\n pages: new Set(selection.touchedChunks),\n transition: fade ? { startedAt: now, pools: affected } : undefined,\n };\n this.cancelUnusedLoads();\n if (selection.indices.length && !fade) this.resolveFirst(this);\n return changed;\n }\n\n private invalidatePendingSelection() {\n this.ready = undefined;\n // A cancelled preparation still owns its physical slots until the reply.\n if (this.preparation) this.preparation.cancelled = true;\n }\n\n private clearSelectionState() {\n this.invalidatePendingSelection();\n this.displayed = undefined;\n this.wanted.clear();\n }\n\n /** Worker snapshots and waiting cuts pin pages without renewing cooldown. */\n private isPagePinned(index: number) {\n return (\n this.traversal?.pages.has(index) ||\n this.ready?.pages.has(index) ||\n this.preparation?.pages.has(index)\n );\n }\n\n private cancelUnusedLoads() {\n for (const page of this.pages.values()) {\n if (\n !this.wanted.has(page.index) &&\n !this.isPagePinned(page.index) &&\n page.index !== 0\n ) {\n page.load?.controller.abort();\n if (page.storage?.phase === \"decoded\") this.releasePage(page);\n }\n }\n }\n\n private updateFade(now: number) {\n const displayed = this.displayed;\n const transition = displayed?.transition;\n if (!displayed || !transition) return false;\n const progress = THREE.MathUtils.clamp(\n (now - transition.startedAt) / this.fadeDurationMs,\n 0,\n 1,\n );\n if (progress > 0 && displayed.selection.indices.length)\n this.resolveFirst(this);\n if (progress === 1) {\n displayed.transition = undefined;\n let changed = false;\n for (const { batch } of transition.pools) {\n changed = batch.finishFade() || changed;\n if (batch.numSplats === 0) batch.removeFromParent();\n }\n return changed;\n }\n let changed = false;\n for (const { batch } of transition.pools)\n if (batch.numSplats > 0)\n changed = batch.setFadeProgress(progress) || changed;\n return changed;\n }\n\n private page(index: number) {\n let page = this.pages.get(index);\n if (!page) {\n const range = getRadChunkSpan(this.meta as RadMeta, index);\n page = {\n index,\n base: range.base,\n count: range.count,\n failures: 0,\n retryAt: 0,\n };\n this.pages.set(index, page);\n }\n return page;\n }\n\n private pump() {\n if (this.disposed || this.refinementStopped || !this.meta) return;\n let loading = 0;\n let pendingBytes = 0;\n for (const page of this.pages.values()) {\n if (page.load?.phase === \"decoding\") loading++;\n pendingBytes += pendingPageBytes(page);\n }\n const pending = new StreamByteBudget(\n streamPendingLimit(this.maxConcurrentLoads, this.maxPagePendingBytes),\n pendingBytes,\n );\n const now = performance.now();\n for (const index of this.wanted) {\n const page = this.page(index);\n if (page.storage || page.load || now < page.retryAt) continue;\n if (\n loading >= this.maxConcurrentLoads ||\n !pending.reserve(this.maxPagePendingBytes)\n )\n break;\n const load: PageLoad = {\n controller: new AbortController(),\n phase: \"decoding\",\n reservedBytes: this.maxPagePendingBytes,\n };\n page.load = load;\n loading++;\n void this.loadPage(page, load);\n }\n }\n\n private async loadPage(page: Page, load: PageLoad) {\n const { signal } = load.controller;\n const active = () =>\n !this.disposed && !signal.aborted && page.load === load;\n try {\n const data = await this.loader.loadChunk(page.index, signal, () => {\n if (!active()) return;\n load.phase = \"registering\";\n this.pump();\n });\n if (!active()) return;\n page.storage = { phase: \"decoded\", data };\n page.failures = 0;\n if (page.index === 0) this.setInitialBounds(data);\n this.reservePages();\n } catch (error) {\n if (active()) {\n if (this.loader.lodWorkerLost) return this.stopRefinement(error);\n page.retryAt = streamRetryAt(error, page.failures++);\n if (page.index === 0 && page.retryAt === Number.POSITIVE_INFINITY)\n this.rejectFirst(error);\n this.failed(error, page.index);\n }\n } finally {\n if (page.load === load) page.load = undefined;\n this.scheduleRetry();\n if (!this.disposed) {\n void this.requestSelection();\n this.changed();\n this.pump();\n }\n }\n }\n\n private setInitialBounds(data: RadStreamChunk) {\n // The page worker computes these bounds during Morton reordering.\n const bounds = data.centerOnlyBoundingBox;\n this.bounds.min.fromArray(bounds);\n this.bounds.max.fromArray(bounds, 3);\n if (this.bounds.min.equals(this.bounds.max))\n this.bounds.expandByScalar(Math.max(0.001, data.rootRadius ?? 1));\n }\n\n private findSlot(): PageSlot {\n for (const pool of this.pools) {\n const slot = pool.slots.indexOf(undefined);\n if (slot !== -1) return { pool, slot };\n }\n const capacity = this.pools.reduce(\n (sum, pool) => sum + pool.slots.length,\n 0,\n );\n // Each chunk owns at most one slot. An unallocated page therefore leaves\n // room below pageBudget, which is the dataset's total chunk count.\n const count = Math.min(8, this.pageBudget - capacity);\n const batch = new RadStreamBatch({\n pageSize: this.pageSize,\n pageCount: count,\n numSh: this.numSh,\n });\n batch.layers.mask = this.group.layers.mask;\n const pool: Pool = {\n batch,\n slots: Array(count).fill(undefined),\n };\n this.pools.push(pool);\n return { pool, slot: 0 };\n }\n\n private reservePages() {\n for (const page of this.pages.values()) {\n const storage = page.storage;\n if (storage?.phase !== \"decoded\" || storage.allocation) continue;\n const available = this.findSlot();\n const { pool, slot } = available;\n pool.slots[slot] = page;\n storage.allocation = available;\n this.revision++;\n }\n }\n\n private uploadPages() {\n let changed = false;\n const pages = new Set([...(this.ready?.pages ?? []), ...this.wanted]);\n for (const index of pages) {\n const page = this.pages.get(index);\n const storage = page?.storage;\n if (!page || storage?.phase !== \"decoded\" || !storage.allocation)\n continue;\n const { pool, slot } = storage.allocation;\n pool.batch.source.writePage(slot, storage.data);\n page.storage = { phase: \"resident\", allocation: storage.allocation };\n page.expiresAt = undefined;\n changed = true;\n }\n return changed;\n }\n\n private releasePage(page: Page) {\n const allocation = page.storage?.allocation;\n if (allocation) {\n const { pool, slot } = allocation;\n pool.slots[slot] = undefined;\n }\n page.storage = undefined;\n page.expiresAt = undefined;\n this.loader.releaseChunk(page.index);\n this.revision++;\n }\n\n private releaseUnused(now: number, allowRelease: boolean) {\n let changed = false;\n for (const page of this.pages.values()) {\n const allocation = page.storage?.allocation;\n if (!allocation || page.index === 0) continue;\n const { pool, slot } = allocation;\n if (\n this.displayed?.pages.has(page.index) ||\n this.wanted.has(page.index) ||\n pool.batch.source.isPageSelected(slot)\n ) {\n page.expiresAt = undefined;\n continue;\n }\n page.expiresAt ??= now + this.cooldownMs;\n // A traversal snapshot delays release without renewing unused pages.\n if (\n !allowRelease ||\n now < page.expiresAt ||\n this.isPagePinned(page.index)\n )\n continue;\n this.releasePage(page);\n changed = true;\n }\n // Like streamed SOG, release source storage once its contents retire.\n for (let index = this.pools.length - 1; index >= 0; index--) {\n const pool = this.pools[index];\n if (pool.slots.every((page) => page === undefined)) {\n pool.batch.dispose();\n this.pools.splice(index, 1);\n changed = true;\n }\n }\n return changed;\n }\n\n /** Map a raycast hit's rendered index back to its stable file index. */\n getGlobalIndex(mesh: THREE.Object3D, renderedIndex: number) {\n const pool = this.pools.find(({ batch }) => batch === mesh);\n if (!pool) throw new Error(\"Mesh does not belong to this RAD dataset\");\n return pool.batch.source.getSourceIndex(renderedIndex);\n }\n\n private changed() {\n if (!this.disposed) notifyStreamChange(this.options);\n }\n\n private failed(error: unknown, index: number) {\n notifyStreamError(this.options, error, this.loader.getChunkUrl(index));\n }\n\n private stopRefinement(error: unknown) {\n this.refinementStopped = true;\n this.ready = undefined;\n this.preparation = undefined;\n this.wanted.clear();\n this.retryTimer.dispose();\n for (const page of this.pages.values()) page.load?.controller.abort(error);\n this.loader.dispose();\n for (const page of this.pages.values())\n if (page.storage?.phase === \"decoded\") this.releasePage(page);\n this.rejectFirst(error);\n this.failed(error, -1);\n this.changed();\n }\n\n private scheduleRetry() {\n if (!this.refinementStopped) this.retryTimer.update(this.retryDeadlines());\n }\n\n private *retryDeadlines() {\n for (const index of this.wanted) {\n const page = this.pages.get(index);\n if (page && !page.storage) yield page.retryAt;\n }\n }\n\n private readonly retryTimer = new RetryTimer(() => this.changed());\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.retryTimer.dispose();\n const reason = new DOMException(\"RAD scheduler disposed\", \"AbortError\");\n this.abort.abort(reason);\n this.rejectFirst(reason);\n for (const page of this.pages.values()) page.load?.controller.abort(reason);\n this.loader.dispose();\n this.preparation = undefined;\n for (const { batch } of this.pools) batch.dispose();\n this.pools.length = 0;\n this.pages.clear();\n this.clearSelectionState();\n this.traversal = undefined;\n this.meta = undefined;\n this.bounds.makeEmpty();\n this.views = [];\n }\n}\n","import type { Box3 } from \"three\";\nimport { IndexedSplats } from \"./IndexedSplats\";\nimport {\n type ReorderedSplatResult,\n SPLAT_TEX_HEIGHT,\n SPLAT_TEX_WIDTH,\n} from \"./defines\";\nimport { resetSplatBounds, unionSplatBounds } from \"./splatData\";\nimport { getTextureSize } from \"./textureLayout\";\n\n// Small allocation blocks avoid a separate 2048-Splat texture row per region.\nconst BLOCK_BITS = 6;\nconst BLOCK_SIZE = 1 << BLOCK_BITS;\nconst MIN_LAYER_SIZE = 8192;\n\nexport function sogBatchAllocationSize(count: number) {\n return Math.ceil(count / BLOCK_SIZE) * BLOCK_SIZE;\n}\n\nexport function sogBatchTextureLayout(count: number) {\n // Grow the layer dimensions instead of splitting a chunk into more Meshes.\n // Keep the same backing-array alignment as Splats to avoid a second copy.\n const aligned = getTextureSize(count).maxSplats;\n const layerSize = Math.min(\n SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT,\n Math.max(MIN_LAYER_SIZE, 2 ** Math.ceil(Math.log2(aligned / 256))),\n );\n return {\n capacity: Math.ceil(aligned / layerSize) * layerSize,\n layerSize,\n };\n}\n\n/** Independently visible regions in fixed source slots. */\nexport class SogRegionSplats extends IndexedSplats {\n private readonly activeRanges = new Map<number, number>();\n private indicesDirty = false;\n private boundsDirty = true;\n private readonly regionBounds = new Map<\n number,\n { centers: Float32Array; full: Float32Array }\n >();\n\n constructor(count: number, numSh: number) {\n const { capacity, layerSize } = sogBatchTextureLayout(count);\n super({ capacity, layerSize, numSh, blockBits: BLOCK_BITS });\n }\n\n write(start: number, data: ReorderedSplatResult) {\n if (\n data.centerOnlyBoundingBox?.length !== 6 ||\n data.boundingBox?.length !== 6\n )\n throw new Error(\"SOG region bounds must contain six values\");\n this.writeRecords(start, data, sogBatchAllocationSize(data.numSplats));\n this.regionBounds.set(start, {\n centers: data.centerOnlyBoundingBox.slice(),\n full: data.boundingBox.slice(),\n });\n if (this.activeRanges.has(start)) this.boundsDirty = true;\n }\n\n setOpacity(start: number, count: number, opacity: number) {\n this.assertLive();\n // The scheduler supplies block-aligned slots and clamped fade values.\n const previous = this.opacities.getOpacity(start);\n if (!this.opacities.setOpacity(start, count, opacity)) return;\n const visible = Math.fround(opacity) > 0;\n const visibilityChanged = previous > 0 !== visible;\n if (visibilityChanged) {\n if (visible) this.activeRanges.set(start, count);\n else this.activeRanges.delete(start);\n this.numSplats += visible ? count : -count;\n this.indicesDirty = true;\n this.boundsDirty = true;\n }\n return { visibilityChanged };\n }\n\n /** The batch hides the region before releasing its slot. */\n release(start: number) {\n this.assertLive();\n this.regionBounds.delete(start);\n this.releaseSpatialBounds(start);\n }\n\n override getBoundingBox(centersOnly = true, target?: Box3) {\n this.assertLive();\n if (this.boundsDirty) {\n resetSplatBounds(this.centerOnlyBounds);\n resetSplatBounds(this.bounds);\n for (const start of this.activeRanges.keys()) {\n const bounds = this.regionBounds.get(start);\n if (!bounds) throw new Error(\"Visible SOG region has no cached bounds\");\n unionSplatBounds(this.centerOnlyBounds, bounds.centers);\n unionSplatBounds(this.bounds, bounds.full);\n }\n this.boundsDirty = false;\n }\n return super.getBoundingBox(centersOnly, target);\n }\n\n override getByteLength() {\n return super.getByteLength() + this.regionBounds.size * 48;\n }\n\n protected override ensureIndices() {\n if (!this.indicesDirty) return;\n const indices = this.prepareIndices(this.numSplats);\n let target = 0;\n for (const [start, count] of this.activeRanges)\n for (let source = start; source < start + count; source++) {\n this.visibleIndices[source] = target;\n indices[target++] = source;\n }\n this.indicesDirty = false;\n }\n\n override dispose() {\n super.dispose();\n this.activeRanges.clear();\n this.regionBounds.clear();\n this.indicesDirty = false;\n }\n}\n","import type * as THREE from \"three\";\nimport { SogRegionSplats } from \"../../../data/SogRegionSplats\";\nimport type { ReorderedSplatResult } from \"../../../data/defines\";\nimport { SplatMesh } from \"../../../scene/SplatMesh\";\n\n/** Regions share one source, one scene node and one accumulator generation call. */\nexport class SogStreamBatch extends SplatMesh {\n private readonly source: SogRegionSplats;\n private readonly slots = new Map<number, number>();\n\n constructor(\n capacity: number,\n readonly numSh: number,\n private readonly group: THREE.Group,\n private readonly onEmpty: () => void,\n ) {\n const source = new SogRegionSplats(capacity, numSh);\n super({ splats: source });\n this.source = source;\n this.name = \"sog-batch\";\n }\n\n get residentBytes() {\n return this.source.residentBytes;\n }\n\n writeRegion(start: number, data: ReorderedSplatResult) {\n const count = data.numSplats;\n // The scheduler assigns disjoint fixed slots; only occupancy changes.\n this.source.write(start, data);\n this.slots.set(start, count);\n }\n\n setRegionOpacity(start: number, opacity: number) {\n const count = this.slots.get(start);\n if (count === undefined) return;\n const changed = this.source.setOpacity(start, count, opacity);\n if (!changed) return;\n if (changed.visibilityChanged) {\n this.numSplats = this.source.getNumSplats();\n this.updateMappingVersion();\n if (this.numSplats > 0 && this.parent !== this.group) {\n this.layers.mask = this.group.layers.mask;\n this.group.add(this);\n } else if (this.numSplats === 0) this.removeFromParent();\n } else this.updateVersion({ sort: false });\n }\n\n releaseRegion(start: number) {\n if (!this.slots.has(start)) return;\n this.setRegionOpacity(start, 0);\n this.source.release(start);\n this.slots.delete(start);\n if (!this.slots.size) {\n this.dispose();\n this.onEmpty();\n }\n }\n}\n","import { WorkerRpc } from \"../../../runtime/WorkerRpc\";\nimport type { SogStreamRpcHandlers } from \"./worker\";\nimport BundledWorker from \"./worker?worker&inline\";\n\n/** Worker assigned either LOD traversal or retained chunk decoding. */\nexport class SogStreamWorker extends WorkerRpc<SogStreamRpcHandlers> {\n constructor(onDispose?: () => void) {\n super(new BundledWorker(), onDispose);\n }\n}\n","import { DefaultLoadingManager } from \"three\";\nimport type { Splats } from \"../../../data/Splats\";\nimport { WorkerTerminatedError } from \"../../../runtime/WorkerRpc\";\nimport { abortable } from \"../../../runtime/abort\";\nimport { getAssetBaseUrl } from \"../../assetUrl\";\nimport type { SplatLoadStatus } from \"../../loadTypes\";\nimport { joinBytes, readResponse, requestOptions } from \"../../source\";\nimport { StreamWorkerPool } from \"../StreamWorkerPool\";\nimport type { StreamRequestOptions } from \"../streamOptions\";\nimport { SogStreamWorker } from \"./SogStreamWorker\";\nimport type { SogLodMetadata } from \"./sogLod\";\nimport type { SogView } from \"./sogVisibility\";\nimport type { SogChunkInfo } from \"./workerHandlers\";\n\nexport type SogStreamLoaderOptions = StreamRequestOptions & {\n url: string;\n /** Returns owned data in file order, or with a complete source ID map. */\n loadChunk?: (url: string, signal: AbortSignal) => Promise<Splats>;\n};\n\n/** A retained worker cache; extraction transfers owned packed arrays to the caller. */\nexport class SogChunkSource {\n private released = false;\n constructor(\n private readonly worker: SogStreamWorker,\n private readonly id: number,\n readonly info: SogChunkInfo,\n private readonly onRelease: () => void,\n ) {}\n\n get alive() {\n return !this.released && !this.worker.disposed;\n }\n\n async extract(ranges: { start: number; count: number }[]) {\n if (!this.alive)\n throw new WorkerTerminatedError(\"Streaming chunk is no longer cached\");\n return this.worker.call(\"extractSogRegions\", { id: this.id, ranges });\n }\n\n dispose() {\n if (this.released) return;\n this.released = true;\n if (!this.worker.disposed)\n void this.worker.call(\"releaseSogChunk\", { id: this.id }).catch(() => {});\n this.onRelease();\n }\n}\n\n/** Dedicated LOD worker, bounded decoders and retained chunk cache handles. */\nexport class SogStreamLoader {\n private readonly lodWorker: SogStreamWorker;\n private readonly pool: StreamWorkerPool<SogStreamWorker>;\n private readonly controller = new AbortController();\n private initialization?: Promise<SogLodMetadata>;\n private baseUrl = \"\";\n private downloadedBytes = 0;\n private retainedIndexBytes = 0;\n\n constructor(\n private readonly options: SogStreamLoaderOptions,\n maxConcurrentLoads: number,\n onChange: () => void,\n ) {\n this.pool = new StreamWorkerPool(\n () => new SogStreamWorker(() => queueMicrotask(onChange)),\n maxConcurrentLoads,\n );\n this.lodWorker = new SogStreamWorker(() => queueMicrotask(onChange));\n }\n\n get stats() {\n return {\n downloadedBytes: this.downloadedBytes + this.pool.downloadedBytes,\n peakWasmMemoryBytes:\n this.pool.peakWasmMemoryBytes + this.lodWorker.peakWasmMemoryBytes,\n retainedIndexBytes: this.lodWorker.disposed ? 0 : this.retainedIndexBytes,\n };\n }\n\n private assertActive() {\n this.controller.signal.throwIfAborted();\n if (this.lodWorker.disposed) throw new Error(\"SOG LOD worker terminated\");\n }\n\n initialize(signal?: AbortSignal) {\n signal?.throwIfAborted();\n this.assertActive();\n this.initialization ??= this.readIndex().catch((error) => {\n this.dispose();\n throw error;\n });\n return abortable(this.initialization, signal);\n }\n\n private async readIndex() {\n const signal = this.controller.signal;\n const manager = this.options.manager ?? DefaultLoadingManager;\n const resolveBase =\n typeof document === \"undefined\" ? undefined : document.baseURI;\n const url = new URL(manager.resolveURL(this.options.url), resolveBase).href;\n const resourceUrl = new URL(this.options.url, resolveBase ?? url).href;\n this.baseUrl = getAssetBaseUrl(url) ?? resourceUrl;\n manager.itemStart(url);\n try {\n const response = await fetch(url, {\n ...requestOptions(this.options, url, resourceUrl),\n signal,\n });\n const { chunks, size } = await readResponse(\n response,\n Number.POSITIVE_INFINITY,\n (bytes) => {\n this.downloadedBytes += bytes;\n },\n signal,\n );\n const bytes = new Uint8Array(joinBytes(chunks, size)).buffer;\n this.assertActive();\n const { retainedIndexBytes, ...index } = await this.lodWorker.call(\n \"parseSogIndex\",\n {\n bytes,\n baseUrl: getAssetBaseUrl(response.url || url) ?? resourceUrl,\n },\n );\n this.assertActive();\n this.retainedIndexBytes = retainedIndexBytes;\n return index;\n } catch (error) {\n manager.itemError(url);\n throw error;\n } finally {\n manager.itemEnd(url);\n }\n }\n\n async selectLod(view: SogView, budget: number): Promise<Uint32Array> {\n this.assertActive();\n return this.lodWorker.call(\"selectSogLod\", { view, budget });\n }\n\n async load(url: string, count: number, signal: AbortSignal) {\n this.assertActive();\n const manager = this.options.manager ?? DefaultLoadingManager;\n return this.pool.run(\n {\n signal,\n manager,\n cancel: (worker, id) => worker.call(\"releaseSogChunk\", { id }),\n },\n async ({ worker, id, signal, retain, start, progress }) => {\n this.assertActive();\n let info: SogChunkInfo;\n if (this.options.loadChunk) {\n const custom = await this.options.loadChunk(url, signal);\n try {\n signal.throwIfAborted();\n info = await worker.call(\"cacheSogChunk\", {\n id,\n data: custom.takeData(),\n });\n } finally {\n custom.dispose();\n }\n } else {\n const resolveBase =\n typeof document === \"undefined\" ? this.baseUrl : document.baseURI;\n const resourceUrl = new URL(url, resolveBase).href;\n const resolved = new URL(manager.resolveURL(url), resolveBase).href;\n start(resolved);\n const sameOrigin =\n new URL(getAssetBaseUrl(resolved) ?? resourceUrl).origin ===\n new URL(this.baseUrl).origin;\n info = await worker.call(\n \"loadSogChunk\",\n {\n id,\n url: resolved,\n baseUrl: resourceUrl,\n fileType: \"sog\",\n requestHeader: sameOrigin\n ? this.options.requestHeader\n : undefined,\n withCredentials: sameOrigin && this.options.withCredentials,\n expectedSogCount: count < 0 ? undefined : count,\n },\n {\n onStatus: (data) => {\n const status = data as SplatLoadStatus;\n if (\"assetRequest\" in status)\n return worker.call(\"resolveAsset\", {\n requestId: status.assetRequest,\n url: new URL(manager.resolveURL(status.url), resolveBase)\n .href,\n });\n if (\"loaded\" in status) progress(status.loaded);\n },\n },\n );\n }\n signal.throwIfAborted();\n this.assertActive();\n return new SogChunkSource(worker, id, info, retain());\n },\n );\n }\n\n dispose() {\n if (this.controller.signal.aborted) return;\n this.controller.abort(\n new DOMException(\"SOG loader disposed\", \"AbortError\"),\n );\n this.pool.dispose(this.controller.signal.reason);\n this.lodWorker.dispose(this.controller.signal.reason);\n this.initialization = undefined;\n this.retainedIndexBytes = 0;\n }\n}\n","import { Box3, Vector3 } from \"three\";\n\nexport type SogLodRange = {\n leaf: number;\n level: number;\n /** -1 for an empty LOD, which has no backing file. */\n file: number;\n offset: number;\n count: number;\n};\n\nexport type SogLodLeaf = {\n id: number;\n /** Coarse to fine, with strictly increasing counts and decreasing levels. */\n lods: SogLodRange[];\n};\n\nexport type SogLodNode = {\n bound: Box3;\n children?: SogLodNode[];\n leaf?: SogLodLeaf;\n};\n\nexport type SogLodFile = {\n url: string;\n count: number;\n ranges: SogLodRange[];\n};\n\nexport type SogLodManifest = {\n tree: SogLodNode;\n leaves: SogLodLeaf[];\n /** Flattened in leaf/LOD order; each leaf's first entry is unused. */\n upgradeRatios: number[];\n files: SogLodFile[];\n environment?: string;\n};\n\nexport const SOG_LOD_STRIDE = 4;\n\nconst DISTANCE_BAND_MULTIPLIER = 1.5;\n\n/** Packed worker index. Float64 preserves source bounds and safe-integer counts. */\nexport type SogLodIndex = {\n /** Preorder nodes: min XYZ, max XYZ, next index after the subtree, leaf ID (-1 for interiors). */\n nodes: Float64Array;\n leafOffsets: Uint32Array;\n /** Per level: level, file, offset, count. */\n lods: Float64Array;\n /** Best reachable distance-error reduction per added splat, in LOD order. */\n upgradeRatios: Float32Array;\n urls: string[];\n counts: Float64Array;\n environment?: string;\n};\n\n/** Scheduler metadata; the complete spatial tree stays in the LOD worker. */\nexport type SogLodMetadata = Omit<SogLodIndex, \"nodes\" | \"upgradeRatios\"> & {\n /** Root min XYZ and max XYZ. */\n bounds: Float64Array;\n};\n\n/** Flatten the tree and ranges into transferable typed arrays. */\nexport function packSogLodIndex(manifest: SogLodManifest): SogLodIndex {\n const { leaves, files, environment } = manifest;\n const nodes = new Float64Array((leaves.length * 2 - 1) * 8);\n let nextNode = 0;\n const writeNode = (node: SogLodNode) => {\n const offset = nextNode++ * 8;\n node.bound.min.toArray(nodes, offset);\n node.bound.max.toArray(nodes, offset + 3);\n nodes[offset + 7] = node.leaf?.id ?? -1;\n for (const child of node.children ?? []) writeNode(child);\n nodes[offset + 6] = nextNode;\n };\n writeNode(manifest.tree);\n const leafOffsets = new Uint32Array(leaves.length + 1);\n let count = 0;\n for (const leaf of leaves) {\n leafOffsets[leaf.id] = count;\n count += leaf.lods.length;\n }\n leafOffsets[leaves.length] = count;\n const lods = new Float64Array(count * SOG_LOD_STRIDE);\n for (const leaf of leaves) {\n leaf.lods.forEach((lod, index) => {\n lods.set(\n [lod.level, lod.file, lod.offset, lod.count],\n (leafOffsets[leaf.id] + index) * SOG_LOD_STRIDE,\n );\n });\n }\n return {\n nodes,\n leafOffsets,\n lods,\n upgradeRatios: Float32Array.from(manifest.upgradeRatios),\n urls: files.map((file) => file.url),\n counts: Float64Array.from(files, (file) => file.count),\n environment,\n };\n}\n\n/** Materialize only leaves visited by the camera, preserving stable range identities. */\nexport function readSogLodLeaf(\n index: Pick<SogLodIndex, \"leafOffsets\" | \"lods\">,\n id: number,\n): SogLodLeaf {\n const leaf: SogLodLeaf = { id, lods: [] };\n const data = index.lods;\n for (let i = index.leafOffsets[id]; i < index.leafOffsets[id + 1]; i++) {\n const offset = i * SOG_LOD_STRIDE;\n leaf.lods.push({\n leaf: id,\n level: data[offset],\n file: data[offset + 1],\n offset: data[offset + 2],\n count: data[offset + 3],\n });\n }\n return leaf;\n}\n\nfunction fail(message: string): never {\n throw new Error(`Streamed SOG: ${message}`);\n}\n\nfunction object(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n fail(\"expected an object\");\n return value as Record<string, unknown>;\n}\n\nfunction integer(value: unknown, name: string): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0)\n fail(`invalid ${name}`);\n return value;\n}\n\nfunction resolve(value: unknown, baseUrl: string): string {\n if (typeof value !== \"string\" || !value) fail(\"invalid asset path\");\n return new URL(value, baseUrl).href;\n}\n\n/** Streamed SOG v1, including the earlier unversioned manifests. */\nexport function parseSogLodManifest(\n value: unknown,\n baseUrl: string,\n): SogLodManifest {\n const root = object(value);\n if (root.version !== undefined && root.version !== 1)\n fail(`unsupported version ${root.version}`);\n const levels = integer(root.lodLevels, \"lodLevels\");\n if (levels < 1) fail(\"lodLevels must be positive\");\n if (!Array.isArray(root.filenames)) fail(\"filenames must be an array\");\n const files: SogLodFile[] = [];\n const urls = new Map<string, number>();\n const fileIndices = root.filenames.map((path) => {\n const url = resolve(path, baseUrl);\n const existing = urls.get(url);\n if (existing !== undefined) return existing;\n urls.set(url, files.length);\n files.push({ url, count: 0, ranges: [] });\n return files.length - 1;\n });\n const leaves: SogLodLeaf[] = [];\n const counts = Array<number>(levels).fill(0);\n const parseNode = (value: unknown): SogLodNode => {\n const node = object(value);\n const bounds = object(node.bound);\n const vector = (value: unknown) => {\n if (\n !Array.isArray(value) ||\n value.length !== 3 ||\n !value.every(Number.isFinite)\n )\n fail(\"invalid bounding box\");\n return new Vector3(value[0], value[1], value[2]);\n };\n const bound = new Box3(vector(bounds.min), vector(bounds.max));\n if (bound.isEmpty()) fail(\"bounding box min exceeds max\");\n if (node.children !== undefined) {\n if (\n node.lods !== undefined ||\n !Array.isArray(node.children) ||\n node.children.length !== 2\n )\n fail(\"interior nodes must have exactly two children and no lods\");\n const children = node.children.map(parseNode);\n // Include children despite rounding in older writers' parent bounds.\n for (const child of children) bound.union(child.bound);\n return { bound, children };\n }\n const leaf: SogLodLeaf = { id: leaves.length, lods: [] };\n leaves.push(leaf);\n for (const [key, value] of Object.entries(object(node.lods))) {\n const level = Number(key);\n if (!/^\\d+$/.test(key) || String(level) !== key || level >= levels)\n fail(`invalid LOD level ${key}`);\n const entry = object(value);\n const count = integer(entry.count, \"splat count\");\n if (count === 0) continue;\n const fileIndex = integer(entry.file, \"file index\");\n if (fileIndex >= fileIndices.length) fail(\"file index is out of bounds\");\n const range: SogLodRange = {\n leaf: leaf.id,\n level,\n file: fileIndices[fileIndex],\n offset: integer(entry.offset, \"splat offset\"),\n count,\n };\n integer(range.offset + range.count, \"range end\");\n counts[level] += range.count;\n files[range.file].ranges.push(range);\n leaf.lods.push(range);\n }\n return { bound, leaf };\n };\n const tree = parseNode(root.tree);\n const bandWeights = new Float64Array(levels);\n for (let level = 1; level < levels; level++)\n bandWeights[level] = DISTANCE_BAND_MULTIPLIER ** (2 * (level - 1));\n const distanceErrors = new Float64Array(levels);\n const upgradeRatios: number[] = [];\n for (const leaf of leaves) {\n leaf.lods.sort((a, b) => b.level - a.level);\n const coarsest = leaf.lods[0];\n // Missing coarser data means this region was decimated away. Price its\n // first nonempty level as an upgrade instead of forcing it into coverage.\n if (coarsest && coarsest.level < levels - 1) {\n leaf.lods.unshift({\n leaf: leaf.id,\n level: coarsest.level + 1,\n file: -1,\n offset: 0,\n count: 0,\n });\n }\n // Include every level before pruning, even with equal or inverted counts.\n let error = 0;\n for (let i = leaf.lods.length - 1; i >= 0; i--) {\n const lod = leaf.lods[i];\n const finer = leaf.lods[i + 1];\n if (finer)\n error += Math.max(finer.count - lod.count, 1) * bandWeights[lod.level];\n distanceErrors[lod.level] = error;\n }\n leaf.lods.sort(\n (a, b) =>\n a.count - b.count || distanceErrors[a.level] - distanceErrors[b.level],\n );\n let bestError = Number.POSITIVE_INFINITY;\n leaf.lods = leaf.lods.filter((lod) => {\n if (distanceErrors[lod.level] >= bestError) return false;\n bestError = distanceErrors[lod.level];\n return true;\n });\n // Include pruned levels' errors when finding the best reachable upgrade ratio.\n if (leaf.lods.length) upgradeRatios.push(0);\n for (let i = 1; i < leaf.lods.length; i++) {\n const coarse = leaf.lods[i - 1];\n let ratio = 0;\n for (let j = i; j < leaf.lods.length; j++) {\n const reach = leaf.lods[j];\n ratio = Math.max(\n ratio,\n (distanceErrors[coarse.level] - distanceErrors[reach.level]) /\n (reach.count - coarse.count),\n );\n }\n upgradeRatios.push(ratio);\n }\n }\n for (const file of files) {\n file.ranges.sort((a, b) => a.offset - b.offset || a.count - b.count);\n const level = file.ranges[0]?.level;\n for (const range of file.ranges) {\n if (range.offset !== file.count || range.level !== level)\n fail(\"chunk ranges must cover one LOD without gaps or overlaps\");\n file.count += range.count;\n }\n }\n const count = counts.reduce((sum, value) => sum + value, 0);\n integer(count, \"total count\");\n if (root.count !== undefined && root.count !== count) fail(\"count mismatch\");\n if (\n root.counts !== undefined &&\n (!Array.isArray(root.counts) ||\n root.counts.length !== levels ||\n root.counts.some((count, level) => count !== counts[level]))\n )\n fail(\"per-LOD counts mismatch\");\n const environment =\n root.environment == null ? undefined : resolve(root.environment, baseUrl);\n if (environment && files.some((file) => file.url === environment))\n fail(\"environment must be separate from LOD chunks\");\n return { tree, leaves, upgradeRatios, files, environment };\n}\n\nexport type SogVisibleLeaf = { leaf: SogLodLeaf; weight: number };\n\n/** Reuse cached refinements up to the target, then split gaps of four or more. */\nexport function resolveSogLod(\n leaf: SogLodLeaf,\n target: SogLodRange,\n current: SogLodRange | undefined,\n isLoaded: (range: SogLodRange) => boolean,\n): {\n range: SogLodRange | undefined;\n load?: SogLodRange;\n /** Wait until range is attached before requesting the next LOD. */\n refinement?: boolean;\n} {\n if (target.count === 0) return { range: undefined };\n if (current === target || isLoaded(target)) return { range: target };\n\n const targetIndex = leaf.lods.indexOf(target);\n const currentIndex = current ? leaf.lods.indexOf(current) : -1;\n // Prefer the finest cached refinement without going beyond the target.\n let index = targetIndex - 1;\n while (\n index > currentIndex &&\n (leaf.lods[index].count === 0 || !isLoaded(leaf.lods[index]))\n )\n index--;\n const range = index > currentIndex ? leaf.lods[index] : current;\n if (!range) return { range, load: leaf.lods.find((lod) => lod.count > 0) };\n\n let load = target;\n if (range.level - target.level >= 4) {\n const midpoint = Math.floor((range.level + target.level) / 2);\n let nextIndex = index + 1;\n // Missing or dominated levels advance to the finer side of the midpoint.\n while (nextIndex < targetIndex && leaf.lods[nextIndex].level > midpoint)\n nextIndex++;\n load = leaf.lods[nextIndex];\n }\n return { range, load, refinement: true };\n}\n\n/** Distance bands within a splat budget, using a small heap. */\nexport function selectSogLods(\n visible: SogVisibleLeaf[],\n budget: number,\n manifest: Pick<SogLodIndex, \"leafOffsets\" | \"upgradeRatios\">,\n): Map<number, SogLodRange> {\n const { leafOffsets, upgradeRatios } = manifest;\n let remaining = budget;\n type Upgrade = SogVisibleLeaf & { index: number; score: number };\n const selected = new Map<number, SogLodRange>();\n const heap: Upgrade[] = [];\n const better = (a: Upgrade, b: Upgrade) =>\n a.score > b.score || (a.score === b.score && a.leaf.id < b.leaf.id);\n const push = (item: Upgrade) => {\n let index = heap.length;\n heap.push(item);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (!better(item, heap[parent])) break;\n heap[index] = heap[parent];\n index = parent;\n }\n heap[index] = item;\n };\n const pop = () => {\n const first = heap[0];\n const last = heap.pop() as Upgrade;\n if (heap.length) {\n let index = 0;\n while (index * 2 + 1 < heap.length) {\n let child = index * 2 + 1;\n if (child + 1 < heap.length && better(heap[child + 1], heap[child]))\n child++;\n if (!better(heap[child], last)) break;\n heap[index] = heap[child];\n index = child;\n }\n heap[index] = last;\n }\n return first;\n };\n const upgrade = (\n leaf: SogLodLeaf,\n weight: number,\n index: number,\n ceiling = Number.POSITIVE_INFINITY,\n ) => {\n if (index >= leaf.lods.length) return;\n // A later step can have a higher ratio; keep it at the priority that opened it.\n const score = Math.min(\n weight * upgradeRatios[leafOffsets[leaf.id] + index],\n ceiling,\n );\n push({ leaf, weight, index, score });\n };\n for (const { leaf, weight } of visible) {\n const coarse = leaf.lods[0];\n if (!coarse) continue;\n selected.set(leaf.id, coarse);\n remaining -= coarse.count;\n upgrade(leaf, weight, 1);\n }\n while (heap.length) {\n const { leaf, weight, index, score } = pop();\n const coarse = leaf.lods[index - 1];\n const fine = leaf.lods[index];\n // Stop at the first unaffordable upgrade; skipping it makes unrelated\n // cheaper regions flicker as the camera moves. Coverage remains the floor.\n if (fine.count - coarse.count > remaining) break;\n remaining -= fine.count - coarse.count;\n selected.set(leaf.id, fine);\n upgrade(leaf, weight, index + 1, score);\n }\n return selected;\n}\n","import * as THREE from \"three\";\nimport { streamViews } from \"../StreamCameras\";\nimport {\n type SogLodIndex,\n type SogLodLeaf,\n type SogVisibleLeaf,\n readSogLodLeaf,\n selectSogLods,\n} from \"./sogLod\";\n\nexport type SogCamera = {\n modelView: number[];\n projection: number[];\n coordinateSystem: THREE.CoordinateSystem;\n reversedDepth: boolean;\n};\n\nexport type SogView = {\n /** The registered cameras that see the group; selection serves all of them. */\n cameras: SogCamera[];\n shown: boolean;\n};\n\ntype CameraState = {\n modelView: THREE.Matrix4;\n frustum: THREE.Frustum;\n cameraPosition: THREE.Vector3;\n fovScale: number;\n};\n\n/**\n * Capture the cameras that see the group without traversing the manifest or\n * reducing matrix precision. WebXR selects detail from each eye's current pose and frustum.\n */\nexport function captureSogView(\n cameras: readonly THREE.Camera[],\n group: THREE.Object3D,\n): SogView {\n group.updateWorldMatrix(true, false);\n const views: SogCamera[] = [];\n for (const camera of streamViews(cameras)) {\n views.push({\n // Invert matrixWorld like the splat projection: Camera.matrixWorldInverse\n // can omit rig scale.\n modelView: new THREE.Matrix4()\n .copy(camera.matrixWorld)\n .invert()\n .multiply(group.matrixWorld).elements,\n projection: camera.projectionMatrix.toArray(),\n coordinateSystem: camera.coordinateSystem,\n reversedDepth: camera.reversedDepth,\n });\n }\n let shown = cameras.length > 0;\n for (let node: THREE.Object3D | null = group; node; node = node.parent)\n shown &&= node.visible;\n return { cameras: views, shown };\n}\n\n/** Stable key of a view, for skipping unchanged selection requests. */\nexport function getSogViewKey(view: SogView) {\n return view.cameras\n .map(\n (camera) =>\n `${camera.modelView.join(\",\")}/${camera.projection.join(\",\")}/${camera.coordinateSystem}/${camera.reversedDepth}`,\n )\n .join(\";\");\n}\n\n/** Worker traversal state keeps leaf identities stable between selections. */\nexport class SogVisibility {\n private readonly leaves = new Map<number, SogLodLeaf>();\n private readonly cameras: CameraState[] = [];\n private readonly clip = new THREE.Matrix4();\n private readonly bound = new THREE.Box3();\n private readonly closest = new THREE.Vector3();\n private readonly inverseModelView = new THREE.Matrix4();\n\n constructor(\n private readonly manifest: Pick<\n SogLodIndex,\n \"nodes\" | \"leafOffsets\" | \"lods\" | \"upgradeRatios\"\n >,\n ) {}\n\n private prepareCameras(view: SogView) {\n const cameras = this.cameras;\n cameras.length = Math.min(cameras.length, view.cameras.length);\n view.cameras.forEach((camera, index) => {\n let state = cameras[index];\n if (!state) {\n state = {\n modelView: new THREE.Matrix4(),\n frustum: new THREE.Frustum(),\n cameraPosition: new THREE.Vector3(),\n fovScale: 1,\n };\n cameras[index] = state;\n }\n state.modelView.fromArray(camera.modelView);\n this.clip.fromArray(camera.projection).multiply(state.modelView);\n this.inverseModelView.copy(state.modelView).invert();\n state.cameraPosition.setFromMatrixPosition(this.inverseModelView);\n state.frustum.setFromProjectionMatrix(\n this.clip,\n camera.coordinateSystem,\n camera.reversedDepth,\n );\n const projection = camera.projection;\n state.fovScale =\n projection[11] === 0\n ? 1\n : 1 /\n (Math.max(Math.abs(projection[0]), Math.abs(projection[5])) *\n Math.tan(Math.PI / 8));\n });\n return cameras;\n }\n\n private collect(view: SogView) {\n const cameras = this.prepareCameras(view);\n const visible: SogVisibleLeaf[] = [];\n const { shown } = view;\n const nodes = this.manifest.nodes;\n for (let index = 0; shown && index < nodes.length / 8; ) {\n const offset = index * 8;\n this.bound.min.fromArray(nodes, offset);\n this.bound.max.fromArray(nodes, offset + 3);\n const id = nodes[offset + 7];\n if (id < 0) {\n // A branch only needs one view that sees it.\n if (cameras.some(({ frustum }) => frustum.intersectsBox(this.bound)))\n index++;\n else index = nodes[offset + 6];\n continue;\n }\n // A leaf tests each view once for visibility and detail together: the\n // nearest view that sees it decides its detail.\n let seen = false;\n let weight = 1e-12;\n for (const { modelView, frustum, cameraPosition, fovScale } of cameras) {\n if (!frustum.intersectsBox(this.bound)) continue;\n seen = true;\n this.bound\n .clampPoint(cameraPosition, this.closest)\n .applyMatrix4(modelView);\n // World-space distance to the box, without weighting by its radius.\n const distance = Math.max(this.closest.length() * fovScale, 1e-6);\n weight = Math.max(weight, 1 / distance ** 1.5);\n }\n if (!seen) {\n index = nodes[offset + 6];\n continue;\n }\n index++;\n let leaf = this.leaves.get(id);\n if (!leaf) {\n leaf = readSogLodLeaf(this.manifest, id);\n this.leaves.set(id, leaf);\n }\n visible.push({ leaf, weight });\n }\n return visible;\n }\n\n /** Transfer only [leaf ID, LOD ordinal] pairs in loading priority order. */\n select(view: SogView, budget: number): Uint32Array {\n const visible = this.collect(view);\n const targets = selectSogLods(visible, budget, this.manifest);\n visible.sort((a, b) => b.weight - a.weight || a.leaf.id - b.leaf.id);\n const result = new Uint32Array(targets.size * 2);\n let offset = 0;\n for (const { leaf } of visible) {\n const target = targets.get(leaf.id);\n if (!target) continue;\n result[offset++] = leaf.id;\n result[offset++] = leaf.lods.indexOf(target);\n }\n return result;\n }\n}\n","import * as THREE from \"three\";\nimport { sogBatchAllocationSize } from \"../../../data/SogRegionSplats\";\nimport type { ReorderedSplatResult } from \"../../../data/defines\";\nimport {\n getSplatByteLength,\n getSplatShDegree,\n getSplatTextureBytes,\n} from \"../../../data/splatData\";\nimport { RetryTimer } from \"../../../runtime/retry\";\nimport { StreamByteBudget } from \"../StreamByteBudget\";\nimport { StreamCameras } from \"../StreamCameras\";\nimport {\n type StreamSchedulerOptions,\n type StreamStats,\n notifyStreamChange,\n notifyStreamError,\n positiveInteger,\n streamPendingLimit,\n streamRetryAt,\n streamSettings,\n} from \"../streamOptions\";\nimport { SogStreamBatch } from \"./SogStreamBatch\";\nimport {\n type SogChunkSource,\n SogStreamLoader,\n type SogStreamLoaderOptions,\n} from \"./SogStreamLoader\";\nimport {\n SOG_LOD_STRIDE,\n type SogLodFile,\n type SogLodLeaf,\n type SogLodMetadata,\n type SogLodRange,\n readSogLodLeaf,\n resolveSogLod,\n} from \"./sogLod\";\nimport { type SogView, captureSogView, getSogViewKey } from \"./sogVisibility\";\n\nexport type SogStreamSchedulerOptions = SogStreamLoaderOptions &\n StreamSchedulerOptions;\nexport type SogStreamStats = StreamStats & { visibleRegions: number };\n\ntype Chunk = {\n file: SogLodFile;\n /** Stable slots keep a chunk together regardless of region arrival order. */\n batchSlots: Map<number, number>;\n batchCapacity: number;\n batch?: SogStreamBatch;\n data?: SogChunkSource;\n controller?: AbortController;\n expiresAt?: number;\n failures: number;\n retryAt: number;\n};\n\ntype Region = {\n batch: SogStreamBatch;\n start: number;\n range: SogLodRange;\n opacity: number;\n expiresAt?: number;\n};\n\ntype PendingRegion = {\n range: SogLodRange;\n chunk: Chunk;\n bytes: number;\n data?: ReorderedSplatResult;\n};\n\ntype LeafState = {\n target?: SogLodRange;\n current?: Region;\n /** Keep at most one previous LOD until its fade-out finishes. */\n outgoing?: Region;\n pending?: PendingRegion;\n};\n\nconst EMPTY_SELECTION = new Uint32Array(0);\n\nfunction* retryDeadlines(chunks: Iterable<Chunk>) {\n for (const chunk of chunks) yield chunk.retryAt;\n}\n\n/** Camera-driven Streamed SOG loading with per-chunk sources and region fades. */\nexport class SogStreamScheduler {\n readonly group: THREE.Group;\n readonly initialized: Promise<this>;\n readonly firstRenderable: Promise<this>;\n readonly cooldownMs: number;\n readonly fadeDurationMs: number;\n readonly maxConcurrentLoads: number;\n\n private _splatBudget: number;\n private readonly options: SogStreamSchedulerOptions;\n private readonly loader: SogStreamLoader;\n private readonly abort = new AbortController();\n private readonly streamCameras = new StreamCameras();\n private manifest?: SogLodMetadata;\n private readonly lodLeaves = new Map<number, SogLodLeaf>();\n private view?: SogView;\n private lastRequestedKey = \"\";\n private selecting = false;\n private selection: Uint32Array = EMPTY_SELECTION;\n private chunks: Chunk[] = [];\n /** Chunks with a batch, cached source or in-flight load. */\n private readonly activeChunks = new Set<Chunk>();\n private environment?: Chunk;\n private leaves = new Map<number, LeafState>();\n private wanted = new Set<Chunk>();\n private readonly fades = new Map<\n Region,\n { from: number; to: number; startedAt: number }\n >();\n private shown = true;\n private disposed = false;\n private resolveFirst!: (value: this) => void;\n private rejectFirst!: (error: unknown) => void;\n\n constructor(options: SogStreamSchedulerOptions) {\n this.options = { ...options };\n this.group = options.group ?? new THREE.Group();\n const settings = streamSettings(options);\n this._splatBudget = settings.splatBudget;\n this.cooldownMs = settings.cooldownMs;\n this.fadeDurationMs = settings.fadeDurationMs;\n this.maxConcurrentLoads = settings.maxConcurrentLoads;\n this.loader = new SogStreamLoader(\n this.options,\n this.maxConcurrentLoads,\n () => this.changed(),\n );\n this.firstRenderable = new Promise((resolve, reject) => {\n this.resolveFirst = resolve;\n this.rejectFirst = reject;\n });\n this.initialized = this.initialize().catch((error) => {\n this.rejectFirst(error);\n this.loader.dispose();\n throw error;\n });\n // Both readiness promises are optional to observe; errors remain available\n // to callers awaiting them and chunk failures go through onError.\n void this.initialized.catch(() => {});\n void this.firstRenderable.catch(() => {});\n }\n\n /** Visible-point target, including the environment. Reassign to reselect LODs. */\n get splatBudget(): number {\n return this._splatBudget;\n }\n\n set splatBudget(value: number) {\n if (value === this._splatBudget) return;\n this._splatBudget = positiveInteger(value, \"splatBudget\");\n void this.requestSelection();\n }\n\n get stats(): SogStreamStats {\n const { retainedIndexBytes, ...loaderStats } = this.loader.stats;\n const manifest = this.manifest;\n const stats: SogStreamStats = {\n visibleSplats: 0,\n visibleRegions: 0,\n visibleMeshes: 0,\n residentMeshes: 0,\n residentChunks: 0,\n residentBytes:\n retainedIndexBytes +\n (manifest\n ? manifest.bounds.byteLength +\n manifest.leafOffsets.byteLength +\n manifest.lods.byteLength +\n manifest.counts.byteLength\n : 0),\n pendingBytes: 0,\n loadingChunks: 0,\n ...loaderStats,\n };\n for (const { batch, data, controller } of this.activeChunks) {\n if (batch) {\n stats.residentMeshes++;\n stats.residentBytes += batch.residentBytes;\n if (this.shown && batch.numSplats > 0) {\n stats.visibleMeshes++;\n stats.visibleSplats += batch.numSplats;\n }\n }\n if (data?.alive) {\n stats.residentChunks++;\n stats.residentBytes += data.info.byteLength;\n }\n if (controller) stats.loadingChunks++;\n }\n for (const { current, outgoing, pending } of this.leaves.values()) {\n stats.pendingBytes += pending?.bytes ?? 0;\n if (this.shown) {\n if (current && Math.fround(current.opacity) > 0) stats.visibleRegions++;\n if (outgoing && Math.fround(outgoing.opacity) > 0)\n stats.visibleRegions++;\n }\n }\n return stats;\n }\n\n /** Group-local bounds from the index; available after initialized resolves. */\n getBoundingBox(): THREE.Box3 {\n const box = new THREE.Box3();\n if (this.manifest) {\n box.min.fromArray(this.manifest.bounds, 0);\n box.max.fromArray(this.manifest.bounds, 3);\n }\n return box;\n }\n\n private async initialize(): Promise<this> {\n const manifest = await this.loader.initialize(this.abort.signal);\n this.abort.signal.throwIfAborted();\n this.manifest = manifest;\n const files: SogLodFile[] = manifest.urls.map((url, index) => ({\n url,\n count: manifest.counts[index],\n ranges: [],\n }));\n if (this.manifest.environment)\n files.push({ url: this.manifest.environment, count: -1, ranges: [] });\n this.chunks = files.map((file) => ({\n file,\n batchSlots: new Map(),\n batchCapacity: 0,\n failures: 0,\n retryAt: 0,\n }));\n for (\n let offset = 0;\n offset < manifest.lods.length;\n offset += SOG_LOD_STRIDE\n ) {\n if (manifest.lods[offset + 3] === 0) continue;\n this.addBatchRange(\n this.chunks[manifest.lods[offset + 1]],\n manifest.lods[offset + 2],\n manifest.lods[offset + 3],\n );\n }\n if (this.manifest.environment)\n this.environment = this.chunks[this.chunks.length - 1];\n if (!this.environment && !this.manifest.lods.length)\n this.resolveFirst(this);\n this.changed();\n return this;\n }\n\n /** Cameras that select detail, in registration order. */\n get cameras(): readonly THREE.Camera[] {\n return this.streamCameras.cameras;\n }\n\n hasCamera(camera: THREE.Camera) {\n return this.streamCameras.has(camera);\n }\n\n /**\n * Select detail for this camera on each update. Detail follows distance,\n * so it needs no resolution. For WebXR register renderer.xr.getCamera(): it\n * selects the greatest detail needed by any eye that sees the region. Returns whether the camera was\n * newly added.\n */\n setCamera(camera: THREE.Camera) {\n return this.streamCameras.add(camera);\n }\n\n /** Stop selecting detail for this camera. Returns whether it was registered. */\n deleteCamera(camera: THREE.Camera) {\n return this.streamCameras.delete(camera);\n }\n\n /**\n * Call before rendering. Returns whether the displayed data changed. Each\n * leaf uses the distance of the nearest registered camera that sees it.\n */\n update(): boolean {\n if (this.disposed) return false;\n const cameras = this.streamCameras.seeing(this.group.layers);\n if (!this.manifest) return false;\n for (const chunk of this.activeChunks) {\n this.pruneChunk(chunk);\n if (chunk.batch) chunk.batch.layers.mask = this.group.layers.mask;\n }\n const view = captureSogView(cameras, this.group);\n // Three can register the XR rig before it supplies the first eye poses.\n // Preserve displayed regions and in-flight loads until those poses arrive.\n if (view.shown && !view.cameras.length) return false;\n this.view = view;\n const { shown } = this.view;\n this.shown = shown;\n if (!shown) {\n this.selection = EMPTY_SELECTION;\n this.lastRequestedKey = \"\";\n }\n const now = performance.now();\n const { selected, refinements } = this.selectRegions();\n const changed = this.applySelection(selected, now);\n this.updateRequests(refinements, now);\n // Start the new view's decision before retiring caches it may reuse.\n void this.requestSelection();\n this.releaseUnused(now, !shown || !this.selecting);\n if (\n shown &&\n [...this.leaves.values()].some(\n ({ current, outgoing }) =>\n (current?.opacity ?? 0) > 0 || (outgoing?.opacity ?? 0) > 0,\n )\n )\n this.resolveFirst(this);\n if (changed) this.changed();\n return changed;\n }\n\n private async requestSelection() {\n const view = this.view;\n if (\n this.disposed ||\n !this.shown ||\n this.selecting ||\n !this.manifest?.lods.length ||\n !view\n )\n return;\n const splatBudget = this.splatBudget;\n const budget = Math.max(\n 0,\n splatBudget - Math.max(0, this.environment?.file.count ?? 0),\n );\n const key = `${getSogViewKey(view)}/${splatBudget}/${budget}`;\n if (key === this.lastRequestedKey) return;\n this.lastRequestedKey = key;\n this.selecting = true;\n try {\n const selection = await this.loader.selectLod(view, budget);\n if (this.disposed || !this.shown || splatBudget !== this.splatBudget)\n return;\n // Keep one completed result; accepting camera lag avoids starving motion.\n // Resolve it against current caches, never worker-time resource snapshots.\n this.selection = selection;\n const { selected, refinements } = this.selectRegions();\n const now = performance.now();\n this.queueExtractions(selected, now);\n this.updateRequests(refinements, now);\n // Retire after every accepted decision so motion cannot postpone cleanup.\n this.releaseUnused(now, true);\n this.changed();\n } catch (error) {\n if (!this.disposed) {\n this.rejectFirst(error);\n this.failed(error, this.options.url);\n this.dispose();\n }\n } finally {\n this.selecting = false;\n // Updates replace the latest view while this task runs; no request queue.\n void this.requestSelection();\n }\n }\n\n private updateRequests(refinements: [LeafState, Chunk][], now: number) {\n // Establish coverage before starting the next LOD request.\n for (const [leaf, chunk] of refinements) {\n if (leaf.current?.range === leaf.target) this.wanted.add(chunk);\n }\n for (const chunk of this.activeChunks) {\n if (chunk.controller && !this.wanted.has(chunk)) chunk.controller.abort();\n }\n this.pump(now);\n }\n\n private selectRegions() {\n for (const leaf of this.leaves.values()) leaf.target = undefined;\n const selected: LeafState[] = [];\n this.wanted.clear();\n const show = (range: SogLodRange) => {\n const leaf = this.leafState(range.leaf);\n leaf.target = range;\n selected.push(leaf);\n if (leaf.current?.range !== range) this.wanted.add(this.chunkFor(range));\n };\n if (this.shown && this.environment) {\n const current = this.leaves.get(-1)?.current;\n const range = current?.range ?? this.environment.file.ranges[0];\n if (range && (current || this.environment.data?.alive)) show(range);\n else if (this.environment.file.count !== 0)\n this.wanted.add(this.environment);\n }\n const refinements: [LeafState, Chunk][] = [];\n for (\n let offset = 0;\n this.shown && offset < this.selection.length;\n offset += 2\n ) {\n const id = this.selection[offset];\n let leaf = this.lodLeaves.get(id);\n if (!leaf) {\n leaf = readSogLodLeaf(this.manifest as SogLodMetadata, id);\n this.lodLeaves.set(id, leaf);\n }\n const target = leaf.lods[this.selection[offset + 1]];\n const state = this.leafState(leaf.id);\n const { range, load, refinement } = resolveSogLod(\n leaf,\n target,\n state.current?.range,\n (lod) => this.chunks[lod.file].data?.alive === true,\n );\n if (range) show(range);\n if (load) {\n const chunk = this.chunks[load.file];\n if (range && refinement) refinements.push([state, chunk]);\n else this.wanted.add(chunk);\n }\n }\n for (const leaf of this.leaves.values()) {\n if (leaf.pending?.data && leaf.target !== leaf.pending.range)\n leaf.pending = undefined;\n }\n return { selected, refinements };\n }\n\n private leafState(id: number) {\n let leaf = this.leaves.get(id);\n if (!leaf) {\n leaf = {};\n this.leaves.set(id, leaf);\n }\n return leaf;\n }\n\n private chunkFor(range: SogLodRange) {\n return range.file < 0\n ? (this.environment as Chunk)\n : this.chunks[range.file];\n }\n\n private applySelection(selected: LeafState[], now: number) {\n // Advance an existing fade before reversing it to avoid opacity jumps.\n let changed = this.updateFades(now);\n changed = this.updateRegionVisibility(now) || changed;\n changed = this.attachPendingRegions(selected, now) || changed;\n this.queueExtractions(selected, now);\n // Complete zero-duration fades in this update as well.\n return this.updateFades(now) || changed;\n }\n\n private updateRegionVisibility(now: number) {\n let changed = false;\n for (const leaf of this.leaves.values()) {\n const { current, outgoing, target } = leaf;\n if (current) changed = this.fadeRegion(current, !!target, now) || changed;\n if (outgoing) changed = this.fadeRegion(outgoing, false, now) || changed;\n }\n return changed;\n }\n\n private attachPendingRegions(selected: LeafState[], now: number) {\n let changed = false;\n for (const leaf of selected) {\n const { current, pending, target: range } = leaf;\n // Finish a crossfade before admitting another LOD for this region.\n if (\n !range ||\n current?.range === range ||\n leaf.outgoing ||\n pending?.range !== range ||\n !pending.data\n )\n continue;\n\n const { data, chunk } = pending;\n const start = chunk.batchSlots.get(range.offset);\n if (start === undefined) throw new Error(\"Missing chunk region slot\");\n const numSh = getSplatShDegree(data.extra);\n let batch = chunk.batch;\n if (!batch) {\n batch = new SogStreamBatch(\n chunk.batchCapacity,\n numSh,\n this.group,\n () => {\n chunk.batch = undefined;\n this.pruneChunk(chunk);\n },\n );\n batch.name =\n range.file < 0 ? \"sog-environment\" : `sog-chunk-${range.file}`;\n chunk.batch = batch;\n this.activeChunks.add(chunk);\n }\n batch.writeRegion(start, data);\n leaf.pending = undefined;\n if (current) {\n leaf.outgoing = current;\n this.fadeRegion(current, false, now);\n }\n leaf.current = { batch, start, range, opacity: 0 };\n this.fadeRegion(leaf.current, true, now);\n changed = true;\n }\n return changed;\n }\n\n private queueExtractions(selected: LeafState[], now: number) {\n // Bound both in-flight and ready copies by their compact packed byte size.\n // One indivisible oversized region may occupy the queue on its own.\n let pendingBytes = 0;\n for (const leaf of this.leaves.values())\n pendingBytes += leaf.pending?.bytes ?? 0;\n const budget = new StreamByteBudget(\n streamPendingLimit(this.maxConcurrentLoads),\n pendingBytes,\n );\n const batches = new Map<\n Chunk,\n { source: SogChunkSource; regions: PendingRegion[] }\n >();\n for (const leaf of selected) {\n const range = leaf.target;\n if (!range || leaf.current?.range === range || leaf.pending) continue;\n const chunk = this.chunkFor(range);\n const source = chunk.data;\n if (!source?.alive || now < chunk.retryAt) continue;\n const bytes =\n getSplatTextureBytes(range.count, source.info.numSh) + range.count * 4;\n if (!budget.reserve(bytes)) continue;\n const pending = { range, chunk, bytes };\n leaf.pending = pending;\n const batch = batches.get(chunk) ?? { source, regions: [] };\n batch.regions.push(pending);\n batches.set(chunk, batch);\n }\n for (const [chunk, { source, regions }] of batches)\n void this.extract(chunk, source, regions);\n }\n\n private addBatchRange(chunk: Chunk, offset: number, count: number) {\n if (!count || chunk.batchSlots.has(offset)) return;\n chunk.batchSlots.set(offset, chunk.batchCapacity);\n chunk.batchCapacity += sogBatchAllocationSize(count);\n }\n\n private fadeRegion(region: Region, visible: boolean, now: number) {\n const to = visible ? 1 : 0;\n if ((this.fades.get(region)?.to ?? region.opacity) === to) return false;\n this.fades.set(region, { from: region.opacity, to, startedAt: now });\n return true;\n }\n\n private updateFades(now: number) {\n let changed = false;\n for (const [region, fade] of this.fades) {\n const progress =\n this.fadeDurationMs === 0 || fade.from === fade.to\n ? 1\n : THREE.MathUtils.clamp(\n (now - fade.startedAt) / this.fadeDurationMs,\n 0,\n 1,\n );\n const opacity = THREE.MathUtils.lerp(fade.from, fade.to, progress);\n if (region.opacity !== opacity) {\n region.opacity = opacity;\n region.batch.setRegionOpacity(region.start, opacity);\n changed = true;\n }\n if (progress === 1) {\n this.fades.delete(region);\n if (this.leaves.get(region.range.leaf)?.outgoing === region)\n this.releaseRegion(region);\n changed = true;\n }\n }\n return changed;\n }\n\n private async extract(\n chunk: Chunk,\n source: SogChunkSource,\n batch: PendingRegion[],\n ) {\n try {\n const results = await source.extract(\n batch.map(({ range }) => ({\n start: range.offset,\n count: range.count,\n })),\n );\n for (let index = 0; index < batch.length; index++) {\n const pending = batch[index];\n const { range } = pending;\n const data = results[index];\n const leaf = this.leaves.get(range.leaf);\n if (\n !this.disposed &&\n leaf?.pending === pending &&\n leaf.target === range\n ) {\n pending.data = data;\n pending.bytes = getSplatByteLength(data);\n } else if (leaf?.pending === pending) leaf.pending = undefined;\n }\n } catch (error) {\n for (const pending of batch) {\n const leaf = this.leaves.get(pending.range.leaf);\n if (leaf?.pending === pending) leaf.pending = undefined;\n }\n if (!this.disposed) {\n chunk.retryAt = streamRetryAt(error, chunk.failures++);\n if (!source.alive) {\n source.dispose();\n this.pruneChunk(chunk);\n }\n this.rejectFirstIfUnavailable(error);\n this.failed(error, chunk.file.url);\n }\n } finally {\n if (!this.disposed) {\n this.pump(performance.now());\n this.changed();\n }\n }\n }\n\n private releaseUnused(now: number, allowRelease: boolean) {\n const referenced = new Set(this.wanted);\n for (const [id, leaf] of this.leaves) {\n const { current, outgoing, pending } = leaf;\n if (pending) referenced.add(pending.chunk);\n if (outgoing) referenced.add(this.chunkFor(outgoing.range));\n if (current) {\n if (\n leaf.target ||\n current.opacity > 0 ||\n this.fades.has(current) ||\n outgoing\n ) {\n current.expiresAt = undefined;\n referenced.add(this.chunkFor(current.range));\n } else {\n current.expiresAt ??= now + this.cooldownMs;\n if (allowRelease && now >= current.expiresAt)\n this.releaseRegion(current);\n }\n }\n if (!leaf.target && !leaf.current && !leaf.outgoing && !leaf.pending)\n this.leaves.delete(id);\n }\n for (const chunk of this.activeChunks) {\n if (referenced.has(chunk) || chunk.controller || !chunk.data) {\n chunk.expiresAt = undefined;\n } else {\n chunk.expiresAt ??= now + this.cooldownMs;\n if (allowRelease && now >= chunk.expiresAt) {\n chunk.data.dispose();\n this.pruneChunk(chunk);\n }\n }\n }\n }\n\n private pump(now: number) {\n if (this.disposed) return;\n let loading = 0;\n for (const chunk of this.activeChunks) {\n this.pruneChunk(chunk);\n if (chunk.controller) loading++;\n }\n for (const chunk of this.wanted) {\n if (loading >= this.maxConcurrentLoads) break;\n if (chunk.data || chunk.controller || now < chunk.retryAt) continue;\n chunk.controller = new AbortController();\n this.activeChunks.add(chunk);\n loading++;\n void this.load(chunk, chunk.controller);\n }\n this.retryTimer.update(retryDeadlines(this.wanted));\n }\n\n private async load(chunk: Chunk, controller: AbortController) {\n let decoded: SogChunkSource | undefined;\n try {\n decoded = await this.loader.load(\n chunk.file.url,\n chunk.file.count,\n controller.signal,\n );\n controller.signal.throwIfAborted();\n if (chunk.batch && decoded.info.numSh !== chunk.batch.numSh)\n throw new Error(\n `Chunk SH degree mismatch: expected ${chunk.batch.numSh}, received ${decoded.info.numSh}`,\n );\n if (chunk === this.environment) {\n chunk.file.count = decoded.info.numSplats;\n this.addBatchRange(chunk, 0, chunk.file.count);\n chunk.file.ranges = chunk.file.count\n ? [\n {\n leaf: -1,\n level: 0,\n file: -1,\n offset: 0,\n count: chunk.file.count,\n },\n ]\n : [];\n } else if (decoded.info.numSplats !== chunk.file.count) {\n throw new Error(\n `Chunk count mismatch: expected ${chunk.file.count}, received ${decoded.info.numSplats}`,\n );\n }\n chunk.data = decoded;\n decoded = undefined;\n chunk.expiresAt = undefined;\n chunk.failures = 0;\n chunk.retryAt = 0;\n if (\n chunk === this.environment &&\n !chunk.file.count &&\n !this.manifest?.lods.length\n )\n this.resolveFirst(this);\n } catch (error) {\n if (!controller.signal.aborted && !this.disposed) {\n chunk.retryAt = streamRetryAt(error, chunk.failures++);\n this.rejectFirstIfUnavailable(error);\n this.failed(error, chunk.file.url);\n }\n } finally {\n decoded?.dispose();\n chunk.controller = undefined;\n this.pruneChunk(chunk);\n if (!this.disposed) {\n this.pump(performance.now());\n // Loading the environment changes the budget available to LOD.\n if (chunk === this.environment) void this.requestSelection();\n this.changed();\n }\n }\n }\n\n private pruneChunk(chunk: Chunk) {\n if (chunk.data && !chunk.data.alive) chunk.data = undefined;\n if (!chunk.data) chunk.expiresAt = undefined;\n if (!chunk.batch && !chunk.data && !chunk.controller)\n this.activeChunks.delete(chunk);\n }\n\n private releaseRegion(region: Region) {\n this.fades.delete(region);\n region.batch.releaseRegion(region.start);\n const leaf = this.leaves.get(region.range.leaf);\n if (leaf?.current === region) leaf.current = undefined;\n if (leaf?.outgoing === region) leaf.outgoing = undefined;\n }\n\n private changed() {\n if (!this.disposed) notifyStreamChange(this.options);\n }\n\n private failed(error: unknown, url: string) {\n notifyStreamError(this.options, error, url);\n }\n\n private readonly retryTimer = new RetryTimer(() => this.changed());\n\n private rejectFirstIfUnavailable(error: unknown) {\n // A failed refinement does not invalidate already renderable coverage.\n if ([...this.leaves.values()].some((leaf) => leaf.current || leaf.pending))\n return;\n if (\n this.wanted.size > 0 &&\n [...this.wanted].every(\n (chunk) => chunk.retryAt === Number.POSITIVE_INFINITY,\n )\n )\n this.rejectFirst(error);\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.retryTimer.dispose();\n this.abort.abort();\n this.rejectFirst(this.abort.signal.reason);\n this.loader.dispose();\n for (const chunk of this.activeChunks) {\n chunk.controller?.abort();\n chunk.data?.dispose();\n chunk.data = undefined;\n }\n for (const leaf of this.leaves.values()) {\n if (leaf.current) this.releaseRegion(leaf.current);\n if (leaf.outgoing) this.releaseRegion(leaf.outgoing);\n }\n this.leaves.clear();\n this.fades.clear();\n this.wanted.clear();\n this.chunks = [];\n this.activeChunks.clear();\n this.environment = undefined;\n this.manifest = undefined;\n this.lodLeaves.clear();\n this.view = undefined;\n this.selection = EMPTY_SELECTION;\n }\n}\n"],"names":["ptr","module","initWasm","_a","error","BundledWorker","index","waiter","THREE","SplatFileType","SplatEditSdfType","SplatEditRgbaBlendMode","encodeQuaternion","axisX","axisY","axisZ","state","loadSplatData","wasm.isInitialized","buffer","buffer2","TSL","NodeUpdateType","value","distance","splatDefines","splatVertex","splatFragment","FullScreenQuad","splatGenerate","NodeMaterial","QuadMesh","camera","size","shaders","Vector2","Matrix4","Vector3","ColorManagement","NeverDepth","AlwaysDepth","makeTexture","StorageArrayTexture","WORKGROUP_SIZE","StorageBufferAttribute","IndirectStorageBufferAttribute","shrinkResources","WebGLRenderTarget","HalfFloatType","DepthTexture","FloatType","Pass","Color","NoToneMapping","ShaderMaterial","GLSL3","NoBlending","TempNode","RenderTarget","RendererUtils","WebGLCoordinateSystem","Opcode","InputField","immediate","register","target","onTrue","onFalse","_SplatPostDecodeProgramImpl","postDecode","DefaultLoadingManager","Loader","bytes","signal","changed","pool","storage"],"mappings":"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"}
1
+ {"version":3,"file":"gaussian-splat-lite.cjs","sources":["../src/runtime/transferable.ts","../rust/gaussian-splat-rs/pkg/gaussian_splat_rs.js","../virtual:decode-64","../src/runtime/wasm.ts","../src/runtime/WorkerRpc.ts","../src/runtime/abort.ts","../src/runtime/SplatWorker.ts","../src/utils/three.ts","../src/rendering/SortCenterCache.ts","../src/data/defines.ts","../src/data/textureLayout.ts","../src/utils/transforms.ts","../src/scene/SplatEdit.ts","../src/utils/numeric.ts","../src/data/splatCodec.ts","../src/data/splatData.ts","../src/data/unpack.ts","../src/data/Splats.ts","../src/data/raycast.ts","../src/scene/SplatMesh.ts","../src/rendering/rendererUtils.ts","../src/rendering/tsl/tslCompat.ts","../src/rendering/tsl/shaderUtils.ts","../src/rendering/tsl/GenerateProgram.ts","../src/rendering/blueNoise.ts","../src/rendering/uniforms.ts","../src/rendering/webgl/shaders/splatDefines.glsl","../src/rendering/webgl/shaders/splatFragment.glsl","../src/rendering/webgl/shaders/splatVertex.glsl","../src/rendering/webgl/shaders.ts","../src/rendering/webgl/shaders/splatGenerate.glsl","../src/rendering/webgl/textureUtils.ts","../src/rendering/webgl/AccumulatorGenerator.ts","../src/rendering/webgl-fallback/AccumulatorGenerator.ts","../src/rendering/SplatAccumulator.ts","../src/rendering/SplatGeometry.ts","../src/rendering/tsl/ProjectionProgram.ts","../src/rendering/tsl/viewUniforms.ts","../src/rendering/tsl/SplatMaterial.ts","../src/rendering/tsl/SplatBackend.ts","../src/rendering/webgl/OrderingTexture.ts","../src/rendering/webgl-fallback/SplatBackend.ts","../src/rendering/webgl/SplatMaterial.ts","../src/rendering/webgl/SplatBackend.ts","../src/addons/taaShared.ts","../src/rendering/webgpu/ProjectionCache.ts","../src/rendering/webgpu/RadixSort.ts","../src/rendering/webgpu/ProjectedSplats.ts","../src/rendering/webgpu/SplatBackend.ts","../src/rendering/backend.ts","../src/rendering/GaussianSplatRenderer.ts","../src/addons/TAAPass.ts","../src/addons/TAANode.ts","../src/capture/WebGLCapture.ts","../src/capture/WebGPUCapture.ts","../src/capture/pixels.ts","../src/capture/rendererState.ts","../src/capture/sceneView.ts","../src/capture/SplatCapture.ts","../src/loaders/assetUrl.ts","../src/loaders/postDecode/protocol.ts","../src/loaders/postDecode/builder.ts","../src/loaders/postDecode/optimizer.ts","../src/loaders/postDecode/compiler.ts","../src/loaders/postDecode/program.ts","../src/loaders/loadSplatData.ts","../src/loaders/SplatLoader.ts","../src/data/SplatOpacityTable.ts","../src/data/IndexedSplats.ts","../src/data/RadPagedSplats.ts","../src/runtime/retry.ts","../src/loaders/rad/radFormat.ts","../src/loaders/stream/StreamByteBudget.ts","../src/loaders/stream/StreamCameras.ts","../src/loaders/stream/streamOptions.ts","../src/loaders/stream/rad-stream/RadStreamBatch.ts","../src/loaders/source.ts","../src/loaders/rad/RadSource.ts","../src/loaders/stream/StreamWorkerPool.ts","../src/loaders/stream/rad-stream/RadStreamWorker.ts","../src/loaders/stream/rad-stream/RadStreamLoader.ts","../src/loaders/stream/rad-stream/radLod.ts","../src/loaders/stream/rad-stream/RadStreamScheduler.ts","../src/data/SogRegionSplats.ts","../src/loaders/stream/sog-stream/SogStreamBatch.ts","../src/loaders/stream/sog-stream/SogStreamWorker.ts","../src/loaders/stream/sog-stream/SogStreamLoader.ts","../src/loaders/stream/sog-stream/sogLod.ts","../src/loaders/stream/sog-stream/sogVisibility.ts","../src/loaders/stream/sog-stream/SogStreamScheduler.ts"],"sourcesContent":["// Recursively finds all ArrayBuffers in an object for structured-clone transfer.\nexport function getTransferable(ctx: unknown): Transferable[] {\n const buffers = new Set<Transferable>();\n const seen = new Set();\n\n function traverse(obj: unknown) {\n if (!obj || typeof obj !== \"object\" || seen.has(obj)) return;\n seen.add(obj);\n\n if (obj instanceof ArrayBuffer) {\n buffers.add(obj);\n } else if (ArrayBuffer.isView(obj)) {\n buffers.add(obj.buffer as ArrayBuffer);\n } else {\n Object.values(obj).forEach(traverse);\n }\n }\n\n traverse(ctx);\n return [...buffers];\n}\n","/* @ts-self-types=\"./gaussian_splat_rs.d.ts\" */\n\nexport class ChunkDecoder {\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ChunkDecoder.prototype);\n obj.__wbg_ptr = ptr;\n ChunkDecoderFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ChunkDecoderFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_chunkdecoder_free(ptr, 0);\n }\n /**\n * @returns {any}\n */\n finish() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.chunkdecoder_finish(ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * @param {Uint8Array} bytes\n */\n push(bytes) {\n const ret = wasm.chunkdecoder_push(this.__wbg_ptr, bytes);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {number} size\n */\n set_expected_input_size(size) {\n const ret = wasm.chunkdecoder_set_expected_input_size(this.__wbg_ptr, size);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n}\nif (Symbol.dispose) ChunkDecoder.prototype[Symbol.dispose] = ChunkDecoder.prototype.free;\n\n/**\n * Owns only dataset metadata and the requested SH codebooks. Call the generated\n * `free()` method when a load finishes or its stream scheduler is disposed.\n */\nexport class RadDecoder {\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n RadDecoderFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_raddecoder_free(ptr, 0);\n }\n /**\n * @param {Uint8Array} bytes\n * @returns {any}\n */\n decode_chunk(bytes) {\n const ret = wasm.raddecoder_decode_chunk(this.__wbg_ptr, bytes);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * Initialize from the root already validated by the first decode worker.\n * @param {Uint8Array} bytes\n */\n initialize_codebooks(bytes) {\n const ret = wasm.raddecoder_initialize_codebooks(this.__wbg_ptr, bytes);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {string} meta_json\n * @param {number} max_sh\n */\n constructor(meta_json, max_sh) {\n const ptr0 = passStringToWasm0(meta_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.raddecoder_new(ptr0, len0, max_sh);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n this.__wbg_ptr = ret[0] >>> 0;\n RadDecoderFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n}\nif (Symbol.dispose) RadDecoder.prototype[Symbol.dispose] = RadDecoder.prototype.free;\n\nexport class RadLodTree {\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n RadLodTreeFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_radlodtree_free(ptr, 0);\n }\n /**\n * @param {string} meta_json\n */\n constructor(meta_json) {\n const ptr0 = passStringToWasm0(meta_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.radlodtree_new(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n this.__wbg_ptr = ret[0] >>> 0;\n RadLodTreeFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @param {number} index\n * @param {number | null} [generation]\n */\n release_chunk(index, generation) {\n wasm.radlodtree_release_chunk(this.__wbg_ptr, index, !isLikeNone(generation), isLikeNone(generation) ? 0 : generation);\n }\n /**\n * @param {number} index\n * @param {number} generation\n * @param {Float32Array} centers\n * @param {Float32Array} radii\n * @param {Uint32Array} child_start\n * @param {Uint16Array} child_count\n */\n retain_chunk(index, generation, centers, radii, child_start, child_count) {\n const ret = wasm.radlodtree_retain_chunk(this.__wbg_ptr, index, generation, centers, radii, child_start, child_count);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {Float64Array} views\n * @param {Uint32Array} resident_chunks\n * @param {number} budget\n * @param {number} threshold\n * @param {number} hysteresis\n * @returns {any}\n */\n select(views, resident_chunks, budget, threshold, hysteresis) {\n const ret = wasm.radlodtree_select(this.__wbg_ptr, views, resident_chunks, budget, threshold, hysteresis);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n}\nif (Symbol.dispose) RadLodTree.prototype[Symbol.dispose] = RadLodTree.prototype.free;\n\nexport class SogDecodeSession {\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n SogDecodeSessionFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_sogdecodesession_free(ptr, 0);\n }\n /**\n * @param {Array<any>} chunks\n * @param {number} method\n * @param {number} uncompressed_size\n * @param {number} crc\n */\n decode_asset(chunks, method, uncompressed_size, crc) {\n const ret = wasm.sogdecodesession_decode_asset(this.__wbg_ptr, chunks, method, uncompressed_size, crc);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @returns {boolean}\n */\n decode_batch() {\n const ret = wasm.sogdecodesession_decode_batch(this.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ret[0] !== 0;\n }\n /**\n * @returns {object}\n */\n finish() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.sogdecodesession_finish(ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * @param {string} metadata\n */\n constructor(metadata) {\n const ptr0 = passStringToWasm0(metadata, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.sogdecodesession_new(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n this.__wbg_ptr = ret[0] >>> 0;\n SogDecodeSessionFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @returns {string}\n */\n plan() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.sogdecodesession_plan(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n}\nif (Symbol.dispose) SogDecodeSession.prototype[Symbol.dispose] = SogDecodeSession.prototype.free;\n\n/**\n * @param {Uint8Array} bytes\n * @returns {any}\n */\nexport function decode_rad_header(bytes) {\n const ret = wasm.decode_rad_header(bytes);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n}\n\n/**\n * @param {Uint8Array} bytes\n * @param {number} method\n * @param {number} size\n * @param {number} crc\n * @returns {string}\n */\nexport function decode_sog_meta(bytes, method, size, crc) {\n let deferred2_0;\n let deferred2_1;\n try {\n const ret = wasm.decode_sog_meta(bytes, method, size, crc);\n var ptr1 = ret[0];\n var len1 = ret[1];\n if (ret[3]) {\n ptr1 = 0; len1 = 0;\n throw takeFromExternrefTable0(ret[2]);\n }\n deferred2_0 = ptr1;\n deferred2_1 = len1;\n return getStringFromWasm0(ptr1, len1);\n } finally {\n wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);\n }\n}\n\n/**\n * @param {string | null} [file_type]\n * @param {string | null} [path_name]\n * @returns {ChunkDecoder}\n */\nexport function decode_to_splats(file_type, path_name) {\n var ptr0 = isLikeNone(file_type) ? 0 : passStringToWasm0(file_type, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len0 = WASM_VECTOR_LEN;\n var ptr1 = isLikeNone(path_name) ? 0 : passStringToWasm0(path_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len1 = WASM_VECTOR_LEN;\n const ret = wasm.decode_to_splats(ptr0, len0, ptr1, len1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ChunkDecoder.__wrap(ret[0]);\n}\n\n/**\n * @returns {Uint32Array}\n */\nexport function get_raycast_buffer() {\n const ret = wasm.get_raycast_buffer();\n return ret;\n}\n\n/**\n * @returns {Uint32Array}\n */\nexport function get_raycast_buffer2() {\n const ret = wasm.get_raycast_buffer2();\n return ret;\n}\n\n/**\n * Record indices corresponding one-for-one to the last raycast distances.\n * This view is valid until the next call to `raycast_splat_buffers`.\n * @returns {Uint32Array}\n */\nexport function get_raycast_indices() {\n const ret = wasm.get_raycast_indices();\n return ret;\n}\n\n/**\n * @param {number} count\n * @param {Array<any>} arrays\n * @param {Uint32Array | null | undefined} sort_centers\n * @param {Uint32Array | null | undefined} source_ids\n * @param {Float32Array} center_only_bounds\n * @param {Float32Array} bounds\n * @param {Float32Array | null | undefined} bounds_blocks\n * @param {Float32Array} spatial_bounds\n * @param {Function | null} [progress]\n * @returns {Uint32Array}\n */\nexport function morton_reorder(count, arrays, sort_centers, source_ids, center_only_bounds, bounds, bounds_blocks, spatial_bounds, progress) {\n const ret = wasm.morton_reorder(count, arrays, isLikeNone(sort_centers) ? 0 : addToExternrefTable0(sort_centers), isLikeNone(source_ids) ? 0 : addToExternrefTable0(source_ids), center_only_bounds, bounds, isLikeNone(bounds_blocks) ? 0 : addToExternrefTable0(bounds_blocks), spatial_bounds, isLikeNone(progress) ? 0 : addToExternrefTable0(progress));\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n}\n\n/**\n * @param {number} origin_x\n * @param {number} origin_y\n * @param {number} origin_z\n * @param {number} dir_x\n * @param {number} dir_y\n * @param {number} dir_z\n * @param {number} min_opacity\n * @param {number} near\n * @param {number} far\n * @param {number} count\n * @returns {Float32Array}\n */\nexport function raycast_splat_buffers(origin_x, origin_y, origin_z, dir_x, dir_y, dir_z, min_opacity, near, far, count) {\n const ret = wasm.raycast_splat_buffers(origin_x, origin_y, origin_z, dir_x, dir_y, dir_z, min_opacity, near, far, count);\n return ret;\n}\n\n/**\n * @param {Uint32Array} center_update_range_indices\n * @param {Float32Array} update_centers\n * @param {Uint32Array} matrix_update_range_indices\n * @param {Float64Array} update_matrices\n * @param {Uint32Array} range_mesh_ids\n * @param {Uint32Array} range_bases\n * @param {Uint32Array} range_counts\n */\nexport function set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts) {\n wasm.set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts);\n}\n\n/**\n * @param {number} num_splats\n * @param {number} camera_x\n * @param {number} camera_y\n * @param {number} camera_z\n * @param {number} direction_x\n * @param {number} direction_y\n * @param {number} direction_z\n * @param {boolean} radial\n * @param {boolean} fast_sort\n * @param {boolean} front_sort\n * @param {Uint32Array} ordering\n * @returns {number}\n */\nexport function sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, fast_sort, front_sort, ordering) {\n const ret = wasm.sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, fast_sort, front_sort, ordering);\n return ret >>> 0;\n}\n\n/**\n * Remains readable after an allocation abort, which otherwise looks like any\n * other `unreachable` trap to JavaScript. The failed instance is then retired.\n * @returns {boolean}\n */\nexport function wasm_allocation_failed() {\n const ret = wasm.wasm_allocation_failed();\n return ret !== 0;\n}\n\nexport function wasm_start() {\n wasm.wasm_start();\n}\n\nfunction __wbg_get_imports() {\n const import0 = {\n __proto__: null,\n __wbg___wbindgen_debug_string_dd5d2d07ce9e6c57: function(arg0, arg1) {\n const ret = debugString(arg1);\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg___wbindgen_throw_81fc77679af83bc6: function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n },\n __wbg_call_368fa9c372d473ba: function() { return handleError(function (arg0, arg1, arg2, arg3) {\n const ret = arg0.call(arg1, arg2, arg3);\n return ret;\n }, arguments); },\n __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {\n let deferred0_0;\n let deferred0_1;\n try {\n deferred0_0 = arg0;\n deferred0_1 = arg1;\n console.error(getStringFromWasm0(arg0, arg1));\n } finally {\n wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);\n }\n },\n __wbg_get_index_983d655608220248: function(arg0, arg1) {\n const ret = arg0[arg1 >>> 0];\n return ret;\n },\n __wbg_get_unchecked_7d7babe32e9e6a54: function(arg0, arg1) {\n const ret = arg0[arg1 >>> 0];\n return ret;\n },\n __wbg_instanceof_Uint32Array_1048c66d96e96680: function(arg0) {\n let result;\n try {\n result = arg0 instanceof Uint32Array;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n },\n __wbg_length_0c32cb8543c8e4c8: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_1e701798fdcaa3b4: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_526c0f6e4ebae15d: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_6e821edde497a532: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_a4ca9e78359b5f1f: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_fd4646b401926788: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_new_227d7c05414eb861: function() {\n const ret = new Error();\n return ret;\n },\n __wbg_new_4f9fafbb3909af72: function() {\n const ret = new Object();\n return ret;\n },\n __wbg_new_e3b04b4d53d1b593: function(arg0, arg1) {\n const ret = new Error(getStringFromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_from_slice_798885084b9cc1d2: function(arg0, arg1) {\n const ret = new Uint32Array(getArrayU32FromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_from_slice_d4e6804502a531e5: function(arg0, arg1) {\n const ret = new Uint16Array(getArrayU16FromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_from_slice_d85ad974cf8f6f35: function(arg0, arg1) {\n const ret = new Float32Array(getArrayF32FromWasm0(arg0, arg1));\n return ret;\n },\n __wbg_new_with_length_26bffbe236bf73f9: function(arg0) {\n const ret = new Float32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_new_with_length_41a22191b9bdfd66: function(arg0) {\n const ret = new Uint32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_parse_545d11396395fbbd: function() { return handleError(function (arg0, arg1) {\n const ret = JSON.parse(getStringFromWasm0(arg0, arg1));\n return ret;\n }, arguments); },\n __wbg_prototypesetcall_021fd89d67217368: function(arg0, arg1, arg2) {\n Float64Array.prototype.set.call(getArrayF64FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_3e05eb9545565046: function(arg0, arg1, arg2) {\n Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_64c287a27cc24d27: function(arg0, arg1, arg2) {\n Uint16Array.prototype.set.call(getArrayU16FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_66c8e1fb820946be: function(arg0, arg1, arg2) {\n Float32Array.prototype.set.call(getArrayF32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_e42275e601e14eeb: function(arg0, arg1, arg2) {\n Uint32Array.prototype.set.call(getArrayU32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_set_448126769bf7c181: function(arg0, arg1, arg2) {\n arg0.set(getArrayU32FromWasm0(arg1, arg2));\n },\n __wbg_set_8ee2d34facb8466e: function() { return handleError(function (arg0, arg1, arg2) {\n const ret = Reflect.set(arg0, arg1, arg2);\n return ret;\n }, arguments); },\n __wbg_set_a98c8da6557e63de: function(arg0, arg1, arg2) {\n arg0.set(getArrayF32FromWasm0(arg1, arg2));\n },\n __wbg_set_index_a561936dd7004b5a: function(arg0, arg1, arg2) {\n arg0[arg1 >>> 0] = arg2;\n },\n __wbg_set_length_3995d60e8394cd98: function(arg0, arg1) {\n arg0.length = arg1 >>> 0;\n },\n __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {\n const ret = arg1.stack;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg_subarray_0f98d3fb634508ad: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_1230568a23d546e8: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_4342405c1ffc86d6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_d51e89458b3fdbf6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbindgen_cast_0000000000000001: function(arg0) {\n // Cast intrinsic for `F64 -> Externref`.\n const ret = arg0;\n return ret;\n },\n __wbindgen_cast_0000000000000002: function(arg0, arg1) {\n // Cast intrinsic for `Ref(Slice(F32)) -> NamedExternref(\"Float32Array\")`.\n const ret = getArrayF32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000003: function(arg0, arg1) {\n // Cast intrinsic for `Ref(Slice(U32)) -> NamedExternref(\"Uint32Array\")`.\n const ret = getArrayU32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000004: function(arg0, arg1) {\n // Cast intrinsic for `Ref(String) -> Externref`.\n const ret = getStringFromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_init_externref_table: function() {\n const table = wasm.__wbindgen_externrefs;\n const offset = table.grow(4);\n table.set(0, undefined);\n table.set(offset + 0, undefined);\n table.set(offset + 1, null);\n table.set(offset + 2, true);\n table.set(offset + 3, false);\n },\n };\n return {\n __proto__: null,\n \"./gaussian_splat_rs_bg.js\": import0,\n };\n}\n\nconst ChunkDecoderFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_chunkdecoder_free(ptr >>> 0, 1));\nconst RadDecoderFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_raddecoder_free(ptr >>> 0, 1));\nconst RadLodTreeFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_radlodtree_free(ptr >>> 0, 1));\nconst SogDecodeSessionFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_sogdecodesession_free(ptr >>> 0, 1));\n\nfunction addToExternrefTable0(obj) {\n const idx = wasm.__externref_table_alloc();\n wasm.__wbindgen_externrefs.set(idx, obj);\n return idx;\n}\n\nfunction debugString(val) {\n // primitive types\n const type = typeof val;\n if (type == 'number' || type == 'boolean' || val == null) {\n return `${val}`;\n }\n if (type == 'string') {\n return `\"${val}\"`;\n }\n if (type == 'symbol') {\n const description = val.description;\n if (description == null) {\n return 'Symbol';\n } else {\n return `Symbol(${description})`;\n }\n }\n if (type == 'function') {\n const name = val.name;\n if (typeof name == 'string' && name.length > 0) {\n return `Function(${name})`;\n } else {\n return 'Function';\n }\n }\n // objects\n if (Array.isArray(val)) {\n const length = val.length;\n let debug = '[';\n if (length > 0) {\n debug += debugString(val[0]);\n }\n for(let i = 1; i < length; i++) {\n debug += ', ' + debugString(val[i]);\n }\n debug += ']';\n return debug;\n }\n // Test for built-in\n const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n let className;\n if (builtInMatches && builtInMatches.length > 1) {\n className = builtInMatches[1];\n } else {\n // Failed to match the standard '[object ClassName]'\n return toString.call(val);\n }\n if (className == 'Object') {\n // we're a user defined class or Object\n // JSON.stringify avoids problems with cycles, and is generally much\n // easier than looping through ownProperties of `val`.\n try {\n return 'Object(' + JSON.stringify(val) + ')';\n } catch (_) {\n return 'Object';\n }\n }\n // errors\n if (val instanceof Error) {\n return `${val.name}: ${val.message}\\n${val.stack}`;\n }\n // TODO we could test for more things here, like `Set`s and `Map`s.\n return className;\n}\n\nfunction getArrayF32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n}\n\nfunction getArrayF64FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);\n}\n\nfunction getArrayU16FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint16ArrayMemory0().subarray(ptr / 2, ptr / 2 + len);\n}\n\nfunction getArrayU32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nlet cachedDataViewMemory0 = null;\nfunction getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n}\n\nlet cachedFloat32ArrayMemory0 = null;\nfunction getFloat32ArrayMemory0() {\n if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {\n cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);\n }\n return cachedFloat32ArrayMemory0;\n}\n\nlet cachedFloat64ArrayMemory0 = null;\nfunction getFloat64ArrayMemory0() {\n if (cachedFloat64ArrayMemory0 === null || cachedFloat64ArrayMemory0.byteLength === 0) {\n cachedFloat64ArrayMemory0 = new Float64Array(wasm.memory.buffer);\n }\n return cachedFloat64ArrayMemory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return decodeText(ptr, len);\n}\n\nlet cachedUint16ArrayMemory0 = null;\nfunction getUint16ArrayMemory0() {\n if (cachedUint16ArrayMemory0 === null || cachedUint16ArrayMemory0.byteLength === 0) {\n cachedUint16ArrayMemory0 = new Uint16Array(wasm.memory.buffer);\n }\n return cachedUint16ArrayMemory0;\n}\n\nlet cachedUint32ArrayMemory0 = null;\nfunction getUint32ArrayMemory0() {\n if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {\n cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);\n }\n return cachedUint32ArrayMemory0;\n}\n\nlet cachedUint8ArrayMemory0 = null;\nfunction getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n}\n\nfunction handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n const idx = addToExternrefTable0(e);\n wasm.__wbindgen_exn_store(idx);\n }\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n if (realloc === undefined) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n\n const mem = getUint8ArrayMemory0();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7F) break;\n mem[ptr + offset] = code;\n }\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = cachedTextEncoder.encodeInto(arg, view);\n\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n\n WASM_VECTOR_LEN = offset;\n return ptr;\n}\n\nfunction takeFromExternrefTable0(idx) {\n const value = wasm.__wbindgen_externrefs.get(idx);\n wasm.__externref_table_dealloc(idx);\n return value;\n}\n\nlet cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\ncachedTextDecoder.decode();\nconst MAX_SAFARI_DECODE_BYTES = 2146435072;\nlet numBytesDecoded = 0;\nfunction decodeText(ptr, len) {\n numBytesDecoded += len;\n if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n numBytesDecoded = len;\n }\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n\nconst cachedTextEncoder = new TextEncoder();\n\nif (!('encodeInto' in cachedTextEncoder)) {\n cachedTextEncoder.encodeInto = function (arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n };\n}\n\nlet WASM_VECTOR_LEN = 0;\n\nlet wasmModule, wasm;\nfunction __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n wasmModule = module;\n cachedDataViewMemory0 = null;\n cachedFloat32ArrayMemory0 = null;\n cachedFloat64ArrayMemory0 = null;\n cachedUint16ArrayMemory0 = null;\n cachedUint32ArrayMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n wasm.__wbindgen_start();\n return wasm;\n}\n\nasync function __wbg_load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n } catch (e) {\n const validResponse = module.ok && expectedResponseType(module.type);\n\n if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {\n console.warn(\"`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else { throw e; }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n } else {\n return instance;\n }\n }\n\n function expectedResponseType(type) {\n switch (type) {\n case 'basic': case 'cors': case 'default': return true;\n }\n return false;\n }\n}\n\nfunction initSync(module) {\n if (wasm !== undefined) return wasm;\n\n\n if (module !== undefined) {\n if (Object.getPrototypeOf(module) === Object.prototype) {\n ({module} = module)\n } else {\n console.warn('using deprecated parameters for `initSync()`; pass a single object instead')\n }\n }\n\n const imports = __wbg_get_imports();\n if (!(module instanceof WebAssembly.Module)) {\n module = new WebAssembly.Module(module);\n }\n const instance = new WebAssembly.Instance(module, imports);\n return __wbg_finalize_init(instance, module);\n}\n\nasync function __wbg_init(module_or_path) {\n if (wasm !== undefined) return wasm;\n\n\n if (module_or_path !== undefined) {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({module_or_path} = module_or_path)\n } else {\n console.warn('using deprecated parameters for the initialization function; pass a single object instead')\n }\n }\n\n\n const imports = __wbg_get_imports();\n\n if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {\n module_or_path = fetch(module_or_path);\n }\n\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nexport { initSync, __wbg_init as default };\n","function b64ToUint6(nChr) {\n return nChr > 64 && nChr < 91\n ? nChr - 65\n : nChr > 96 && nChr < 123\n ? nChr - 71\n : nChr > 47 && nChr < 58\n ? nChr + 4\n : nChr === 43\n ? 62\n : nChr === 47\n ? 63\n : 0\n}\n\nfunction base64ToUint8(sBase64, nBlocksSize) {\n const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, \"\")\n const nInLen = sB64Enc.length\n const nOutLen = nBlocksSize\n ? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize\n : (nInLen * 3 + 1) >> 2\n const taBytes = new Uint8Array(nOutLen)\n\n let nMod3\n let nMod4\n let nUint24 = 0\n let nOutIdx = 0\n for (let nInIdx = 0; nInIdx < nInLen; nInIdx++) {\n nMod4 = nInIdx & 3\n nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4))\n if (nMod4 === 3 || nInLen - nInIdx === 1) {\n nMod3 = 0\n while (nMod3 < 3 && nOutIdx < nOutLen) {\n taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255\n nMod3++\n nOutIdx++\n }\n nUint24 = 0\n }\n }\n\n return taBytes\n}\nfunction toUint8(b64) {\n if (typeof Uint8Array.fromBase64 === \"function\") return Uint8Array.fromBase64(b64)\n let bin = atob(b64)\n let len = bin.length\n let bytes = new Uint8Array(len)\n for (let i = 0; i < len; i++) {\n bytes[i] = bin.charCodeAt(i)\n }\n return bytes\n}\n\nconst decode64 = typeof atob === \"function\" ? toUint8 : base64ToUint8\n\nexport default decode64\n","import initWasm from \"gaussian-splat-rs\";\nimport wasmBytes from \"gaussian-splat-rs/gaussian_splat_rs_bg.wasm?arraybuffer&base64\";\n\nexport const WASM_MODULE = WebAssembly.compile(wasmBytes);\n\nlet initialized = false;\n\n/** Initializes the main-thread WASM instance used by raycasting. */\nexport const WASM_READY = initWasm({ module_or_path: WASM_MODULE }).then(() => {\n initialized = true;\n});\n// Consumers still receive the rejection; loading the module alone must not\n// create an unhandled rejection when WebAssembly initialization fails.\nvoid WASM_READY.catch(() => {});\n\nexport function isInitialized() {\n return initialized;\n}\n","import { getTransferable } from \"./transferable\";\nimport { WASM_MODULE } from \"./wasm\";\n\ntype PromiseRecord = {\n resolve: (value: unknown) => void;\n reject: (reason?: unknown) => void;\n onStatus?: (data: unknown) => void | Promise<void>;\n statusQueue: Promise<void>;\n};\n\n/** Transport/cache loss is recoverable by obtaining a fresh worker. */\nexport class WorkerTerminatedError extends Error {\n constructor(reason: unknown = \"Worker terminated\") {\n super(String(reason));\n this.name = \"WorkerTerminatedError\";\n }\n}\n\n/** Typed main-thread transport shared by ordinary and streaming workers. */\nexport class WorkerRpc<\n Handlers extends { [K in keyof Handlers]: (...args: never[]) => unknown },\n> {\n messages: Record<number, PromiseRecord> = {};\n peakWasmMemoryBytes = 0;\n disposed = false;\n static currentId = 0;\n\n constructor(\n readonly worker: Worker,\n private readonly onDispose?: () => void,\n ) {\n this.worker.onmessage = (event) => this.onMessage(event);\n this.worker.onerror = (event) =>\n this.dispose(new WorkerTerminatedError(event.message));\n this.worker.onmessageerror = () =>\n this.dispose(new WorkerTerminatedError(\"Invalid worker message\"));\n void WASM_MODULE.then((module) => {\n if (!this.disposed)\n this.worker.postMessage({ name: \"init-wasm\", module });\n }).catch((error) => this.dispose(error));\n }\n\n onMessage(event: MessageEvent) {\n const { id, result, error, fatal, status, wasmMemoryBytes } = event.data;\n const promise = this.messages[id];\n if (fatal) {\n // Every pending call failed with this instance, not a transient transport\n // loss. Keep the fatal classification when retiring the worker.\n Object.defineProperty(error, \"fatal\", { value: true });\n this.dispose(error);\n return;\n }\n if (!promise) return;\n\n if (status !== undefined) {\n const handle = () => {\n if (this.messages[id] === promise) return promise.onStatus?.(status);\n };\n promise.statusQueue = promise.statusQueue.then(handle);\n void promise.statusQueue.catch((error) => this.dispose(error));\n return;\n }\n\n this.peakWasmMemoryBytes = Math.max(\n this.peakWasmMemoryBytes,\n wasmMemoryBytes,\n );\n void promise.statusQueue\n .then(() => {\n if (error !== undefined) throw error;\n return result;\n })\n .then(promise.resolve, promise.reject);\n }\n\n async call<Name extends keyof Handlers>(\n name: Name,\n args: Parameters<Handlers[Name]>[0],\n options: {\n onStatus?: (data: unknown) => void | Promise<void>;\n signal?: AbortSignal;\n } = {},\n ): Promise<Awaited<ReturnType<Handlers[Name]>>> {\n type Result = Awaited<ReturnType<Handlers[Name]>>;\n options.signal?.throwIfAborted();\n if (this.disposed) throw new WorkerTerminatedError();\n const id = ++WorkerRpc.currentId;\n const promise = new Promise<Result>((resolve, reject) => {\n this.messages[id] = {\n resolve: (value) => resolve(value as Result),\n reject,\n onStatus: options.onStatus,\n statusQueue: Promise.resolve(),\n };\n });\n // Pool jobs own their worker exclusively. Termination also interrupts\n // synchronous WASM decoding and releases its linear memory immediately.\n const abort = () => this.dispose(options.signal?.reason);\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n try {\n this.worker.postMessage(\n { id, name, args },\n { transfer: getTransferable(args) },\n );\n return await promise;\n } finally {\n delete this.messages[id];\n options.signal?.removeEventListener(\"abort\", abort);\n }\n }\n\n dispose(reason: unknown = new Error(\"Worker terminated\")) {\n if (this.disposed) return;\n this.disposed = true;\n this.worker.terminate();\n\n const messages = Object.values(this.messages);\n this.messages = {};\n for (const message of messages) {\n message.reject(reason);\n }\n this.onDispose?.();\n }\n}\n","/** Reject promptly on cancellation while still observing the underlying task. */\nexport function abortable<T>(\n task: Promise<T>,\n signal?: AbortSignal,\n): Promise<T> {\n if (!signal) return task;\n return new Promise<T>((resolve, reject) => {\n const abort = () => reject(signal.reason);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (signal.aborted) abort();\n void task.then(resolve, reject).finally(() => {\n signal.removeEventListener(\"abort\", abort);\n });\n });\n}\n\n/** Link lifetime and per-request cancellation without retaining completed listeners. */\nexport function linkedAbortController(...signals: (AbortSignal | undefined)[]) {\n const controller = new AbortController();\n const listeners = signals.flatMap((signal) => {\n if (!signal) return [];\n const abort = () => controller.abort(signal.reason);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (signal.aborted) abort();\n return [{ signal, abort }];\n });\n return {\n controller,\n signal: controller.signal,\n cleanup() {\n for (const { signal, abort } of listeners)\n signal.removeEventListener(\"abort\", abort);\n },\n };\n}\n","import { WorkerRpc } from \"./WorkerRpc\";\nimport { abortable } from \"./abort\";\nimport type { RpcHandlers } from \"./worker\";\nimport BundledWorker from \"./worker?worker&inline\";\n\nexport class SplatWorker extends WorkerRpc<RpcHandlers> {\n constructor(onDispose?: () => void) {\n super(new BundledWorker(), onDispose);\n }\n}\n\nconst MEBIBYTE = 1024 * 1024;\n\nconst SMALL_WORKER_MEMORY_BYTES = 64 * MEBIBYTE;\nconst LARGE_WORKER_MEMORY_BYTES = 256 * MEBIBYTE;\nconst SMALL_WORKER_IDLE_TIMEOUT_MS = 3 * 60 * 1000;\nconst LARGE_WORKER_IDLE_TIMEOUT_MS = 3 * 1000;\n\n/**\n * Keep small workers around for reuse, while releasing workers whose WASM\n * linear memory has grown large much sooner.\n */\nfunction getWorkerIdleTimeoutMs(peakWasmMemoryBytes: number): number {\n const clampedMemoryBytes = Math.min(\n LARGE_WORKER_MEMORY_BYTES,\n Math.max(SMALL_WORKER_MEMORY_BYTES, peakWasmMemoryBytes),\n );\n const memoryRatio =\n (clampedMemoryBytes - SMALL_WORKER_MEMORY_BYTES) /\n (LARGE_WORKER_MEMORY_BYTES - SMALL_WORKER_MEMORY_BYTES);\n\n return Math.round(\n SMALL_WORKER_IDLE_TIMEOUT_MS +\n memoryRatio *\n (LARGE_WORKER_IDLE_TIMEOUT_MS - SMALL_WORKER_IDLE_TIMEOUT_MS),\n );\n}\n\n/**\n * Prefer the smallest idle worker so workers with large WASM heaps can reach\n * their shorter expiry timers. Equal-sized workers retain LIFO behavior.\n */\nfunction getWorkerReuseIndex(\n workers: readonly { peakWasmMemoryBytes: number }[],\n): number {\n let selectedIndex = -1;\n let selectedMemoryBytes = Number.POSITIVE_INFINITY;\n\n for (let index = workers.length - 1; index >= 0; index -= 1) {\n const memoryBytes = workers[index].peakWasmMemoryBytes;\n if (memoryBytes < selectedMemoryBytes) {\n selectedIndex = index;\n selectedMemoryBytes = memoryBytes;\n }\n }\n\n return selectedIndex;\n}\n\nclass SplatWorkerPool {\n private heavyJobs: Promise<void> = Promise.resolve();\n numWorkers = 0;\n freelist: SplatWorker[] = [];\n idleWorkerTimeouts = new Map<SplatWorker, ReturnType<typeof setTimeout>>();\n queue: ((worker: SplatWorker) => void)[] = [];\n\n constructor(private readonly maxWorkers = 4) {}\n\n async withWorker<T>(\n callback: (worker: SplatWorker) => Promise<T>,\n memoryHeavy = false,\n signal?: AbortSignal,\n ): Promise<T> {\n signal?.throwIfAborted();\n if (memoryHeavy) {\n const next = this.heavyJobs.then(() =>\n this.withWorker(callback, false, signal),\n );\n this.heavyJobs = next.then(\n () => {},\n () => {},\n );\n return abortable(next, signal);\n }\n\n return abortable(\n this.allocWorker().then(async (worker) => {\n try {\n signal?.throwIfAborted();\n return await callback(worker);\n } finally {\n this.freeWorker(worker);\n }\n }),\n signal,\n );\n }\n\n async allocWorker(): Promise<SplatWorker> {\n for (let index = this.freelist.length - 1; index >= 0; index--) {\n const worker = this.freelist[index];\n if (!worker.disposed) continue;\n clearTimeout(this.idleWorkerTimeouts.get(worker));\n this.idleWorkerTimeouts.delete(worker);\n this.freelist.splice(index, 1);\n this.numWorkers -= 1;\n }\n const workerIndex = getWorkerReuseIndex(this.freelist);\n if (workerIndex !== -1) {\n const worker = this.freelist.splice(workerIndex, 1)[0];\n clearTimeout(this.idleWorkerTimeouts.get(worker));\n this.idleWorkerTimeouts.delete(worker);\n return worker;\n }\n\n if (this.numWorkers < this.maxWorkers) {\n const worker = new SplatWorker();\n this.numWorkers += 1;\n return worker;\n }\n\n return new Promise((resolve) => {\n this.queue.push(resolve);\n });\n }\n\n freeWorker(worker: SplatWorker) {\n if (worker.disposed) {\n this.numWorkers -= 1;\n const waiter = this.queue.shift();\n if (waiter) {\n this.numWorkers += 1;\n waiter(new SplatWorker());\n }\n return;\n }\n const waiter = this.queue.shift();\n if (waiter) {\n waiter(worker);\n return;\n }\n\n this.freelist.push(worker);\n const timeout = setTimeout(() => {\n this.idleWorkerTimeouts.delete(worker);\n // Removing an idle worker elsewhere cancels this timer.\n this.freelist.splice(this.freelist.indexOf(worker), 1);\n worker.dispose();\n this.numWorkers -= 1;\n }, getWorkerIdleTimeoutMs(worker.peakWasmMemoryBytes));\n this.idleWorkerTimeouts.set(worker, timeout);\n }\n}\n\nexport const workerPool = new SplatWorkerPool();\n","import * as THREE from \"three\";\n\nexport function resolveTimer(timer?: THREE.Timer): {\n timer: THREE.Timer;\n ownsTimer: boolean;\n} {\n return {\n timer: timer ?? new THREE.Timer(),\n // A caller-supplied timer may be shared with other systems, so only update\n // the timer that Gaussian Splat Lite creates and owns itself.\n ownsTimer: timer === undefined,\n };\n}\n\nexport const threeRevision = Number.parseInt(THREE.REVISION);\n","import type { SplatMesh } from \"../scene/SplatMesh\";\nimport type { SplatAccumulator, SplatMapping } from \"./SplatAccumulator\";\n\ntype SortCenterEntry = {\n meshId: number;\n centerVersion: number;\n sortVersion: number;\n};\n\n/** Tracks raw-center and matrix revisions cached by the sort worker. */\nexport class SortCenterCache {\n private entries = new Map<SplatMesh, SortCenterEntry>();\n private freeMeshIds: number[] = [];\n private nextMeshId = 0;\n\n private allocateMeshId() {\n return this.freeMeshIds.pop() ?? this.nextMeshId++;\n }\n\n dispose() {\n this.entries.clear();\n this.freeMeshIds.length = 0;\n this.nextMeshId = 0;\n }\n\n prepare(current: SplatAccumulator) {\n const { mapping } = current;\n // Commit the versions captured now, even if the mapping changes before\n // the worker accepts this state.\n const committed: {\n entry: SortCenterEntry;\n centerVersion: number;\n sortVersion: number;\n }[] = [];\n const rangeMeshIds = new Uint32Array(mapping.length);\n const rangeBases = new Uint32Array(mapping.length);\n const rangeCounts = new Uint32Array(mapping.length);\n const retiredEntries = new Map(this.entries);\n const changedCenters: {\n source: SplatMapping[\"source\"];\n count: number;\n rangeIndex: number;\n }[] = [];\n const changedMatrices: {\n matrixWorld: SplatMapping[\"matrixWorld\"];\n rangeIndex: number;\n }[] = [];\n let updateCount = 0;\n\n mapping.forEach(\n (\n { node, source, matrixWorld, base, count, centerVersion, sortVersion },\n rangeIndex,\n ) => {\n retiredEntries.delete(node);\n let entry = this.entries.get(node);\n if (!entry) {\n // Store a provisional entry immediately so a failed worker call can\n // retry with the same ID. Its sentinel version forces a re-upload.\n entry = {\n meshId: this.allocateMeshId(),\n centerVersion: -1,\n sortVersion: -1,\n };\n this.entries.set(node, entry);\n }\n\n committed.push({ entry, centerVersion, sortVersion });\n rangeMeshIds[rangeIndex] = entry.meshId;\n rangeBases[rangeIndex] = base;\n rangeCounts[rangeIndex] = count;\n\n if (entry.centerVersion !== centerVersion) {\n changedCenters.push({\n source,\n count,\n rangeIndex,\n });\n updateCount += count;\n }\n if (entry.sortVersion !== sortVersion) {\n changedMatrices.push({\n matrixWorld,\n rangeIndex,\n });\n }\n },\n );\n\n const centerUpdateRangeIndices = new Uint32Array(changedCenters.length);\n const updateCenters = new Float32Array(updateCount * 3);\n\n let updateBase = 0;\n changedCenters.forEach(({ source, count, rangeIndex }, updateIndex) => {\n centerUpdateRangeIndices[updateIndex] = rangeIndex;\n\n if (!source) throw new Error(\"Splat mapping has no source\");\n source.copySortCenters(updateCenters, updateBase * 3, count);\n updateBase += count;\n });\n\n const matrixUpdateRangeIndices = new Uint32Array(changedMatrices.length);\n const updateMatrices = new Float64Array(changedMatrices.length * 16);\n changedMatrices.forEach(({ matrixWorld, rangeIndex }, updateIndex) => {\n matrixUpdateRangeIndices[updateIndex] = rangeIndex;\n updateMatrices.set(matrixWorld.elements, updateIndex * 16);\n });\n\n return {\n payload: {\n centerUpdateRangeIndices,\n updateCenters,\n matrixUpdateRangeIndices,\n updateMatrices,\n rangeMeshIds,\n rangeBases,\n rangeCounts,\n },\n commit: () => {\n // The renderer serializes updates and skips commit after disposal.\n for (const { entry, centerVersion, sortVersion } of committed) {\n entry.centerVersion = centerVersion;\n entry.sortVersion = sortVersion;\n }\n // Recycle IDs only after the worker accepted the replacement state.\n // A mesh that later becomes active again gets a fresh entry and must\n // upload all of its centers before using its recycled ID.\n for (const [node, entry] of retiredEntries) {\n this.entries.delete(node);\n this.freeMeshIds.push(entry.meshId);\n }\n },\n };\n }\n}\n","// Gsplats are stored in textures that are 2^11 x 2^11 x up to 2^11\n// Most WebGL2 implementations support 2D textures up to 2^12 x 2^12 (max 16M Gsplats)\n// 2D array textures and 3D textures up to 2^11 x 2^11 x 2^11 (max 8G Gsplats),\n// so we use 2D array textures for our representation for higher limits.\n\nexport const SPLAT_TEX_WIDTH_BITS = 11;\nexport const SPLAT_TEX_HEIGHT_BITS = 11;\n\nexport const SPLAT_TEX_WIDTH = 1 << SPLAT_TEX_WIDTH_BITS; // 2048\nexport const SPLAT_TEX_HEIGHT = 1 << SPLAT_TEX_HEIGHT_BITS; // 2048\nexport const SPLAT_TEX_MIN_HEIGHT = 1;\n\n/** Valid block shifts include zero (one opacity per Splat). */\nexport const SPLAT_BLOCKS_DISABLED = 32;\n\nexport enum SplatFileType {\n PLY = \"ply\",\n SPZ = \"spz\",\n SOG = \"sog\",\n RAD = \"rad\",\n}\n\nexport type SplatExtra = {\n sh1?: Uint32Array;\n sh2?: Uint32Array;\n sh3a?: Uint32Array;\n sh3b?: Uint32Array;\n};\n\n/** Morton storage records per cached spatial bounds block. */\nexport const SPLAT_BOUNDS_BLOCK_SIZE = 256;\n\nexport type SplatResult = {\n numSplats: number;\n splatArrays: [Uint32Array, Uint32Array];\n sortCenters?: Float32Array;\n /** Storage index to original source index; absent for identity order. */\n sourceIds?: Uint32Array;\n /** Local finite center bounds: min XYZ followed by max XYZ. */\n centerOnlyBoundingBox?: Float32Array;\n /** Local scale/rotation bounds at source alpha 0.01, including kernel shape. */\n boundingBox?: Float32Array;\n /** Per 256 records: min/max XYZ at source alpha 0.01, including scale, rotation and shape. */\n spatialBounds?: Float32Array;\n extra: SplatExtra;\n};\n\n/** Spatially reordered records with source IDs and cached local bounds. */\nexport type ReorderedSplatResult = SplatResult & {\n sourceIds: Uint32Array;\n centerOnlyBoundingBox: Float32Array;\n boundingBox: Float32Array;\n spatialBounds: Float32Array;\n};\n","import * as THREE from \"three\";\nimport {\n SPLAT_TEX_HEIGHT,\n SPLAT_TEX_MIN_HEIGHT,\n SPLAT_TEX_WIDTH,\n} from \"./defines\";\n\n// Keep rows compact for small sources and power-of-two layers for large ones.\n// 256 layers is the WebGL2 minimum; larger devices need no special layout.\nexport function getTextureSize(\n numSplats: number,\n maxLayers = 256,\n): {\n width: number;\n height: number;\n depth: number;\n maxSplats: number;\n} {\n const width = SPLAT_TEX_WIDTH;\n const rows = Math.ceil(Math.max(1, numSplats) / width);\n const height =\n rows <= SPLAT_TEX_HEIGHT\n ? Math.max(SPLAT_TEX_MIN_HEIGHT, rows)\n : Math.min(\n SPLAT_TEX_HEIGHT,\n 2 ** Math.ceil(Math.log2(Math.ceil(rows / maxLayers))),\n );\n const depth = Math.ceil(Math.max(1, numSplats) / (width * height));\n return { width, height, depth, maxSplats: width * height * depth };\n}\n\nexport const emptyUintTexture = /* @__PURE__ */ (() => {\n const texture = new THREE.DataTexture(\n new Uint32Array(4),\n 1,\n 1,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n );\n texture.needsUpdate = true;\n return texture;\n})();\n\nexport const emptySplatTexture = /* @__PURE__ */ (() => {\n const { width, height, depth, maxSplats } = getTextureSize(1);\n const texture = new THREE.DataArrayTexture(\n new Uint32Array(maxSplats * 4),\n width,\n height,\n depth,\n );\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.needsUpdate = true;\n return texture;\n})();\n","import * as THREE from \"three\";\n\nconst rotationMatrix = new THREE.Matrix4();\nconst axisX = new THREE.Vector3();\nconst axisY = new THREE.Vector3();\nconst axisZ = new THREE.Vector3();\nconst sourceAxis = new THREE.Vector3();\n\n/**\n * Extracts the positive per-axis scale and approximate rotation used by the\n * PlayCanvas-style splat work-buffer transform.\n *\n * Unlike Matrix4.decompose(), this remains finite when a model scale axis is\n * zero. When possible, the missing basis axis is reconstructed from the other\n * two so degenerate transforms retain a stable orientation.\n */\nexport function decomposeSplatTransform(\n matrix: THREE.Matrix4,\n scale: THREE.Vector3,\n rotation: THREE.Quaternion,\n) {\n const source = matrix.elements;\n const sx = Math.hypot(source[0], source[1], source[2]);\n const sy = Math.hypot(source[4], source[5], source[6]);\n const sz = Math.hypot(source[8], source[9], source[10]);\n scale.set(sx, sy, sz);\n\n axisX.set(source[0], source[1], source[2]);\n axisY.set(source[4], source[5], source[6]);\n axisZ.set(source[8], source[9], source[10]);\n if (sx > 0) axisX.multiplyScalar(1 / sx);\n if (sy > 0) axisY.multiplyScalar(1 / sy);\n if (sz > 0) axisZ.multiplyScalar(1 / sz);\n\n const nonZeroAxes = Number(sx > 0) + Number(sy > 0) + Number(sz > 0);\n if (nonZeroAxes === 0) {\n rotation.identity();\n return false;\n }\n\n if (nonZeroAxes === 1) {\n const localAxis = sx > 0 ? 0 : sy > 0 ? 1 : 2;\n sourceAxis.set(\n localAxis === 0 ? 1 : 0,\n localAxis === 1 ? 1 : 0,\n localAxis === 2 ? 1 : 0,\n );\n rotation\n .setFromUnitVectors(\n sourceAxis,\n localAxis === 0 ? axisX : localAxis === 1 ? axisY : axisZ,\n )\n .normalize();\n return false;\n }\n\n if (sx === 0) axisX.copy(axisY).cross(axisZ).normalize();\n if (sy === 0) axisY.copy(axisZ).cross(axisX).normalize();\n if (sz === 0) axisZ.copy(axisX).cross(axisY).normalize();\n const reflected = matrix.determinant() < 0;\n if (reflected) axisX.negate();\n\n rotationMatrix.makeBasis(axisX, axisY, axisZ);\n rotation.setFromRotationMatrix(rotationMatrix).normalize();\n return reflected;\n}\n\n/**\n * Re-expresses an affine transform so it consumes positions relative to\n * `origin` instead of absolute world positions.\n *\n * If `matrix` maps p to A * p + t, the rebased matrix maps (p - origin) to\n * A * (p - origin) + (A * origin + t), which is the same result without doing\n * a large-coordinate subtraction in float32 shader code.\n */\nexport function rebaseAffineTransform(\n matrix: THREE.Matrix4,\n origin: THREE.Vector3,\n) {\n const elements = matrix.elements;\n const x = origin.x;\n const y = origin.y;\n const z = origin.z;\n\n const tx = elements[0] * x + elements[4] * y + elements[8] * z + elements[12];\n const ty = elements[1] * x + elements[5] * y + elements[9] * z + elements[13];\n const tz =\n elements[2] * x + elements[6] * y + elements[10] * z + elements[14];\n\n elements[12] = tx;\n elements[13] = ty;\n elements[14] = tz;\n return matrix;\n}\n","import * as THREE from \"three\";\n\nimport { emptyUintTexture } from \"../data/textureLayout\";\nimport { rebaseAffineTransform } from \"../utils/transforms\";\n\nexport enum SplatEditSdfType {\n ALL = \"all\",\n PLANE = \"plane\",\n SPHERE = \"sphere\",\n BOX = \"box\",\n ELLIPSOID = \"ellipsoid\",\n CYLINDER = \"cylinder\",\n CAPSULE = \"capsule\",\n INFINITE_CONE = \"infinite_cone\",\n}\n\n/** RGBA-only operations supported by the SDF pipeline. */\nexport enum SplatEditRgbaBlendMode {\n MULTIPLY_RGBA = \"multiply_rgba\",\n SET_RGBA = \"set_rgba\",\n ADD_RGBA = \"add_rgba\",\n}\n\nexport type SplatEditSdfColor = {\n r?: number;\n g?: number;\n b?: number;\n};\n\nexport type SplatEditSdfOptions = {\n type?: SplatEditSdfType;\n invert?: boolean;\n opacity?: number;\n color?: SplatEditSdfColor;\n radius?: number;\n};\n\n/** A signed-distance shape carrying optional color and opacity channels. */\nexport class SplatEditSdf extends THREE.Object3D {\n type: SplatEditSdfType;\n invert: boolean;\n opacity?: number;\n color: SplatEditSdfColor;\n radius: number;\n\n constructor(options: SplatEditSdfOptions = {}) {\n super();\n this.type = options.type ?? SplatEditSdfType.SPHERE;\n this.invert = options.invert ?? false;\n this.opacity = options.opacity;\n this.color = options.color ?? {};\n this.radius = options.radius ?? 0;\n }\n}\n\nexport type SplatEditOptions = {\n name?: string;\n rgbaBlendMode?: SplatEditRgbaBlendMode;\n sdfSmooth?: number;\n softEdge?: number;\n invert?: boolean;\n sdfs?: SplatEditSdf[];\n};\n\n/** An ordered RGBA operation evaluated over one or more SDF shapes. */\nexport class SplatEdit extends THREE.Object3D {\n ordering: number;\n rgbaBlendMode: SplatEditRgbaBlendMode;\n sdfSmooth: number;\n softEdge: number;\n invert: boolean;\n sdfs: SplatEditSdf[] | null;\n\n static nextOrdering = 1;\n\n constructor(options: SplatEditOptions = {}) {\n super();\n this.rgbaBlendMode =\n options.rgbaBlendMode ?? SplatEditRgbaBlendMode.MULTIPLY_RGBA;\n this.sdfSmooth = options.sdfSmooth ?? 0;\n this.softEdge = options.softEdge ?? 0;\n this.invert = options.invert ?? false;\n this.sdfs = options.sdfs ?? null;\n this.ordering = SplatEdit.nextOrdering++;\n this.name = options.name ?? `Edit ${this.ordering}`;\n }\n\n addSdf(sdf: SplatEditSdf) {\n this.sdfs ??= [];\n if (!this.sdfs.includes(sdf)) {\n this.sdfs.push(sdf);\n }\n }\n\n removeSdf(sdf: SplatEditSdf) {\n if (this.sdfs) {\n this.sdfs = this.sdfs.filter((candidate) => candidate !== sdf);\n }\n }\n}\n\nexport type SplatEditGroup = { edit: SplatEdit; sdfs: SplatEditSdf[] };\n\nconst SDF_TEXELS = 6;\nconst SDF_RGBA_MASK_SHIFT = 16;\nconst MIN_CAPACITY = 16;\nconst scratchFloat = new Float32Array(1);\nconst scratchUint = new Uint32Array(scratchFloat.buffer);\n\n/** Encodes SDF geometry/RGBA and edit operations as regular integer textures. */\nexport class SplatEdits {\n maxSdfs: number;\n numSdfs = 0;\n sdfData: Uint32Array;\n sdfTexture: THREE.DataTexture;\n\n maxEdits: number;\n numEdits = 0;\n editData: Uint32Array;\n editTexture: THREE.DataTexture;\n\n constructor({ maxSdfs = 0, maxEdits = 0 } = {}) {\n this.maxSdfs = Math.max(MIN_CAPACITY, maxSdfs);\n this.sdfData = new Uint32Array(this.maxSdfs * SDF_TEXELS * 4);\n this.sdfTexture = makeUintTexture(this.sdfData, SDF_TEXELS, this.maxSdfs);\n\n this.maxEdits = Math.max(MIN_CAPACITY, maxEdits);\n this.editData = new Uint32Array(this.maxEdits * 4);\n this.editTexture = makeUintTexture(this.editData, 1, this.maxEdits);\n }\n\n dispose() {\n this.sdfTexture.dispose();\n this.editTexture.dispose();\n }\n\n update(\n groups: SplatEditGroup[],\n coordinateOrigin?: THREE.Vector3,\n ): { updated: boolean } {\n const sdfCount = groups.reduce(\n (total, group) => total + group.sdfs.length,\n 0,\n );\n let updated = this.ensureCapacity(sdfCount, groups.length);\n\n if (this.numSdfs !== sdfCount || this.numEdits !== groups.length) {\n this.numSdfs = sdfCount;\n this.numEdits = groups.length;\n updated = true;\n }\n\n const sizes = new THREE.Vector4();\n const inverseOwnScale = new THREE.Vector3();\n const worldToSdf = new THREE.Matrix4();\n let sdfIndex = 0;\n let sdfUpdated = false;\n let editUpdated = false;\n\n groups.forEach(({ edit, sdfs }, editIndex) => {\n editUpdated =\n this.encodeEdit(editIndex, edit, sdfIndex, sdfs.length) || editUpdated;\n\n for (const sdf of sdfs) {\n sdf.updateWorldMatrix(true, false);\n worldToSdf.copy(sdf.matrixWorld);\n // These shapes already use scale as dimensions. Preserve their\n // independent corner/cap radius instead of scaling it a second time.\n const dimensional =\n sdf.type === SplatEditSdfType.BOX ||\n sdf.type === SplatEditSdfType.ELLIPSOID ||\n sdf.type === SplatEditSdfType.CAPSULE;\n sizes.set(\n dimensional ? Math.abs(sdf.scale.x) : 1,\n dimensional ? Math.abs(sdf.scale.y) : 1,\n dimensional ? Math.abs(sdf.scale.z) : 1,\n sdf.radius,\n );\n const collapsed = worldToSdf.determinant() === 0;\n if (dimensional && !collapsed)\n worldToSdf.scale(\n inverseOwnScale.set(\n 1 / sdf.scale.x,\n 1 / sdf.scale.y,\n 1 / sdf.scale.z,\n ),\n );\n const e = worldToSdf.elements;\n const distanceScale = collapsed\n ? 0\n : Math.min(\n Math.hypot(e[0], e[1], e[2]),\n Math.hypot(e[4], e[5], e[6]),\n Math.hypot(e[8], e[9], e[10]),\n );\n worldToSdf.invert();\n if (coordinateOrigin)\n rebaseAffineTransform(worldToSdf, coordinateOrigin);\n sdfUpdated =\n this.encodeSdf(sdfIndex, sdf, worldToSdf, distanceScale, sizes) ||\n sdfUpdated;\n sdfIndex += 1;\n }\n });\n\n if (sdfUpdated) {\n this.sdfTexture.needsUpdate = true;\n }\n if (editUpdated) {\n this.editTexture.needsUpdate = true;\n }\n return { updated: updated || sdfUpdated || editUpdated };\n }\n\n private ensureCapacity(sdfs: number, edits: number) {\n let updated = false;\n if (sdfs > this.maxSdfs) {\n this.maxSdfs = Math.max(sdfs, this.maxSdfs * 2);\n this.sdfTexture.dispose();\n this.sdfData = new Uint32Array(this.maxSdfs * SDF_TEXELS * 4);\n this.sdfTexture = makeUintTexture(this.sdfData, SDF_TEXELS, this.maxSdfs);\n updated = true;\n }\n if (edits > this.maxEdits) {\n this.maxEdits = Math.max(edits, this.maxEdits * 2);\n this.editTexture.dispose();\n this.editData = new Uint32Array(this.maxEdits * 4);\n this.editTexture = makeUintTexture(this.editData, 1, this.maxEdits);\n updated = true;\n }\n return updated;\n }\n\n private encodeEdit(\n index: number,\n edit: SplatEdit,\n sdfFirst: number,\n sdfCount: number,\n ) {\n if (sdfFirst > 0xffff || sdfCount > 0xffff) {\n throw new Error(\"An SDF edit supports at most 65535 shapes\");\n }\n const base = index * 4;\n const blend = rgbaBlendModeToNumber(edit.rgbaBlendMode);\n const flags = blend | (edit.invert ? 1 << 8 : 0);\n let updated = this.setEditUint(base, flags);\n updated =\n this.setEditUint(base + 1, sdfFirst | (sdfCount << 16)) || updated;\n updated = this.setEditFloat(base + 2, edit.softEdge) || updated;\n updated = this.setEditFloat(base + 3, edit.sdfSmooth) || updated;\n return updated;\n }\n\n private encodeSdf(\n index: number,\n sdf: SplatEditSdf,\n matrix: THREE.Matrix4,\n distanceScale: number,\n sizes: THREE.Vector4,\n ) {\n const base = index * SDF_TEXELS * 4;\n const color = sdf.color;\n const rgbaMask =\n (color.r === undefined ? 0 : 1) |\n (color.g === undefined ? 0 : 1 << 1) |\n (color.b === undefined ? 0 : 1 << 2) |\n (sdf.opacity === undefined ? 0 : 1 << 3);\n const flags =\n sdfTypeToNumber(sdf.type) |\n (sdf.invert ? 1 << 8 : 0) |\n (rgbaMask << SDF_RGBA_MASK_SHIFT);\n const e = matrix.elements;\n let updated = this.setSdfFloat(base, e[12]);\n updated = this.setSdfFloat(base + 1, e[13]) || updated;\n updated = this.setSdfFloat(base + 2, e[14]) || updated;\n updated = this.setSdfUint(base + 3, flags) || updated;\n for (let axis = 0; axis < 3; axis++) {\n updated = this.setSdfFloat(base + 4 + axis, e[axis]) || updated;\n updated = this.setSdfFloat(base + 8 + axis, e[4 + axis]) || updated;\n updated = this.setSdfFloat(base + 20 + axis, e[8 + axis]) || updated;\n }\n updated = this.setSdfFloat(base + 23, distanceScale) || updated;\n\n updated = this.setSdfFloat(base + 12, sizes.x) || updated;\n updated = this.setSdfFloat(base + 13, sizes.y) || updated;\n updated = this.setSdfFloat(base + 14, sizes.z) || updated;\n updated = this.setSdfFloat(base + 15, sizes.w) || updated;\n\n updated = this.setSdfFloat(base + 16, color.r ?? 0) || updated;\n updated = this.setSdfFloat(base + 17, color.g ?? 0) || updated;\n updated = this.setSdfFloat(base + 18, color.b ?? 0) || updated;\n updated = this.setSdfFloat(base + 19, sdf.opacity ?? 0) || updated;\n return updated;\n }\n\n private setSdfUint(offset: number, value: number) {\n const updated = this.sdfData[offset] !== value;\n this.sdfData[offset] = value;\n return updated;\n }\n\n private setSdfFloat(offset: number, value: number) {\n scratchFloat[0] = value;\n return this.setSdfUint(offset, scratchUint[0]);\n }\n\n private setEditUint(offset: number, value: number) {\n const updated = this.editData[offset] !== value;\n this.editData[offset] = value;\n return updated;\n }\n\n private setEditFloat(offset: number, value: number) {\n scratchFloat[0] = value;\n return this.setEditUint(offset, scratchUint[0]);\n }\n\n static emptyTexture = emptyUintTexture;\n}\n\nfunction rgbaBlendModeToNumber(mode: SplatEditRgbaBlendMode) {\n switch (mode) {\n case SplatEditRgbaBlendMode.MULTIPLY_RGBA:\n return 0;\n case SplatEditRgbaBlendMode.SET_RGBA:\n return 1;\n case SplatEditRgbaBlendMode.ADD_RGBA:\n return 2;\n }\n}\n\nfunction sdfTypeToNumber(type: SplatEditSdfType) {\n switch (type) {\n case SplatEditSdfType.ALL:\n return 0;\n case SplatEditSdfType.PLANE:\n return 1;\n case SplatEditSdfType.SPHERE:\n return 2;\n case SplatEditSdfType.BOX:\n return 3;\n case SplatEditSdfType.ELLIPSOID:\n return 4;\n case SplatEditSdfType.CYLINDER:\n return 5;\n case SplatEditSdfType.CAPSULE:\n return 6;\n case SplatEditSdfType.INFINITE_CONE:\n return 7;\n }\n}\n\nfunction makeUintTexture(data: Uint32Array, width: number, height: number) {\n const texture = new THREE.DataTexture(\n data,\n width,\n height,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n );\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n","const f32 = new Float32Array(1);\nconst u32 = new Uint32Array(f32.buffer);\nconst supportsFloat16Array = \"Float16Array\" in globalThis;\nconst f16 = supportsFloat16Array\n ? new globalThis[\"Float16Array\" as keyof typeof globalThis](1)\n : null;\nconst u16 = new Uint16Array(f16?.buffer);\n\nfunction toHalfNative(value: number): number {\n f16[0] = value;\n return u16[0];\n}\n\nfunction roundEven(value: number): number {\n const integer = Math.floor(value);\n const fraction = value - integer;\n return (\n integer +\n Number(fraction > 0.5 || (fraction === 0.5 && (integer & 1) !== 0))\n );\n}\n\nfunction toHalfJs(value: number): number {\n const sign = value < 0 || Object.is(value, -0) ? 0x8000 : 0;\n const magnitude = Math.abs(value);\n if (Number.isNaN(magnitude)) return 0x7e00;\n if (magnitude >= 65520) return sign | 0x7c00;\n if (magnitude < 2 ** -14) return sign | roundEven(magnitude * 2 ** 24);\n // Round the original double, avoiding double rounding through float32.\n f32[0] = magnitude;\n const exponent = ((u32[0] >>> 23) & 0xff) - 127;\n const mantissa = roundEven(magnitude * 2 ** (10 - exponent));\n return sign | ((exponent + 14) * 1024 + mantissa);\n}\n\nfunction fromHalfNative(value: number): number {\n u16[0] = value;\n return f16[0];\n}\n\nfunction fromHalfJs(value: number): number {\n const sign = (value >>> 15) & 1;\n const exponent = (value >>> 10) & 0x1f;\n const fraction = value & 0x3ff;\n let bits: number;\n\n if (exponent === 0) {\n if (fraction === 0) {\n bits = sign << 31;\n } else {\n let mantissa = fraction;\n let adjustedExponent = -14;\n while ((mantissa & 0x400) === 0) {\n mantissa <<= 1;\n adjustedExponent -= 1;\n }\n bits =\n (sign << 31) |\n ((adjustedExponent + 127) << 23) |\n ((mantissa & 0x3ff) << 13);\n }\n } else if (exponent === 0x1f) {\n bits = (sign << 31) | (fraction === 0 ? 0x7f80_0000 : 0x7fc0_0000);\n } else {\n bits = (sign << 31) | ((exponent - 15 + 127) << 23) | (fraction << 13);\n }\n\n u32[0] = bits;\n return f32[0];\n}\n\nexport const toHalf = supportsFloat16Array ? toHalfNative : toHalfJs;\nexport const fromHalf = supportsFloat16Array ? fromHalfNative : fromHalfJs;\n\nconst f32buffer = new Float32Array(1);\nconst u32buffer = new Uint32Array(f32buffer.buffer);\n\n// Reinterpret the bits of a float32 as a uint32\nexport function floatBitsToUint(f: number): number {\n f32buffer[0] = f;\n return u32buffer[0];\n}\n\n// Reinterpret the bits of a uint32 as a float32\nexport function uintBitsToFloat(u: number): number {\n u32buffer[0] = u;\n return f32buffer[0];\n}\n","import { fromHalf, toHalf } from \"../utils/numeric\";\n\nconst F32_EPSILON = 1.192_092_895_507_812_5e-7;\nconst ENCODED_IDENTITY_QUATERNION = (512 << 10) | 1023;\n\n// Keep JS double precision; the destination array controls decode precision.\nconst QUAT_ROTATION_LOOKUP = Float64Array.from({ length: 4096 * 2 }, (_, i) => {\n const halfTheta = ((i >>> 1) / 4095) * 0.5 * Math.PI;\n return i & 1 ? Math.cos(halfTheta) : Math.sin(halfTheta);\n});\nconst SH_SCALE_LOOKUP = Float64Array.from(\n { length: 32 },\n (_, exponent) => 2 ** (exponent - 15) / 255,\n);\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.min(max, Math.max(min, value));\n}\n\nexport function decodeSplatOpacity(word: number) {\n const shapeAmount = fromHalf(word >>> 16);\n if (shapeAmount > 0) {\n const kernelShape = Math.min(shapeAmount, 1) * 4 + 1;\n return Math.exp((kernelShape * kernelShape - 1) / Math.E);\n }\n return fromHalf(word & 0xffff);\n}\n\nexport function encodeSplatOpacity(opacity: number) {\n if (opacity > 0 && opacity <= 1) return toHalf(opacity);\n const value = Math.max(opacity || 0, 0);\n if (value > 1) {\n const shapeAmount = 0.25 * (Math.sqrt(Math.log(value) * Math.E + 1) - 1);\n // Match the renderer's shape range [0, 1].\n return (toHalf(1) | (toHalf(Math.min(shapeAmount, 1)) << 16)) >>> 0;\n }\n return toHalf(value);\n}\n\ntype CodecOutput = Float32Array | number[];\n\n// NaN channels encode as zero without affecting the shared exponent. All\n// magnitudes are nonnegative, so Math.round also gives ties away from zero.\n// Keep JS precision here; the destination array controls decode precision.\nexport function encodeShRgb(red: number, green: number, blue: number) {\n const maxAbsolute = Math.max(\n Math.abs(red) || 0,\n Math.abs(green) || 0,\n Math.abs(blue) || 0,\n );\n // The shared exponent must cover the largest channel before quantization.\n const exponent = clamp(Math.ceil(Math.log2(maxAbsolute)) + 15, 0, 31);\n const divisor = 2 ** (exponent - 15) / 255;\n const encodedRed = Math.round(clamp(Math.abs(red) / divisor, 0, 255));\n const encodedGreen = Math.round(clamp(Math.abs(green) / divisor, 0, 255));\n const encodedBlue = Math.round(clamp(Math.abs(blue) / divisor, 0, 255));\n const signs = (red < 0 ? 1 : 0) | (green < 0 ? 2 : 0) | (blue < 0 ? 4 : 0);\n return (\n (encodedRed |\n (encodedGreen << 8) |\n (encodedBlue << 16) |\n (((exponent << 3) | signs) << 24)) >>>\n 0\n );\n}\n\nexport function decodeShRgbToArray(\n word: number,\n output: CodecOutput,\n base = 0,\n stride = 1,\n) {\n const exponentAndSigns = word >>> 24;\n const multiplier = SH_SCALE_LOOKUP[exponentAndSigns >>> 3];\n for (let component = 0; component < 3; component += 1) {\n const magnitude = ((word >>> (component * 8)) & 0xff) * multiplier;\n output[base + component * stride] =\n exponentAndSigns & (1 << component) ? -magnitude : magnitude;\n }\n}\n\nexport function decodeQuatOctXy1010R12ToArray(\n word: number,\n output: CodecOutput,\n base = 0,\n stride = 1,\n) {\n const u = word & 0x3ff;\n const v = (word >>> 10) & 0x3ff;\n const angle = word >>> 20;\n let x = (u / 1023) * 2 - 1;\n let y = (v / 1023) * 2 - 1;\n const z = 1 - Math.abs(x) - Math.abs(y);\n const fold = Math.max(-z, 0);\n x += x >= 0 ? -fold : fold;\n y += y >= 0 ? -fold : fold;\n const inverseLength = 1 / Math.sqrt(x * x + y * y + z * z);\n const sine = QUAT_ROTATION_LOOKUP[angle * 2];\n output[base] = x * inverseLength * sine;\n output[base + stride] = y * inverseLength * sine;\n output[base + stride * 2] = z * inverseLength * sine;\n output[base + stride * 3] = QUAT_ROTATION_LOOKUP[angle * 2 + 1];\n}\n\nfunction encodeQuaternion(\n qx: number,\n qy: number,\n qz: number,\n qw: number,\n minimumLengthSquared: number,\n) {\n const lengthSquared = qx * qx + qy * qy + qz * qz + qw * qw;\n if (\n !Number.isFinite(lengthSquared) ||\n lengthSquared <= minimumLengthSquared\n ) {\n return undefined;\n }\n if (qx === 0 && qy === 0 && qz === 0) {\n return ENCODED_IDENTITY_QUATERNION;\n }\n\n const inverseLength = 1 / Math.sqrt(lengthSquared);\n let x = qx * inverseLength;\n let y = qy * inverseLength;\n let z = qz * inverseLength;\n let w = qw * inverseLength;\n if (w < 0) {\n x = -x;\n y = -y;\n z = -z;\n w = -w;\n }\n\n const theta = 2 * Math.acos(clamp(w, 0, 1));\n const sine = Math.sin(theta * 0.5);\n const axisX = Math.abs(sine) < 1e-6 ? 1 : x / sine;\n const axisY = Math.abs(sine) < 1e-6 ? 0 : y / sine;\n const axisZ = Math.abs(sine) < 1e-6 ? 0 : z / sine;\n const sum = Math.abs(axisX) + Math.abs(axisY) + Math.abs(axisZ);\n let octX = axisX / sum;\n let octY = axisY / sum;\n if (axisZ < 0) {\n const previousX = octX;\n octX = (1 - Math.abs(octY)) * (octX >= 0 ? 1 : -1);\n octY = (1 - Math.abs(previousX)) * (octY >= 0 ? 1 : -1);\n }\n\n const u = Math.round(clamp((octX * 0.5 + 0.5) * 1023, 0, 1023));\n const v = Math.round(clamp((octY * 0.5 + 0.5) * 1023, 0, 1023));\n const angle = Math.round(clamp((theta / Math.PI) * 4095, 0, 4095));\n return ((angle << 20) | (v << 10) | u) >>> 0;\n}\n\nexport function encodeQuatOctXy1010R12(\n qx: number,\n qy: number,\n qz: number,\n qw: number,\n): number {\n return (encodeQuaternion(qx, qy, qz, qw, 0) ?? 0) >>> 0;\n}\n\nexport function tryEncodeQuatOctXy1010R12(\n qx: number,\n qy: number,\n qz: number,\n qw: number,\n) {\n return encodeQuaternion(qx, qy, qz, qw, F32_EPSILON);\n}\n","import type { SplatExtra } from \"./defines\";\n\nexport const SH_KEYS = [\"sh1\", \"sh2\", \"sh3a\", \"sh3b\"] as const;\nexport const SH_ARRAY_COUNTS = [0, 1, 2, 4] as const;\n\n/** Merge cached min XYZ / max XYZ values without decoding records. */\nexport function unionSplatBounds(\n target: Float32Array,\n source: Float32Array,\n offset = 0,\n) {\n for (let axis = 0; axis < 3; axis++) {\n target[axis] = Math.min(target[axis], source[offset + axis]);\n target[axis + 3] = Math.max(target[axis + 3], source[offset + axis + 3]);\n }\n}\n\nexport function resetSplatBounds(bounds: Float32Array) {\n bounds.fill(Number.POSITIVE_INFINITY, 0, 3);\n bounds.fill(Number.NEGATIVE_INFINITY, 3, 6);\n}\n\nexport function getSplatShDegree(extra: SplatExtra) {\n return !extra.sh1 ? 0 : !extra.sh2 ? 1 : !extra.sh3a || !extra.sh3b ? 2 : 3;\n}\n\n/** Packed texture storage; capacity includes padding, but excludes sort centers. */\nexport function getSplatTextureBytes(capacity: number, numSh: number) {\n return capacity * (2 + SH_ARRAY_COUNTS[numSh]) * 16;\n}\n\n/** Retained CPU arrays, including sort centers and extra attribute buffers. */\nexport function getSplatByteLength(data: {\n splatArrays: readonly Uint32Array[];\n sortCenters?: Float32Array;\n sourceIds?: Uint32Array;\n centerOnlyBoundingBox?: Float32Array;\n boundingBox?: Float32Array;\n spatialBounds?: Float32Array;\n extra: SplatExtra;\n}) {\n let bytes =\n (data.sortCenters?.byteLength ?? 0) +\n (data.sourceIds?.byteLength ?? 0) +\n (data.centerOnlyBoundingBox?.byteLength ?? 0) +\n (data.boundingBox?.byteLength ?? 0) +\n (data.spatialBounds?.byteLength ?? 0);\n for (const array of data.splatArrays) bytes += array.byteLength;\n for (const array of Object.values(data.extra))\n bytes += array?.byteLength ?? 0;\n return bytes;\n}\n","import * as THREE from \"three\";\nimport { fromHalf, uintBitsToFloat } from \"../utils/numeric\";\nimport {\n decodeQuatOctXy1010R12ToArray,\n decodeSplatOpacity,\n} from \"./splatCodec\";\n\nexport function decodeSplat(\n splatArrays: [Uint32Array, Uint32Array],\n index: number,\n result = {\n center: new THREE.Vector3(),\n scales: new THREE.Vector3(),\n quaternion: new THREE.Quaternion(),\n color: new THREE.Color(),\n opacity: 0,\n },\n): {\n center: THREE.Vector3;\n scales: THREE.Vector3;\n quaternion: THREE.Quaternion;\n color: THREE.Color;\n opacity: number;\n} {\n const i4 = index * 4;\n const [splatA, splatB] = splatArrays;\n result.center.x = uintBitsToFloat(splatA[i4]);\n result.center.y = uintBitsToFloat(splatA[i4 + 1]);\n result.center.z = uintBitsToFloat(splatA[i4 + 2]);\n result.opacity = decodeSplatOpacity(splatA[i4 + 3]);\n result.color.r = fromHalf(splatB[i4] & 0xffff);\n result.color.g = fromHalf(splatB[i4] >>> 16);\n result.color.b = fromHalf(splatB[i4 + 1] & 0xffff);\n result.scales.x = Math.exp(fromHalf(splatB[i4 + 1] >>> 16));\n result.scales.y = Math.exp(fromHalf(splatB[i4 + 2] & 0xffff));\n result.scales.z = Math.exp(fromHalf(splatB[i4 + 2] >>> 16));\n decodeQuatOctXy1010R12(splatB[i4 + 3], result.quaternion);\n return result;\n}\n\nconst decodedQuaternion = [0, 0, 0, 1];\n\nexport function decodeQuatOctXy1010R12(\n encoded: number,\n out: THREE.Quaternion,\n): THREE.Quaternion {\n decodeQuatOctXy1010R12ToArray(encoded, decodedQuaternion);\n out.set(\n decodedQuaternion[0],\n decodedQuaternion[1],\n decodedQuaternion[2],\n decodedQuaternion[3],\n );\n return out;\n}\n","import * as THREE from \"three\";\n\nimport type {\n SplatFileResolver,\n SplatProgressEvent,\n} from \"../loaders/loadTypes\";\nimport type { SplatPostDecodeProgram } from \"../loaders/postDecode/program\";\nimport {\n type ReorderedSplatResult,\n SPLAT_BLOCKS_DISABLED,\n SPLAT_BOUNDS_BLOCK_SIZE,\n SPLAT_TEX_WIDTH_BITS,\n type SplatExtra,\n type SplatFileType,\n type SplatResult,\n} from \"./defines\";\nimport type { RaycastRangeCallback, SplatRaycastQuery } from \"./raycast\";\nimport { decodeShRgbToArray } from \"./splatCodec\";\nimport {\n SH_KEYS,\n getSplatByteLength,\n getSplatShDegree,\n resetSplatBounds,\n} from \"./splatData\";\nimport { getTextureSize } from \"./textureLayout\";\nimport { decodeSplat } from \"./unpack\";\n\ntype SplatShTextures = {\n sh1?: THREE.DataArrayTexture;\n sh2?: THREE.DataArrayTexture;\n sh3a?: THREE.DataArrayTexture;\n sh3b?: THREE.DataArrayTexture;\n};\n\nconst SH_COUNTS = [0, 3, 8, 15] as const;\n\ntype DecodedSplat = ReturnType<typeof decodeSplat>;\ntype DecodedSplatWithSh = DecodedSplat & { sh: THREE.Color[] };\n\nexport type SplatsOptions = {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n /** Resolve external SOG images or RAD chunks by metadata filename. */\n resolveFile?: SplatFileResolver;\n /** Declarative per-splat transform executed in the decode worker. */\n postDecode?: SplatPostDecodeProgram;\n onProgress?: (event: SplatProgressEvent) => void;\n};\n\ntype SplatsState = ReorderedSplatResult & {\n maxSplats: number;\n};\n\nfunction validateInitializationInputs(options: SplatsOptions) {\n if (\"splatArrays\" in options)\n throw new Error(\n \"splatArrays initialization is not supported; use url, file, or fileBytes\",\n );\n const inputs: string[] = [];\n if (options.url !== undefined) inputs.push(\"url\");\n if (options.file !== undefined) inputs.push(\"file\");\n if (options.fileBytes !== undefined) inputs.push(\"fileBytes\");\n if (inputs.length > 1) {\n throw new Error(\n `Splats initialization inputs are mutually exclusive; provide only one of url, file, or fileBytes (received: ${inputs.join(\", \")})`,\n );\n }\n return inputs.length > 0;\n}\n\nfunction createDecodedState(data: ReorderedSplatResult): SplatsState {\n const [first, second] = data.splatArrays;\n if (first.length !== second.length) {\n throw new Error(\"splatArrays must have the same length\");\n }\n if (first.length % 4 !== 0) {\n throw new Error(\"splatArrays must contain complete four-word records\");\n }\n\n const inputCapacity = first.length / 4;\n const numSplats = data.numSplats;\n if (\n !Number.isSafeInteger(numSplats) ||\n numSplats < 0 ||\n numSplats > inputCapacity\n ) {\n throw new Error(\"numSplats must be an integer within splatArrays\");\n }\n if (\n data.sortCenters !== undefined &&\n data.sortCenters.length < numSplats * 3\n ) {\n throw new Error(\"sortCenters is smaller than numSplats\");\n }\n if (data.sourceIds.length < numSplats)\n throw new Error(\"sourceIds is smaller than numSplats\");\n if (data.centerOnlyBoundingBox?.length !== 6)\n throw new Error(\"Decoded center bounds must contain six values\");\n if (data.boundingBox?.length !== 6)\n throw new Error(\"Decoded bounds must contain six values\");\n if (\n data.spatialBounds?.length !==\n Math.ceil(numSplats / SPLAT_BOUNDS_BLOCK_SIZE) * 6\n )\n throw new Error(\"Incorrect spatial bounds block length\");\n const maxSplats = getTextureSize(inputCapacity).maxSplats;\n let splatArrays = data.splatArrays;\n if (maxSplats !== inputCapacity) {\n splatArrays = [\n new Uint32Array(maxSplats * 4),\n new Uint32Array(maxSplats * 4),\n ];\n splatArrays[0].set(first);\n splatArrays[1].set(second);\n }\n return { ...data, maxSplats, splatArrays };\n}\n\nfunction createEmptyState(): SplatsState {\n const bounds = new Float32Array(6);\n resetSplatBounds(bounds);\n return {\n maxSplats: 0,\n numSplats: 0,\n splatArrays: [new Uint32Array(0), new Uint32Array(0)],\n sourceIds: new Uint32Array(0),\n spatialBounds: new Float32Array(0),\n centerOnlyBoundingBox: bounds,\n boundingBox: bounds.slice(),\n extra: {},\n };\n}\n\n/** An encoded splat source with two 16-byte texture records per splat. */\nexport class Splats {\n maxSplats = 0;\n numSplats = 0;\n private splatArrays: [Uint32Array, Uint32Array] = [\n new Uint32Array(0),\n new Uint32Array(0),\n ];\n private sortCenters?: Float32Array;\n protected sourceIds!: Uint32Array;\n protected centerOnlyBounds!: Float32Array;\n protected bounds!: Float32Array;\n private spatialBounds!: Float32Array;\n private extra: SplatExtra = {};\n\n initialized: Promise<Splats>;\n isInitialized = false;\n needsUpdate = true;\n\n private textures: [THREE.DataArrayTexture, THREE.DataArrayTexture];\n private shTextures: SplatShTextures = {};\n private loadController?: AbortController;\n\n constructor(options: SplatsOptions = {}) {\n this.textures = [Splats.emptyTexture, Splats.emptyTexture];\n this.initialized = Promise.resolve(this);\n this.initialize(options);\n }\n\n initialize(options: SplatsOptions = {}): Promise<Splats> {\n const isAsync = validateInitializationInputs(options);\n const state = createEmptyState();\n this.loadController?.abort();\n const controller = isAsync ? new AbortController() : undefined;\n this.loadController = controller;\n\n this.isInitialized = false;\n this.commitState(state);\n\n if (controller) {\n // Publish the readiness promise before starting the file load.\n this.initialized = Promise.resolve()\n .then(() => {\n controller.signal.throwIfAborted();\n return this.asyncInitialize(options, controller.signal);\n })\n .then((state) => {\n if (this.loadController === controller) {\n this.commitState(state);\n this.isInitialized = true;\n }\n return this;\n })\n .finally(() => {\n if (this.loadController === controller)\n this.loadController = undefined;\n });\n // Disposing may cancel a load whose readiness promise was not observed.\n void this.initialized.catch(() => {});\n } else {\n this.isInitialized = true;\n this.initialized = Promise.resolve(this);\n }\n\n return this.initialized;\n }\n\n private commitState(state: SplatsState) {\n this.disposeTextures();\n this.maxSplats = state.maxSplats;\n this.numSplats = state.numSplats;\n this.splatArrays = state.splatArrays;\n this.sortCenters = state.sortCenters;\n this.sourceIds = state.sourceIds;\n this.centerOnlyBounds = state.centerOnlyBoundingBox;\n this.bounds = state.boundingBox;\n this.spatialBounds = state.spatialBounds;\n this.extra = state.extra;\n this.needsUpdate = true;\n }\n\n /** @internal Adopt a loader result with precomputed bounds. */\n initializeDecoded(data: ReorderedSplatResult) {\n const state = createDecodedState(data);\n this.initialize();\n this.commitState(state);\n }\n\n private async asyncInitialize(\n options: SplatsOptions,\n signal: AbortSignal,\n ): Promise<SplatsState> {\n const { loadSplatData } = await import(\"../loaders/loadSplatData\");\n const decoded = await loadSplatData({ ...options, signal });\n return createDecodedState(decoded);\n }\n\n dispose() {\n this.loadController?.abort();\n this.loadController = undefined;\n this.isInitialized = false;\n this.commitState(createEmptyState());\n }\n\n private disposeTextures() {\n this.disposeMainTextures();\n for (const texture of Object.values(this.shTextures)) {\n texture?.dispose();\n }\n this.shTextures = {};\n }\n\n getNumSplats() {\n return this.numSplats;\n }\n\n /** @internal Copy cached local bounds into the target box. */\n getBoundingBox(centersOnly = true, target = new THREE.Box3()): THREE.Box3 {\n if (!this.isInitialized) throw new Error(\"Splats is not initialized\");\n const bounds = centersOnly ? this.centerOnlyBounds : this.bounds;\n target.min.fromArray(bounds, 0);\n target.max.fromArray(bounds, 3);\n return target;\n }\n\n getNumSh() {\n return getSplatShDegree(this.extra);\n }\n\n /** Current retained bytes for encoded Splat, sort-center, and SH arrays. */\n getByteLength() {\n return getSplatByteLength({\n splatArrays: this.splatArrays,\n sortCenters: this.sortCenters,\n sourceIds: this.sourceIds,\n centerOnlyBoundingBox: this.centerOnlyBounds,\n boundingBox: this.bounds,\n spatialBounds: this.spatialBounds,\n extra: this.extra,\n });\n }\n\n /** @internal Consume owned arrays for transfer to a streaming worker. */\n takeData(): SplatResult & { sourceIds: Uint32Array } {\n if (!this.isInitialized) throw new Error(\"Splats is not initialized\");\n const data = {\n numSplats: this.numSplats,\n splatArrays: this.splatArrays,\n sortCenters: this.sortCenters,\n sourceIds: this.sourceIds,\n centerOnlyBoundingBox: this.centerOnlyBounds,\n boundingBox: this.bounds,\n spatialBounds: this.spatialBounds,\n extra: this.extra,\n } satisfies SplatResult;\n this.dispose();\n return data;\n }\n\n /** Original source ID, retained across reordering and range extraction. */\n getSourceIndex(index: number) {\n if (!Number.isSafeInteger(index) || index < 0 || index >= this.numSplats)\n throw new Error(\"Invalid splat index\");\n return this.sourceIds[index];\n }\n\n getSplat(index: number): DecodedSplatWithSh;\n getSplat(index: number, includeSh: true): DecodedSplatWithSh;\n getSplat(index: number, includeSh: false): DecodedSplat;\n getSplat(index: number, includeSh: boolean): DecodedSplat;\n getSplat(index: number, includeSh = true) {\n if (index < 0 || index >= this.numSplats) {\n throw new Error(\"Invalid splat index\");\n }\n const splat = decodeSplat(this.splatArrays, index);\n return includeSh\n ? { ...splat, sh: decodeSplatSh(this.extra, index, this.getNumSh()) }\n : splat;\n }\n\n /** @internal Consecutive visible records surviving spatial block picking. */\n forEachRaycastRange(\n query: SplatRaycastQuery,\n callback: RaycastRangeCallback,\n ) {\n query.forEachRange(this.spatialBounds, this.numSplats, callback);\n }\n\n copySplatRecords(\n firstTarget: Uint32Array,\n secondTarget: Uint32Array,\n sourceStart: number,\n count: number,\n ) {\n const wordStart = sourceStart * 4;\n const wordEnd = wordStart + count * 4;\n firstTarget.set(this.splatArrays[0].subarray(wordStart, wordEnd));\n secondTarget.set(this.splatArrays[1].subarray(wordStart, wordEnd));\n }\n\n copySortCenters(target: Float32Array, targetStart: number, count: number) {\n if (count > this.numSplats || targetStart + count * 3 > target.length) {\n throw new Error(\"Invalid sort center copy range\");\n }\n target.set(this.getSortCenters().subarray(0, count * 3), targetStart);\n }\n\n private getSortCenters() {\n if (this.sortCenters) return this.sortCenters;\n const centers = new Float32Array(this.numSplats * 3);\n const [splatA, splatB] = this.splatArrays;\n const centerView = new Float32Array(\n splatA.buffer,\n splatA.byteOffset,\n splatA.length,\n );\n for (let index = 0; index < this.numSplats; index += 1) {\n const i3 = index * 3;\n const i4 = index * 4;\n const disabled =\n splatB[i4 + 1] >>> 16 === 0xfc00 && splatB[i4 + 2] === 0xfc00fc00;\n centers[i3] = disabled ? Number.NaN : centerView[i4];\n centers[i3 + 1] = disabled ? Number.NaN : centerView[i4 + 1];\n centers[i3 + 2] = disabled ? Number.NaN : centerView[i4 + 2];\n }\n this.sortCenters = centers;\n return centers;\n }\n\n forEachCenter(\n callback: (index: number, x: number, y: number, z: number) => void,\n ) {\n const centers = this.getSortCenters();\n for (let index = 0; index < this.numSplats; index += 1) {\n const i3 = index * 3;\n callback(index, centers[i3], centers[i3 + 1], centers[i3 + 2]);\n }\n }\n\n forEachSplat(\n callback: (\n index: number,\n center: THREE.Vector3,\n scales: THREE.Vector3,\n quaternion: THREE.Quaternion,\n opacity: number,\n color: THREE.Color,\n ) => void,\n ) {\n let splat: ReturnType<typeof decodeSplat> | undefined;\n for (let index = 0; index < this.numSplats; index += 1) {\n splat = decodeSplat(this.splatArrays, index, splat);\n callback(\n index,\n splat.center,\n splat.scales,\n splat.quaternion,\n splat.opacity,\n splat.color,\n );\n }\n }\n\n setTextureUniforms(uniforms: Record<string, THREE.IUniform>) {\n const [splats, splats2] = this.getSplatTextures();\n const sh = this.getShTextures();\n const height = (splats.image as { height: number }).height;\n const layerBits = SPLAT_TEX_WIDTH_BITS + Math.ceil(Math.log2(height));\n uniforms.sourceLayerBits.value = layerBits;\n uniforms.sourceLayerMask.value = 2 ** layerBits - 1;\n uniforms.sourceBlockBits.value = SPLAT_BLOCKS_DISABLED;\n uniforms.sourceBlocks.value = Splats.emptyTexture;\n uniforms.sourceOpacities.value = Splats.emptyTexture;\n uniforms.sourceIndexed.value = false;\n uniforms.sourceIndices.value = Splats.emptyTexture;\n uniforms.sourceSplats.value = splats;\n uniforms.sourceSplats2.value = splats2;\n uniforms.sh1Texture.value = sh.sh1 ?? Splats.emptyTexture;\n uniforms.sh2Texture.value = sh.sh2 ?? Splats.emptyTexture;\n uniforms.sh3TextureA.value = sh.sh3a ?? Splats.emptyTexture;\n uniforms.sh3TextureB.value = sh.sh3b ?? Splats.emptyTexture;\n this.needsUpdate = false;\n }\n\n private getSplatTextures() {\n if (this.maxSplats === 0 || this.splatArrays[0].length === 0) {\n return [Splats.emptyTexture, Splats.emptyTexture] as const;\n }\n\n if (this.textures[0] === Splats.emptyTexture) {\n const { width, height, depth } = getTextureSize(this.maxSplats);\n this.textures = [\n newUintArrayTexture(this.splatArrays[0], width, height, depth),\n newUintArrayTexture(this.splatArrays[1], width, height, depth),\n ];\n } else if (this.needsUpdate) {\n this.textures[0].needsUpdate = true;\n this.textures[1].needsUpdate = true;\n }\n return this.textures;\n }\n\n private disposeMainTextures() {\n for (const texture of this.textures) {\n if (texture !== Splats.emptyTexture) {\n texture.dispose();\n }\n }\n this.textures = [Splats.emptyTexture, Splats.emptyTexture];\n }\n\n private getShTextures(): SplatShTextures {\n for (const key of SH_KEYS) {\n this.shTextures[key] = this.ensureShTexture(key, this.shTextures[key]);\n }\n return this.shTextures;\n }\n\n private ensureShTexture(\n key: (typeof SH_KEYS)[number],\n current?: THREE.DataArrayTexture,\n ) {\n if (current) {\n if (this.needsUpdate) current.needsUpdate = true;\n return current;\n }\n const data = this.extra[key];\n if (!data) return undefined;\n const { width, height, depth, maxSplats } = getTextureSize(\n Math.max(1, data.length / 4),\n );\n let padded = data;\n if (data.length < maxSplats * 4) {\n padded = new Uint32Array(maxSplats * 4);\n padded.set(data);\n this.extra[key] = padded;\n }\n return newUintArrayTexture(padded, width, height, depth);\n }\n\n static emptyTexture = newUintArrayTexture(new Uint32Array(4), 1, 1, 1);\n}\n\nfunction newUintArrayTexture(\n data: Uint32Array,\n width: number,\n height: number,\n depth: number,\n) {\n const texture = new THREE.DataArrayTexture(data, width, height, depth);\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n\nfunction decodeSplatSh(extra: SplatExtra, index: number, degree: number) {\n const count = SH_COUNTS[degree];\n const result = new Array<THREE.Color>(count);\n const rgb = [0, 0, 0];\n const base = index * 4;\n for (let coefficient = 0; coefficient < count; coefficient += 1) {\n const data = extra[SH_KEYS[coefficient >> 2]];\n const word = data?.[base + (coefficient & 3)] ?? 0;\n decodeShRgbToArray(word, rgb);\n result[coefficient] = new THREE.Color(rgb[0], rgb[1], rgb[2]);\n }\n return result;\n}\n","import type { Vector3 } from \"three\";\nimport { SPLAT_BOUNDS_BLOCK_SIZE } from \"./defines\";\n\n/** Picking uses the same f32 ray and world-distance parameter as WASM. */\nexport class SplatRaycastQuery {\n private readonly origin: Float32Array;\n private readonly direction: Float32Array;\n private readonly near: number;\n private readonly far: number;\n\n constructor(origin: Vector3, direction: Vector3, near: number, far: number) {\n this.origin = Float32Array.of(origin.x, origin.y, origin.z);\n this.direction = Float32Array.of(direction.x, direction.y, direction.z);\n this.near = Math.fround(near);\n this.far = Math.fround(far);\n }\n\n /** Visit consecutive candidate records in one Morton-ordered chunk. */\n forEachRange(\n bounds: Float32Array,\n count: number,\n callback: RaycastRangeCallback,\n ) {\n let start = -1;\n for (let base = 0; base < count; base += SPLAT_BOUNDS_BLOCK_SIZE) {\n if (this.intersects(bounds, (base / SPLAT_BOUNDS_BLOCK_SIZE) * 6)) {\n if (start < 0) start = base;\n } else if (start >= 0) {\n callback(start, base - start);\n start = -1;\n }\n }\n if (start >= 0) callback(start, count - start);\n }\n\n private intersects(bounds: Float32Array, offset: number) {\n if (bounds[offset] > bounds[offset + 3]) return false;\n // Invalid bounds retain the per-Splat path.\n for (let i = offset; i < offset + 6; i++) {\n if (!Number.isFinite(bounds[i])) return true;\n }\n let near = this.near;\n let far = this.far;\n for (let axis = 0; axis < 3; axis++) {\n const origin = this.origin[axis];\n const direction = this.direction[axis];\n const min = bounds[offset + axis];\n const max = bounds[offset + axis + 3];\n // Enclose rounding in the f32 sphere/ellipsoid arithmetic, including\n // cancellation for distant rays and very thin Splats.\n const padding =\n 1e-5 * (Math.abs(origin) + Math.max(Math.abs(min), Math.abs(max)));\n if (direction === 0) {\n if (origin < min - padding || origin > max + padding) return false;\n } else {\n const a = (min - padding - origin) / direction;\n const b = (max + padding - origin) / direction;\n near = Math.max(near, Math.min(a, b));\n far = Math.min(far, Math.max(a, b));\n if (near > far) return false;\n }\n }\n return true;\n }\n}\n\nexport type RaycastRangeCallback = (start: number, count: number) => void;\n","import * as THREE from \"three\";\n\nimport {\n get_raycast_buffer,\n get_raycast_buffer2,\n get_raycast_indices,\n raycast_splat_buffers,\n} from \"gaussian-splat-rs\";\nimport { Splats } from \"../data/Splats\";\nimport type { SplatFileType } from \"../data/defines\";\nimport { SplatRaycastQuery } from \"../data/raycast\";\nimport type {\n SplatFileResolver,\n SplatProgressEvent,\n} from \"../loaders/loadTypes\";\nimport type { SplatPostDecodeProgram } from \"../loaders/postDecode/program\";\nimport * as wasm from \"../runtime/wasm\";\nimport { SplatEdit, SplatEditSdf, SplatEdits } from \"./SplatEdit\";\n\nlet raycastVisibleIndices = new Uint32Array(0);\nconst raycastWorldToMesh = new THREE.Matrix4();\nconst raycastDirectionMatrix = new THREE.Matrix3();\nconst raycastOrigin = new THREE.Vector3();\nconst raycastDirection = new THREE.Vector3();\n\nexport type SplatMeshOptions = {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n resolveFile?: SplatFileResolver;\n /** Declarative per-splat transform executed in the decode worker. */\n postDecode?: SplatPostDecodeProgram;\n splats?: Splats;\n onProgress?: (event: SplatProgressEvent) => void;\n onLoad?: (mesh: SplatMesh) => Promise<void> | void;\n editable?: boolean;\n raycastable?: boolean;\n minRaycastOpacity?: number;\n onFrame?: (context: {\n mesh: SplatMesh;\n time: number;\n deltaTime: number;\n }) => void;\n};\n\nexport type SplatMeshFrameContext = {\n time: number;\n deltaTime: number;\n globalEdits: SplatEdit[];\n};\n\nexport type SplatIntersection = THREE.Intersection<SplatMesh> & {\n /** Current readable index in this mesh's Splats. */\n index: number;\n /** Original file index; for streamed SOG, relative to this batch's chunk. */\n sourceIndex: number;\n};\n\nfunction validateSplatMeshInitializationInputs(options: SplatMeshOptions) {\n const inputs: string[] = [];\n if (options.url !== undefined) inputs.push(\"url\");\n if (options.file !== undefined) inputs.push(\"file\");\n if (options.fileBytes !== undefined) inputs.push(\"fileBytes\");\n if (options.splats !== undefined) inputs.push(\"splats\");\n if (inputs.length > 1) {\n throw new Error(\n `SplatMesh initialization inputs are mutually exclusive; provide only one of url, file, fileBytes, or splats (received: ${inputs.join(\", \")})`,\n );\n }\n}\n\n/** A scene object backed by a fixed encoded splat source and RGBA SDF edits. */\nexport class SplatMesh extends THREE.Object3D {\n private lastInitialization?: Promise<Splats>;\n private readiness!: Promise<SplatMesh>;\n private onLoad?: SplatMeshOptions[\"onLoad\"];\n\n get isInitialized() {\n return this.splats?.isInitialized ?? false;\n }\n\n get initialized(): Promise<SplatMesh> {\n const source = this.splats;\n if (!source) return Promise.resolve(this);\n const pending = source.initialized;\n if (pending !== this.lastInitialization) {\n this.lastInitialization = pending;\n this.readiness = pending.then(\n async () => {\n if (pending !== this.splats?.initialized) return this.initialized;\n this.numSplats = source.getNumSplats();\n this.updateMappingVersion();\n await this.onLoad?.(this);\n return this;\n },\n (error) => {\n if (pending !== this.splats?.initialized) return this.initialized;\n throw error;\n },\n );\n void this.readiness.catch(() => {});\n }\n return this.readiness;\n }\n\n splats?: Splats;\n\n numSplats = 0;\n recolor = new THREE.Color(1, 1, 1);\n opacity = 1;\n maxSh = 3;\n\n edits: SplatEdit[] | null = null;\n editable: boolean;\n raycastable: boolean;\n minRaycastOpacity: number;\n sdfEdits: SplatEdits | null = null;\n\n onFrame?: SplatMeshOptions[\"onFrame\"];\n\n version = 0;\n sortVersion = 0;\n centerVersion = 0;\n mappingVersion = 0;\n\n private lastSplats?: Splats;\n private lastNumSplats = -1;\n private lastMaxSh = -1;\n private lastMatrixWorld = new THREE.Matrix4();\n private hasLastMatrixWorld = false;\n private lastRecolor = new THREE.Vector4().setScalar(Number.NaN);\n private sdfCoordinateOrigin = new THREE.Vector3();\n\n constructor(options: SplatMeshOptions = {}) {\n super();\n\n if (options.splats && !(options.splats instanceof Splats)) {\n throw new TypeError(\"SplatMesh splats must be a Splats instance\");\n }\n validateSplatMeshInitializationInputs(options);\n this.splats =\n options.splats ??\n new Splats({\n url: options.url,\n file: options.file,\n fileBytes: options.fileBytes,\n fileType: options.fileType,\n fileName: options.fileName,\n resolveFile: options.resolveFile,\n postDecode: options.postDecode,\n onProgress: options.onProgress,\n });\n\n this.numSplats = this.splats.getNumSplats();\n this.editable = options.editable ?? true;\n this.raycastable = options.raycastable ?? true;\n this.minRaycastOpacity = options.minRaycastOpacity ?? 0.15;\n this.onFrame = options.onFrame;\n\n this.onLoad = options.onLoad;\n void this.initialized;\n }\n\n forEachSplat(\n callback: (\n index: number,\n center: THREE.Vector3,\n scales: THREE.Vector3,\n quaternion: THREE.Quaternion,\n opacity: number,\n color: THREE.Color,\n ) => void,\n ) {\n this.splats?.forEachSplat(callback);\n }\n\n dispose() {\n super.dispose();\n\n this.sdfEdits?.dispose();\n this.sdfEdits = null;\n this.splats?.dispose();\n this.splats = undefined;\n this.numSplats = 0;\n this.updateMappingVersion();\n }\n\n /** Copy cached local bounds; false includes scale/rotation and shape at source alpha 0.01. */\n getBoundingBox(centersOnly = true, target = new THREE.Box3()): THREE.Box3 {\n if (!this.isInitialized) {\n throw new Error(\n \"Cannot get bounding box before SplatMesh is initialized\",\n );\n }\n return (\n this.splats?.getBoundingBox(centersOnly, target) ?? target.makeEmpty()\n );\n }\n\n frameUpdate(\n { time, deltaTime, globalEdits }: SplatMeshFrameContext,\n callbacks = true,\n ) {\n if (callbacks) this.onFrame?.({ mesh: this, time, deltaTime });\n\n const source = this.splats;\n if (!source) {\n return;\n }\n // Follow source reinitialization even when callers only keep rendering.\n void this.initialized;\n let updated = false;\n let centersUpdated = false;\n let transformUpdated = false;\n const count = source.getNumSplats();\n if (source !== this.lastSplats) {\n this.lastSplats = source;\n updated = true;\n centersUpdated = true;\n }\n if (count !== this.lastNumSplats) {\n this.lastNumSplats = count;\n this.numSplats = count;\n this.mappingVersion += 1;\n updated = true;\n centersUpdated = true;\n }\n if (source.needsUpdate) {\n updated = true;\n centersUpdated = true;\n }\n if (this.maxSh !== this.lastMaxSh) {\n this.lastMaxSh = this.maxSh;\n updated = true;\n }\n\n this.updateWorldMatrix(true, false);\n if (\n !this.hasLastMatrixWorld ||\n !this.lastMatrixWorld.equals(this.matrixWorld)\n ) {\n this.lastMatrixWorld.copy(this.matrixWorld);\n this.hasLastMatrixWorld = true;\n updated = true;\n transformUpdated = true;\n }\n\n const recolor = new THREE.Vector4(\n this.recolor.r,\n this.recolor.g,\n this.recolor.b,\n THREE.MathUtils.clamp(this.opacity, 0, 1),\n );\n if (!recolor.equals(this.lastRecolor)) {\n this.lastRecolor.copy(recolor);\n updated = true;\n }\n\n const edits = new Set<SplatEdit>();\n if (this.editable) {\n for (const edit of globalEdits) edits.add(edit);\n if (this.edits) {\n for (const edit of this.edits) edits.add(edit);\n } else {\n this.traverseVisible((node) => {\n if (node instanceof SplatEdit) edits.add(node);\n });\n }\n }\n const orderedEdits = Array.from(edits).sort(\n (left, right) => left.ordering - right.ordering,\n );\n const groups = orderedEdits.map((edit) => {\n if (edit.sdfs) return { edit, sdfs: edit.sdfs };\n const sdfs: SplatEditSdf[] = [];\n edit.traverseVisible((node) => {\n if (node instanceof SplatEditSdf) sdfs.push(node);\n });\n return { edit, sdfs };\n });\n\n if (groups.length > 0 && !this.sdfEdits) {\n this.sdfEdits = new SplatEdits({\n maxEdits: groups.length,\n maxSdfs: groups.reduce((total, group) => total + group.sdfs.length, 0),\n });\n updated = true;\n }\n const sdfCoordinateOrigin = this.sdfCoordinateOrigin.setFromMatrixPosition(\n this.matrixWorld,\n );\n if (this.sdfEdits?.update(groups, sdfCoordinateOrigin).updated) {\n // RGBA-only SDF changes preserve centers and their existing sort order.\n updated = true;\n }\n\n if (updated) {\n this.version += 1;\n if (centersUpdated || transformUpdated) this.sortVersion += 1;\n if (centersUpdated) this.centerVersion += 1;\n }\n }\n\n updateVersion({ sort = true }: { sort?: boolean } = {}) {\n this.version += 1;\n if (sort) {\n this.sortVersion += 1;\n this.centerVersion += 1;\n }\n }\n\n updateMappingVersion() {\n this.mappingVersion += 1;\n this.updateVersion();\n }\n\n set needsUpdate(value: boolean) {\n if (value) this.updateVersion();\n }\n\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n if (!wasm.isInitialized() || !this.raycastable || !this.splats) {\n return;\n }\n\n const { near, far, ray } = raycaster;\n if (\n this.numSplats === 0 ||\n !Number.isFinite(this.minRaycastOpacity) ||\n this.minRaycastOpacity >= 1 ||\n near > far\n ) {\n return;\n }\n const worldToMesh = raycastWorldToMesh.copy(this.matrixWorld).invert();\n const origin = raycastOrigin.copy(ray.origin).applyMatrix4(worldToMesh);\n const direction = raycastDirection\n .copy(ray.direction)\n .applyMatrix3(raycastDirectionMatrix.setFromMatrix4(worldToMesh));\n const buffer = get_raycast_buffer();\n const buffer2 = get_raycast_buffer2();\n const capacity = buffer.length / 4;\n const splats = this.splats;\n\n if (raycastVisibleIndices.length !== capacity)\n raycastVisibleIndices = new Uint32Array(capacity);\n let count = 0;\n const flush = () => {\n const distances = raycast_splat_buffers(\n origin.x,\n origin.y,\n origin.z,\n direction.x,\n direction.y,\n direction.z,\n this.minRaycastOpacity,\n near,\n far,\n count,\n );\n const hitIndices = get_raycast_indices();\n\n for (let index = 0; index < distances.length; index += 1) {\n const distance = distances[index];\n const splatIndex = raycastVisibleIndices[hitIndices[index]];\n const hit: SplatIntersection = {\n distance,\n point: ray.at(distance, new THREE.Vector3()),\n object: this,\n index: splatIndex,\n sourceIndex: splats.getSourceIndex(splatIndex),\n };\n intersects.push(hit);\n }\n count = 0;\n };\n const query = new SplatRaycastQuery(origin, direction, near, far);\n splats.forEachRaycastRange(query, (start, length) => {\n for (let base = start; base < start + length; ) {\n const copied = Math.min(capacity - count, start + length - base);\n splats.copySplatRecords(\n buffer.subarray(count * 4),\n buffer2.subarray(count * 4),\n base,\n copied,\n );\n for (let i = 0; i < copied; i++)\n raycastVisibleIndices[count + i] = base + i;\n count += copied;\n base += copied;\n if (count === capacity) flush();\n }\n });\n if (count) flush();\n }\n}\n","import * as THREE from \"three\";\n\ntype WebGPURenderer = import(\"three/webgpu\").WebGPURenderer;\n\nexport type GaussianSplatCompatibleRenderer =\n | THREE.WebGLRenderer\n | WebGPURenderer;\n\nexport function isWebGPURenderer(\n renderer: GaussianSplatCompatibleRenderer,\n): renderer is WebGPURenderer {\n return \"isWebGPURenderer\" in renderer && renderer.isWebGPURenderer === true;\n}\n\nexport function usesNativeWebGPU(\n renderer: GaussianSplatCompatibleRenderer,\n): boolean {\n return (\n isWebGPURenderer(renderer) &&\n renderer.coordinateSystem === THREE.WebGPUCoordinateSystem\n );\n}\n\n/**\n * The eyes of a WebXR camera, or the camera itself. An ArrayCamera without\n * eyes draws as a single view.\n */\nexport function getViews(camera: THREE.Camera): THREE.Camera[] {\n const array = camera as THREE.ArrayCamera;\n return array.isArrayCamera && array.cameras.length > 0\n ? array.cameras\n : [camera];\n}\n\nconst viewVectorTmp = new THREE.Vector3();\n\n/**\n * Stores the views' mean position and forward direction: the camera's pose,\n * or for WebXR eyes the shared head. Reads world matrices as Three composed\n * them with any camera rig.\n */\nexport function getMeanViewPose(\n views: readonly THREE.Camera[],\n position: THREE.Vector3,\n direction: THREE.Vector3,\n) {\n position.set(0, 0, 0);\n direction.set(0, 0, 0);\n for (const view of views) {\n position.add(viewVectorTmp.setFromMatrixPosition(view.matrixWorld));\n direction.add(\n viewVectorTmp.setFromMatrixColumn(view.matrixWorld, 2).normalize(),\n );\n }\n position.divideScalar(views.length);\n direction.normalize().negate();\n}\n\nexport function getRenderFrame(renderer: GaussianSplatCompatibleRenderer) {\n return isWebGPURenderer(renderer)\n ? renderer.info.render.calls\n : renderer.info.render.frame;\n}\n\ntype XRRenderTarget = THREE.RenderTarget & { isXRRenderTarget?: boolean };\n\nexport function isXRRenderTarget(\n renderTarget: THREE.RenderTarget | null,\n): boolean {\n return (renderTarget as XRRenderTarget | null)?.isXRRenderTarget === true;\n}\n\nexport function assertSupportedRenderer(\n renderer: GaussianSplatCompatibleRenderer,\n) {\n if (!isWebGPURenderer(renderer)) return;\n if (renderer.initialized !== true) {\n throw new Error(\n \"Initialize WebGPURenderer with await renderer.init() before using Gaussian Splat Lite\",\n );\n }\n const backend = renderer.backend as {\n isWebGPUBackend?: boolean;\n isWebGLBackend?: boolean;\n };\n if (backend.isWebGPUBackend !== true && backend.isWebGLBackend !== true) {\n throw new Error(\"Gaussian Splat Lite requires a WebGPU or WebGL backend\");\n }\n}\n\nexport function setRendererRenderTarget(\n renderer: GaussianSplatCompatibleRenderer,\n target: THREE.RenderTarget | null,\n activeCubeFace?: number,\n activeMipmapLevel?: number,\n) {\n renderer.setRenderTarget(\n target as THREE.WebGLRenderTarget | null,\n activeCubeFace,\n activeMipmapLevel,\n );\n}\n","import type { Camera, Texture } from \"three\";\nimport * as TSL from \"three/tsl\";\nimport type {\n ComputeNode,\n IndirectStorageBufferAttribute,\n Node,\n NodeBuilder,\n StorageBufferAttribute,\n StorageBufferNode,\n TextureNode,\n WorkgroupInfoNode,\n} from \"three/webgpu\";\n\n// @types/three r186 omits these fluent operations. Keep the additions on\n// interfaces used by these shaders, preserving their result types.\ndeclare module \"three/src/nodes/core/Node.js\" {\n interface IntegerExtensions<TInteger> {\n min(value: Node<TInteger> | number): Node<TInteger>;\n max(value: Node<TInteger> | number): Node<TInteger>;\n }\n interface IntOrVecExtensions<TNodeType> {\n shiftRight(value: Node<TNodeType> | number): Node<TNodeType>;\n clamp(low: Node<TNodeType>, high: Node<TNodeType>): Node<TNodeType>;\n }\n interface NumOrBoolVec4Extensions<TNumOrBool> {\n element(index: Node<\"int\"> | Node<\"uint\"> | number): Node<TNumOrBool>;\n }\n interface Mat4Extensions {\n element(index: Node<\"int\"> | Node<\"uint\"> | number): Node<\"vec4\">;\n }\n interface FloatOrVecExtensions<TNodeType> {\n negateAssign(): Node<TNodeType>;\n }\n}\n\ntype FloatToUint = {\n float: \"uint\";\n vec2: \"uvec2\";\n vec3: \"uvec3\";\n vec4: \"uvec4\";\n};\ntype UintToFloat = {\n uint: \"float\";\n uvec2: \"vec2\";\n uvec3: \"vec3\";\n uvec4: \"vec4\";\n};\ntype UintWorkgroup = WorkgroupInfoNode & {\n element(index: Node<\"uint\"> | Node<\"int\"> | number): Node<\"uint\">;\n setName(name: string): UintWorkgroup;\n};\n\n// Only override incomplete declarations; every other export keeps Three's\n// original overloads. These assertions do not wrap or replace runtime nodes.\ntype Compatibility = {\n convertColorSpace(\n value: Node<\"vec4\">,\n source: string,\n target: string,\n ): Node<\"vec4\">;\n floatBitsToUint<T extends keyof FloatToUint>(\n value: Node<T>,\n ): Node<FloatToUint[T]>;\n uintBitsToFloat<T extends keyof UintToFloat>(\n value: Node<T>,\n ): Node<UintToFloat[T]>;\n packHalf2x16(value: Node<\"vec2\">): Node<\"uint\">;\n unpackHalf2x16(value: Node<\"uint\">): Node<\"vec2\">;\n packSnorm2x16(value: Node<\"vec2\">): Node<\"uint\">;\n unpackSnorm2x16(value: Node<\"uint\">): Node<\"vec2\">;\n storage(\n value: StorageBufferAttribute,\n type: \"uint\",\n count?: number,\n ): StorageBufferNode<\"uint\">;\n workgroupArray(type: \"uint\", count: number): UintWorkgroup;\n builtin(name: \"gl_ViewID_OVR\"): Node<\"uint\">;\n countOneBits(value: Node<\"uint\">): Node<\"uint\">;\n ivec2: typeof TSL.ivec2 &\n ((x: Node<\"uint\">, y: Node<\"uint\">) => Node<\"ivec2\">);\n ivec3: typeof TSL.ivec3 &\n ((x: Node<\"uint\">, y: Node<\"uint\">, z: Node<\"uint\">) => Node<\"ivec3\">);\n Loop: typeof TSL.Loop &\n (<Name extends string, Type extends \"int\" | \"uint\">(\n params: {\n name: Name;\n type: Type;\n start: Node<Type>;\n end: Node<Type>;\n condition: string;\n },\n callback: (inputs: Record<Name, Node<Type>>) => void,\n ) => ReturnType<typeof TSL.Loop>);\n};\n\nexport const N = TSL as unknown as Omit<typeof TSL, keyof Compatibility> &\n Compatibility;\n\n/** Packed integer texture loads are incorrectly declared as vec4 upstream. */\nexport function uintTexture(texture: Texture): TextureNode<\"uvec4\"> {\n return TSL.texture<\"uvec4\">(texture).setSampler(false);\n}\n\n/** NodeBuilder.camera is present when building a material shader. */\nexport function materialCamera(builder: NodeBuilder): Camera {\n return (builder as NodeBuilder & { camera: Camera }).camera;\n}\n\n/** r186 supports an indirect attribute, but its declaration lists only counts. */\nexport function setIndirectDispatch(\n node: ComputeNode,\n dispatch: IndirectStorageBufferAttribute,\n) {\n (node as { dispatchSize: unknown }).dispatchSize = dispatch;\n}\n","import * as THREE from \"three\";\nimport * as TSL from \"three/tsl\";\nimport {\n type Node,\n NodeUpdateType,\n type TextureNode,\n type UniformNode,\n} from \"three/webgpu\";\nimport {\n SPLAT_TEX_HEIGHT_BITS,\n SPLAT_TEX_WIDTH_BITS,\n} from \"../../data/defines\";\nimport type { Uniforms } from \"../uniforms\";\n\nimport { N, uintTexture } from \"./tslCompat\";\nexport { N } from \"./tslCompat\";\n\nconst SPLAT_TEX_LAYER_BITS = SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS;\n\nconst SPLAT_TEX_WIDTH_MASK = (1 << SPLAT_TEX_WIDTH_BITS) - 1;\n\nconst SPLAT_TEX_HEIGHT_MASK = (1 << SPLAT_TEX_HEIGHT_BITS) - 1;\n\nexport const E = Math.E;\n\nexport type UniformType =\n | \"bool\"\n | \"float\"\n | \"int\"\n | \"uint\"\n | \"vec2\"\n | \"vec3\"\n | \"vec4\"\n | \"mat3\"\n | \"mat4\";\n\nexport function uniformBinding<Type extends UniformType>(\n uniforms: Uniforms,\n name: string,\n type: Type,\n): UniformNode<Type, unknown> {\n const uniform = TSL.uniform as <T extends UniformType>(\n value: unknown,\n type: T,\n ) => UniformNode<T, unknown>;\n return uniform(uniforms[name].value, type).onObjectUpdate(\n () => uniforms[name].value,\n );\n}\n\nexport function textureBinding(\n uniforms: Uniforms,\n name: string,\n array = false,\n) {\n const data = new Uint32Array(4);\n const placeholder = array\n ? new THREE.DataArrayTexture(data, 1, 1, 1)\n : new THREE.DataTexture(data, 1, 1);\n placeholder.format = THREE.RGBAIntegerFormat;\n placeholder.type = THREE.UnsignedIntType;\n placeholder.magFilter = THREE.NearestFilter;\n placeholder.minFilter = THREE.NearestFilter;\n placeholder.generateMipmaps = false;\n placeholder.needsUpdate = true;\n\n const getTexture = () => uniforms[name].value as THREE.Texture;\n const binding = uintTexture(placeholder).onObjectUpdate(getTexture);\n // Dynamic bindings can temporarily share an empty texture before diverging.\n // Keep them distinct when a pipeline rebuilds the material shader.\n binding.getUniformHash = () => binding.uuid;\n return binding;\n}\n\nexport function load2D<T extends TextureNode<unknown>>(\n binding: T,\n coord: Node<\"ivec2\">,\n): T {\n const texel = binding.load(coord);\n texel.updateMatrix = false;\n return updateTextureLoad(binding, texel);\n}\n\nexport function loadArray<T extends TextureNode<unknown>>(\n binding: T,\n coord: Node<\"ivec3\">,\n): T {\n return updateTextureLoad(binding, binding.load(coord.xy).depth(coord.z));\n}\n\nfunction updateTextureLoad<T extends TextureNode<unknown>>(\n binding: T,\n texel: T,\n) {\n texel.getUniformHash = (builder) => binding.getUniformHash(builder);\n texel.updateBeforeType = NodeUpdateType.OBJECT;\n texel.updateBefore = (frame) => {\n // Bind the real texture before r186's texture update or r187's shared\n // uniforms derive the GL render-target Y flip.\n frame.updateNode(binding);\n return undefined;\n };\n return texel;\n}\n\nexport const splatTexCoord = N.Fn(([index]: [Node<\"uint\">]) => {\n const value = N.uint(index);\n return N.ivec3(\n N.int(value.bitAnd(SPLAT_TEX_WIDTH_MASK)),\n N.int(value.shiftRight(SPLAT_TEX_WIDTH_BITS).bitAnd(SPLAT_TEX_HEIGHT_MASK)),\n N.int(value.shiftRight(SPLAT_TEX_LAYER_BITS)),\n );\n});\n\nexport const quatVec = N.Fn(\n ([quaternion, vector]: [Node<\"vec4\">, Node<\"vec3\">]) => {\n const t = quaternion.xyz.cross(vector).mul(2);\n return vector.add(quaternion.w.mul(t)).add(quaternion.xyz.cross(t));\n },\n);\n\nexport const quatQuat = N.Fn(\n ([first, second]: [Node<\"vec4\">, Node<\"vec4\">]) => {\n return N.vec4(\n first.w\n .mul(second.x)\n .add(first.x.mul(second.w))\n .add(first.y.mul(second.z))\n .sub(first.z.mul(second.y)),\n first.w\n .mul(second.y)\n .sub(first.x.mul(second.z))\n .add(first.y.mul(second.w))\n .add(first.z.mul(second.x)),\n first.w\n .mul(second.z)\n .add(first.x.mul(second.y))\n .sub(first.y.mul(second.x))\n .add(first.z.mul(second.w)),\n first.w\n .mul(second.w)\n .sub(first.x.mul(second.x))\n .sub(first.y.mul(second.y))\n .sub(first.z.mul(second.z)),\n );\n },\n);\n\nexport const decodeCenter = N.Fn(([data]: [Node<\"uvec4\">]) => {\n return N.uintBitsToFloat(data.xyz);\n});\n\nexport const decodeAlphaShape = N.Fn(([data]: [Node<\"uvec4\">]) => {\n return N.unpackHalf2x16(data.w);\n});\n\nexport const decodeRgba = N.Fn(\n ([data, alpha]: [Node<\"uvec4\">, Node<\"float\">]) => {\n return N.vec4(N.unpackHalf2x16(data.x), N.unpackHalf2x16(data.y).x, alpha);\n },\n);\n\nexport const decodeLnScales = N.Fn(([data]: [Node<\"uvec4\">]) => {\n return N.vec3(N.unpackHalf2x16(data.y).y, N.unpackHalf2x16(data.z));\n});\n\nexport const decodeQuaternion = N.Fn(([encodedValue]: [Node<\"uint\">]) => {\n const encoded = N.uint(encodedValue);\n const quantU = encoded.bitAnd(0x3ff);\n const quantV = encoded.shiftRight(10).bitAnd(0x3ff);\n const angleInt = encoded.shiftRight(20);\n const folded = N.vec2(N.float(quantU), N.float(quantV))\n .div(1023)\n .mul(2)\n .sub(1);\n const axis = N.vec3(\n folded,\n N.float(1).sub(folded.x.abs()).sub(folded.y.abs()),\n ).toVar();\n const t = axis.z.negate().max(0);\n axis.x.addAssign(N.select(axis.x.greaterThanEqual(0), t.negate(), t));\n axis.y.addAssign(N.select(axis.y.greaterThanEqual(0), t.negate(), t));\n axis.assign(axis.normalize());\n\n const halfTheta = N.float(angleInt)\n .div(4095)\n .mul(Math.PI * 0.5);\n return N.vec4(axis.mul(halfTheta.sin()), halfTheta.cos());\n});\n","import type { Node } from \"three/webgpu\";\nimport { SPLAT_TEX_WIDTH, SPLAT_TEX_WIDTH_BITS } from \"../../data/defines\";\nimport type { Uniforms } from \"../uniforms\";\nimport {\n E,\n N,\n type UniformType,\n decodeAlphaShape,\n decodeCenter,\n decodeLnScales,\n decodeQuaternion,\n decodeRgba,\n load2D,\n loadArray,\n quatQuat,\n quatVec,\n splatTexCoord,\n textureBinding,\n uniformBinding,\n} from \"./shaderUtils\";\n\n// Finite sentinel for empty/unbounded SDFs. Runtime infinity arithmetic is not\n// portable in WGSL, and smooth ALL shapes otherwise evaluate exp(inf - inf).\nconst SDF_DISTANCE_LIMIT = 1e20;\n\ntype ShInputs = [\n first: Node<\"uvec4\">,\n second: Node<\"uvec4\">,\n direction: Node<\"vec3\">,\n];\n\ntype DeferredColor = {\n coord: Node<\"ivec3\">;\n center: Node<\"vec3\">;\n scale: Node<\"vec3\">;\n offset: Node<\"vec3\">;\n};\n\nconst encodeQuaternion = N.Fn(([input]: [Node<\"vec4\">]) => {\n const quaternion = N.select(input.w.lessThan(0), input.negate(), input);\n const theta = quaternion.w.clamp(0, 1).acos().mul(2);\n const sum = quaternion.x\n .abs()\n .add(quaternion.y.abs())\n .add(quaternion.z.abs());\n const projected = N.select(\n sum.lessThan(1e-6),\n N.vec2(1, 0),\n quaternion.xy.div(sum.max(1e-6)),\n ).toVar();\n N.If(quaternion.z.lessThan(0), () => {\n const oldX = projected.x.toVar();\n projected.x.assign(\n N.float(1)\n .sub(projected.y.abs())\n .mul(N.select(projected.x.greaterThanEqual(0), 1, -1)),\n );\n projected.y.assign(\n N.float(1)\n .sub(oldX.abs())\n .mul(N.select(projected.y.greaterThanEqual(0), 1, -1)),\n );\n });\n\n const quantized = projected\n .mul(0.5)\n .add(0.5)\n .mul(1023)\n .round()\n .clamp(0, 1023);\n const quantU = N.uint(quantized.x);\n const quantV = N.uint(quantized.y);\n const angle = N.uint(theta.div(Math.PI).mul(4095).round().clamp(0, 4095));\n return angle.shiftLeft(20).bitOr(quantV.shiftLeft(10)).bitOr(quantU);\n});\n\nconst decodeShRgb = N.Fn(([encoded]: [Node<\"uint\">]) => {\n const biasedBase = encoded.shiftRight(27).bitAnd(0x1f);\n const divisor = N.uintBitsToFloat(biasedBase.add(112).shiftLeft(23)).div(255);\n const rgb = N.vec3(\n N.float(encoded.bitAnd(0xff)),\n N.float(encoded.shiftRight(8).bitAnd(0xff)),\n N.float(encoded.shiftRight(16).bitAnd(0xff)),\n )\n .mul(divisor)\n .toVar();\n return N.vec3(\n N.select(\n encoded.bitAnd(0x1000000).notEqual(N.uint(0)),\n rgb.x.negate(),\n rgb.x,\n ),\n N.select(\n encoded.bitAnd(0x2000000).notEqual(N.uint(0)),\n rgb.y.negate(),\n rgb.y,\n ),\n N.select(\n encoded.bitAnd(0x4000000).notEqual(N.uint(0)),\n rgb.z.negate(),\n rgb.z,\n ),\n );\n}).setLayout({\n name: \"gslDecodeShRgb\",\n type: \"vec3\",\n inputs: [{ name: \"encoded\", type: \"uint\" }],\n});\n\nconst decodeSemanticOpacity = N.Fn(\n ([alpha, shapeAmount]: [Node<\"float\">, Node<\"float\">]) => {\n const result = alpha.toVar();\n N.If(shapeAmount.greaterThan(0), () => {\n const kernelShape = shapeAmount.min(1).mul(4).add(1);\n const kernelOpacity = kernelShape.mul(kernelShape).sub(1).div(E).exp();\n result.assign(alpha.mul(kernelOpacity));\n });\n return result;\n },\n);\n\nconst encodeWideSemanticOpacity = N.Fn(([opacity]: [Node<\"float\">]) => {\n return opacity.log().mul(E).add(1).sqrt().sub(1).mul(0.25).min(1);\n});\n\nexport function createGenerateProgram({ uniforms }: { uniforms: Uniforms }) {\n const bindUniform = <Type extends UniformType>(name: string, type: Type) =>\n uniformBinding(uniforms, name, type);\n const bindTexture = (name: string, array = false) =>\n textureBinding(uniforms, name, array);\n\n const targetCount = bindUniform(\"targetCount\", \"uint\");\n const stochasticSeedBase = bindUniform(\"stochasticSeedBase\", \"uint\");\n const sourceSplats = bindTexture(\"sourceSplats\", true);\n const sourceSplats2 = bindTexture(\"sourceSplats2\", true);\n const sourceLayerBits = bindUniform(\"sourceLayerBits\", \"uint\");\n const sourceLayerMask = bindUniform(\"sourceLayerMask\", \"uint\");\n const sourceBlockBits = bindUniform(\"sourceBlockBits\", \"uint\");\n const sourceBlocks = bindTexture(\"sourceBlocks\", true);\n const sourceOpacities = bindTexture(\"sourceOpacities\", true);\n const sourceIndexed = bindUniform(\"sourceIndexed\", \"bool\");\n const sourceIndices = bindTexture(\"sourceIndices\", true);\n const numSh = bindUniform(\"numSh\", \"int\");\n const sh1Texture = bindTexture(\"sh1Texture\", true);\n const sh2Texture = bindTexture(\"sh2Texture\", true);\n const sh3TextureA = bindTexture(\"sh3TextureA\", true);\n const sh3TextureB = bindTexture(\"sh3TextureB\", true);\n const objectBasis = bindUniform(\"objectBasis\", \"mat3\");\n const objectOffset = bindUniform(\"objectOffset\", \"vec3\");\n const objectLnScale = bindUniform(\"objectLnScale\", \"vec3\");\n const objectQuaternion = bindUniform(\"objectQuaternion\", \"vec4\");\n const objectReflected = bindUniform(\"objectReflected\", \"bool\");\n const recolor = bindUniform(\"recolor\", \"vec4\");\n const numSdfs = bindUniform(\"numSdfs\", \"int\");\n const numEdits = bindUniform(\"numEdits\", \"int\");\n const sdfTexture = bindTexture(\"sdfTexture\");\n const editTexture = bindTexture(\"editTexture\");\n\n const evaluateSH1 = N.Fn(\n ([data, direction]: [Node<\"uvec4\">, Node<\"vec3\">]) => {\n return decodeShRgb(data.x)\n .mul(direction.y.mul(-0.4886025))\n .add(decodeShRgb(data.y).mul(direction.z.mul(0.4886025)))\n .add(decodeShRgb(data.z).mul(direction.x.mul(-0.4886025)));\n },\n );\n\n const evaluateSH12 = N.Fn(([first, second, direction]: ShInputs) => {\n const result = evaluateSH1(first, direction).toVar();\n result.addAssign(\n decodeShRgb(first.w).mul(direction.x.mul(direction.y).mul(1.0925484)),\n );\n result.addAssign(\n decodeShRgb(second.x).mul(direction.y.mul(direction.z).mul(-1.0925484)),\n );\n result.addAssign(\n decodeShRgb(second.y).mul(\n direction.z\n .mul(direction.z)\n .mul(2)\n .sub(direction.x.mul(direction.x))\n .sub(direction.y.mul(direction.y))\n .mul(0.3153915),\n ),\n );\n result.addAssign(\n decodeShRgb(second.z).mul(direction.x.mul(direction.z).mul(-1.0925484)),\n );\n result.addAssign(\n decodeShRgb(second.w).mul(\n direction.x\n .mul(direction.x)\n .sub(direction.y.mul(direction.y))\n .mul(0.5462742),\n ),\n );\n return result;\n });\n\n const evaluateSH3 = N.Fn(([first, second, direction]: ShInputs) => {\n const xx = direction.x.mul(direction.x);\n const yy = direction.y.mul(direction.y);\n const zz = direction.z.mul(direction.z);\n return decodeShRgb(first.x)\n .mul(direction.y.mul(xx.mul(3).sub(yy)).mul(-0.5900436))\n .add(\n decodeShRgb(first.y).mul(\n direction.x.mul(direction.y).mul(direction.z).mul(2.8906114),\n ),\n )\n .add(\n decodeShRgb(first.z).mul(\n direction.y.mul(zz.mul(4).sub(xx).sub(yy)).mul(-0.4570458),\n ),\n )\n .add(\n decodeShRgb(first.w).mul(\n direction.z\n .mul(zz.mul(2).sub(xx.mul(3)).sub(yy.mul(3)))\n .mul(0.3731763),\n ),\n )\n .add(\n decodeShRgb(second.x).mul(\n direction.x.mul(zz.mul(4).sub(xx).sub(yy)).mul(-0.4570458),\n ),\n )\n .add(\n decodeShRgb(second.y).mul(direction.z.mul(xx.sub(yy)).mul(1.4453057)),\n )\n .add(\n decodeShRgb(second.z).mul(\n direction.x.mul(xx.sub(yy.mul(3))).mul(-0.5900436),\n ),\n );\n });\n\n const evaluateSH = N.Fn(\n ([coord, direction]: [Node<\"ivec3\">, Node<\"vec3\">]) => {\n const result = N.vec3(0).toVar();\n N.If(numSh.equal(N.int(1)), () => {\n result.assign(evaluateSH1(loadArray(sh1Texture, coord), direction));\n }).ElseIf(numSh.greaterThanEqual(N.int(2)), () => {\n result.assign(\n evaluateSH12(\n loadArray(sh1Texture, coord),\n loadArray(sh2Texture, coord),\n direction,\n ),\n );\n N.If(numSh.greaterThanEqual(N.int(3)), () => {\n result.addAssign(\n evaluateSH3(\n loadArray(sh3TextureA, coord),\n loadArray(sh3TextureB, coord),\n direction,\n ),\n );\n });\n });\n return result;\n },\n );\n\n const addShColor = (\n rgb: Node<\"vec3\">,\n coord: Node<\"ivec3\">,\n center: Node<\"vec3\">,\n ) => {\n N.If(numSh.greaterThan(N.int(0)), () => {\n const inverseObjectQuaternion = N.vec4(\n objectQuaternion.xyz.negate(),\n objectQuaternion.w,\n );\n const sourceViewDirection = quatVec(\n inverseObjectQuaternion,\n center.add(objectOffset),\n )\n .normalize()\n .toVar();\n N.If(objectReflected, () => {\n sourceViewDirection.x.negateAssign();\n });\n rgb.addAssign(evaluateSH(coord, sourceViewDirection));\n });\n };\n\n const generateValues = (\n index: Node<\"uint\">,\n deferredColor?: DeferredColor,\n ) => {\n const valid = N.bool(false).toVar();\n const center = N.vec3(0).toVar();\n const lnScales = N.vec3(0).toVar();\n const quaternion = N.vec4(0, 0, 0, 1).toVar();\n const rgba = N.vec4(0).toVar();\n const shapeAmount = N.float(0).toVar();\n const stochasticSeed = N.uint(0).toVar();\n\n N.If(index.lessThan(targetCount), () => {\n const sourceIndex = N.uint(index).toVar();\n N.If(sourceIndexed, () => {\n const indices = loadArray(\n sourceIndices,\n splatTexCoord(index.shiftRight(2)),\n );\n sourceIndex.assign(indices.element(index.bitAnd(3)));\n });\n // Use the source record, not its position in the visible-index list.\n stochasticSeed.assign(sourceIndex.bitXor(stochasticSeedBase));\n const blockOpacity = N.float(1).toVar();\n N.If(sourceBlockBits.lessThan(N.uint(32)), () => {\n const blockMask = sourceLayerMask.shiftRight(sourceBlockBits);\n const block = sourceIndex.shiftRight(sourceBlockBits);\n const group = loadArray(\n sourceBlocks,\n N.ivec3(\n N.int(block.bitAnd(blockMask.min(N.uint(SPLAT_TEX_WIDTH - 1)))),\n N.int(block.bitAnd(blockMask).shiftRight(SPLAT_TEX_WIDTH_BITS)),\n N.int(sourceIndex.shiftRight(sourceLayerBits)),\n ),\n ).r;\n blockOpacity.assign(\n N.uintBitsToFloat(loadArray(sourceOpacities, splatTexCoord(group)).r),\n );\n });\n const coord = N.ivec3(\n N.int(sourceIndex.bitAnd(SPLAT_TEX_WIDTH - 1)),\n N.int(\n sourceIndex.bitAnd(sourceLayerMask).shiftRight(SPLAT_TEX_WIDTH_BITS),\n ),\n N.int(sourceIndex.shiftRight(sourceLayerBits)),\n );\n const sourceA = loadArray(sourceSplats, coord);\n const sourceB = loadArray(sourceSplats2, coord);\n // Deleted scales are three packed -infinity half floats. Inspect their\n // bits before unpacking so the shader never has to compare infinities.\n const isDeleted = sourceB.y\n .shiftRight(16)\n .equal(N.uint(0xfc00))\n .and(sourceB.z.equal(N.uint(0xfc00fc00)));\n N.If(isDeleted.not().and(blockOpacity.greaterThan(0)), () => {\n const alphaShape = decodeAlphaShape(sourceA);\n valid.assign(true);\n center.assign(objectBasis.mul(decodeCenter(sourceA)));\n lnScales.assign(decodeLnScales(sourceB).add(objectLnScale));\n const sourceQuaternion = decodeQuaternion(sourceB.w).toVar();\n N.If(objectReflected, () => {\n sourceQuaternion.yz.negateAssign();\n });\n quaternion.assign(quatQuat(objectQuaternion, sourceQuaternion));\n rgba.assign(decodeRgba(sourceB, alphaShape.x));\n shapeAmount.assign(alphaShape.y);\n\n if (deferredColor) {\n deferredColor.coord.assign(coord);\n deferredColor.center.assign(center);\n } else {\n addShColor(rgba.rgb, coord, center);\n }\n\n const editPosition = center.toVar();\n center.addAssign(objectOffset);\n const semanticOpacityDecoded = N.bool(false).toVar();\n\n N.Loop(\n { start: N.int(0), end: numEdits, type: \"int\", condition: \"<\" },\n ({ i: editIndex }) => {\n const edit = load2D(editTexture, N.ivec2(N.int(0), editIndex));\n const blendMode = edit.x.bitAnd(0xff);\n const invert = edit.x.bitAnd(0x100).notEqual(N.uint(0));\n const sdfFirst = N.int(edit.y.bitAnd(0xffff));\n const sdfCount = N.int(edit.y.shiftRight(16));\n const softEdge = N.uintBitsToFloat(edit.z);\n const smoothAmount = N.uintBitsToFloat(edit.w);\n const distanceAccum = N.select(\n smoothAmount.equal(0),\n SDF_DISTANCE_LIMIT,\n 0,\n ).toVar();\n const maxExponent = N.float(0).toVar();\n const sdfRgba = N.vec4(0).toVar();\n const sdfRgbaMask = N.vec4(0).toVar();\n const sdfLast = sdfFirst.add(sdfCount).min(numSdfs);\n\n N.Loop(\n {\n start: sdfFirst,\n end: sdfLast,\n type: \"int\",\n condition: \"<\",\n name: \"sdfIndex\",\n },\n ({ sdfIndex }: { sdfIndex: Node<\"int\"> }) => {\n const data0 = load2D(\n sdfTexture,\n N.ivec2(N.int(0), sdfIndex),\n ).toVar();\n const data1 = load2D(\n sdfTexture,\n N.ivec2(N.int(1), sdfIndex),\n ).toVar();\n const data2 = load2D(\n sdfTexture,\n N.ivec2(N.int(2), sdfIndex),\n ).toVar();\n const data3 = load2D(\n sdfTexture,\n N.ivec2(N.int(3), sdfIndex),\n ).toVar();\n const data4 = load2D(\n sdfTexture,\n N.ivec2(N.int(4), sdfIndex),\n ).toVar();\n const flags = data0.w;\n const sdfCenter = N.uintBitsToFloat(data0.xyz);\n const data5 = load2D(sdfTexture, N.ivec2(N.int(5), sdfIndex));\n N.If(N.uintBitsToFloat(data5.w).lessThanEqual(0), () => {\n N.Continue();\n });\n const sdfBasis = N.mat3(\n N.uintBitsToFloat(data1.xyz),\n N.uintBitsToFloat(data2.xyz),\n N.uintBitsToFloat(data5.xyz),\n );\n // These expressions are shared by mutually exclusive branches.\n // Materialize them here so TSL cannot first cache them in just\n // one shape/blend branch and leave the others uninitialized.\n const sizes = N.uintBitsToFloat(data3).toVar();\n const value = N.uintBitsToFloat(data4).toVar();\n const valueMask = N.vec4(\n N.select(flags.bitAnd(0x10000).notEqual(N.uint(0)), 1, 0),\n N.select(flags.bitAnd(0x20000).notEqual(N.uint(0)), 1, 0),\n N.select(flags.bitAnd(0x40000).notEqual(N.uint(0)), 1, 0),\n N.select(flags.bitAnd(0x80000).notEqual(N.uint(0)), 1, 0),\n ).toVar();\n const sdfPosition = sdfBasis\n .mul(editPosition)\n .add(sdfCenter)\n .toVar();\n const sdfType = flags.bitAnd(0xff);\n const distance = N.float(SDF_DISTANCE_LIMIT).toVar();\n\n N.If(sdfType.equal(N.uint(0)), () => {\n distance.assign(-SDF_DISTANCE_LIMIT);\n })\n .ElseIf(sdfType.equal(N.uint(1)), () => {\n distance.assign(sdfPosition.z);\n })\n .ElseIf(sdfType.equal(N.uint(2)), () => {\n distance.assign(sdfPosition.length().sub(sizes.w));\n })\n .ElseIf(sdfType.equal(N.uint(3)), () => {\n const q = sdfPosition.abs().sub(sizes.xyz).add(sizes.w);\n distance.assign(\n q\n .max(0)\n .length()\n .add(q.x.max(q.y.max(q.z)).min(0))\n .sub(sizes.w),\n );\n })\n .ElseIf(sdfType.equal(N.uint(4)), () => {\n const radii = sizes.xyz.abs();\n N.If(N.all(radii.greaterThan(N.vec3(0))), () => {\n const scaledPosition = sdfPosition.div(radii);\n const k0 = scaledPosition.length();\n const k1 = scaledPosition.div(radii).length();\n // The approximation divides by zero at the center;\n // its exact signed distance there is the shortest radius.\n distance.assign(\n radii.x.min(radii.y).min(radii.z).negate(),\n );\n N.If(k1.greaterThan(0), () => {\n distance.assign(k0.mul(k0.sub(1)).div(k1));\n });\n });\n })\n .ElseIf(sdfType.equal(N.uint(5)), () => {\n const d = N.vec2(sdfPosition.xz.length(), sdfPosition.y)\n .abs()\n .sub(sizes.wy);\n distance.assign(d.x.max(d.y).min(0).add(d.max(0).length()));\n })\n .ElseIf(sdfType.equal(N.uint(6)), () => {\n sdfPosition.y.subAssign(\n sdfPosition.y.clamp(sizes.y.mul(-0.5), sizes.y.mul(0.5)),\n );\n distance.assign(sdfPosition.length().sub(sizes.w));\n })\n .ElseIf(sdfType.equal(N.uint(7)), () => {\n const angle = sizes.w.mul(Math.PI * 0.25);\n const c = N.vec2(angle.sin(), angle.cos());\n const q = N.vec2(\n sdfPosition.xy.length(),\n sdfPosition.z.negate(),\n );\n const sign = N.select(\n q.x.mul(c.y).sub(q.y.mul(c.x)).lessThan(0),\n -1,\n 1,\n );\n distance.assign(\n q\n .sub(c.mul(q.dot(c).max(0)))\n .length()\n .mul(sign),\n );\n });\n\n distance.mulAssign(N.uintBitsToFloat(data5.w));\n N.If(flags.bitAnd(0x100).notEqual(N.uint(0)), () => {\n distance.negateAssign();\n });\n\n N.If(smoothAmount.equal(0), () => {\n N.If(distance.lessThan(distanceAccum), () => {\n distanceAccum.assign(distance);\n sdfRgba.assign(value.mul(valueMask));\n sdfRgbaMask.assign(valueMask);\n });\n }).Else(() => {\n const exponent = distance.negate().div(smoothAmount).toVar();\n N.If(distanceAccum.equal(0), () => {\n maxExponent.assign(exponent);\n }).ElseIf(exponent.greaterThan(maxExponent), () => {\n const rescale = maxExponent.sub(exponent).exp();\n distanceAccum.mulAssign(rescale);\n sdfRgba.mulAssign(rescale);\n sdfRgbaMask.mulAssign(rescale);\n maxExponent.assign(exponent);\n });\n const weight = exponent.sub(maxExponent).exp();\n distanceAccum.addAssign(weight);\n sdfRgba.addAssign(weight.mul(value).mul(valueMask));\n sdfRgbaMask.addAssign(weight.mul(valueMask));\n });\n },\n );\n\n const distance = distanceAccum.toVar();\n N.If(smoothAmount.notEqual(0), () => {\n N.If(distanceAccum.equal(0), () => {\n distance.assign(SDF_DISTANCE_LIMIT);\n }).Else(() => {\n sdfRgba.divAssign(distanceAccum);\n sdfRgbaMask.divAssign(distanceAccum);\n distance.assign(\n distanceAccum\n .log()\n .negate()\n .sub(maxExponent)\n .mul(smoothAmount),\n );\n });\n });\n N.If(invert, () => {\n distance.negateAssign();\n });\n const amount = N.select(\n softEdge.equal(0),\n N.select(distance.lessThan(0), 1, 0),\n distance.negate().div(softEdge).add(0.5).clamp(0, 1),\n );\n const editOpacity = amount\n .greaterThan(0)\n .and(sdfRgbaMask.a.greaterThan(0));\n N.If(editOpacity.and(semanticOpacityDecoded.not()), () => {\n rgba.a.assign(\n decodeSemanticOpacity(rgba.a.clamp(0, 1), shapeAmount),\n );\n semanticOpacityDecoded.assign(true);\n });\n\n // Alpha keeps the original per-edit operations. Native rendering\n // composes RGB edits so SH can wait for the final visibility test.\n const input = deferredColor ? rgba.a : rgba;\n const value = deferredColor ? sdfRgba.a : sdfRgba;\n const mask = deferredColor ? sdfRgbaMask.a : sdfRgbaMask;\n const one = deferredColor ? N.float(1) : N.vec4(1);\n const target = input.toVar();\n N.If(blendMode.equal(N.uint(0)), () => {\n target.assign(input.mul(one.add(value).sub(mask)));\n if (deferredColor) {\n const scale = N.vec3(1)\n .add(sdfRgba.rgb.sub(sdfRgbaMask.rgb).mul(amount))\n .toVar();\n deferredColor.scale.mulAssign(scale);\n deferredColor.offset.mulAssign(scale);\n }\n })\n .ElseIf(blendMode.equal(N.uint(1)), () => {\n target.assign(input.mul(one.sub(mask)).add(value));\n if (deferredColor) {\n const scale = N.vec3(1)\n .sub(sdfRgbaMask.rgb.mul(amount))\n .toVar();\n deferredColor.scale.mulAssign(scale);\n deferredColor.offset.assign(\n deferredColor.offset\n .mul(scale)\n .add(sdfRgba.rgb.mul(amount)),\n );\n }\n })\n .ElseIf(blendMode.equal(N.uint(2)), () => {\n target.assign(input.add(value));\n if (deferredColor)\n deferredColor.offset.addAssign(sdfRgba.rgb.mul(amount));\n });\n input.assign(N.mix(input, target, amount));\n },\n );\n\n if (!deferredColor) rgba.rgb.mulAssign(recolor.rgb);\n const opacityScale = recolor.a.mul(blockOpacity);\n N.If(\n semanticOpacityDecoded.not().and(opacityScale.greaterThanEqual(1)),\n () => {\n rgba.a.assign(rgba.a.clamp(0, 1));\n },\n ).Else(() => {\n N.If(semanticOpacityDecoded.not(), () => {\n rgba.a.assign(\n decodeSemanticOpacity(rgba.a.clamp(0, 1), shapeAmount),\n );\n });\n const semanticOpacity = rgba.a.mul(opacityScale);\n N.If(semanticOpacity.lessThanEqual(1), () => {\n rgba.a.assign(semanticOpacity.clamp(0, 1));\n shapeAmount.assign(0);\n }).Else(() => {\n rgba.a.assign(1);\n shapeAmount.assign(encodeWideSemanticOpacity(semanticOpacity));\n });\n });\n });\n });\n\n return {\n valid,\n center,\n lnScales,\n quaternion,\n rgba,\n shapeAmount,\n stochasticSeed,\n };\n };\n\n const packAccumulator = (generated: ReturnType<typeof generateValues>) => {\n const accumulatorA = N.uvec4(0).toVar();\n const accumulatorB = N.uvec4(0).toVar();\n\n N.If(generated.valid, () => {\n accumulatorA.assign(\n N.uvec4(\n N.floatBitsToUint(generated.center),\n N.packHalf2x16(\n N.vec2(generated.rgba.a, generated.shapeAmount).clamp(0, 1),\n ),\n ),\n );\n accumulatorB.assign(\n N.uvec4(\n N.packHalf2x16(generated.rgba.rg),\n N.packHalf2x16(N.vec2(generated.rgba.b, generated.lnScales.x)),\n N.packHalf2x16(generated.lnScales.yz),\n encodeQuaternion(generated.quaternion),\n ),\n );\n });\n\n return {\n accumulatorA,\n accumulatorB,\n stochasticSeed: generated.stochasticSeed,\n };\n };\n\n const generateAccumulator = (index: Node<\"uint\">) =>\n packAccumulator(generateValues(index));\n\n // SDFs update alpha and compose RGB scale/offset in one traversal. Apply the\n // composed color transform after visibility and SH. Composition preserves\n // the affine edit semantics, but can change float32 rounding between edits.\n const prepare = (index: Node<\"uint\">) => {\n const color = {\n coord: N.ivec3(0).toVar(),\n center: N.vec3(0).toVar(),\n scale: N.vec3(1).toVar(),\n offset: N.vec3(0).toVar(),\n };\n const generated = generateValues(index, color);\n return {\n ...generated,\n // Call in the branch that passes projection and screen-footprint culling.\n resolveRgb: () => {\n const rgb = generated.rgba.rgb.toVar();\n addShColor(rgb, color.coord, color.center);\n rgb.assign(rgb.mul(color.scale).add(color.offset));\n rgb.mulAssign(recolor.rgb);\n // Preserve the accumulator's half-float color quantization before\n // the nonnegative clamp and vertex color conversion.\n return N.vec3(\n N.unpackHalf2x16(N.packHalf2x16(rgb.rg)),\n N.unpackHalf2x16(N.packHalf2x16(N.vec2(rgb.b, 0))).x,\n ).max(0);\n },\n };\n };\n\n return Object.assign(generateAccumulator, { prepare });\n}\n","import * as THREE from \"three\";\nimport ranks from \"./blueNoise32.bin?arraybuffer&base64\";\n\n/** Tileable 32-frame STBN atlas generated by scripts/generate-blue-noise.js. */\nexport function createBlueNoiseTexture() {\n // Three's WebGPU backend supports R32UI; keep the embedded ranks at 16 bits.\n const texture = new THREE.DataTexture(\n Uint32Array.from(new Uint16Array(ranks)),\n 32,\n 32 * 32,\n THREE.RedIntegerFormat,\n THREE.UnsignedIntType,\n );\n texture.name = \"GaussianSplatSpatiotemporalBlueNoise\";\n texture.needsUpdate = true;\n return texture;\n}\n","import * as THREE from \"three\";\nimport {\n SPLAT_BLOCKS_DISABLED,\n SPLAT_TEX_HEIGHT_BITS,\n SPLAT_TEX_WIDTH_BITS,\n} from \"../data/defines\";\nimport { emptySplatTexture } from \"../data/textureLayout\";\nimport { SplatEdits } from \"../scene/SplatEdit\";\nimport { createBlueNoiseTexture } from \"./blueNoise\";\n\nexport type Uniforms = Record<string, THREE.IUniform>;\n\nexport const ORDERING_TEXTURE_WIDTH = 4096;\nexport const SPLATS_PER_ORDERING_ROW = ORDERING_TEXTURE_WIDTH * 4;\n\nexport const emptyOrdering = new THREE.DataTexture(\n new Uint32Array(SPLATS_PER_ORDERING_ROW),\n ORDERING_TEXTURE_WIDTH,\n 1,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n);\nemptyOrdering.needsUpdate = true;\n\nexport const DEFAULT_MIN_ALPHA = 0.5 / 255;\n\nexport function makeSplatUniforms() {\n const emptySplats: THREE.Texture = emptySplatTexture;\n const uniforms = {\n // Size of render viewport in pixels\n renderSize: { value: new THREE.Vector2() },\n viewportOrigin: { value: new THREE.Vector2() },\n renderOrigin: { value: new THREE.Vector3() },\n // Near and far plane distances\n near: { value: 0.1 },\n far: { value: 1000.0 },\n // SplatAccumulator to view transformation quaternion\n renderToViewQuat: { value: new THREE.Quaternion() },\n // SplatAccumulator to view transformation translation\n renderToViewPos: { value: new THREE.Vector3() },\n // SplatAccumulator to view transformation uniform scale\n renderToViewScale: { value: 1 },\n // Maximum distance (in stddevs) from Gsplat center to render\n maxStdDev: { value: 1.0 },\n // Minimum pixel radius for splat rendering\n minPixelRadius: { value: 1.0 },\n // Minimum alpha value for splat rendering\n minAlpha: { value: DEFAULT_MIN_ALPHA },\n // Scale and offset from a Gaussian's alpha to its edge fade, which takes\n // the alpha maxStdDev would cut it off at down to minAlpha\n edgeFade: { value: new THREE.Vector2() },\n // Add to projected 2D splat covariance diagonal (thickens and brightens)\n preBlurAmount: { value: 0.3 },\n // Add to 2D splat covariance diagonal and adjust opacity (anti-aliasing)\n blurAmount: { value: 0.0 },\n // Clip Gsplats that are clipXY times beyond the +-1 frustum bounds\n clipXY: { value: 1.25 },\n // Debug renderSize scale factor\n focalAdjustment: { value: 2.0 },\n // Resolved from GaussianSplatRenderer.encodeLinear or the active blend space.\n encodeLinear: { value: false },\n // Exact draw count; the final instance may contain unused quads.\n splatCount: { value: 0 },\n // Back-to-front sort ordering of splat indices\n ordering: { type: \"t\", value: emptyOrdering },\n // Gsplat collection to render\n splats: { type: \"t\", value: emptySplats },\n splats2: { type: \"t\", value: emptySplats },\n stochasticSeeds: { type: \"t\", value: emptySplats },\n stochasticNoise: { value: createBlueNoiseTexture() },\n stochasticSample: { value: 0 },\n // Manual stochastic transparency\n stochastic: { value: false },\n stochasticOrdering: { value: false },\n };\n return uniforms;\n}\n\nexport function makeGenerateUniforms(): Uniforms {\n return {\n targetLayer: { value: 0 },\n targetBase: { value: 0 },\n targetCount: { value: 0 },\n // Stable mesh identity, independent of accumulator layout and visibility.\n stochasticSeedBase: { value: 0 },\n sourceSplats: { value: emptySplatTexture },\n sourceSplats2: { value: emptySplatTexture },\n sourceLayerBits: { value: SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS },\n // Precompute masks on the CPU: ANGLE/D3D11 can miscompile dynamic shifts\n // used to construct a mask, leaving layer bits in the texture Y coordinate.\n sourceLayerMask: {\n value: (1 << (SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS)) - 1,\n },\n sourceBlockBits: { value: SPLAT_BLOCKS_DISABLED },\n sourceBlocks: { value: emptySplatTexture },\n sourceOpacities: { value: emptySplatTexture },\n sourceIndexed: { value: false },\n sourceIndices: { value: emptySplatTexture },\n numSh: { value: 0 },\n sh1Texture: { value: emptySplatTexture },\n sh2Texture: { value: emptySplatTexture },\n sh3TextureA: { value: emptySplatTexture },\n sh3TextureB: { value: emptySplatTexture },\n objectBasis: { value: new THREE.Matrix3() },\n objectOffset: { value: new THREE.Vector3() },\n objectLnScale: { value: new THREE.Vector3() },\n objectQuaternion: { value: new THREE.Quaternion() },\n objectReflected: { value: false },\n recolor: { value: new THREE.Vector4(1, 1, 1, 1) },\n numSdfs: { value: 0 },\n numEdits: { value: 0 },\n sdfTexture: { value: SplatEdits.emptyTexture },\n editTexture: { value: SplatEdits.emptyTexture },\n };\n}\n","const uint SPLAT_TEX_WIDTH_BITS = 11u;\nconst uint SPLAT_TEX_HEIGHT_BITS = 11u;\nconst uint SPLAT_TEX_LAYER_BITS = SPLAT_TEX_WIDTH_BITS + SPLAT_TEX_HEIGHT_BITS;\n\nconst uint SPLAT_TEX_WIDTH = 1u << SPLAT_TEX_WIDTH_BITS;\nconst uint SPLAT_TEX_HEIGHT = 1u << SPLAT_TEX_HEIGHT_BITS;\n\nconst uint SPLAT_TEX_WIDTH_MASK = SPLAT_TEX_WIDTH - 1u;\nconst uint SPLAT_TEX_HEIGHT_MASK = SPLAT_TEX_HEIGHT - 1u;\n\nconst float PI = 3.1415926535897932384626433832795;\n\nvec3 srgbToLinear(vec3 rgb) {\n // Match Three's sRGB transfer.\n return mix(\n pow(rgb * 0.9478672986 + vec3(0.0521327014), vec3(2.4)),\n rgb * 0.0773993808, lessThanEqual(rgb, vec3(0.04045)));\n}\n\nuint encodeQuatOctXy1010R12(vec4 q) {\n // Ensure minimal representation: flip if q.w is negative.\n if (q.w < 0.0) {\n q = -q;\n }\n // Compute rotation angle: θ = 2 * acos(q.w) ∈ [0,π]\n float theta = 2.0 * acos(clamp(q.w, 0.0, 1.0));\n\n // --- Folded Octahedral Mapping (inline) ---\n // q.xyz = axis * sin(theta / 2). The common sine factor cancels during\n // octahedral normalization, so the rotation axis need not be recovered.\n float sum = abs(q.x) + abs(q.y) + abs(q.z);\n // Use the canonical +X axis when the vector part is too small to project.\n vec2 p = (sum < 1e-6) ? vec2(1.0, 0.0) : q.xy / sum;\n // Fold the lower hemisphere.\n if (q.z < 0.0) {\n float oldPx = p.x;\n p.x = (1.0 - abs(p.y)) * (p.x >= 0.0 ? 1.0 : -1.0);\n p.y = (1.0 - abs(oldPx)) * (p.y >= 0.0 ? 1.0 : -1.0);\n }\n // Remap from [-1,1] to [0,1]\n float u_f = p.x * 0.5 + 0.5;\n float v_f = p.y * 0.5 + 0.5;\n // Quantize to 10 bits (0 to 1023)\n uint quantU = uint(clamp(round(u_f * 1023.0), 0.0, 1023.0));\n uint quantV = uint(clamp(round(v_f * 1023.0), 0.0, 1023.0));\n \n // --- Angle Quantization ---\n // Quantize θ ∈ [0,π] to 12 bits (0 to 4095)\n uint angleInt = uint(clamp(round((theta / PI) * 4095.0), 0.0, 4095.0));\n \n // Pack bits: bits [0–9]: quantU, [10–19]: quantV, [20–31]: angleInt.\n return (angleInt << 20u) | (quantV << 10u) | quantU;\n}\n\nvec4 decodeQuatOctXy1010R12(uint encoded) {\n // Extract the fields.\n uint quantU = encoded & uint(0x3FFu); // bits 0–9\n uint quantV = (encoded >> 10u) & uint(0x3FFu); // bits 10–19\n uint angleInt = encoded >> 20u; // bits 20–31\n\n // Recover u and v in [0,1], then map to [-1,1].\n float u_f = float(quantU) / 1023.0;\n float v_f = float(quantV) / 1023.0;\n vec2 f = vec2(u_f * 2.0 - 1.0, v_f * 2.0 - 1.0);\n\n vec3 axis = vec3(f.xy, 1.0 - abs(f.x) - abs(f.y));\n float t = max(-axis.z, 0.0);\n axis.x += (axis.x >= 0.0) ? -t : t;\n axis.y += (axis.y >= 0.0) ? -t : t;\n axis = normalize(axis);\n \n // Decode the angle θ ∈ [0,π].\n float theta = (float(angleInt) / 4095.0) * PI;\n float halfTheta = theta * 0.5;\n float s = sin(halfTheta);\n float w = cos(halfTheta);\n \n return vec4(axis * s, w);\n}\n\nvec3 decodeSplatCenter(uvec4 splatData) {\n return vec3(\n uintBitsToFloat(splatData.x),\n uintBitsToFloat(splatData.y),\n uintBitsToFloat(splatData.z)\n );\n}\n\n// Encode a Splat whose scale is already logarithmic into the standard\n// two-record representation. The first record's final word stores alpha and\n// special-kernel shape amount as float16.\nvoid encodeSplatLnScale(\n out uvec4 splatData, out uvec4 splatData2,\n vec3 center, vec3 lnScales, vec4 quaternion, vec4 rgba, float shapeAmount\n) {\n splatData.x = floatBitsToUint(center.x);\n splatData.y = floatBitsToUint(center.y);\n splatData.z = floatBitsToUint(center.z);\n splatData.w = packHalf2x16(clamp(vec2(rgba.a, shapeAmount), 0.0, 1.0));\n\n splatData2.x = packHalf2x16(rgba.rg);\n splatData2.y = packHalf2x16(vec2(rgba.b, lnScales.x));\n splatData2.z = packHalf2x16(lnScales.yz);\n splatData2.w = encodeQuatOctXy1010R12(quaternion);\n}\n\nvec2 decodeSplatAlphaShapeAmount(uvec4 splatData) {\n return unpackHalf2x16(splatData.w);\n}\n\nvoid decodeSplatAttributesLnScale(\n uvec4 splatData2,\n float alpha,\n out vec3 lnScales, out vec4 quaternion, out vec4 rgba\n) {\n rgba.a = alpha;\n\n rgba.rg = unpackHalf2x16(splatData2.x);\n vec2 split = unpackHalf2x16(splatData2.y);\n rgba.b = split.x;\n lnScales.x = split.y;\n lnScales.yz = unpackHalf2x16(splatData2.z);\n quaternion = decodeQuatOctXy1010R12(splatData2.w);\n}\n\nvec3 decodeSplatShRgb(uint encoded) {\n uint biasedBase = (encoded >> 27u) & 0x1fu;\n // Re-bias the exponent from the packed bias of 15 to float32's bias of 127,\n // then construct the exact power of two directly (127 - 15 = 112).\n float divisor = uintBitsToFloat((biasedBase + 112u) << 23u) / 255.0;\n\n vec3 rgb = vec3(uvec3(encoded & 0xffu, (encoded >> 8u) & 0xffu, (encoded >> 16u) & 0xffu));\n rgb *= divisor;\n\n return vec3(\n ((encoded & 0x1000000u) != 0u) ? -rgb.r : rgb.r,\n ((encoded & 0x2000000u) != 0u) ? -rgb.g : rgb.g,\n ((encoded & 0x4000000u) != 0u) ? -rgb.b : rgb.b\n );\n}\n\n// Rotate vector v by quaternion q\nvec3 quatVec(vec4 q, vec3 v) {\n // Rotate vector v by quaternion q\n vec3 t = 2.0 * cross(q.xyz, v);\n return v + q.w * t + cross(q.xyz, t);\n}\n\n// Apply quaternion q1 after quaternion q2\nvec4 quatQuat(vec4 q1, vec4 q2) {\n return vec4(\n q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,\n q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x,\n q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w,\n q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n );\n}\n\nmat3 scaleQuaternionToMatrix(vec3 s, vec4 q) {\n // Compute the matrix of scaling by s then rotating by q\n return mat3(\n s.x * (1.0 - 2.0 * (q.y * q.y + q.z * q.z)),\n s.x * (2.0 * (q.x * q.y + q.w * q.z)),\n s.x * (2.0 * (q.x * q.z - q.w * q.y)),\n s.y * (2.0 * (q.x * q.y - q.w * q.z)),\n s.y * (1.0 - 2.0 * (q.x * q.x + q.z * q.z)),\n s.y * (2.0 * (q.y * q.z + q.w * q.x)),\n s.z * (2.0 * (q.x * q.z + q.w * q.y)),\n s.z * (2.0 * (q.y * q.z - q.w * q.x)),\n s.z * (1.0 - 2.0 * (q.x * q.x + q.y * q.y))\n );\n}\n\nivec3 splatTexCoord(int index) {\n uint x = uint(index) & SPLAT_TEX_WIDTH_MASK;\n uint y = (uint(index) >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK;\n uint z = uint(index) >> SPLAT_TEX_LAYER_BITS;\n return ivec3(x, y, z);\n}\n","\nprecision highp float;\nprecision highp int;\n\nuniform float minAlpha;\nuniform vec2 edgeFade;\n#if GSL_STOCHASTIC\nuniform highp usampler2D stochasticNoise;\n#endif\n\nout vec4 fragColor;\n\nflat in uvec4 vSplat;\nin vec2 vSplatUv;\n#if GSL_STOCHASTIC\n// Noise tile offset: x in bits 0-4, y from bit 5.\nflat in uint vStochasticOffset;\n#endif\n\n#include <logdepthbuf_pars_fragment>\n\nvoid main() {\n float z2 = dot(vSplatUv, vSplatUv);\n if (z2 > uintBitsToFloat(vSplat.w)) {\n discard;\n }\n\n vec2 blueKernelPower = unpackHalf2x16(vSplat.y);\n float kernelPower = blueKernelPower.y;\n float kernelAlpha = exp(-0.5 * z2);\n float alpha = uintBitsToFloat(vSplat.z);\n // A kernel still above minAlpha where its support ends fades to minAlpha\n // there: it is rescaled about its peak. A Gaussian's fade follows from\n // its alpha; a wide kernel carries its own in the low half of its squared\n // radius.\n float fade;\n if (kernelPower != 0.0) {\n kernelAlpha = 1.0 - pow(1.0 - kernelAlpha, kernelPower);\n fade = unpackHalf2x16(vSplat.w).x;\n } else {\n fade = max(alpha * edgeFade.x - edgeFade.y, 0.0);\n }\n alpha = (alpha + fade) * kernelAlpha - fade;\n\n if (alpha < minAlpha) {\n discard;\n }\n #if GSL_STOCHASTIC\n uvec2 offset = uvec2(vStochasticOffset, vStochasticOffset >> 5u);\n ivec2 coord = ivec2((uvec2(gl_FragCoord.xy) + offset) & uvec2(31u));\n coord.y += int(vStochasticOffset >> 10u) * 32;\n float randomValue = (float(texelFetch(stochasticNoise, coord, 0).r) + 0.5) / 32768.0;\n if (randomValue >= alpha) {\n discard;\n }\n #endif\n\n // Decode color only after the fragment survives coverage tests.\n vec4 rgba = vec4(unpackHalf2x16(vSplat.x), blueKernelPower.x, alpha);\n\n #if GSL_STOCHASTIC\n fragColor = vec4(rgba.rgb, 1.0);\n #elif defined(PREMULTIPLIED_ALPHA)\n fragColor = vec4(rgba.rgb * rgba.a, rgba.a);\n #else\n fragColor = rgba;\n #endif\n\n #include <logdepthbuf_fragment>\n}\n","\nprecision highp float;\nprecision highp int;\nprecision highp usampler2DArray;\n\n#include <splatDefines>\n\nflat out uvec4 vSplat;\nout vec2 vSplatUv;\n#if GSL_STOCHASTIC\n// Noise atlas offset: x in bits 0-4, y in 5-9, temporal slice in 10-14.\nflat out uint vStochasticOffset;\n#endif\n\nuniform vec2 renderSize;\nuniform vec4 renderToViewQuat;\nuniform vec3 renderToViewPos;\n// Uniform scale of the render-to-view transform (1.0 unless the camera is scaled)\nuniform float renderToViewScale;\nuniform float maxStdDev;\nuniform float minPixelRadius;\nuniform float minAlpha;\nuniform float blurAmount;\nuniform float preBlurAmount;\nuniform float clipXY;\nuniform float focalAdjustment;\nuniform bool encodeLinear;\nuniform uint splatCount;\n\nuniform usampler2D ordering;\nuniform usampler2DArray splats;\nuniform usampler2DArray splats2;\n\n#if GSL_STOCHASTIC\nuniform bool stochasticOrdering;\nuniform uint stochasticSample;\nuniform vec2 viewportOrigin;\nuniform usampler2DArray stochasticSeeds;\n#endif\n\n// Required by logdepthbuf_pars_vertex (normally defined in three.js #include <common>)\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == -1.0;\n}\n\n#include <logdepthbuf_pars_vertex>\n\n// Chris Wellons' \"prospector\" mix, constant across each Splat's fragments.\nuint hashU32(uint value) {\n value ^= value >> 16u;\n value *= 0x7feb352du;\n value ^= value >> 15u;\n value *= 0x846ca68bu;\n value ^= value >> 16u;\n return value;\n}\n\nfloat gaussianSupportRadius(float alpha, float maximumRadius) {\n if (minAlpha <= 0.0) return maximumRadius;\n float radiusSquared = 2.0 * log(alpha / minAlpha);\n return min(maximumRadius, sqrt(max(0.0, radiusSquared)));\n}\n\nfloat wideSupportRadius(float alpha, float power, float maximumRadius) {\n if (minAlpha <= 0.0) return maximumRadius;\n // 1 - (1 - x)^power <= power * x for power >= 1. Only remove\n // coverage that cannot reach minAlpha, without inverting pow near 1.\n float radiusSquared = 2.0 * log(alpha * power / minAlpha);\n return min(maximumRadius, sqrt(max(0.0, radiusSquared)));\n}\n\n// A wide kernel can still be above minAlpha where its support ends. Return\n// the edge fade: the amount the fragment stage subtracts so the kernel,\n// rescaled about its peak, reaches minAlpha there instead. A Gaussian's fade\n// follows from its alpha alone; see the edgeFade uniform.\nfloat wideEdgeFade(float alpha, float power, float radiusSquared) {\n float edgeKernel = 1.0 - pow(1.0 - exp(-0.5 * radiusSquared), power);\n // A kernel still flat at its edge cannot fade; bound the slope instead.\n return max(0.0, alpha * edgeKernel - minAlpha)\n / max(1.0 - edgeKernel, 0.001);\n}\n\nvoid main() {\n // Default to outside the frustum so it's discarded if we return early\n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n\n uint index = uint(gl_InstanceID) * uint(SPLATS_PER_INSTANCE) + uint(position.z);\n if (index >= splatCount) return;\n\n uint splatIndex;\n #if GSL_STOCHASTIC\n if (!stochasticOrdering) {\n // Use source indices when stochastic ordering is disabled or not ready.\n splatIndex = index;\n } else\n #endif\n {\n ivec2 orderingCoord = ivec2(int((index >> 2u) & 4095u), int(index >> 14u));\n splatIndex = texelFetch(ordering, orderingCoord, 0)[index & 3u];\n }\n if (splatIndex == 0xffffffffu) {\n // Special value reserved for \"no splat\"\n return;\n }\n\n ivec3 texCoord = splatTexCoord(int(splatIndex));\n uvec4 splat1 = texelFetch(splats, texCoord, 0);\n vec2 alphaShapeAmount = decodeSplatAlphaShapeAmount(splat1);\n float alpha = alphaShapeAmount.x;\n if ((alpha == 0.0) || (alpha < minAlpha)) {\n return;\n }\n vec3 center = decodeSplatCenter(splat1);\n // Compute the view space center of the splat\n vec3 viewCenter = renderToViewScale * quatVec(renderToViewQuat, center) + renderToViewPos;\n\n // Discard splats behind the camera\n if (isPerspectiveMatrix(projectionMatrix) && viewCenter.z >= 0.0) {\n return;\n }\n\n // Compute the clip space center of the splat\n vec4 clipCenter = projectionMatrix * vec4(viewCenter, 1.0);\n\n // Discard splats outside near/far planes\n if (abs(clipCenter.z) >= clipCenter.w) {\n return;\n }\n\n // Discard splats more than clipXY times outside the XY frustum\n float clip = clipXY * clipCenter.w;\n if (abs(clipCenter.x) > clip || abs(clipCenter.y) > clip) {\n return;\n }\n\n // The second record is only needed by splats whose centers survive the\n // view-frustum checks above.\n vec3 lnScales;\n vec4 quaternion, rgba;\n uvec4 splat2 = texelFetch(splats2, texCoord, 0);\n decodeSplatAttributesLnScale(splat2, alpha, lnScales, quaternion, rgba);\n vec3 scales = exp(lnScales);\n if (all(equal(scales, vec3(0.0)))) {\n return;\n }\n\n // Match the reference 3DGS rasterizer by clamping SH-evaluated RGB positive.\n rgba.rgb = max(rgba.rgb, vec3(0.0));\n\n // Decode the shape amount independently from mesh/SDF opacity, which\n // remains in the main splat's alpha.\n float kernelShape = 1.0 + 4.0 * min(alphaShapeAmount.y, 1.0);\n // Zero marks the ordinary Gaussian path; wider kernels reuse this power\n // for every covered fragment.\n float kernelPower = 0.0;\n if (kernelShape > 1.0) {\n kernelPower = exp(\n (kernelShape * kernelShape - 1.0) / 2.718281828459045\n );\n }\n\n // Expand wider shape kernels until alpha is nearly zero before clipping.\n float maximumSupportRadius = maxStdDev\n + 0.7 * max(kernelShape - 1.0, 0.0);\n float supportRadius = maximumSupportRadius;\n\n scales *= renderToViewScale;\n\n // Compute view space quaternion of splat\n vec4 viewQuaternion = quatQuat(renderToViewQuat, quaternion);\n\n // Compute the scaled rotation basis of the splat.\n mat3 RS = scaleQuaternionToMatrix(scales, viewQuaternion);\n\n // Compute the two relevant columns of the projection Jacobian.\n vec2 scaledRenderSize = renderSize * focalAdjustment;\n vec2 focal = 0.5 * scaledRenderSize * vec2(projectionMatrix[0][0], projectionMatrix[1][1]);\n\n vec3 j0;\n vec3 j1;\n if (isOrthographic) {\n j0 = vec3(focal.x, 0.0, 0.0);\n j1 = vec3(0.0, focal.y, 0.0);\n } else {\n float invZ = 1.0 / viewCenter.z;\n vec2 J1 = focal * invZ;\n vec2 J2 = -(J1 * viewCenter.xy) * invZ;\n j0 = vec3(J1.x, 0.0, J2.x);\n j1 = vec3(0.0, J1.y, J2.y);\n }\n\n // Project only the 2D covariance entries that are consumed below:\n // j^T * RS * RS^T * j = dot(RS^T * j, RS^T * j).\n vec3 p0 = transpose(RS) * j0;\n vec3 p1 = transpose(RS) * j1;\n float a = dot(p0, p0);\n float b = dot(p0, p1);\n float d = dot(p1, p1);\n\n // Optionally pre-blur the splat to match non-antialias optimized splats\n a += preBlurAmount;\n d += preBlurAmount;\n\n float detOrig = a * d - b * b;\n // Do convolution with a 0.5-pixel Gaussian for anti-aliasing: sqrt(0.3) ~= 0.5\n a += blurAmount;\n d += blurAmount;\n float det = a * d - b * b;\n if (det <= 0.0) return;\n\n // Compute anti-aliasing intensity scaling factor\n float blurAdjust = sqrt(max(0.0, detOrig / det));\n alpha *= blurAdjust;\n if (!(alpha > 0.0) || alpha < minAlpha) {\n return;\n }\n\n // Only cover fragments that can reach minAlpha for either kernel.\n if (kernelPower == 0.0) {\n supportRadius = gaussianSupportRadius(alpha, supportRadius);\n } else {\n supportRadius = wideSupportRadius(alpha, kernelPower, supportRadius);\n }\n\n // Compute the eigenvalue and eigenvectors of the 2D covariance matrix\n float eigenAvg = 0.5 * (a + d);\n float eigenDelta = length(vec2(0.5 * (a - d), b));\n float eigen1 = eigenAvg + eigenDelta;\n // Keep a small positive minor axis when subtraction rounds to zero.\n float eigen2 = max(eigenAvg - eigenDelta, 1e-4);\n\n vec2 eigenVec1 = (abs(b) > 0.001)\n ? normalize(vec2(b, eigen1 - a))\n : ((a >= d) ? vec2(1.0, 0.0) : vec2(0.0, 1.0));\n vec2 eigenVec2 = vec2(eigenVec1.y, -eigenVec1.x);\n\n // Limit support to the viewport's short side, then shrink both the quad\n // and its UV extent by the same ratio to preserve the Gaussian profile.\n float maxProjectedRadius = min(renderSize.x, renderSize.y) * focalAdjustment;\n float scale1 = min(maxProjectedRadius, maximumSupportRadius * sqrt(eigen1));\n float scale2 = min(maxProjectedRadius, maximumSupportRadius * sqrt(eigen2));\n float supportScale = (maximumSupportRadius > 0.0)\n ? supportRadius / maximumSupportRadius\n : 0.0;\n // Projected radii use scaledRenderSize; convert the screen-pixel cutoff too.\n float minProjectedRadius = minPixelRadius * focalAdjustment;\n if (scale1 * supportScale < minProjectedRadius && scale2 * supportScale < minProjectedRadius) {\n return;\n }\n\n float supportRadiusSquared = supportRadius * supportRadius;\n if (kernelPower != 0.0) {\n // A wide kernel carries its edge fade in the low half of its squared\n // radius. Round that radius down to its high half first, with room\n // for the fade, so the support never grows. Only kernels that passed\n // the size cutoff pay for this.\n uint highHalf = floatBitsToUint(supportRadiusSquared * 0.996)\n & 0xffff0000u;\n float edgeFade = wideEdgeFade(\n alpha, kernelPower, uintBitsToFloat(highHalf)\n );\n supportRadiusSquared = uintBitsToFloat(\n highHalf | packHalf2x16(vec2(edgeFade, 0.0))\n );\n supportRadius = sqrt(supportRadiusSquared);\n supportScale = (maximumSupportRadius > 0.0)\n ? supportRadius / maximumSupportRadius\n : 0.0;\n }\n vSplatUv = position.xy * supportRadius;\n scale1 *= supportScale;\n scale2 *= supportScale;\n\n #if GSL_STOCHASTIC\n // Fetch stable coverage seeds only after all projection cutoffs pass.\n // Keep XY fixed so consecutive samples follow the same STBN time sequence.\n // Independent per-Splat XYZ offsets decorrelate overlapping coverage tests.\n uint seed = texelFetch(stochasticSeeds, texCoord, 0).r;\n uint hash = hashU32(seed);\n uvec2 offset = uvec2(hash, hash >> 5u) - uvec2(viewportOrigin);\n uint phase = ((hash >> 10u) + stochasticSample) & 31u;\n vStochasticOffset = (offset.x & 31u) | ((offset.y & 31u) << 5u) | (phase << 10u);\n #endif\n\n // RGB is constant across the quad, so convert before rasterization.\n if (encodeLinear) {\n rgba.rgb = srgbToLinear(rgba.rgb);\n }\n // Match the TSL varying layout: half RGB/kernel power, float32 alpha/radius.\n vec3 rgb = min(rgba.rgb, vec3(65504.0));\n vSplat = uvec4(\n packHalf2x16(rgb.rg),\n packHalf2x16(vec2(rgb.b, kernelPower)),\n floatBitsToUint(alpha),\n floatBitsToUint(supportRadiusSquared)\n );\n\n // Compute the NDC coordinates for the ellipsoid's diagonal axes.\n vec2 pixelOffset = position.x * eigenVec1 * scale1 + position.y * eigenVec2 * scale2;\n vec2 ndcOffset = (2.0 / scaledRenderSize) * pixelOffset;\n\n // Compute NDC center of the splat\n vec3 ndcCenter = clipCenter.xyz / clipCenter.w;\n vec3 ndc = vec3(ndcCenter.xy + ndcOffset, ndcCenter.z);\n\n gl_Position = vec4(ndc.xy * clipCenter.w, clipCenter.zw);\n #include <logdepthbuf_vertex>\n}\n","import * as THREE from \"three\";\n\nimport splatDefines from \"./shaders/splatDefines.glsl\";\nimport splatFragment from \"./shaders/splatFragment.glsl\";\nimport splatVertex from \"./shaders/splatVertex.glsl\";\n\nlet shaders: Record<string, string> | null = null;\n\nexport function getShaders(): Record<string, string> {\n if (!shaders) {\n // @ts-ignore\n THREE.ShaderChunk.splatDefines = splatDefines;\n shaders = {\n splatVertex,\n splatFragment,\n };\n }\n return shaders;\n}\n","precision highp float;\nprecision highp int;\nprecision highp usampler2D;\nprecision highp usampler2DArray;\n\n#include <splatDefines>\n\nuniform uint targetLayer;\nuniform int targetBase;\nuniform int targetCount;\nuniform uint stochasticSeedBase;\n\nuniform usampler2DArray sourceSplats;\nuniform usampler2DArray sourceSplats2;\nuniform uint sourceLayerBits;\nuniform uint sourceLayerMask;\nuniform uint sourceBlockBits;\nuniform usampler2DArray sourceBlocks;\nuniform usampler2DArray sourceOpacities;\nuniform bool sourceIndexed;\nuniform usampler2DArray sourceIndices;\n\nuniform int numSh;\nuniform usampler2DArray sh1Texture;\nuniform usampler2DArray sh2Texture;\nuniform usampler2DArray sh3TextureA;\nuniform usampler2DArray sh3TextureB;\n\nuniform mat3 objectBasis;\nuniform vec3 objectOffset;\nuniform vec3 objectLnScale;\nuniform vec4 objectQuaternion;\nuniform bool objectReflected;\nuniform vec4 recolor;\n\nuniform int numSdfs;\nuniform int numEdits;\nuniform usampler2D sdfTexture;\nuniform usampler2D editTexture;\n\nlayout(location = 0) out uvec4 target;\nlayout(location = 1) out uvec4 target2;\n#if GSL_STOCHASTIC_SEEDS\nlayout(location = 2) out uint targetSeed;\n#endif\n\n// Match WebGPU's finite sentinel for empty/unbounded SDFs. Smooth ALL shapes\n// must not evaluate exp(inf - inf).\nconst float SDF_DISTANCE_LIMIT = 1e20;\n\nfloat decodeSemanticOpacity(float alpha, float shapeAmount) {\n if (shapeAmount <= 0.0) return alpha;\n\n float kernelShape = 1.0 + 4.0 * min(shapeAmount, 1.0);\n float kernelOpacity = exp(\n (kernelShape * kernelShape - 1.0) / 2.718281828459045\n );\n return alpha * kernelOpacity;\n}\n\nfloat encodeWideSemanticOpacity(float opacity) {\n float kernelShape = sqrt(log(opacity) * 2.718281828459045 + 1.0);\n return min(1.0, 0.25 * (kernelShape - 1.0));\n}\n\nvec3 evaluateSH1(uvec4 data, vec3 direction) {\n return decodeSplatShRgb(data.x) * (-0.4886025 * direction.y)\n + decodeSplatShRgb(data.y) * (0.4886025 * direction.z)\n + decodeSplatShRgb(data.z) * (-0.4886025 * direction.x);\n}\n\nvec3 evaluateSH12(uvec4 first, uvec4 second, vec3 direction) {\n vec3 result = evaluateSH1(first, direction);\n result += decodeSplatShRgb(first.w) * (1.0925484 * direction.x * direction.y);\n result += decodeSplatShRgb(second.x) * (-1.0925484 * direction.y * direction.z);\n result += decodeSplatShRgb(second.y) * (0.3153915 * (2.0 * direction.z * direction.z - direction.x * direction.x - direction.y * direction.y));\n result += decodeSplatShRgb(second.z) * (-1.0925484 * direction.x * direction.z);\n result += decodeSplatShRgb(second.w) * (0.5462742 * (direction.x * direction.x - direction.y * direction.y));\n return result;\n}\n\nvec3 evaluateSH3(uvec4 first, uvec4 second, vec3 direction) {\n float xx = direction.x * direction.x;\n float yy = direction.y * direction.y;\n float zz = direction.z * direction.z;\n return decodeSplatShRgb(first.x) * (-0.5900436 * direction.y * (3.0 * xx - yy))\n + decodeSplatShRgb(first.y) * (2.8906114 * direction.x * direction.y * direction.z)\n + decodeSplatShRgb(first.z) * (-0.4570458 * direction.y * (4.0 * zz - xx - yy))\n + decodeSplatShRgb(first.w) * (0.3731763 * direction.z * (2.0 * zz - 3.0 * xx - 3.0 * yy))\n + decodeSplatShRgb(second.x) * (-0.4570458 * direction.x * (4.0 * zz - xx - yy))\n + decodeSplatShRgb(second.y) * (1.4453057 * direction.z * (xx - yy))\n + decodeSplatShRgb(second.z) * (-0.5900436 * direction.x * (xx - 3.0 * yy));\n}\n\nvec3 evaluateSH(ivec3 coord, vec3 direction) {\n vec3 result = vec3(0.0);\n if (numSh == 1) {\n result = evaluateSH1(texelFetch(sh1Texture, coord, 0), direction);\n } else if (numSh >= 2) {\n result = evaluateSH12(\n texelFetch(sh1Texture, coord, 0),\n texelFetch(sh2Texture, coord, 0),\n direction\n );\n if (numSh >= 3) {\n result += evaluateSH3(\n texelFetch(sh3TextureA, coord, 0),\n texelFetch(sh3TextureB, coord, 0),\n direction\n );\n }\n }\n return result;\n}\n\nvoid unpackSdf(\n int index,\n out uint flags,\n out vec3 center,\n out mat3 basis,\n out float distanceScale,\n out vec4 sizes,\n out vec4 sdfRgba\n) {\n uvec4 data = texelFetch(sdfTexture, ivec2(0, index), 0);\n center = vec3(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z));\n flags = data.w;\n uvec4 firstAxis = texelFetch(sdfTexture, ivec2(1, index), 0);\n uvec4 secondAxis = texelFetch(sdfTexture, ivec2(2, index), 0);\n uvec4 thirdAxis = texelFetch(sdfTexture, ivec2(5, index), 0);\n basis = mat3(uintBitsToFloat(firstAxis.xyz), uintBitsToFloat(secondAxis.xyz), uintBitsToFloat(thirdAxis.xyz));\n distanceScale = uintBitsToFloat(thirdAxis.w);\n data = texelFetch(sdfTexture, ivec2(3, index), 0);\n sizes = vec4(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z), uintBitsToFloat(data.w));\n data = texelFetch(sdfTexture, ivec2(4, index), 0);\n sdfRgba = vec4(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z), uintBitsToFloat(data.w));\n}\n\nfloat sdfDistance(uint type, vec3 position, vec4 sizes) {\n switch (type) {\n case 0u: return -SDF_DISTANCE_LIMIT;\n case 1u: return position.z;\n case 2u: return length(position) - sizes.w;\n case 3u: {\n vec3 q = abs(position) - sizes.xyz + sizes.w;\n return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0) - sizes.w;\n }\n case 4u: {\n vec3 radii = abs(sizes.xyz);\n if (any(lessThanEqual(radii, vec3(0.0)))) return SDF_DISTANCE_LIMIT;\n vec3 scaledPosition = position / radii;\n float k0 = length(scaledPosition);\n float k1 = length(scaledPosition / radii);\n // At the center, the exact signed distance is the shortest radius.\n if (k1 <= 0.0) return -min(radii.x, min(radii.y, radii.z));\n return k0 * (k0 - 1.0) / k1;\n }\n case 5u: {\n vec2 d = abs(vec2(length(position.xz), position.y)) - sizes.wy;\n return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));\n }\n case 6u: {\n position.y -= clamp(position.y, -0.5 * sizes.y, 0.5 * sizes.y);\n return length(position) - sizes.w;\n }\n case 7u: {\n float angle = 0.25 * PI * sizes.w;\n vec2 c = vec2(sin(angle), cos(angle));\n vec2 q = vec2(length(position.xy), -position.z);\n float distance = length(q - c * max(dot(q, c), 0.0));\n return distance * (((q.x * c.y - q.y * c.x) < 0.0) ? -1.0 : 1.0);\n }\n }\n return SDF_DISTANCE_LIMIT;\n}\n\nfloat evaluateSdfs(\n int sdfFirst,\n int sdfCount,\n vec3 position,\n float smoothAmount,\n out vec4 resultRgba,\n out vec4 resultRgbaMask\n) {\n float distanceAccum = smoothAmount == 0.0 ? SDF_DISTANCE_LIMIT : 0.0;\n float maxExponent = 0.0;\n resultRgba = vec4(0.0);\n resultRgbaMask = vec4(0.0);\n int sdfLast = min(sdfFirst + sdfCount, numSdfs);\n\n for (int index = sdfFirst; index < sdfLast; ++index) {\n uint flags;\n vec3 center;\n mat3 basis;\n float distanceScale;\n vec4 sizes;\n vec4 value;\n unpackSdf(index, flags, center, basis, distanceScale, sizes, value);\n if (distanceScale <= 0.0) continue;\n vec4 valueMask = vec4(\n (flags & 0x10000u) != 0u ? 1.0 : 0.0,\n (flags & 0x20000u) != 0u ? 1.0 : 0.0,\n (flags & 0x40000u) != 0u ? 1.0 : 0.0,\n (flags & 0x80000u) != 0u ? 1.0 : 0.0\n );\n vec3 sdfPosition = basis * position + center;\n float distance = sdfDistance(flags & 0xffu, sdfPosition, sizes) * distanceScale;\n if ((flags & 0x100u) != 0u) distance = -distance;\n\n if (smoothAmount == 0.0) {\n if (distance < distanceAccum) {\n distanceAccum = distance;\n resultRgba = value * valueMask;\n resultRgbaMask = valueMask;\n }\n } else {\n float exponent = -distance / smoothAmount;\n if (distanceAccum == 0.0) {\n maxExponent = exponent;\n } else if (exponent > maxExponent) {\n float rescale = exp(maxExponent - exponent);\n distanceAccum *= rescale;\n resultRgba *= rescale;\n resultRgbaMask *= rescale;\n maxExponent = exponent;\n }\n float weight = exp(exponent - maxExponent);\n distanceAccum += weight;\n resultRgba += weight * value * valueMask;\n resultRgbaMask += weight * valueMask;\n }\n }\n\n // A hard union can have distance zero on the surface; it is not empty.\n if (smoothAmount == 0.0) return distanceAccum;\n if (distanceAccum == 0.0) return SDF_DISTANCE_LIMIT;\n resultRgba /= distanceAccum;\n resultRgbaMask /= distanceAccum;\n return (-log(distanceAccum) - maxExponent) * smoothAmount;\n}\n\nbool applySdfEdits(\n vec3 position,\n inout vec4 rgba,\n float shapeAmount\n) {\n bool semanticOpacityDecoded = false;\n for (int editIndex = 0; editIndex < numEdits; ++editIndex) {\n uvec4 edit = texelFetch(editTexture, ivec2(0, editIndex), 0);\n uint blendMode = edit.x & 0xffu;\n bool invert = (edit.x & 0x100u) != 0u;\n int sdfFirst = int(edit.y & 0xffffu);\n int sdfCount = int(edit.y >> 16u);\n float softEdge = uintBitsToFloat(edit.z);\n float smoothAmount = uintBitsToFloat(edit.w);\n\n vec4 sdfRgba;\n vec4 sdfRgbaMask;\n float distance = evaluateSdfs(\n sdfFirst,\n sdfCount,\n position,\n smoothAmount,\n sdfRgba,\n sdfRgbaMask\n );\n if (invert) distance = -distance;\n float amount = softEdge == 0.0\n ? (distance < 0.0 ? 1.0 : 0.0)\n : clamp(-distance / softEdge + 0.5, 0.0, 1.0);\n bool editOpacity = amount > 0.0 && sdfRgbaMask.a > 0.0;\n if (editOpacity && !semanticOpacityDecoded) {\n // SDF opacity values operate on semantic opacity, not on the alpha\n // half of the nonlinear wide-kernel encoding.\n rgba.a = decodeSemanticOpacity(\n clamp(rgba.a, 0.0, 1.0),\n shapeAmount\n );\n semanticOpacityDecoded = true;\n }\n vec4 target = rgba;\n switch (blendMode) {\n case 0u:\n target = rgba * (vec4(1.0) + sdfRgba - sdfRgbaMask);\n break;\n case 1u:\n target = rgba * (vec4(1.0) - sdfRgbaMask) + sdfRgba;\n break;\n case 2u:\n target = rgba + sdfRgba;\n break;\n }\n rgba = mix(rgba, target, amount);\n }\n return semanticOpacityDecoded;\n}\n\nvoid produceSplat(int index) {\n uint sourceIndex = uint(index);\n if (sourceIndexed) {\n uvec4 indices = texelFetch(sourceIndices, splatTexCoord(index >> 2), 0);\n sourceIndex = indices[index & 3];\n }\n #if GSL_STOCHASTIC_SEEDS\n targetSeed = sourceIndex ^ stochasticSeedBase;\n #endif\n float blockOpacity = 1.0;\n if (sourceBlockBits < 32u) {\n // Group layers follow the source layers, at one texel per block.\n uint blockMask = sourceLayerMask >> sourceBlockBits;\n uint block = sourceIndex >> sourceBlockBits;\n uint group = texelFetch(sourceBlocks, ivec3(\n block & min(blockMask, SPLAT_TEX_WIDTH_MASK),\n (block & blockMask) >> SPLAT_TEX_WIDTH_BITS,\n sourceIndex >> sourceLayerBits\n ), 0).r;\n blockOpacity = uintBitsToFloat(texelFetch(sourceOpacities, splatTexCoord(int(group)), 0).r);\n }\n if (blockOpacity <= 0.0) return;\n ivec3 coord = ivec3(\n sourceIndex & SPLAT_TEX_WIDTH_MASK,\n (sourceIndex & sourceLayerMask) >> SPLAT_TEX_WIDTH_BITS,\n sourceIndex >> sourceLayerBits\n );\n uvec4 sourceSplat2 = texelFetch(sourceSplats2, coord, 0);\n // Detect the three packed -infinity scales before unpacking any floats.\n if ((sourceSplat2.y >> 16u) == 0xfc00u && sourceSplat2.z == 0xfc00fc00u) return;\n uvec4 sourceSplat = texelFetch(sourceSplats, coord, 0);\n vec2 alphaShapeAmount = decodeSplatAlphaShapeAmount(sourceSplat);\n vec3 center = decodeSplatCenter(sourceSplat);\n vec3 lnScales;\n vec4 quaternion;\n vec4 rgba;\n decodeSplatAttributesLnScale(\n sourceSplat2,\n alphaShapeAmount.x,\n lnScales,\n quaternion,\n rgba\n );\n float shapeAmount = alphaShapeAmount.y;\n\n // Match PlayCanvas' work-buffer transform. Centers retain the complete\n // affine transform, while Gaussian shape is approximated by composing the\n // model rotation and its positive per-axis scale with each splat.\n center = objectBasis * center;\n if (numSh > 0) {\n vec3 worldViewDirection = center + objectOffset;\n vec4 inverseObjectQuaternion = vec4(-objectQuaternion.xyz, objectQuaternion.w);\n vec3 sourceViewDirection = normalize(quatVec(inverseObjectQuaternion, worldViewDirection));\n if (objectReflected) sourceViewDirection.x = -sourceViewDirection.x;\n rgba.rgb += evaluateSH(coord, sourceViewDirection);\n }\n lnScales += objectLnScale;\n if (objectReflected) quaternion.yz = -quaternion.yz;\n quaternion = quatQuat(objectQuaternion, quaternion);\n\n vec3 editPosition = center;\n center += objectOffset;\n// The center is camera-relative while editPosition is mesh-origin-relative,\n// matching the rebased SDF transforms without reconstructing world position.\n // Opacity is clamped once on the CPU when preparing this mesh.\n float opacityScale = recolor.a * blockOpacity;\n bool semanticOpacityDecoded = applySdfEdits(\n editPosition,\n rgba,\n shapeAmount\n );\n rgba.rgb *= recolor.rgb;\n if (!semanticOpacityDecoded && opacityScale >= 1.0) {\n // Neither SDFs nor the mesh opacity changed opacity, so preserve the\n // source alpha/shape encoding without any transcendental operations.\n rgba.a = clamp(rgba.a, 0.0, 1.0);\n } else {\n if (!semanticOpacityDecoded) {\n rgba.a = decodeSemanticOpacity(\n clamp(rgba.a, 0.0, 1.0),\n shapeAmount\n );\n }\n float semanticOpacity = rgba.a * opacityScale;\n if (semanticOpacity <= 1.0) {\n rgba.a = clamp(semanticOpacity, 0.0, 1.0);\n shapeAmount = 0.0;\n } else {\n rgba.a = 1.0;\n shapeAmount = encodeWideSemanticOpacity(semanticOpacity);\n }\n }\n\n encodeSplatLnScale(\n target,\n target2,\n center,\n lnScales,\n quaternion,\n rgba,\n shapeAmount\n );\n}\n\nvoid main() {\n int targetIndex = int(targetLayer << SPLAT_TEX_LAYER_BITS)\n + int(uint(gl_FragCoord.y) << SPLAT_TEX_WIDTH_BITS)\n + int(gl_FragCoord.x);\n int index = targetIndex - targetBase;\n\n target = uvec4(0u);\n target2 = uvec4(0u);\n #if GSL_STOCHASTIC_SEEDS\n targetSeed = 0u;\n #endif\n if (index >= 0 && index < targetCount) {\n produceSplat(index);\n }\n}\n","import * as THREE from \"three\";\n\n// \"Identity\" vertex shader that just passes through the position.\nexport const IDENT_VERTEX_SHADER = `\nprecision highp float;\n\nin vec3 position;\n\nvoid main() {\n gl_Position = vec4(position.xy, 0.0, 1.0);\n}\n`;\n\n// Synchronous uploads share this CPU-only view; it has no GPU storage.\nconst uploadView = new THREE.DataTexture(\n null,\n 1,\n 1,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n);\n\nexport function uploadU32DataTextureRows(\n renderer: THREE.WebGLRenderer,\n texture: THREE.Texture,\n width: number,\n rows: number,\n data: Uint32Array,\n) {\n // Initialize before filling the shared view: onUpdate may trigger another upload.\n renderer.initTexture(texture);\n uploadView.image.data = data;\n uploadView.image.width = width;\n uploadView.image.height = rows;\n try {\n renderer.copyTextureToTexture(uploadView, texture);\n } finally {\n // Do not retain the sort buffer between uploads.\n uploadView.image.data = null;\n }\n}\n","import * as THREE from \"three\";\nimport { FullScreenQuad } from \"three/addons/postprocessing/Pass.js\";\nimport { SPLAT_TEX_HEIGHT, SPLAT_TEX_WIDTH } from \"../../data/defines\";\nimport {\n type GaussianSplatCompatibleRenderer,\n isWebGPURenderer,\n setRendererRenderTarget,\n} from \"../rendererUtils\";\nimport { type Uniforms, makeGenerateUniforms } from \"../uniforms\";\nimport { getShaders } from \"./shaders\";\nimport splatGenerate from \"./shaders/splatGenerate.glsl\";\nimport { IDENT_VERTEX_SHADER } from \"./textureUtils\";\n\n// Generate materials without and with the stochastic seed output.\nconst webGLMaterials: (THREE.RawShaderMaterial | undefined)[] = [];\nlet webGLUniforms: Uniforms | null = null;\nconst fullScreenQuad = new FullScreenQuad(\n new THREE.RawShaderMaterial({ visible: false }),\n);\n\n/** Sorted rendering needs no seed layer; stochastic draws read one per Splat. */\nexport function createWebGLAccumulatorTarget(\n width: number,\n height: number,\n depth: number,\n stochasticSeeds: boolean,\n) {\n const target = new THREE.WebGLArrayRenderTarget(width, height, depth, {\n depthBuffer: false,\n stencilBuffer: false,\n generateMipmaps: false,\n magFilter: THREE.NearestFilter,\n minFilter: THREE.NearestFilter,\n format: THREE.RGBAIntegerFormat,\n type: THREE.UnsignedIntType,\n });\n target.scissorTest = true;\n\n const second = target.texture.clone();\n target.textures = [target.texture, second];\n if (stochasticSeeds) {\n const seeds = target.texture.clone();\n seeds.format = THREE.RedIntegerFormat;\n seeds.name = \"SplatAccumulator.stochasticSeeds\";\n target.textures.push(seeds);\n }\n return target;\n}\n\n/** Whether an accumulator target stores stochastic sampling seeds. */\nexport function hasStochasticSeeds(target: THREE.WebGLArrayRenderTarget) {\n return target.textures.length > 2;\n}\n\nfunction getMaterial(stochasticSeeds: boolean) {\n const index = Number(stochasticSeeds);\n let material = webGLMaterials[index];\n if (!material) {\n getShaders();\n material = new THREE.RawShaderMaterial({\n glslVersion: THREE.GLSL3,\n vertexShader: IDENT_VERTEX_SHADER,\n fragmentShader: splatGenerate,\n // Both variants share one uniform set.\n uniforms: getWebGLGenerateUniforms(),\n defines: { GSL_STOCHASTIC_SEEDS: index },\n depthTest: false,\n depthWrite: false,\n });\n webGLMaterials[index] = material;\n }\n return material;\n}\n\nexport function getWebGLGenerateUniforms() {\n webGLUniforms ??= makeGenerateUniforms();\n return webGLUniforms;\n}\n\nexport function generateWebGLAccumulator(\n options: AccumulatorRenderOptions<THREE.WebGLRenderer>,\n) {\n const material = getMaterial(hasStochasticSeeds(options.target));\n fullScreenQuad.material = material;\n renderAccumulatorLayers(options, material.uniforms, () =>\n fullScreenQuad.render(options.renderer),\n );\n}\n\nexport type AccumulatorRenderOptions<\n Renderer extends\n GaussianSplatCompatibleRenderer = GaussianSplatCompatibleRenderer,\n> = {\n renderer: Renderer;\n target: THREE.WebGLArrayRenderTarget;\n base: number;\n count: number;\n};\n\n/** Draw row-aligned ranges into array layers with either WebGL renderer API. */\nexport function renderAccumulatorLayers(\n { renderer, target, base, count }: AccumulatorRenderOptions,\n uniforms: Uniforms,\n draw: () => void,\n) {\n const nodeRenderer = isWebGPURenderer(renderer) ? renderer : null;\n const previous = {\n target: renderer.getRenderTarget(),\n face: renderer.getActiveCubeFace(),\n level: renderer.getActiveMipmapLevel(),\n xr: renderer.xr.enabled,\n autoClear: renderer.autoClear,\n scissorTest: renderer.getScissorTest(),\n mrt: nodeRenderer?.getMRT() ?? null,\n };\n uniforms.targetBase.value = base;\n uniforms.targetCount.value = count;\n const nextBase =\n Math.ceil((base + count) / SPLAT_TEX_WIDTH) * SPLAT_TEX_WIDTH;\n const layerSize = SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT;\n\n try {\n renderer.xr.enabled = false;\n renderer.autoClear = false;\n nodeRenderer?.setScissorTest(true);\n nodeRenderer?.setMRT(null);\n while (base < nextBase) {\n const layer = Math.floor(base / layerSize);\n uniforms.targetLayer.value = layer;\n const layerBase = layer * layerSize;\n const yStart = Math.floor((base - layerBase) / SPLAT_TEX_WIDTH);\n const yEnd = Math.min(\n SPLAT_TEX_HEIGHT,\n Math.ceil((nextBase - layerBase) / SPLAT_TEX_WIDTH),\n );\n target.scissor.set(0, yStart, SPLAT_TEX_WIDTH, yEnd - yStart);\n renderer.setRenderTarget(target, layer);\n draw();\n base += SPLAT_TEX_WIDTH * (yEnd - yStart);\n }\n } finally {\n setRendererRenderTarget(\n renderer,\n previous.target,\n previous.face,\n previous.level,\n );\n nodeRenderer?.setMRT(previous.mrt);\n renderer.xr.enabled = previous.xr;\n renderer.autoClear = previous.autoClear;\n nodeRenderer?.setScissorTest(previous.scissorTest);\n }\n}\n","import * as THREE from \"three\";\nimport { NodeMaterial, QuadMesh, type WebGPURenderer } from \"three/webgpu\";\nimport { SPLAT_TEX_HEIGHT, SPLAT_TEX_WIDTH } from \"../../data/defines\";\nimport { createGenerateProgram } from \"../tsl/GenerateProgram\";\nimport { N, uniformBinding } from \"../tsl/shaderUtils\";\nimport { makeGenerateUniforms } from \"../uniforms\";\nimport {\n type AccumulatorRenderOptions,\n createWebGLAccumulatorTarget,\n renderAccumulatorLayers,\n} from \"../webgl/AccumulatorGenerator\";\n\nexport function createWebGLFallbackAccumulatorTarget(\n width: number,\n height: number,\n depth: number,\n stochasticSeeds: boolean,\n) {\n // The r186 fallback backend recognizes array attachments only at depth > 1.\n return createWebGLAccumulatorTarget(\n width,\n height,\n Math.max(2, depth),\n stochasticSeeds,\n );\n}\n\n/**\n * Rasterizes Splat records, and for stochastic targets stable sampling seeds,\n * into integer arrays.\n */\nexport class WebGLFallbackAccumulatorGenerator {\n readonly uniforms = makeGenerateUniforms();\n private readonly material = new NodeMaterial();\n private readonly quad = new QuadMesh(this.material);\n\n constructor(stochasticSeeds: boolean) {\n const targetBase = uniformBinding(this.uniforms, \"targetBase\", \"uint\");\n const targetLayer = uniformBinding(this.uniforms, \"targetLayer\", \"uint\");\n const generate = createGenerateProgram({ uniforms: this.uniforms });\n const second = N.property(\"uvec4\", \"gslAccumulatorB\");\n const seed = N.property(\"uint\", \"gslAccumulatorSeed\");\n const first = N.Fn(() => {\n // TSL texture loads and scissor rectangles use the same top-left origin.\n const pixel = N.uvec2(N.screenCoordinate.xy);\n const index = targetLayer\n .mul(SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT)\n .add(pixel.y.mul(SPLAT_TEX_WIDTH))\n .add(pixel.x)\n .sub(targetBase);\n const { accumulatorA, accumulatorB, stochasticSeed } = generate(index);\n second.assign(accumulatorB);\n if (stochasticSeeds) seed.assign(stochasticSeed);\n return accumulatorA;\n })();\n this.material.fragmentNode = stochasticSeeds\n ? N.outputStruct(first, second, seed)\n : N.outputStruct(first, second);\n this.material.depthTest = false;\n this.material.depthWrite = false;\n this.material.blending = THREE.NoBlending;\n this.material.toneMapped = false;\n }\n\n generate(options: AccumulatorRenderOptions<WebGPURenderer>) {\n if (options.count <= 0) return;\n renderAccumulatorLayers(options, this.uniforms, () =>\n this.quad.render(options.renderer),\n );\n }\n\n dispose() {\n this.material.dispose();\n }\n}\n","import * as THREE from \"three\";\n\nimport { SPLAT_TEX_WIDTH } from \"../data/defines\";\nimport { emptySplatTexture, getTextureSize } from \"../data/textureLayout\";\nimport { SplatEdit, SplatEdits } from \"../scene/SplatEdit\";\nimport { SplatMesh } from \"../scene/SplatMesh\";\nimport { threeRevision } from \"../utils/three\";\nimport { decomposeSplatTransform } from \"../utils/transforms\";\nimport {\n type GaussianSplatCompatibleRenderer,\n getViews,\n isWebGPURenderer,\n usesNativeWebGPU,\n} from \"./rendererUtils\";\nimport {\n WebGLFallbackAccumulatorGenerator,\n createWebGLFallbackAccumulatorTarget,\n} from \"./webgl-fallback/AccumulatorGenerator\";\nimport {\n createWebGLAccumulatorTarget,\n generateWebGLAccumulator,\n getWebGLGenerateUniforms,\n hasStochasticSeeds,\n} from \"./webgl/AccumulatorGenerator\";\n\nexport type SplatMapping = {\n node: SplatMesh;\n matrixWorld: THREE.Matrix4;\n source: SplatMesh[\"splats\"];\n version: number;\n sortVersion: number;\n centerVersion: number;\n mappingVersion: number;\n base: number;\n count: number;\n};\n\ntype GenerateUniforms = Record<string, THREE.IUniform>;\ntype SplatDataTextures = readonly [THREE.Texture, THREE.Texture];\n\nexport class SplatAccumulator {\n time = 0;\n deltaTime = 0;\n viewOrigin = new THREE.Vector3();\n private readonly previousOrigin = new THREE.Vector3();\n viewDirection = new THREE.Vector3();\n maxSplats = 0;\n numSplats = 0;\n target: THREE.WebGLArrayRenderTarget | null = null;\n mapping: SplatMapping[] = [];\n version = -1;\n mappingVersion = -1;\n\n private transformScale = new THREE.Vector3();\n private transformQuaternion = new THREE.Quaternion();\n private fallbackGenerator: WebGLFallbackAccumulatorGenerator | null = null;\n\n constructor() {\n if (threeRevision < 186) {\n throw new Error(\"Gaussian Splat Lite requires Three.js r186 or above\");\n }\n }\n\n dispose() {\n this.disposeStorage();\n this.mapping = [];\n this.numSplats = 0;\n this.version = -1;\n this.mappingVersion = -1;\n }\n\n private disposeStorage() {\n this.target?.dispose();\n this.target = null;\n this.fallbackGenerator?.dispose();\n this.fallbackGenerator = null;\n this.maxSplats = 0;\n }\n\n getTextures(): SplatDataTextures {\n const textures = this.target?.textures;\n return textures\n ? [textures[0], textures[1]]\n : SplatAccumulator.emptyTextures;\n }\n\n getStochasticSeeds(): THREE.Texture {\n return this.target?.textures[2] ?? SplatAccumulator.emptyTexture;\n }\n\n /** Whether this accumulator was generated for stochastic rendering. */\n get hasStochasticSeeds() {\n return this.target !== null && hasStochasticSeeds(this.target);\n }\n\n /**\n * Regenerate moved meshes in place, without changing the source ranges used\n * by an in-flight sort. WebGL backends only.\n */\n refreshTransforms(renderer: GaussianSplatCompatibleRenderer) {\n let changed = false;\n for (const entry of this.mapping) {\n const { node, source, base, count } = entry;\n if (entry.matrixWorld.equals(node.matrixWorld)) continue;\n // A new source/LOD mapping needs matching indices before it can be shown.\n if (\n !source ||\n source !== node.splats ||\n source.needsUpdate ||\n source.getNumSplats() !== count ||\n entry.centerVersion !== node.centerVersion ||\n entry.mappingVersion !== node.mappingVersion\n )\n continue;\n this.generate({ mesh: node, base, count, renderer });\n entry.matrixWorld.copy(node.matrixWorld);\n changed = true;\n }\n if (changed) this.version++;\n }\n\n generateMapping(splatCounts: number[], compact = false) {\n let maxSplats = 0;\n const mapping = splatCounts.map((count) => {\n const base = maxSplats;\n maxSplats += compact\n ? count\n : Math.ceil(count / SPLAT_TEX_WIDTH) * SPLAT_TEX_WIDTH;\n return { base, count };\n });\n return { maxSplats, mapping };\n }\n\n ensureGenerate({\n maxSplats,\n renderer,\n shrinkResources = false,\n stochasticSeeds = false,\n }: {\n maxSplats: number;\n renderer?: GaussianSplatCompatibleRenderer;\n shrinkResources?: boolean;\n stochasticSeeds?: boolean;\n }) {\n if (renderer && usesNativeWebGPU(renderer)) {\n throw new Error(\n \"Accumulator texture generation requires a WebGL backend\",\n );\n }\n const {\n width,\n height,\n depth,\n maxSplats: capacity,\n } = getTextureSize(Math.max(1, maxSplats), 1);\n const reusable = shrinkResources\n ? capacity === this.maxSplats\n : capacity <= this.maxSplats;\n\n const fallback = renderer !== undefined && isWebGPURenderer(renderer);\n if (\n this.target &&\n reusable &&\n fallback === (this.fallbackGenerator !== null) &&\n stochasticSeeds === hasStochasticSeeds(this.target)\n ) {\n return false;\n }\n // Keep the prepared mapping and versions while replacing only its GPU\n // storage. Full dispose() also severs references to source meshes.\n this.disposeStorage();\n\n this.maxSplats = capacity;\n this.target = fallback\n ? createWebGLFallbackAccumulatorTarget(\n width,\n height,\n depth,\n stochasticSeeds,\n )\n : createWebGLAccumulatorTarget(width, height, depth, stochasticSeeds);\n if (fallback)\n this.fallbackGenerator = new WebGLFallbackAccumulatorGenerator(\n stochasticSeeds,\n );\n return true;\n }\n\n prepareUniforms(\n mesh: SplatMesh,\n uniforms: GenerateUniforms,\n matrixWorld = mesh.matrixWorld,\n ) {\n const source = mesh.splats;\n if (!source) {\n throw new Error(\"SplatMesh has no source\");\n }\n source.setTextureUniforms(uniforms);\n // A mesh keeps its seed when other meshes enter/leave the packed mapping.\n // Combine it on the GPU with the physical source index, before LOD compaction.\n uniforms.stochasticSeedBase.value =\n Math.imul(mesh.id + 1, 0x9e3779b9) >>> 0;\n uniforms.numSh.value = Math.min(mesh.maxSh, source.getNumSh());\n\n uniforms.objectReflected.value = decomposeSplatTransform(\n matrixWorld,\n this.transformScale,\n this.transformQuaternion,\n );\n uniforms.objectBasis.value.setFromMatrix4(matrixWorld);\n uniforms.objectOffset.value.setFromMatrixPosition(matrixWorld);\n // THREE.Vector3 and Matrix4 use JS numbers, so this subtraction happens\n // before the value is narrowed to a float32 WebGL uniform.\n uniforms.objectOffset.value.sub(this.viewOrigin);\n // Match PlayCanvas' work-buffer transform: centers use the complete affine\n // basis, while splat shape uses the decomposed rotation and positive\n // per-axis scale. This is intentionally an approximation for non-uniform\n // transforms while preserving ordinary scale/quaternion storage and zero\n // scale axes.\n uniforms.objectLnScale.value.set(\n Math.log(this.transformScale.x),\n Math.log(this.transformScale.y),\n Math.log(this.transformScale.z),\n );\n uniforms.objectQuaternion.value.copy(this.transformQuaternion);\n uniforms.recolor.value.set(\n mesh.recolor.r,\n mesh.recolor.g,\n mesh.recolor.b,\n THREE.MathUtils.clamp(mesh.opacity, 0, 1),\n );\n\n const edits = mesh.sdfEdits;\n uniforms.numSdfs.value = edits?.numSdfs ?? 0;\n uniforms.numEdits.value = edits?.numEdits ?? 0;\n uniforms.sdfTexture.value = edits?.sdfTexture ?? SplatEdits.emptyTexture;\n uniforms.editTexture.value = edits?.editTexture ?? SplatEdits.emptyTexture;\n }\n\n generate({\n mesh,\n base,\n count,\n renderer,\n }: {\n mesh: SplatMesh;\n base: number;\n count: number;\n renderer: GaussianSplatCompatibleRenderer;\n }) {\n if (usesNativeWebGPU(renderer)) {\n throw new Error(\n \"Accumulator texture generation requires a WebGL backend\",\n );\n }\n if (base + count > this.maxSplats) {\n throw new Error(\"Splat generation range exceeds accumulator capacity\");\n }\n\n if (!this.target) throw new Error(\"Accumulator target is not initialized\");\n if (isWebGPURenderer(renderer)) {\n if (!this.fallbackGenerator)\n throw new Error(\"WebGL fallback accumulator is not initialized\");\n this.prepareUniforms(mesh, this.fallbackGenerator.uniforms);\n this.fallbackGenerator.generate({\n renderer,\n target: this.target,\n base,\n count,\n });\n return;\n }\n this.prepareUniforms(mesh, getWebGLGenerateUniforms());\n generateWebGLAccumulator({ renderer, target: this.target, base, count });\n }\n\n prepareGenerate({\n renderer,\n scene,\n timer,\n camera,\n layerCamera = camera,\n previous,\n frameCallbacks = true,\n }: {\n renderer: GaussianSplatCompatibleRenderer;\n scene: THREE.Scene;\n timer: THREE.Timer;\n camera: THREE.Camera;\n layerCamera?: THREE.Camera;\n previous: SplatAccumulator;\n frameCallbacks?: boolean;\n }) {\n // Preserve the previous metadata before replacing this accumulator's\n // mapping. Native WebGPU prepares this metadata in place, so reading these\n // values later would compare the new mapping with itself and suppress\n // required updates.\n const previousMapping = previous.mapping;\n const previousVersion = previous.version;\n const previousMappingVersion = previous.mappingVersion;\n\n const previousOrigin = this.previousOrigin.copy(previous.viewOrigin);\n this.viewOrigin.setFromMatrixPosition(camera.matrixWorld);\n this.viewDirection\n .setFromMatrixColumn(camera.matrixWorld, 2)\n .normalize()\n .negate();\n this.time = timer.getElapsed();\n this.deltaTime = timer.getDelta();\n\n // Meshes on any eye's layers draw in both eyes; each eye's projection\n // still culls to its own view.\n const layerMask = getViews(layerCamera).reduce(\n (mask, view) => mask | view.layers.mask,\n 0,\n );\n\n const allMeshes: SplatMesh[] = [];\n scene.traverse((node) => {\n if (node instanceof SplatMesh && (layerMask & node.layers.mask) !== 0) {\n allMeshes.push(node);\n }\n });\n\n const globalEdits = new Set<SplatEdit>();\n scene.traverseVisible((node) => {\n if (!(node instanceof SplatEdit)) return;\n let ancestor = node.parent;\n while (ancestor && !(ancestor instanceof SplatMesh)) {\n ancestor = ancestor.parent;\n }\n if (!ancestor) globalEdits.add(node);\n });\n\n const frameContext = {\n time: this.time,\n deltaTime: this.deltaTime,\n globalEdits: Array.from(globalEdits),\n };\n for (const mesh of allMeshes) {\n mesh.frameUpdate(frameContext, frameCallbacks);\n }\n\n const visibleMeshes: SplatMesh[] = [];\n scene.traverseVisible((node) => {\n // Mesh opacity is the final multiplier after SDF opacity edits, so zero\n // remains fully transparent even when an SDF sets or adds opacity.\n // Meshes without data reserve no range: native sorting reads every\n // index below numSplats.\n if (\n node instanceof SplatMesh &&\n node.splats &&\n (layerMask & node.layers.mask) !== 0 &&\n node.opacity > 0\n ) {\n visibleMeshes.push(node);\n }\n });\n const { maxSplats, mapping: ranges } = this.generateMapping(\n visibleMeshes.map((mesh) => mesh.numSplats),\n usesNativeWebGPU(renderer),\n );\n\n // Native WebGPU rebuilds the mapping every frame. Reuse this accumulator's\n // pose snapshots; its previous mapping is only compared by version below.\n const poses = this.mapping.map(({ matrixWorld }) => matrixWorld);\n this.mapping = [];\n this.numSplats = 0;\n ranges.forEach(({ base, count }, index) => {\n const node = visibleMeshes[index];\n if (!node.splats || count <= 0) return;\n this.mapping.push({\n node,\n matrixWorld: (poses.pop() ?? new THREE.Matrix4()).copy(\n node.matrixWorld,\n ),\n source: node.splats,\n version: node.version,\n sortVersion: node.sortVersion,\n centerVersion: node.centerVersion,\n mappingVersion: node.mappingVersion,\n base,\n count,\n });\n this.numSplats = Math.max(this.numSplats, base + count);\n });\n\n const { splatsUpdated, mappingUpdated, sortUpdated } = checkMappingVersions(\n previousMapping,\n this.mapping,\n );\n const shViewChanged =\n !this.viewOrigin.equals(previousOrigin) &&\n this.mapping.some(\n ({ node, source }) => node.maxSh > 0 && (source?.getNumSh() ?? 0) > 0,\n );\n this.version = previousVersion + (splatsUpdated || shViewChanged ? 1 : 0);\n this.mappingVersion = previousMappingVersion + (mappingUpdated ? 1 : 0);\n\n return {\n version: this.version,\n sortUpdated,\n requiredMaxSplats: getTextureSize(\n Math.max(1, maxSplats),\n usesNativeWebGPU(renderer) ? 256 : 1,\n ).maxSplats,\n generate: (shrinkResources = false, stochasticSeeds = false) => {\n this.ensureGenerate({\n maxSplats,\n renderer,\n shrinkResources,\n stochasticSeeds,\n });\n for (const { node, base, count } of this.mapping) {\n this.generate({ mesh: node, base, count, renderer });\n }\n },\n };\n }\n\n checkVersions(other: SplatMapping[]) {\n return checkMappingVersions(this.mapping, other);\n }\n\n static emptyTexture = emptySplatTexture;\n\n static emptyTextures: SplatDataTextures = [\n SplatAccumulator.emptyTexture,\n SplatAccumulator.emptyTexture,\n ];\n}\n\nfunction checkMappingVersions(\n previousMapping: SplatMapping[],\n nextMapping: SplatMapping[],\n) {\n if (previousMapping.length !== nextMapping.length) {\n return { splatsUpdated: true, mappingUpdated: true, sortUpdated: true };\n }\n const mappingUpdated = previousMapping.some((item, index) => {\n const next = nextMapping[index];\n return (\n item.node !== next.node ||\n item.base !== next.base ||\n item.count !== next.count ||\n item.mappingVersion !== next.mappingVersion\n );\n });\n if (mappingUpdated) {\n return { splatsUpdated: true, mappingUpdated: true, sortUpdated: true };\n }\n return {\n splatsUpdated: previousMapping.some(\n (item, index) => item.version !== nextMapping[index].version,\n ),\n mappingUpdated: false,\n sortUpdated: previousMapping.some(\n (item, index) => item.sortVersion !== nextMapping[index].sortVersion,\n ),\n };\n}\n","import * as THREE from \"three\";\n\nexport const SPLATS_PER_INSTANCE = 128;\n\n/** Repeated quads; position.z identifies the Splat within each instance. */\nexport class SplatGeometry extends THREE.InstancedBufferGeometry {\n constructor() {\n super();\n const vertices = new Float32Array(SPLATS_PER_INSTANCE * 12);\n const indices = new Uint16Array(SPLATS_PER_INSTANCE * 6);\n for (let splat = 0; splat < SPLATS_PER_INSTANCE; splat++) {\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = splat * 12 + vertex * 3;\n vertices[offset] = QUAD_VERTICES[vertex * 3];\n vertices[offset + 1] = QUAD_VERTICES[vertex * 3 + 1];\n vertices[offset + 2] = splat;\n }\n for (let index = 0; index < 6; index++)\n indices[splat * 6 + index] = splat * 4 + QUAD_INDICES[index];\n }\n this.setAttribute(\"position\", new THREE.BufferAttribute(vertices, 3));\n this.setIndex(new THREE.BufferAttribute(indices, 1));\n }\n\n setSplatCount(count: number) {\n this.instanceCount = Math.ceil(count / SPLATS_PER_INSTANCE);\n }\n}\n\nconst QUAD_VERTICES = new Float32Array([\n -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0,\n]);\n\n// The projected covariance basis reverses handedness, so clockwise local\n// triangles become counter-clockwise screen-space faces for FrontSide culling.\nconst QUAD_INDICES = new Uint16Array([0, 2, 1, 0, 3, 2]);\n","import type { Node } from \"three/webgpu\";\nimport type { Uniforms } from \"../uniforms\";\nimport {\n E,\n N,\n decodeAlphaShape,\n decodeCenter,\n decodeLnScales,\n decodeQuaternion,\n decodeRgba,\n quatQuat,\n quatVec,\n uniformBinding,\n} from \"./shaderUtils\";\n\nexport type ProjectionView = {\n projectionMatrix: Node<\"mat4\">;\n renderToViewQuat: Node<\"vec4\">;\n renderToViewPos: Node<\"vec3\">;\n renderToViewScale: Node<\"float\">;\n near: Node<\"float\">;\n far: Node<\"float\">;\n renderSize: Node<\"vec2\">;\n};\n\ntype ProjectionInput =\n | { first: Node<\"uvec4\">; second: Node<\"uvec4\"> }\n | {\n valid: Node<\"bool\">;\n center: Node<\"vec3\">;\n lnScales: Node<\"vec3\">;\n quaternion: Node<\"vec4\">;\n rgba: Node<\"vec4\">;\n shapeAmount: Node<\"float\">;\n };\n\nexport type SplatProjection = {\n valid: Node<\"bool\">;\n clipCenter: Node<\"vec4\">;\n viewDepth: Node<\"float\">;\n /** NDC offsets for each +/-1 quad corner. */\n axis1: Node<\"vec2\">;\n axis2: Node<\"vec2\">;\n /** Source color space; the draw stage applies encodeLinear. */\n rgba: Node<\"vec4\">;\n supportRadius: Node<\"float\">;\n /** A wide kernel's low 16 bits hold its edge fade as a half. */\n supportRadiusSquared: Node<\"float\">;\n kernelPower: Node<\"float\">;\n};\n\nconst scaleQuaternionToMatrix = N.Fn(\n ([scale, quaternion]: [Node<\"vec3\">, Node<\"vec4\">]) => {\n const x = quaternion.x;\n const y = quaternion.y;\n const z = quaternion.z;\n const w = quaternion.w;\n return N.mat3(\n N.vec3(\n scale.x.mul(N.float(1).sub(y.mul(y).add(z.mul(z)).mul(2))),\n scale.x.mul(x.mul(y).add(w.mul(z)).mul(2)),\n scale.x.mul(x.mul(z).sub(w.mul(y)).mul(2)),\n ),\n N.vec3(\n scale.y.mul(x.mul(y).sub(w.mul(z)).mul(2)),\n scale.y.mul(N.float(1).sub(x.mul(x).add(z.mul(z)).mul(2))),\n scale.y.mul(y.mul(z).add(w.mul(x)).mul(2)),\n ),\n N.vec3(\n scale.z.mul(x.mul(z).add(w.mul(y)).mul(2)),\n scale.z.mul(y.mul(z).sub(w.mul(x)).mul(2)),\n scale.z.mul(N.float(1).sub(x.mul(x).add(y.mul(y)).mul(2))),\n ),\n );\n },\n);\n\nconst gaussianSupportRadius = N.Fn(\n ([alpha, maximumRadius, minimumAlpha]: [\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n ]) => {\n const radius = maximumRadius.toVar();\n N.If(minimumAlpha.greaterThan(0), () => {\n radius.assign(\n maximumRadius.min(alpha.div(minimumAlpha).log().mul(2).max(0).sqrt()),\n );\n });\n return radius;\n },\n);\n\nconst wideSupportRadius = N.Fn(\n ([alpha, power, maximumRadius, minimumAlpha]: [\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n ]) => {\n const radius = maximumRadius.toVar();\n N.If(minimumAlpha.greaterThan(0), () => {\n // 1 - (1 - x)^power <= power * x for power >= 1.\n radius.assign(\n maximumRadius.min(\n alpha.mul(power).div(minimumAlpha).log().mul(2).max(0).sqrt(),\n ),\n );\n });\n return radius;\n },\n);\n\n// A wide kernel can still be above minAlpha where its support ends. Returns\n// the edge fade: the amount the fragment stage subtracts so the kernel,\n// rescaled about its peak, reaches minAlpha there instead. A Gaussian's fade\n// follows from its alpha alone; see the edgeFade uniform.\nconst wideEdgeFade = N.Fn(\n ([alpha, power, radiusSquared, minimumAlpha]: [\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n Node<\"float\">,\n ]) => {\n const edgeKernel = N.float(1)\n .sub(N.float(1).sub(radiusSquared.mul(-0.5).exp()).pow(power))\n .toVar();\n // A kernel still flat at its edge cannot fade; bound the slope instead.\n return alpha\n .mul(edgeKernel)\n .sub(minimumAlpha)\n .max(0)\n .div(N.float(1).sub(edgeKernel).max(0.001));\n },\n);\n\n/** Shared projection for vertex and compute paths. Call inside a TSL Fn. */\nexport function createProjectionProgram(\n uniforms: Uniforms,\n view: ProjectionView,\n) {\n const {\n projectionMatrix,\n renderToViewQuat,\n renderToViewPos,\n renderToViewScale,\n near,\n far,\n renderSize,\n } = view;\n const maxStdDev = uniformBinding(uniforms, \"maxStdDev\", \"float\");\n const minPixelRadius = uniformBinding(uniforms, \"minPixelRadius\", \"float\");\n const minAlpha = uniformBinding(uniforms, \"minAlpha\", \"float\");\n const preBlurAmount = uniformBinding(uniforms, \"preBlurAmount\", \"float\");\n const blurAmount = uniformBinding(uniforms, \"blurAmount\", \"float\");\n const clipXY = uniformBinding(uniforms, \"clipXY\", \"float\");\n const focalAdjustment = uniformBinding(uniforms, \"focalAdjustment\", \"float\");\n\n return (source: ProjectionInput, includeColor = true): SplatProjection => {\n // This is a JS-time choice, not a shader branch. WebGL still reads its\n // packed accumulator; native compute consumes transformed float32 values.\n const packed = \"first\" in source;\n const valid = N.bool(false).toVar();\n const projectedClipCenter = N.vec4(0, 0, 2, 1).toVar();\n const projectedViewDepth = N.float(0).toVar();\n const projectedAxis1 = N.vec2(0).toVar();\n const projectedAxis2 = N.vec2(0).toVar();\n const projectedRgba = N.vec4(0).toVar();\n const projectedSupportRadius = N.float(0).toVar();\n const projectedSupportRadiusSquared = N.float(0).toVar();\n const projectedKernelPower = N.float(0).toVar();\n const alphaShape = packed\n ? decodeAlphaShape(source.first)\n : N.vec2(source.rgba.a, source.shapeAmount).clamp(0, 1);\n const alpha = alphaShape.x.toVar();\n const sourceValid = packed ? N.bool(true) : source.valid;\n\n const sourceVisible = sourceValid\n .and(alpha.greaterThanEqual(minAlpha))\n .and(alpha.greaterThan(0));\n N.If(sourceVisible, () => {\n const center = packed ? decodeCenter(source.first) : source.center;\n const viewCenter = quatVec(renderToViewQuat, center)\n .mul(renderToViewScale)\n .add(renderToViewPos);\n const clipCenter = N.vec4(0).toVar();\n const centerVisible = N.bool(false).toVar();\n const depthVisible = viewCenter.z\n .lessThan(near.negate())\n .and(viewCenter.z.greaterThan(far.negate()));\n N.If(depthVisible, () => {\n clipCenter.assign(projectionMatrix.mul(N.vec4(viewCenter, 1)));\n const clip = clipCenter.w.mul(clipXY);\n centerVisible.assign(\n clipCenter.x\n .abs()\n .lessThanEqual(clip)\n .and(clipCenter.y.abs().lessThanEqual(clip)),\n );\n });\n\n N.If(centerVisible, () => {\n const lnScales = packed\n ? decodeLnScales(source.second)\n : source.lnScales;\n const scales = lnScales.exp().mul(renderToViewScale).toVar();\n N.If(N.all(scales.equal(N.vec3(0))).not(), () => {\n const kernelShape = alphaShape.y.min(1).mul(4).add(1);\n const kernelPower = N.float(0).toVar();\n N.If(kernelShape.greaterThan(1), () => {\n kernelPower.assign(\n kernelShape.mul(kernelShape).sub(1).div(E).exp(),\n );\n });\n const maximumSupportRadius = maxStdDev.add(\n kernelShape.sub(1).max(0).mul(0.7),\n );\n const supportRadius = maximumSupportRadius.toVar();\n\n const viewQuaternion = quatQuat(\n renderToViewQuat,\n // Keep the unit-quaternion constraint without oct/angle quantization.\n packed\n ? decodeQuaternion(source.second.w)\n : source.quaternion.normalize(),\n );\n const rotationScale = scaleQuaternionToMatrix(scales, viewQuaternion);\n const scaledRenderSize = renderSize.mul(focalAdjustment).toVar();\n const focal = scaledRenderSize\n .mul(0.5)\n .mul(\n N.vec2(\n projectionMatrix.element(0).element(0),\n projectionMatrix.element(1).element(1),\n ),\n );\n const j0 = N.vec3(0).toVar();\n const j1 = N.vec3(0).toVar();\n const isOrthographic = projectionMatrix\n .element(2)\n .element(3)\n .equal(0);\n N.If(isOrthographic, () => {\n j0.assign(N.vec3(focal.x, 0, 0));\n j1.assign(N.vec3(0, focal.y, 0));\n }).Else(() => {\n const invZ = N.float(1).div(viewCenter.z);\n const firstJacobian = focal.mul(invZ);\n const secondJacobian = firstJacobian\n .mul(viewCenter.xy)\n .mul(invZ)\n .negate();\n j0.assign(N.vec3(firstJacobian.x, 0, secondJacobian.x));\n j1.assign(N.vec3(0, firstJacobian.y, secondJacobian.y));\n });\n\n const transposed = rotationScale.transpose();\n const p0 = transposed.mul(j0);\n const p1 = transposed.mul(j1);\n const a = p0.dot(p0).add(preBlurAmount).toVar();\n const b = p0.dot(p1);\n const d = p1.dot(p1).add(preBlurAmount).toVar();\n const detOrig = a.mul(d).sub(b.mul(b)).toVar();\n N.If(blurAmount.equal(0), () => {\n // No opacity compensation is needed, but reject degenerate covariance.\n N.If(detOrig.greaterThan(0).not(), () => {\n alpha.assign(0);\n });\n }).Else(() => {\n a.addAssign(blurAmount);\n d.addAssign(blurAmount);\n const det = a.mul(d).sub(b.mul(b)).toVar();\n N.If(det.greaterThan(0), () => {\n alpha.mulAssign(detOrig.div(det).max(0).sqrt());\n }).Else(() => {\n alpha.assign(0);\n });\n });\n\n const alphaVisible = alpha\n .greaterThanEqual(minAlpha)\n .and(alpha.greaterThan(0));\n N.If(alphaVisible, () => {\n N.If(kernelPower.equal(0), () => {\n supportRadius.assign(\n gaussianSupportRadius(alpha, supportRadius, minAlpha),\n );\n }).Else(() => {\n supportRadius.assign(\n wideSupportRadius(alpha, kernelPower, supportRadius, minAlpha),\n );\n });\n const eigenAverage = a.add(d).mul(0.5).toVar();\n const eigenDelta = N.vec2(a.sub(d).mul(0.5), b).length().toVar();\n const eigen1 = eigenAverage.add(eigenDelta).toVar();\n // Keep a small positive minor axis when subtraction rounds to zero.\n const eigen2 = eigenAverage.sub(eigenDelta).max(1e-4).toVar();\n const supportScale = N.select(\n maximumSupportRadius.greaterThan(0),\n supportRadius.div(maximumSupportRadius),\n 0,\n ).toVar();\n const maxProjectedRadius = renderSize.x\n .min(renderSize.y)\n .mul(focalAdjustment);\n const fullScale1 = maxProjectedRadius.min(\n maximumSupportRadius.mul(eigen1.sqrt()),\n );\n const fullScale2 = maxProjectedRadius.min(\n maximumSupportRadius.mul(eigen2.sqrt()),\n );\n // Match the internal projection scale to keep the cutoff in screen pixels.\n const minProjectedRadius = minPixelRadius.mul(focalAdjustment);\n\n N.If(\n fullScale1\n .mul(supportScale)\n .greaterThanEqual(minProjectedRadius)\n .or(\n fullScale2\n .mul(supportScale)\n .greaterThanEqual(minProjectedRadius),\n ),\n () => {\n const supportRadiusSquared = supportRadius\n .mul(supportRadius)\n .toVar();\n N.If(kernelPower.notEqual(0), () => {\n // A wide kernel carries its edge fade in the low half of\n // its squared radius. Round that radius down to its high\n // half first, with room for the fade, so the support never\n // grows. Only kernels that passed the size cutoff pay for\n // this.\n const highHalf = N.floatBitsToUint(\n supportRadiusSquared.mul(0.996),\n )\n .bitAnd(N.uint(0xffff0000))\n .toVar();\n const edgeFade = wideEdgeFade(\n alpha,\n kernelPower,\n N.uintBitsToFloat(highHalf),\n minAlpha,\n );\n supportRadiusSquared.assign(\n N.uintBitsToFloat(\n highHalf.bitOr(N.packHalf2x16(N.vec2(edgeFade, 0))),\n ),\n );\n supportRadius.assign(supportRadiusSquared.sqrt());\n supportScale.assign(\n N.select(\n maximumSupportRadius.greaterThan(0),\n supportRadius.div(maximumSupportRadius),\n 0,\n ),\n );\n });\n // Only surviving splats need an oriented covariance basis.\n const eigenVector1 = N.vec2(0).toVar();\n N.If(b.abs().greaterThan(0.001), () => {\n eigenVector1.assign(N.vec2(b, eigen1.sub(a)).normalize());\n }).Else(() => {\n eigenVector1.assign(\n N.select(a.greaterThanEqual(d), N.vec2(1, 0), N.vec2(0, 1)),\n );\n });\n const eigenVector2 = N.vec2(\n eigenVector1.y,\n eigenVector1.x.negate(),\n );\n projectedClipCenter.assign(clipCenter);\n projectedViewDepth.assign(viewCenter.z.negate());\n const scale1 = fullScale1.mul(supportScale);\n const scale2 = fullScale2.mul(supportScale);\n projectedAxis1.assign(\n eigenVector1.mul(scale1).mul(2).div(scaledRenderSize),\n );\n projectedAxis2.assign(\n eigenVector2.mul(scale2).mul(2).div(scaledRenderSize),\n );\n projectedRgba.assign(\n N.vec4(\n includeColor\n ? (packed\n ? decodeRgba(source.second, alpha).rgb\n : source.rgba.rgb\n ).max(0)\n : N.vec3(0),\n alpha,\n ),\n );\n projectedSupportRadius.assign(supportRadius);\n projectedSupportRadiusSquared.assign(supportRadiusSquared);\n projectedKernelPower.assign(kernelPower);\n valid.assign(true);\n },\n );\n });\n });\n });\n });\n\n return {\n valid,\n clipCenter: projectedClipCenter,\n viewDepth: projectedViewDepth,\n axis1: projectedAxis1,\n axis2: projectedAxis2,\n rgba: projectedRgba,\n supportRadius: projectedSupportRadius,\n supportRadiusSquared: projectedSupportRadiusSquared,\n kernelPower: projectedKernelPower,\n };\n };\n}\n","import * as THREE from \"three\";\nimport type { Node } from \"three/webgpu\";\nimport { getViews } from \"../rendererUtils\";\nimport type { Uniforms } from \"../uniforms\";\nimport type { ProjectionView } from \"./ProjectionProgram\";\nimport { N, uniformBinding } from \"./shaderUtils\";\n\n/** Eye of the current WebXR draw; multiview draws both eyes at once. */\nexport function viewIndex(camera: THREE.Camera): Node<\"uint\"> {\n if (getViews(camera)[0] === camera) return N.uint(0);\n return (camera as { isMultiViewCamera?: boolean }).isMultiViewCamera\n ? N.builtin(\"gl_ViewID_OVR\")\n : N.cameraIndex;\n}\n\n/** Viewport data for drawing splats that have already been projected. */\nexport function splatViewportUniforms(\n uniforms: Uniforms,\n camera: THREE.Camera,\n) {\n const eyes = getViews(camera);\n if (eyes[0] === camera) {\n return {\n renderSize: uniformBinding(uniforms, \"renderSize\", \"vec2\"),\n viewportOrigin: uniformBinding(uniforms, \"viewportOrigin\", \"vec2\"),\n };\n }\n\n // WebXR eye viewports are physical pixels; Three draws them as given.\n const views = eyes.map(() => new THREE.Vector4());\n const viewData = N.uniformArray<\"vec4\">(views, \"vec4\").onObjectUpdate(\n ({ camera }) => {\n getViews(camera as THREE.Camera).forEach((eye, i) => {\n const size = uniforms.renderSize.value;\n views[i].set(\n eye.viewport?.z ?? size.x,\n eye.viewport?.w ?? size.y,\n eye.viewport?.x ?? 0,\n eye.viewport?.y ?? 0,\n );\n });\n },\n );\n const index = viewIndex(camera);\n const viewport = viewData.element(index);\n return { renderSize: viewport.xy, viewportOrigin: viewport.zw };\n}\n\nexport function splatViewUniforms(\n uniforms: Uniforms,\n camera: THREE.Camera,\n): Omit<ProjectionView, \"projectionMatrix\"> & { viewportOrigin: Node<\"vec2\"> } {\n const eyes = getViews(camera);\n if (eyes[0] === camera) {\n return {\n renderSize: uniformBinding(uniforms, \"renderSize\", \"vec2\"),\n viewportOrigin: uniformBinding(uniforms, \"viewportOrigin\", \"vec2\"),\n renderToViewQuat: uniformBinding(uniforms, \"renderToViewQuat\", \"vec4\"),\n renderToViewPos: uniformBinding(uniforms, \"renderToViewPos\", \"vec3\"),\n renderToViewScale: uniformBinding(uniforms, \"renderToViewScale\", \"float\"),\n near: uniformBinding(uniforms, \"near\", \"float\"),\n far: uniformBinding(uniforms, \"far\", \"float\"),\n };\n }\n\n // WebXR draws do not call onBeforeRender separately for each eye.\n // Pack rotation, position/scale, viewport/clipping and pixel origin per eye.\n const views = eyes.flatMap(() => [\n new THREE.Vector4(),\n new THREE.Vector4(),\n new THREE.Vector4(),\n new THREE.Vector4(),\n ]);\n const matrix = new THREE.Matrix4();\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n const viewData = N.uniformArray<\"vec4\">(views, \"vec4\").onObjectUpdate(\n ({ camera }) => {\n (getViews(camera as THREE.Camera) as THREE.PerspectiveCamera[]).forEach(\n (eye, i) => {\n // Subtract the world origin in CPU double precision before GPU upload.\n matrix.makeTranslation(uniforms.renderOrigin.value);\n matrix.premultiply(eye.matrixWorldInverse);\n matrix.decompose(position, rotation, scale);\n views[i * 4].set(rotation.x, rotation.y, rotation.z, rotation.w);\n views[i * 4 + 1].set(\n position.x,\n position.y,\n position.z,\n (scale.x + scale.y + scale.z) / 3,\n );\n const size = uniforms.renderSize.value;\n views[i * 4 + 2].set(\n eye.viewport?.z ?? size.x,\n eye.viewport?.w ?? size.y,\n eye.near,\n eye.far,\n );\n views[i * 4 + 3].set(\n eye.viewport?.x ?? 0,\n eye.viewport?.y ?? 0,\n 0,\n 0,\n );\n },\n );\n },\n );\n const index = viewIndex(camera);\n const offset = index.mul(4);\n const positionScale = viewData.element(offset.add(1));\n const viewportClip = viewData.element(offset.add(2));\n return {\n renderSize: viewportClip.xy,\n viewportOrigin: viewData.element(offset.add(3)).xy,\n renderToViewQuat: viewData.element(offset),\n renderToViewPos: positionScale.xyz,\n renderToViewScale: positionScale.w,\n near: viewportClip.z,\n far: viewportClip.w,\n };\n}\n","import * as THREE from \"three\";\nimport type { Node, NodeBuilder } from \"three/webgpu\";\nimport { NodeMaterial, type TextureNode } from \"three/webgpu\";\nimport { SPLATS_PER_INSTANCE } from \"../SplatGeometry\";\nimport { ORDERING_TEXTURE_WIDTH, type Uniforms } from \"../uniforms\";\nimport { createProjectionProgram } from \"./ProjectionProgram\";\nimport {\n N,\n load2D,\n loadArray,\n splatTexCoord,\n textureBinding,\n uniformBinding,\n} from \"./shaderUtils\";\nimport { materialCamera } from \"./tslCompat\";\nimport { splatViewUniforms } from \"./viewUniforms\";\n\nexport type ProjectedVertexData = {\n clipPosition: Node<\"vec4\">;\n /** Source color space; this material applies encodeLinear. */\n rgba: Node<\"vec4\">;\n splatUv: Node<\"vec2\">;\n /** Stochastic variant only. */\n stochasticSeed?: Node<\"uint\">;\n /** A wide kernel's low 16 bits hold its edge fade as a half. */\n supportRadiusSquared: Node<\"float\">;\n kernelPower: Node<\"float\">;\n viewportOrigin: Node<\"vec2\">;\n};\n\nexport type SplatNodeMaterial = NodeMaterial & { uniforms: Uniforms };\n\nconst stochasticHash = N.Fn(([input]: [Node<\"uint\">]) => {\n const value = N.uint(input).toVar();\n value.bitXorAssign(value.shiftRight(16));\n value.mulAssign(N.uint(0x7feb352d));\n value.bitXorAssign(value.shiftRight(15));\n value.mulAssign(N.uint(0x846ca68b));\n value.bitXorAssign(value.shiftRight(16));\n return value;\n});\n\nfunction createSplatFragment(\n minAlpha: Node<\"float\">,\n edgeFade: Node<\"vec2\">,\n stochasticNoise: TextureNode<\"uvec4\"> | null,\n) {\n // Per-Splat constants share one flat varying: RGB and kernel power as\n // halves, alpha and squared support radius as float32 bits. See packSplatVarying.\n const vSplat = N.varyingProperty(\"uvec4\", \"gslSplat\");\n const vSplatUv = N.varyingProperty(\"vec2\", \"gslSplatUv\");\n // Atlas offset: x in bits 0-4, y in 5-9, time in 10-14. See stochasticTileOffset.\n const vStochasticOffset = stochasticNoise\n ? N.varyingProperty(\"uint\", \"gslStochasticOffset\")\n : null;\n\n const fragmentNode = N.Fn(() => {\n const z2 = vSplatUv.dot(vSplatUv);\n z2.greaterThan(N.uintBitsToFloat(vSplat.w)).discard();\n const blueKernelPower = N.unpackHalf2x16(vSplat.y);\n const kernelPower = blueKernelPower.y;\n const kernelAlpha = z2.mul(-0.5).exp().toVar();\n const peakAlpha = N.uintBitsToFloat(vSplat.z);\n // A kernel still above minAlpha where its support ends fades to minAlpha\n // there: it is rescaled about its peak. A Gaussian's fade follows from\n // its alpha; a wide kernel carries its own in the low half of its squared\n // radius.\n const fade = N.float(0).toVar();\n N.If(kernelPower.notEqual(0), () => {\n kernelAlpha.assign(\n N.float(1).sub(N.float(1).sub(kernelAlpha).pow(kernelPower)),\n );\n fade.assign(N.unpackHalf2x16(vSplat.w).x);\n }).Else(() => {\n fade.assign(peakAlpha.mul(edgeFade.x).sub(edgeFade.y).max(0));\n });\n const alpha = peakAlpha.add(fade).mul(kernelAlpha).sub(fade).toVar();\n alpha.lessThan(minAlpha).discard();\n if (stochasticNoise && vStochasticOffset) {\n const pixel = N.uvec2(N.screenCoordinate.xy);\n const coord = N.ivec2(\n pixel.x.add(vStochasticOffset).bitAnd(31),\n pixel.y\n .add(vStochasticOffset.shiftRight(5))\n .bitAnd(31)\n .add(vStochasticOffset.shiftRight(10).mul(32)),\n );\n const randomValue = N.float(load2D(stochasticNoise, coord).r)\n .add(0.5)\n .div(32768);\n randomValue.greaterThanEqual(alpha).discard();\n }\n // Decode color only after the fragment survives coverage tests.\n return N.vec4(\n N.unpackHalf2x16(vSplat.x),\n blueKernelPower.x,\n stochasticNoise ? 1 : alpha,\n );\n })();\n\n return {\n vSplat,\n vSplatUv,\n vStochasticOffset,\n fragmentNode,\n };\n}\n\n// Keep XY fixed while advancing the STBN time axis. Independent per-Splat XYZ\n// offsets decorrelate overlapping coverage tests without translating the field.\nfunction stochasticTileOffset(\n seed: Node<\"uint\">,\n sample: Node<\"uint\">,\n viewportOrigin: Node<\"vec2\">,\n) {\n const hash = stochasticHash(seed).toVar();\n const origin = N.uvec2(viewportOrigin);\n const x = hash.sub(origin.x);\n const y = hash.shiftRight(5).sub(origin.y);\n const phase = hash.shiftRight(10).add(sample).bitAnd(31);\n return x\n .bitAnd(31)\n .bitOr(y.bitAnd(31).shiftLeft(5))\n .bitOr(phase.shiftLeft(10));\n}\n\n// Half RGB saturates at its largest finite value instead of overflowing after\n// sRGB linearization. Source alpha keeps float32 bits, but half kernel power\n// can still change the final coverage of wide kernels. The squared support\n// radius passes bit for bit: a wide kernel's low half is its edge fade.\nfunction packSplatVarying(\n rgba: Node<\"vec4\">,\n supportRadiusSquared: Node<\"float\">,\n kernelPower: Node<\"float\">,\n) {\n const rgb = rgba.rgb.min(65504);\n return N.uvec4(\n N.packHalf2x16(rgb.xy),\n N.packHalf2x16(N.vec2(rgb.z, kernelPower)),\n N.floatBitsToUint(rgba.a),\n N.floatBitsToUint(supportRadiusSquared),\n );\n}\n\n/**\n * Sorted and stochastic variants compile separate graphs, so sorted drawing\n * carries no coverage varyings, seed loads or mode branches.\n */\nexport function createSplatNodeMaterial({\n uniforms,\n orderingNode,\n vertexData,\n premultipliedAlpha,\n transparent,\n depthTest,\n depthWrite,\n stochastic,\n}: {\n uniforms: Uniforms;\n /** CPU ordering for drawing from accumulator textures. */\n orderingNode?: TextureNode<\"uvec4\">;\n /** Replaces accumulator projection, e.g. with a GPU projection cache. */\n vertexData?: (\n camera: THREE.Camera,\n stochastic: boolean,\n ) => ProjectedVertexData;\n premultipliedAlpha: boolean;\n transparent: boolean;\n depthTest: boolean;\n depthWrite: boolean;\n stochastic: boolean;\n}): SplatNodeMaterial {\n const minAlpha = uniformBinding(uniforms, \"minAlpha\", \"float\");\n const edgeFade = uniformBinding(uniforms, \"edgeFade\", \"vec2\");\n const encodeLinear = uniformBinding(uniforms, \"encodeLinear\", \"bool\");\n const stochasticSample = stochastic\n ? uniformBinding(uniforms, \"stochasticSample\", \"uint\")\n : null;\n // Accumulator textures are only read without a projection cache.\n const accumulator = vertexData\n ? null\n : {\n splats: textureBinding(uniforms, \"splats\", true),\n splats2: textureBinding(uniforms, \"splats2\", true),\n seeds: stochastic\n ? textureBinding(uniforms, \"stochasticSeeds\", true)\n : null,\n };\n const { vSplat, vSplatUv, vStochasticOffset, fragmentNode } =\n createSplatFragment(\n minAlpha,\n edgeFade,\n stochastic ? textureBinding(uniforms, \"stochasticNoise\") : null,\n );\n\n function buildVertex(builder: NodeBuilder) {\n const camera = materialCamera(builder);\n const clipPosition = N.vec4(0, 0, 2, 1).toVar();\n vSplat.assign(N.uvec4(0));\n vSplatUv.assign(N.vec2(0));\n vStochasticOffset?.assign(N.uint(0));\n const assignVertexData = (data: ProjectedVertexData) => {\n const rgba = data.rgba.toVar();\n // RGB is constant across the quad; decode its color space once\n // per vertex rather than for every covered fragment.\n N.If(encodeLinear, () => {\n rgba.rgb.assign(N.sRGBTransferEOTF(rgba.rgb));\n });\n clipPosition.assign(data.clipPosition);\n vSplat.assign(\n packSplatVarying(rgba, data.supportRadiusSquared, data.kernelPower),\n );\n vSplatUv.assign(data.splatUv);\n if (vStochasticOffset && stochasticSample && data.stochasticSeed) {\n // Coverage uses the same offset across every fragment of this Splat.\n vStochasticOffset.assign(\n stochasticTileOffset(\n data.stochasticSeed,\n stochasticSample,\n data.viewportOrigin,\n ),\n );\n }\n };\n\n if (vertexData) {\n assignVertexData(vertexData(camera, stochastic));\n return clipPosition;\n }\n if (!accumulator || !orderingNode) {\n throw new Error(\"Accumulator splat drawing requires an ordering texture\");\n }\n\n const view = splatViewUniforms(uniforms, camera);\n const project = createProjectionProgram(uniforms, {\n ...view,\n projectionMatrix: N.cameraProjectionMatrix,\n });\n const index = N.uint(N.instanceIndex)\n .mul(SPLATS_PER_INSTANCE)\n .add(N.uint(N.positionGeometry.z))\n .toVar();\n const splatIndex = N.uint(0xffffffff).toVar();\n // Every view, including both WebXR eyes, draws the one shared order.\n const loadOrdered = () => {\n const texel = index.shiftRight(2);\n const coord = N.ivec2(\n texel.mod(ORDERING_TEXTURE_WIDTH),\n texel.div(N.uint(ORDERING_TEXTURE_WIDTH)),\n );\n splatIndex.assign(load2D(orderingNode, coord).element(index.bitAnd(3)));\n };\n N.If(index.lessThan(uniformBinding(uniforms, \"splatCount\", \"uint\")), () => {\n if (!stochastic) {\n loadOrdered();\n return;\n }\n // Unsorted stochastic draws use source indices directly.\n splatIndex.assign(index);\n N.If(uniformBinding(uniforms, \"stochasticOrdering\", \"bool\"), loadOrdered);\n });\n\n N.If(splatIndex.notEqual(N.uint(0xffffffff)), () => {\n const texCoord = splatTexCoord(splatIndex);\n const first = loadArray(accumulator.splats, texCoord);\n const projected = project({\n first,\n second: loadArray(accumulator.splats2, texCoord),\n });\n N.If(projected.valid, () => {\n const ndcOffset = projected.axis1\n .mul(N.positionGeometry.x)\n .add(projected.axis2.mul(N.positionGeometry.y));\n const ndcCenter = projected.clipCenter.xyz.div(projected.clipCenter.w);\n assignVertexData({\n clipPosition: N.vec4(\n ndcCenter.xy.add(ndcOffset).mul(projected.clipCenter.w),\n projected.clipCenter.zw,\n ),\n rgba: projected.rgba,\n splatUv: N.positionGeometry.xy.mul(projected.supportRadius),\n // Fetch stable coverage seeds only after all projection cutoffs.\n stochasticSeed: accumulator.seeds\n ? loadArray(accumulator.seeds, texCoord).r\n : undefined,\n supportRadiusSquared: projected.supportRadiusSquared,\n kernelPower: projected.kernelPower,\n viewportOrigin: view.viewportOrigin,\n });\n });\n });\n\n return clipPosition;\n }\n\n return Object.assign(new NodeMaterial(), {\n uniforms,\n vertexNode: N.Fn(buildVertex)(),\n colorNode: fragmentNode,\n premultipliedAlpha,\n transparent,\n depthTest,\n depthWrite,\n side: THREE.FrontSide,\n allowOverride: false,\n fog: false,\n toneMapped: false,\n });\n}\n","import type * as THREE from \"three\";\nimport type { TextureNode, WebGPURenderer } from \"three/webgpu\";\nimport type { SplatMaterialOptions } from \"../backend\";\nimport type { Uniforms } from \"../uniforms\";\nimport {\n type ProjectedVertexData,\n type SplatNodeMaterial,\n createSplatNodeMaterial,\n} from \"./SplatMaterial\";\n\n/** Drawing shared by both WebGPURenderer backends. */\nexport class NodeSplatBackend {\n readonly sortedMaterial: SplatNodeMaterial;\n readonly stochasticMaterial: SplatNodeMaterial;\n\n constructor(\n readonly renderer: WebGPURenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n orderingNode?: TextureNode<\"uvec4\">,\n vertexData?: (\n camera: THREE.Camera,\n stochastic: boolean,\n ) => ProjectedVertexData,\n ) {\n const create = (stochastic: boolean) =>\n createSplatNodeMaterial({\n uniforms,\n ...options,\n orderingNode,\n vertexData,\n stochastic,\n });\n this.sortedMaterial = create(false);\n this.stochasticMaterial = create(true);\n }\n\n selectMaterial(stochastic: boolean) {\n return stochastic ? this.stochasticMaterial : this.sortedMaterial;\n }\n\n dispose() {\n this.sortedMaterial.dispose();\n this.stochasticMaterial.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport type { CPUOrderingUpdate } from \"../backend\";\nimport { ORDERING_TEXTURE_WIDTH, SPLATS_PER_ORDERING_ROW } from \"../uniforms\";\n\n/** CPU ordering storage shared by both WebGL backends; uploads stay backend-specific. */\nexport class OrderingTexture {\n texture: THREE.DataTexture | null = null;\n\n getCapacity(count: number) {\n return (\n Math.max(1, Math.ceil(count / SPLATS_PER_ORDERING_ROW)) *\n SPLATS_PER_ORDERING_ROW\n );\n }\n\n get data(): Uint32Array | null {\n return (this.texture?.image.data as Uint32Array | null) ?? null;\n }\n\n update(\n { ordering, activeSplats, requiredCapacity, shrink }: CPUOrderingUpdate,\n uploadRows: (texture: THREE.DataTexture, rows: number) => void,\n ) {\n const rows = requiredCapacity / SPLATS_PER_ORDERING_ROW;\n if (\n this.texture &&\n (rows > this.texture.image.height ||\n (shrink && rows !== this.texture.image.height))\n )\n this.dispose();\n if (!this.texture) {\n this.texture = new THREE.DataTexture(\n ordering,\n ORDERING_TEXTURE_WIDTH,\n rows,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n );\n this.texture.needsUpdate = true;\n } else {\n this.texture.image.data = ordering;\n if (activeSplats > 0)\n uploadRows(\n this.texture,\n Math.ceil(activeSplats / SPLATS_PER_ORDERING_ROW),\n );\n }\n return this.texture;\n }\n\n dispose() {\n this.texture?.dispose();\n this.texture = null;\n }\n}\n","import type * as THREE from \"three\";\nimport type { TextureNode, WebGPURenderer } from \"three/webgpu\";\nimport type { CPUOrderingUpdate, SplatMaterialOptions } from \"../backend\";\nimport { NodeSplatBackend } from \"../tsl/SplatBackend\";\nimport { uintTexture } from \"../tsl/tslCompat\";\nimport { type Uniforms, emptyOrdering } from \"../uniforms\";\nimport { OrderingTexture } from \"../webgl/OrderingTexture\";\n\ntype TextureUploadBackend = {\n updateTexture(\n texture: THREE.DataTexture,\n options: {\n width: number;\n height: number;\n image: THREE.DataTexture[\"image\"];\n },\n ): void;\n};\n\n/** TSL drawing with CPU-sorted indices stored in an integer texture. */\nexport class WebGLFallbackSplatBackend extends NodeSplatBackend {\n readonly kind = \"webgl-fallback\";\n private readonly ordering = new OrderingTexture();\n // Shared by the sorted and stochastic materials.\n private readonly orderingNode: TextureNode<\"uvec4\">;\n\n constructor(\n renderer: WebGPURenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n ) {\n const orderingNode = uintTexture(emptyOrdering);\n super(renderer, uniforms, options, orderingNode);\n this.orderingNode = orderingNode;\n }\n\n getOrderingCapacity(count: number) {\n return this.ordering.getCapacity(count);\n }\n\n get cpuOrdering(): Uint32Array | null {\n return this.ordering.data;\n }\n\n setCPUOrdering(update: CPUOrderingUpdate) {\n this.orderingNode.value = this.ordering.update(update, (texture, rows) => {\n // Finish any pending allocation before uploading only active rows.\n this.renderer.initTexture(texture);\n // The r186 fallback's copyTextureToTexture allocates a GPU source;\n // update the destination directly to avoid that staging texture.\n const backend = this.renderer.backend as unknown as TextureUploadBackend;\n backend.updateTexture(texture, {\n width: texture.image.width,\n height: rows,\n image: texture.image,\n });\n });\n }\n\n /** Unsorted draws read no ordering; the next sort allocates it again. */\n releaseOrdering() {\n this.ordering.dispose();\n this.orderingNode.value = emptyOrdering;\n }\n\n dispose() {\n super.dispose();\n this.ordering.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport { SPLATS_PER_INSTANCE } from \"../SplatGeometry\";\nimport type { SplatMaterialOptions } from \"../backend\";\nimport type { Uniforms } from \"../uniforms\";\nimport { getShaders } from \"./shaders\";\n\nexport function createWebGLSplatMaterial(\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n) {\n const shaders = getShaders();\n return new THREE.ShaderMaterial({\n ...options,\n defines: {\n SPLATS_PER_INSTANCE,\n GSL_STOCHASTIC: 0,\n },\n glslVersion: THREE.GLSL3,\n vertexShader: shaders.splatVertex,\n fragmentShader: shaders.splatFragment,\n uniforms,\n side: THREE.FrontSide,\n allowOverride: false,\n });\n}\n","import type * as THREE from \"three\";\nimport type { CPUOrderingUpdate, SplatMaterialOptions } from \"../backend\";\nimport { type Uniforms, emptyOrdering } from \"../uniforms\";\nimport { OrderingTexture } from \"./OrderingTexture\";\nimport { createWebGLSplatMaterial } from \"./SplatMaterial\";\nimport { uploadU32DataTextureRows } from \"./textureUtils\";\n\n/** WebGL materials and ordering-texture uploads. */\nexport class WebGLSplatBackend {\n readonly kind = \"webgl\";\n readonly material: THREE.ShaderMaterial;\n private readonly ordering = new OrderingTexture();\n\n constructor(\n readonly renderer: THREE.WebGLRenderer,\n private readonly uniforms: Uniforms,\n options: SplatMaterialOptions,\n ) {\n this.material = createWebGLSplatMaterial(uniforms, options);\n const extension = renderer\n .getContext()\n .getExtension(\"WEBGL_provoking_vertex\");\n extension?.provokingVertexWEBGL(extension.FIRST_VERTEX_CONVENTION_WEBGL);\n }\n\n selectMaterial(stochastic: boolean) {\n const { material } = this;\n const value = Number(stochastic);\n if (material.defines.GSL_STOCHASTIC !== value) {\n material.defines.GSL_STOCHASTIC = value;\n material.needsUpdate = true;\n }\n return material;\n }\n\n getOrderingCapacity(count: number) {\n return this.ordering.getCapacity(count);\n }\n\n get cpuOrdering(): Uint32Array | null {\n return this.ordering.data;\n }\n\n setCPUOrdering(update: CPUOrderingUpdate) {\n this.uniforms.ordering.value = this.ordering.update(\n update,\n (texture, rows) => {\n uploadU32DataTextureRows(\n this.renderer,\n texture,\n texture.image.width,\n rows,\n update.ordering,\n );\n },\n );\n }\n\n /** Unsorted draws read no ordering; the next sort allocates it again. */\n releaseOrdering() {\n this.ordering.dispose();\n this.uniforms.ordering.value = emptyOrdering;\n }\n\n dispose() {\n this.ordering.dispose();\n this.material.dispose();\n }\n}\n","import {\n AlwaysDepth,\n type Camera,\n ColorManagement,\n DepthFormat,\n DepthStencilFormat,\n type DepthTexture,\n Matrix4,\n NeverDepth,\n type OrthographicCamera,\n type PerspectiveCamera,\n type RenderTarget,\n type TextureDataType,\n Vector2,\n Vector3,\n} from \"three\";\n\ntype TAACamera = PerspectiveCamera | OrthographicCamera;\ntype TAAParameters = {\n depthThreshold: number;\n edgeDepthDiff: number;\n maxMotionLength: number;\n useSubpixelCorrection: boolean;\n};\n\nexport function createTAAState<\n FloatUniform extends { value: number },\n BoolUniform extends { value: boolean },\n Vec2Uniform extends { value: Vector2 },\n Vec3Uniform extends { value: Vector3 },\n Mat4Uniform extends { value: Matrix4 },\n>(\n makeUniform: {\n (value: number): FloatUniform;\n (value: boolean): BoolUniform;\n (value: Vector2): Vec2Uniform;\n (value: Vector3): Vec3Uniform;\n (value: Matrix4): Mat4Uniform;\n },\n targets: RenderTarget[],\n // Logarithmic depth is log2(distance + 1) / log2(far + 1) on WebGLRenderer\n // and log2(distance / near) / log2(far / near) on the node renderers.\n nodeLogDepth = false,\n) {\n const uniforms = {\n renderSize: makeUniform(new Vector2(1, 1)),\n projection: makeUniform(new Matrix4()),\n unjitteredProjection: makeUniform(new Matrix4()),\n previousProjection: makeUniform(new Matrix4()),\n viewToPreviousClip: makeUniform(new Matrix4()),\n previousViewToView: makeUniform(new Matrix4()),\n valid: makeUniform(false),\n reversed: makeUniform(false),\n logarithmic: makeUniform(false),\n // Log-depth parameters: x is the current frame, y is the previous frame.\n logFar: makeUniform(new Vector2()),\n logNear: makeUniform(new Vector2()),\n // Parameters are copied from the owner before each resolve.\n depthThreshold: makeUniform(0),\n edgeDepthDiff: makeUniform(0),\n maxMotionLength: makeUniform(0),\n useSubpixelCorrection: makeUniform(false),\n luminanceCoefficients: makeUniform(new Vector3()),\n };\n const baseProjection = new Matrix4();\n const previousViewProjection = new Matrix4();\n const previousWorld = new Matrix4();\n const viewMatrix = new Matrix4();\n return {\n uniforms,\n historyIndex: 0,\n jitterIndex: 0,\n reset() {\n uniforms.valid.value = false;\n this.jitterIndex = 0;\n },\n setSize(width: number, height: number) {\n const w = Math.max(1, Math.floor(width));\n const h = Math.max(1, Math.floor(height));\n if (targets[0].width === w && targets[0].height === h) return;\n for (const target of targets) target.setSize(w, h);\n uniforms.renderSize.value.set(w, h);\n this.reset();\n },\n // Only the capture target takes stencil; history stores plain depth.\n setStencil(stencil: boolean, depthType: TextureDataType) {\n const source = targets[0];\n const depthTexture = source.depthTexture as DepthTexture;\n if (source.stencilBuffer === stencil && depthTexture.type === depthType)\n return;\n source.dispose();\n source.stencilBuffer = stencil;\n depthTexture.format = stencil ? DepthStencilFormat : DepthFormat;\n depthTexture.type = depthType;\n },\n beginCapture(camera: TAACamera) {\n jitterProjection(\n camera,\n baseProjection,\n this.jitterIndex,\n uniforms.renderSize.value.x,\n uniforms.renderSize.value.y,\n );\n },\n endCapture(camera: TAACamera) {\n uniforms.projection.value.copy(camera.projectionMatrix);\n restoreProjection(camera, baseProjection);\n },\n prepareResolve(camera: TAACamera, parameters: TAAParameters) {\n // Three.js clamps the near plane the same way.\n const near = Math.max(camera.near, 1e-6);\n uniforms.logFar.value.x = Math.log2(\n nodeLogDepth ? camera.far / near : camera.far + 1,\n );\n uniforms.logNear.value.x = near;\n uniforms.unjitteredProjection.value.copy(camera.projectionMatrix);\n uniforms.viewToPreviousClip.value.multiplyMatrices(\n previousViewProjection,\n camera.matrixWorld,\n );\n uniforms.previousViewToView.value.multiplyMatrices(\n viewMatrix.copy(camera.matrixWorld).invert(),\n previousWorld,\n );\n uniforms.depthThreshold.value = parameters.depthThreshold;\n uniforms.edgeDepthDiff.value = parameters.edgeDepthDiff;\n uniforms.maxMotionLength.value = parameters.maxMotionLength;\n uniforms.useSubpixelCorrection.value = parameters.useSubpixelCorrection;\n ColorManagement.getLuminanceCoefficients(\n uniforms.luminanceCoefficients.value,\n );\n // Three r186 reverses AlwaysDepth/NeverDepth on both GPU backends.\n return uniforms.reversed.value ? NeverDepth : AlwaysDepth;\n },\n advance(camera: TAACamera) {\n previousViewProjection.multiplyMatrices(\n camera.projectionMatrix,\n viewMatrix,\n );\n previousWorld.copy(camera.matrixWorld);\n uniforms.previousProjection.value.copy(uniforms.projection.value);\n uniforms.logFar.value.y = uniforms.logFar.value.x;\n uniforms.logNear.value.y = uniforms.logNear.value.x;\n this.historyIndex = 1 - this.historyIndex;\n uniforms.valid.value = true;\n this.jitterIndex = (this.jitterIndex + 1) % taaJitterOffsets.length;\n },\n };\n}\n\nfunction halton(index: number, base: number) {\n let i = index;\n let fraction = 1;\n let result = 0;\n while (i > 0) {\n fraction /= base;\n result += fraction * (i % base);\n i = Math.floor(i / base);\n }\n return result;\n}\n\nconst taaJitterOffsets = Array.from({ length: 32 }, (_, i) => [\n halton(i + 1, 2) - 0.5,\n halton(i + 1, 3) - 0.5,\n]);\n\n// Native Splat projection uses the unjittered matrix for its compute cache.\nconst projections = new WeakMap<Camera, Matrix4>();\nexport const getTAAProjection = (camera: Camera) => projections.get(camera);\n\nfunction jitterProjection(\n camera: Camera,\n base: Matrix4,\n index: number,\n width: number,\n height: number,\n) {\n base.copy(camera.projectionMatrix);\n projections.set(camera, base);\n const [x, y] = taaJitterOffsets[index];\n const elements = camera.projectionMatrix.elements;\n for (let column = 0; column < 16; column += 4) {\n elements[column] -= ((2 * x) / width) * elements[column + 3];\n elements[column + 1] += ((2 * y) / height) * elements[column + 3];\n }\n camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();\n}\n\nfunction restoreProjection(camera: Camera, base: Matrix4) {\n projections.delete(camera);\n camera.projectionMatrix.copy(base);\n camera.projectionMatrixInverse.copy(base).invert();\n}\n","import * as THREE from \"three\";\nimport type { Node } from \"three/webgpu\";\nimport { StorageArrayTexture } from \"three/webgpu\";\nimport type { SplatProjection } from \"../tsl/ProjectionProgram\";\nimport { N, loadArray } from \"../tsl/shaderUtils\";\nimport { uintTexture } from \"../tsl/tslCompat\";\n\ntype TextureLimits = {\n maxTextureDimension2D: number;\n maxTextureArrayLayers: number;\n};\n\nfunction makeTexture() {\n const texture = new StorageArrayTexture(1, 1, 1);\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.minFilter = THREE.NearestFilter;\n texture.magFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n return texture;\n}\n\n// Round near-square caches to rows instead of source-data layers. Power-of-two\n// widths keep addressing cheap; balance array layers beyond a single plane.\nexport function getProjectionCacheSize(count: number, limits: TextureLimits) {\n if (!Number.isSafeInteger(count) || count > 0x1_0000_0000) {\n throw new RangeError(\"Projected Splat entries exceed uint32 addressing\");\n }\n const side = limits.maxTextureDimension2D;\n const maxWidth = 2 ** Math.floor(Math.log2(side));\n const depth = Math.ceil(count / (maxWidth * side));\n if (depth > limits.maxTextureArrayLayers) {\n throw new RangeError(\n \"Projected Splat textures exceed the WebGPU device texture limits\",\n );\n }\n const perLayer = Math.ceil(count / depth);\n const width = Math.min(\n maxWidth,\n 2 ** Math.ceil(Math.log2(Math.ceil(Math.sqrt(perLayer)))),\n );\n const height = Math.ceil(perLayer / width);\n return { width, height, depth };\n}\n\nconst cacheTexCoord = N.Fn(([index, size]: [Node<\"uint\">, Node<\"uvec4\">]) => {\n const value = N.uint(index);\n const row = value.shiftRight(size.w).toVar();\n const layer = N.uint(0).toVar();\n N.If(size.z.greaterThan(N.uint(1)), () => {\n layer.assign(row.div(size.y));\n });\n // Integer addressing stays exact above 2^24 entries; mono-layer caches need\n // no division. The fourth size component holds log2(width).\n return N.ivec3(\n value.bitAnd(size.x.sub(N.uint(1))),\n row.sub(layer.mul(size.y)),\n layer,\n );\n});\n\nfunction store(\n texture: StorageArrayTexture,\n coord: Node<\"ivec3\">,\n value: Node<\"uvec4\">,\n) {\n N.storageTexture(texture, coord.xy, value)\n .depth(coord.z)\n .toWriteOnly()\n .toStack();\n}\n\n/** Native projected records: compact layout, paired codec and texture ownership. */\nexport class ProjectionCache {\n // 32 bytes per compact slot and eye. RGB retains half precision; alpha,\n // squared support radius, kernel power and view depth retain their float32\n // bits.\n readonly textures = [makeTexture(), makeTexture()];\n readonly size = new THREE.Vector4(1, 1, 1, 0);\n private readonly dimensions = N.uniform(this.size, \"uvec4\").onObjectUpdate(\n () => this.size,\n );\n\n resize(size: ReturnType<typeof getProjectionCacheSize>) {\n for (const texture of this.textures)\n texture.setSize(size.width, size.height, size.depth);\n this.size.set(size.width, size.height, size.depth, Math.log2(size.width));\n }\n\n // Call after visibility and deferred color evaluation, inside the same guard.\n write(\n index: Node<\"uint\">,\n projection: SplatProjection,\n ndc: Node<\"vec2\">,\n pixelScale: Node<\"vec2\">,\n centerRange: Node<\"float\">,\n ) {\n const coord = cacheTexCoord(index, this.dimensions).toVar();\n // The axes are orthogonal before the per-component viewport division.\n const axis1 = projection.axis1.mul(pixelScale).toVar();\n const axis2 = projection.axis2.mul(pixelScale).toVar();\n const largest = axis1.abs().max(axis2.abs());\n // Scale only unusually large axes, per splat, to avoid overflowing half\n // without reducing the precision of unrelated splats.\n const exponent = N.int(\n N.floatBitsToUint(largest.x.max(largest.y)).shiftRight(23),\n );\n const scaleCode = N.uint(exponent.sub(141).max(0).add(7).div(8)).toVar();\n // Construct the reciprocal power of two without division.\n const invAxisScale = N.uintBitsToFloat(\n N.uint(127).sub(scaleCode.mul(8)).shiftLeft(23),\n ).toVar();\n const packedAxis = N.packHalf2x16(axis1.mul(invAxisScale)).toVar();\n // Cache the ratio of the existing half-precision lengths once per splat.\n const minorLength = N.unpackHalf2x16(\n N.packHalf2x16(N.vec2(axis2.mul(invAxisScale).length(), 0)),\n ).x;\n const axisRatio = minorLength\n .div(N.unpackHalf2x16(packedAxis).length().max(1e-20))\n .min(65504); // Keep degenerate axes finite when packing to half.\n // RGB and axis ratio are nonnegative. Their four unused sign bits\n // hold the shared axis exponent; the float32 fields remain untouched.\n const ratioRed = N.packHalf2x16(N.vec2(axisRatio, projection.rgba.r))\n .bitAnd(N.uint(0x7fff7fff))\n .bitOr(scaleCode.bitAnd(1).shiftLeft(15))\n .bitOr(scaleCode.bitAnd(2).shiftLeft(30));\n const greenBlue = N.packHalf2x16(projection.rgba.gb)\n .bitAnd(N.uint(0x7fff7fff))\n .bitOr(scaleCode.bitAnd(4).shiftLeft(13))\n .bitOr(scaleCode.bitAnd(8).shiftLeft(28));\n store(\n this.textures[0],\n coord,\n N.uvec4(\n N.packSnorm2x16(ndc.div(centerRange)),\n N.floatBitsToUint(projection.viewDepth),\n packedAxis,\n ratioRed,\n ),\n );\n store(\n this.textures[1],\n coord,\n N.uvec4(\n greenBlue,\n N.floatBitsToUint(projection.rgba.a),\n N.floatBitsToUint(projection.supportRadiusSquared),\n N.floatBitsToUint(projection.kernelPower),\n ),\n );\n }\n\n /**\n * A shared WebXR slot another eye draws: a transparent record whose\n * corners collapse to one point, behind a perspective camera.\n */\n writeHidden(index: Node<\"uint\">) {\n const coord = cacheTexCoord(index, this.dimensions).toVar();\n store(\n this.textures[0],\n coord,\n N.uvec4(0, N.floatBitsToUint(N.float(-1)), 0, 0),\n );\n store(this.textures[1], coord, N.uvec4(0));\n }\n\n // Call inside the per-eye visible-count guard. No cache loads precede it.\n read(\n index: Node<\"uint\">,\n pixelScale: Node<\"vec2\">,\n centerRange: Node<\"float\">,\n /** NDC translation from the cached projection to the drawn one. */\n jitter: Node<\"vec2\">,\n ) {\n const coord = cacheTexCoord(index, this.dimensions).toVar();\n const first = loadArray(uintTexture(this.textures[0]), coord).toVar();\n const second = loadArray(uintTexture(this.textures[1]), coord).toVar();\n const ndc = N.unpackSnorm2x16(first.x).mul(centerRange).add(jitter);\n const viewZ = N.uintBitsToFloat(first.y).negate();\n const matrix = N.cameraProjectionMatrix;\n const col0 = matrix.element(0);\n const col1 = matrix.element(1);\n const col2 = matrix.element(2);\n const col3 = matrix.element(3);\n const clipW = col2.w.mul(viewZ).add(col3.w).toVar();\n const clipZ = col2.z.mul(viewZ).add(col3.z).toVar();\n // Standard perspective, orthographic and asymmetric XR projections take\n // the fast path. Oblique/custom depth rows also depend on view X/Y.\n N.If(\n N.any(col0.zw.notEqual(N.vec2(0))).or(N.any(col1.zw.notEqual(N.vec2(0)))),\n () => {\n const a = col0.xy.sub(ndc.mul(col0.w));\n const b = col1.xy.sub(ndc.mul(col1.w));\n const rhs = ndc.mul(clipW).sub(col2.xy.mul(viewZ).add(col3.xy));\n const determinant = a.x.mul(b.y).sub(b.x.mul(a.y));\n const xy = N.vec2(\n rhs.x.mul(b.y).sub(b.x.mul(rhs.y)),\n a.x.mul(rhs.y).sub(rhs.x.mul(a.y)),\n )\n .div(determinant)\n .toVar();\n clipW.addAssign(col0.w.mul(xy.x).add(col1.w.mul(xy.y)));\n clipZ.addAssign(col0.z.mul(xy.x).add(col1.z.mul(xy.y)));\n },\n );\n const scaleCode = first.w\n .shiftRight(15)\n .bitAnd(1)\n .bitOr(first.w.shiftRight(30).bitAnd(2))\n .bitOr(second.x.shiftRight(13).bitAnd(4))\n .bitOr(second.x.shiftRight(28).bitAnd(8));\n const axisScale = N.uintBitsToFloat(\n scaleCode.mul(8).add(127).shiftLeft(23),\n );\n const axis1 = N.unpackHalf2x16(first.z).toVar();\n const ratioRed = N.unpackHalf2x16(first.w.bitAnd(N.uint(0x7fff7fff)));\n const greenBlue = N.unpackHalf2x16(second.x.bitAnd(N.uint(0x7fff7fff)));\n const axis2 = N.vec2(axis1.y, axis1.x.negate()).mul(ratioRed.x);\n const offset = axis1\n .mul(N.positionGeometry.x)\n .add(axis2.mul(N.positionGeometry.y))\n .mul(axisScale.div(pixelScale));\n // The squared radius passes to the fragment stage bit for bit: a wide\n // kernel's low half carries its edge fade.\n const supportRadiusSquared = N.uintBitsToFloat(second.z);\n return {\n clipPosition: N.vec4(ndc.add(offset).mul(clipW), clipZ, clipW),\n rgba: N.vec4(ratioRed.y, greenBlue, N.uintBitsToFloat(second.y)),\n splatUv: N.positionGeometry.xy.mul(supportRadiusSquared.sqrt()),\n supportRadiusSquared,\n kernelPower: N.uintBitsToFloat(second.w),\n };\n }\n\n dispose() {\n for (const texture of this.textures) texture.dispose();\n }\n}\n","import {\n type ComputeNode,\n IndirectStorageBufferAttribute,\n type Node,\n StorageBufferAttribute,\n type StorageBufferNode,\n} from \"three/webgpu\";\n\nimport { N, setIndirectDispatch } from \"../tsl/tslCompat\";\n\n/**\n * Key layout of one sort: full 32-bit or fast 24-bit back-to-front keys, or\n * 16-bit front-to-back keys for stochastic ordering.\n */\nexport type RadixSortMode = \"full\" | \"fast\" | \"front\";\n/** Values of the GPU mode uniform. */\nexport const RADIX_SORT_MODE_IDS = {\n full: 0,\n fast: 1,\n front: 2,\n} as const satisfies Record<RadixSortMode, number>;\n/**\n * Input key of an absent record. The first pass drops these records and\n * compacts the rest in input order, so the output order is deterministic.\n */\nexport const INVALID_SORT_KEY = 0xffffffff;\n\nconst RADIX_BITS = 8;\nconst RADIX_BUCKETS = 1 << RADIX_BITS;\nconst RADIX_PASSES = 32 / RADIX_BITS;\nconst MODE_PASSES = {\n full: RADIX_PASSES,\n fast: 24 / RADIX_BITS,\n front: 16 / RADIX_BITS,\n} satisfies Record<RadixSortMode, number>;\nconst MODES = Object.keys(MODE_PASSES) as RadixSortMode[];\nconst WORKGROUP_SIZE = 256;\nconst ELEMENTS_PER_THREAD = 8;\nconst ELEMENTS_PER_WORKGROUP = WORKGROUP_SIZE * ELEMENTS_PER_THREAD;\nconst PREFIX_ITEMS_PER_WORKGROUP = WORKGROUP_SIZE * 2;\nconst PREFIX_LEVELS = 3;\n\ntype BufferRef = { value: StorageBufferAttribute };\n\ntype WebGPURadixSortOptions = {\n /** GPU count of input keys other than INVALID_SORT_KEY. */\n count: Node<\"uint\">;\n /** RADIX_SORT_MODE_IDS value matching the input key encoding. */\n mode: Node<\"uint\">;\n maxComputeWorkgroupsPerDimension: number;\n maxStorageBufferBindingSize: number;\n};\n\ntype PrefixLevel = {\n scan: ComputeNode;\n add: ComputeNode | null;\n dispatch: IndirectStorageBufferAttribute;\n blockSums: BufferRef;\n};\n\nfunction storage(buffer: BufferRef, name: string) {\n return N.storage(buffer.value, \"uint\")\n .setName(name)\n .onObjectUpdate(() => buffer.value);\n}\n\nfunction makeBuffer(count: number) {\n return new StorageBufferAttribute(new Uint32Array(count), 1);\n}\n\nfunction makeBufferRef(count: number): BufferRef {\n return { value: makeBuffer(count) };\n}\n\nfunction workgroupIndex() {\n return N.workgroupId.y.mul(N.numWorkgroups.x).add(N.workgroupId.x);\n}\n\nfunction makeHistogramTask({\n input,\n blockSums,\n elementCount,\n bitOffset,\n workgroupCount,\n}: {\n input: BufferRef;\n blockSums: BufferRef;\n elementCount: Node<\"uint\">;\n bitOffset: number;\n workgroupCount: Node<\"uint\">;\n}) {\n const inputKeys = storage(input, \"gslRadixInputKeys\").toReadOnly();\n const sums = storage(blockSums, \"gslRadixBlockSums\");\n const bit = N.uint(bitOffset);\n const histogram = N.workgroupArray(\"uint\", RADIX_BUCKETS)\n .toAtomic()\n .setName(\"gslRadixHistogram\");\n\n return N.Fn(() => {\n const tid = N.invocationLocalIndex;\n const workgroup = workgroupIndex();\n\n N.atomicStore(histogram.element(tid), N.uint(0));\n N.workgroupBarrier();\n\n N.Loop(\n {\n start: N.uint(0),\n end: N.uint(ELEMENTS_PER_THREAD),\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: round }) => {\n const index = workgroup\n .mul(ELEMENTS_PER_WORKGROUP)\n .add(round.mul(WORKGROUP_SIZE))\n .add(tid);\n N.If(index.lessThan(elementCount), () => {\n const key = inputKeys.element(index).toVar();\n const tally = () => {\n const digit = key.shiftRight(bit).bitAnd(RADIX_BUCKETS - 1);\n N.atomicAdd(histogram.element(digit), N.uint(1));\n };\n // The first pass drops absent records.\n if (bitOffset === 0)\n N.If(key.notEqual(N.uint(INVALID_SORT_KEY)), tally);\n else tally();\n });\n },\n );\n\n N.workgroupBarrier();\n sums\n .element(tid.mul(workgroupCount).add(workgroup))\n .assign(N.atomicLoad(histogram.element(tid)));\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix histogram\");\n}\n\nfunction makePrefixScanTask(\n itemsBuffer: BufferRef,\n blockSumsBuffer: BufferRef,\n elementCount: Node<\"uint\">,\n) {\n const items = storage(itemsBuffer, \"gslPrefixItems\");\n const blockSums = storage(blockSumsBuffer, \"gslPrefixBlockSums\");\n const temp = N.workgroupArray(\"uint\", PREFIX_ITEMS_PER_WORKGROUP).setName(\n \"gslPrefixTemp\",\n );\n\n return N.Fn(() => {\n const tid = N.invocationLocalIndex;\n const workgroup = workgroupIndex();\n const first = workgroup.mul(PREFIX_ITEMS_PER_WORKGROUP).add(tid.mul(2));\n const second = first.add(1);\n\n temp.element(tid.mul(2)).assign(0);\n temp.element(tid.mul(2).add(1)).assign(0);\n N.If(first.lessThan(elementCount), () => {\n temp.element(tid.mul(2)).assign(items.element(first));\n });\n N.If(second.lessThan(elementCount), () => {\n temp.element(tid.mul(2).add(1)).assign(items.element(second));\n });\n\n // Expand the fixed scan levels while building the shader.\n for (\n let distance = PREFIX_ITEMS_PER_WORKGROUP >> 1, offset = 1;\n distance > 0;\n distance >>= 1, offset <<= 1\n ) {\n N.workgroupBarrier();\n N.If(tid.lessThan(distance), () => {\n const a = tid.mul(2).add(1).mul(offset).sub(1);\n const b = tid.mul(2).add(2).mul(offset).sub(1);\n temp.element(b).addAssign(temp.element(a));\n });\n }\n N.workgroupBarrier();\n\n N.If(tid.equal(0), () => {\n blockSums\n .element(workgroup)\n .assign(temp.element(N.uint(PREFIX_ITEMS_PER_WORKGROUP - 1)));\n temp.element(N.uint(PREFIX_ITEMS_PER_WORKGROUP - 1)).assign(0);\n });\n\n for (\n let distance = 1, offset = PREFIX_ITEMS_PER_WORKGROUP >> 1;\n distance < PREFIX_ITEMS_PER_WORKGROUP;\n distance <<= 1, offset >>= 1\n ) {\n N.workgroupBarrier();\n N.If(tid.lessThan(distance), () => {\n const a = tid.mul(2).add(1).mul(offset).sub(1);\n const b = tid.mul(2).add(2).mul(offset).sub(1);\n const value = temp.element(a).toVar();\n temp.element(a).assign(temp.element(b));\n temp.element(b).addAssign(value);\n });\n }\n\n N.workgroupBarrier();\n N.If(first.lessThan(elementCount), () => {\n items.element(first).assign(temp.element(tid.mul(2)));\n });\n N.If(second.lessThan(elementCount), () => {\n items.element(second).assign(temp.element(tid.mul(2).add(1)));\n });\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix prefix scan\");\n}\n\nfunction makePrefixAddTask(\n itemsBuffer: BufferRef,\n blockSumsBuffer: BufferRef,\n elementCount: Node<\"uint\">,\n) {\n const items = storage(itemsBuffer, \"gslPrefixItems\");\n const blockSums = storage(blockSumsBuffer, \"gslPrefixBlockSums\").toReadOnly();\n\n return N.Fn(() => {\n const workgroup = workgroupIndex();\n const first = workgroup\n .mul(PREFIX_ITEMS_PER_WORKGROUP)\n .add(N.invocationLocalIndex.mul(2));\n const second = first.add(1);\n N.If(first.lessThan(elementCount), () => {\n const value = blockSums.element(workgroup);\n items.element(first).addAssign(value);\n N.If(second.lessThan(elementCount), () => {\n items.element(second).addAssign(value);\n });\n });\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix prefix add\");\n}\n\nfunction makeReorderTask({\n inputKeysAttribute,\n outputKeysAttribute,\n inputValuesAttribute,\n outputValuesAttribute,\n prefixAttribute,\n elementCount,\n bitOffset,\n lastPass,\n workgroupCount,\n}: {\n inputKeysAttribute: BufferRef;\n outputKeysAttribute: BufferRef;\n inputValuesAttribute: BufferRef;\n outputValuesAttribute: BufferRef;\n prefixAttribute: BufferRef;\n elementCount: Node<\"uint\">;\n bitOffset: number;\n lastPass: boolean | Node<\"bool\">;\n workgroupCount: Node<\"uint\">;\n}) {\n const inputKeys = storage(\n inputKeysAttribute,\n \"gslRadixInputKeys\",\n ).toReadOnly();\n const outputKeys = storage(outputKeysAttribute, \"gslRadixOutputKeys\");\n const inputValues = storage(\n inputValuesAttribute,\n \"gslRadixInputValues\",\n ).toReadOnly();\n const outputValues = storage(outputValuesAttribute, \"gslRadixOutputValues\");\n const prefix = storage(prefixAttribute, \"gslRadixPrefix\").toReadOnly();\n const bitOffsetNode = N.uint(bitOffset);\n // Shared masks use [word][bucket] for the parallel bucket scan.\n const digitMasks = N.workgroupArray(\"uint\", RADIX_BUCKETS * 8)\n .toAtomic()\n .setName(\"gslRadixDigitMasks\");\n const digitOffsets = N.workgroupArray(\"uint\", RADIX_BUCKETS).setName(\n \"gslRadixDigitOffsets\",\n );\n\n return N.Fn(() => {\n const tid = N.invocationLocalIndex;\n const workgroup = workgroupIndex();\n const word = tid.shiftRight(5);\n const bit = tid.bitAnd(31);\n\n digitOffsets\n .element(tid)\n .assign(prefix.element(tid.mul(workgroupCount).add(workgroup)));\n // Each thread clears one mask word per group of WORKGROUP_SIZE words.\n for (let offset = 0; offset < RADIX_BUCKETS * 8; offset += WORKGROUP_SIZE)\n N.atomicStore(digitMasks.element(tid.add(offset)), N.uint(0));\n N.workgroupBarrier();\n\n N.Loop(\n {\n start: N.uint(0),\n end: N.uint(ELEMENTS_PER_THREAD),\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: round }) => {\n const index = workgroup\n .mul(ELEMENTS_PER_WORKGROUP)\n .add(round.mul(WORKGROUP_SIZE))\n .add(tid);\n const valid = index.lessThan(elementCount).toVar();\n const key = N.uint(0).toVar();\n const digit = N.uint(0).toVar();\n const value = N.uint(0).toVar();\n N.If(valid, () => {\n key.assign(inputKeys.element(index));\n // Absent records take no rank or output slot.\n if (bitOffset === 0)\n valid.assign(key.notEqual(N.uint(INVALID_SORT_KEY)));\n });\n N.If(valid, () => {\n digit.assign(key.shiftRight(bitOffsetNode).bitAnd(RADIX_BUCKETS - 1));\n value.assign(inputValues.element(index));\n N.atomicOr(\n digitMasks.element(word.mul(RADIX_BUCKETS).add(digit)),\n N.uint(1).shiftLeft(bit),\n );\n });\n\n N.workgroupBarrier();\n N.If(valid, () => {\n const sortedIndex = digitOffsets.element(digit).toVar();\n N.Loop(\n {\n start: N.uint(0),\n end: word,\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: precedingWord }) => {\n sortedIndex.addAssign(\n N.countOneBits(\n N.atomicLoad(\n digitMasks.element(\n precedingWord.mul(RADIX_BUCKETS).add(digit),\n ),\n ),\n ),\n );\n },\n );\n const lowerBits = N.uint(1).shiftLeft(bit).sub(1);\n sortedIndex.addAssign(\n N.countOneBits(\n N.atomicLoad(\n digitMasks.element(word.mul(RADIX_BUCKETS).add(digit)),\n ).bitAnd(lowerBits),\n ),\n );\n // Boolean cases are resolved while building the shader.\n if (lastPass === false) {\n outputKeys.element(sortedIndex).assign(key);\n } else if (lastPass !== true) {\n N.If(lastPass.not(), () => {\n outputKeys.element(sortedIndex).assign(key);\n });\n }\n outputValues.element(sortedIndex).assign(value);\n });\n\n N.If(round.lessThan(ELEMENTS_PER_THREAD - 1), () => {\n // Finish all rank reads before updating offsets and clearing masks.\n N.workgroupBarrier();\n const count = N.uint(0).toVar();\n N.Loop(\n {\n start: N.uint(0),\n end: N.uint(8),\n type: \"uint\",\n condition: \"<\",\n },\n ({ i: maskWord }) => {\n const maskIndex = maskWord.mul(RADIX_BUCKETS).add(tid);\n count.addAssign(\n N.countOneBits(\n N.atomicAnd(digitMasks.element(maskIndex), N.uint(0)),\n ),\n );\n },\n );\n digitOffsets.element(tid).addAssign(count);\n N.workgroupBarrier();\n });\n },\n );\n })()\n .computeKernel([WORKGROUP_SIZE])\n .setName(\"Splat radix reorder\");\n}\n\n/**\n * Stable 16-, 24- or 32-bit radix sort. The first pass compacts records whose\n * key is not INVALID_SORT_KEY, with the values the caller wrote to\n * `inputValues`. Borrows and overwrites input keys; their owner manages storage.\n */\nexport class WebGPURadixSort {\n capacity: number;\n readonly maxCapacity: number;\n readonly nodes: ComputeNode[];\n\n private readonly elementCount = N.uniform(0, \"uint\");\n private readonly keys: [BufferRef, BufferRef];\n private readonly values: [BufferRef, BufferRef];\n private readonly blockSums: BufferRef;\n // Count, padded histogram workgroups, and item count for each prefix level.\n private readonly counts = makeBufferRef(PREFIX_LEVELS + 2);\n private readonly sortDispatch = new IndirectStorageBufferAttribute(\n new Uint32Array(3),\n 1,\n );\n private readonly prefixLevels: PrefixLevel[] = [];\n // Mode of the last prepared sort; its pass count selects the output buffer.\n private mode: RadixSortMode = \"full\";\n private readonly maxWorkgroups: number;\n // Per mode, the dispatch list for each prefix depth.\n private readonly dispatchNodes: Record<RadixSortMode, ComputeNode[][]>;\n\n constructor(\n capacity: number,\n inputKeys: BufferRef,\n options: WebGPURadixSortOptions,\n ) {\n this.maxWorkgroups = options.maxComputeWorkgroupsPerDimension;\n this.maxCapacity = Math.min(\n 0xffffffff - ELEMENTS_PER_WORKGROUP + 1,\n Math.floor(options.maxStorageBufferBindingSize / 4),\n );\n const safeCapacity = this.validateCapacity(capacity);\n this.capacity = safeCapacity;\n // Projection fills the borrowed buffer before each sort. Reuse it for\n // ping-pong instead of allocating and copying another full set of keys.\n this.keys = [inputKeys, makeBufferRef(safeCapacity)];\n this.values = [makeBufferRef(safeCapacity), makeBufferRef(safeCapacity)];\n\n const histogramCount =\n RADIX_BUCKETS *\n this.paddedWorkgroups(safeCapacity, ELEMENTS_PER_WORKGROUP);\n this.blockSums = makeBufferRef(histogramCount);\n const counts = storage(this.counts, \"gslRadixCounts\").toReadOnly();\n this.createPrefixLevels(histogramCount, counts);\n // The first pass reads every input record; later passes read only the\n // valid records it compacted.\n const inputSetup = this.makeSetupTask(\n this.elementCount,\n \"Splat radix input setup\",\n );\n const compactSetup = this.makeSetupTask(\n options.count.min(this.elementCount),\n \"Splat radix compact setup\",\n );\n // Prebuild dispatch lists for every supported prefix depth. Choosing a\n // smaller list only omits work; it never creates or recompiles a node.\n const prefixNodes = this.prefixLevels.map((_, lastLevel) => {\n const nodes = this.prefixLevels\n .slice(0, lastLevel + 1)\n .map((level) => level.scan);\n for (let index = lastLevel - 1; index >= 0; index--) {\n const add = this.prefixLevels[index].add;\n if (add) nodes.push(add);\n }\n return nodes;\n });\n this.nodes = [inputSetup, compactSetup, ...prefixNodes[PREFIX_LEVELS - 1]];\n this.dispatchNodes = {\n full: prefixNodes.map(() => [inputSetup]),\n fast: prefixNodes.map(() => [inputSetup]),\n front: prefixNodes.map(() => [inputSetup]),\n };\n for (let pass = 0; pass < RADIX_PASSES; pass++) {\n const inputIndex = pass & 1;\n const outputIndex = inputIndex ^ 1;\n const histogram = makeHistogramTask({\n input: this.keys[inputIndex],\n blockSums: this.blockSums,\n elementCount: counts.element(0),\n workgroupCount: counts.element(1),\n bitOffset: pass * RADIX_BITS,\n });\n const reorder = makeReorderTask({\n inputKeysAttribute: this.keys[inputIndex],\n outputKeysAttribute: this.keys[outputIndex],\n inputValuesAttribute: this.values[inputIndex],\n outputValuesAttribute: this.values[outputIndex],\n prefixAttribute: this.blockSums,\n elementCount: counts.element(0),\n workgroupCount: counts.element(1),\n bitOffset: pass * RADIX_BITS,\n lastPass:\n pass === RADIX_PASSES - 1\n ? true\n : pass === MODE_PASSES.front - 1\n ? options.mode.equal(N.uint(RADIX_SORT_MODE_IDS.front))\n : pass === MODE_PASSES.fast - 1\n ? options.mode.equal(N.uint(RADIX_SORT_MODE_IDS.fast))\n : false,\n });\n setIndirectDispatch(histogram, this.sortDispatch);\n setIndirectDispatch(reorder, this.sortDispatch);\n this.nodes.push(histogram, reorder);\n for (let level = 0; level < PREFIX_LEVELS; level++) {\n const nodes = [histogram, ...prefixNodes[level], reorder];\n if (pass === 0) nodes.push(compactSetup);\n for (const mode of MODES)\n if (pass < MODE_PASSES[mode])\n this.dispatchNodes[mode][level].push(...nodes);\n }\n }\n }\n\n /** Values the caller writes for valid input records; sorting overwrites them. */\n get inputValues() {\n return this.values[0].value;\n }\n\n get ordering() {\n // Each pass writes the other value buffer.\n return this.values[MODE_PASSES[this.mode] & 1].value;\n }\n\n private validateCapacity(capacity: number) {\n const required = Math.max(1, capacity);\n if (!Number.isSafeInteger(required) || required > this.maxCapacity) {\n throw new RangeError(\n `GPU radix sort capacity ${capacity} exceeds the device's scalar storage buffer capacity (${this.maxCapacity} splats)`,\n );\n }\n return required;\n }\n\n private paddedWorkgroups(count: number, itemsPerWorkgroup: number) {\n const groups = Math.ceil(count / itemsPerWorkgroup);\n const width = Math.min(groups, this.maxWorkgroups);\n return width * Math.ceil(groups / this.maxWorkgroups);\n }\n\n private makeSetupTask(inputCount: Node<\"uint\">, name: string) {\n const counts = storage(this.counts, \"gslRadixCounts\");\n const dispatchBuffers = [\n this.sortDispatch,\n ...this.prefixLevels.map((level) => level.dispatch),\n ].map((value, index) => storage({ value }, `gslRadixDispatch${index}`));\n const maxWorkgroups = N.uint(this.maxWorkgroups);\n\n return N.Fn(() => {\n const count = inputCount.toVar();\n counts.element(0).assign(count);\n let itemCount = count;\n for (let index = 0; index < dispatchBuffers.length; index++) {\n const itemsPerWorkgroup =\n index === 0 ? ELEMENTS_PER_WORKGROUP : PREFIX_ITEMS_PER_WORKGROUP;\n const groups = itemCount\n .add(itemsPerWorkgroup - 1)\n .div(N.uint(itemsPerWorkgroup))\n .toVar();\n const width = groups.min(maxWorkgroups).toVar();\n const height = groups\n .add(this.maxWorkgroups - 1)\n .div(maxWorkgroups)\n .max(N.uint(1))\n .toVar();\n const dispatch = dispatchBuffers[index];\n dispatch.element(0).assign(width);\n dispatch.element(1).assign(height);\n dispatch.element(2).assign(1);\n // Include the empty tail of a 2D dispatch in the histogram/prefix\n // layout. Every workgroup can then execute barriers unconditionally.\n const paddedGroups = width.mul(height).toVar();\n if (index === 0) {\n counts.element(1).assign(paddedGroups);\n itemCount = paddedGroups.mul(RADIX_BUCKETS).toVar();\n } else {\n itemCount = paddedGroups;\n }\n if (index < PREFIX_LEVELS) counts.element(index + 2).assign(itemCount);\n }\n })()\n .compute(1, [1])\n .setName(name);\n }\n\n private replaceBuffer(buffer: BufferRef, count: number) {\n if (buffer.value.count === count) return;\n\n const previous = buffer.value;\n buffer.value = makeBuffer(count);\n previous.dispose();\n }\n\n private createPrefixLevels(\n itemCount: number,\n counts: StorageBufferNode<\"uint\">,\n ) {\n let items = this.blockSums;\n let currentCount = itemCount;\n\n for (let levelIndex = 0; levelIndex < PREFIX_LEVELS; levelIndex++) {\n const blockCount = this.paddedWorkgroups(\n currentCount,\n PREFIX_ITEMS_PER_WORKGROUP,\n );\n const blockSums = makeBufferRef(blockCount);\n const dispatch = new IndirectStorageBufferAttribute(\n new Uint32Array(3),\n 1,\n );\n const elementCount = counts.element(levelIndex + 2);\n const scan = makePrefixScanTask(items, blockSums, elementCount);\n const add =\n levelIndex < PREFIX_LEVELS - 1\n ? makePrefixAddTask(items, blockSums, elementCount)\n : null;\n setIndirectDispatch(scan, dispatch);\n if (add) setIndirectDispatch(add, dispatch);\n this.prefixLevels.push({ scan, add, dispatch, blockSums });\n items = blockSums;\n currentCount = blockCount;\n }\n }\n\n resize(capacity: number, shrinkResources = false) {\n const requiredCapacity = this.validateCapacity(capacity);\n if (!shrinkResources && requiredCapacity <= this.capacity) return;\n if (requiredCapacity === this.capacity) return;\n\n this.replaceBuffer(this.keys[1], requiredCapacity);\n for (const buffer of this.values)\n this.replaceBuffer(buffer, requiredCapacity);\n\n let itemCount =\n RADIX_BUCKETS *\n this.paddedWorkgroups(requiredCapacity, ELEMENTS_PER_WORKGROUP);\n this.replaceBuffer(this.blockSums, itemCount);\n for (const level of this.prefixLevels) {\n itemCount = this.paddedWorkgroups(itemCount, PREFIX_ITEMS_PER_WORKGROUP);\n this.replaceBuffer(level.blockSums, itemCount);\n }\n this.capacity = requiredCapacity;\n }\n\n /**\n * Prepare the persistent graph for this many input records. The GPU count\n * of valid records is clamped to it.\n */\n prepare(elementCount: number, mode: RadixSortMode): ComputeNode[] {\n if (\n !Number.isSafeInteger(elementCount) ||\n elementCount < 0 ||\n elementCount > this.capacity\n ) {\n throw new RangeError(\n \"Sort count must be an integer within buffer capacity\",\n );\n }\n this.mode = mode;\n if (elementCount === 0) return [];\n this.elementCount.value = elementCount;\n // The CPU knows an upper bound, while the live count stays on the GPU.\n // Include 2D dispatch padding just as the GPU setup does, so every possible\n // live count fits the selected hierarchy without a count readback.\n let items =\n RADIX_BUCKETS *\n this.paddedWorkgroups(elementCount, ELEMENTS_PER_WORKGROUP);\n let lastLevel = 0;\n while (lastLevel < PREFIX_LEVELS - 1) {\n items = this.paddedWorkgroups(items, PREFIX_ITEMS_PER_WORKGROUP);\n if (items === 1) break;\n lastLevel++;\n }\n return this.dispatchNodes[mode][lastLevel];\n }\n\n dispose() {\n for (const node of this.nodes) node.dispose();\n for (const level of this.prefixLevels) {\n level.blockSums.value.dispose();\n level.dispatch.dispose();\n }\n this.sortDispatch.dispose();\n this.counts.value.dispose();\n this.blockSums.value.dispose();\n this.keys[1].value.dispose();\n for (const buffer of this.values) buffer.value.dispose();\n this.capacity = 0;\n }\n}\n","import * as THREE from \"three\";\nimport type { ComputeNode } from \"three/webgpu\";\nimport {\n IndirectStorageBufferAttribute,\n StorageBufferAttribute,\n type WebGPURenderer,\n} from \"three/webgpu\";\nimport { getTAAProjection } from \"../../addons/taaShared\";\n\nimport type { SplatAccumulator } from \"../SplatAccumulator\";\nimport { SPLATS_PER_INSTANCE, type SplatGeometry } from \"../SplatGeometry\";\nimport { getMeanViewPose, getViews } from \"../rendererUtils\";\nimport { createGenerateProgram } from \"../tsl/GenerateProgram\";\nimport { createProjectionProgram } from \"../tsl/ProjectionProgram\";\nimport type { ProjectedVertexData } from \"../tsl/SplatMaterial\";\nimport { N, type UniformType, uniformBinding } from \"../tsl/shaderUtils\";\nimport { splatViewportUniforms } from \"../tsl/viewUniforms\";\nimport { type Uniforms, makeGenerateUniforms } from \"../uniforms\";\nimport { ProjectionCache, getProjectionCacheSize } from \"./ProjectionCache\";\nimport {\n INVALID_SORT_KEY,\n RADIX_SORT_MODE_IDS,\n type RadixSortMode,\n WebGPURadixSort,\n} from \"./RadixSort\";\n\nconst WORKGROUP_SIZE = 256;\nconst PROJECT_SLOTS = 8;\n\ntype BufferRef = { value: StorageBufferAttribute; name: string };\ntype ComputeSlot = { uniforms: Uniforms; node: ComputeNode };\ntype SlotSet = { slots: ComputeSlot[]; compiled: number };\ntype DeviceLimits = {\n maxStorageBufferBindingSize: number;\n maxBufferSize: number;\n maxTextureArrayLayers: number;\n maxTextureDimension2D: number;\n maxComputeWorkgroupsPerDimension: number;\n};\ntype ComputeRenderer = WebGPURenderer & {\n compileComputeAsync(nodes: ComputeNode[]): Promise<void>;\n backend: { device: { limits: DeviceLimits } };\n};\n\nfunction buffer(name: string): BufferRef {\n return { value: new StorageBufferAttribute(new Uint32Array(1), 1), name };\n}\n\n/**\n * Stores in `jitter` the NDC translation that `jittered` adds to `base`, as\n * TAA's sub-pixel view offsets do. Returns false for any other difference.\n */\nfunction getProjectionJitter(\n jittered: THREE.Matrix4,\n base: THREE.Matrix4,\n jitter: THREE.Vector2,\n) {\n const a = jittered.elements;\n const b = base.elements;\n for (let i = 0; i < 16; i++) {\n if (\n i !== 8 &&\n i !== 9 &&\n i !== 12 &&\n i !== 13 &&\n Math.abs(a[i] - b[i]) >\n 4 * Number.EPSILON * Math.max(1, Math.abs(a[i]), Math.abs(b[i]))\n ) {\n return false;\n }\n }\n // Perspective offsets scale with view depth (w = -z); orthographic ones\n // translate clip space directly (w = 1). Each projection uses only one.\n jitter.set(a[12] - b[12] - (a[8] - b[8]), a[13] - b[13] - (a[9] - b[9]));\n return true;\n}\n\nfunction bindBuffer(ref: BufferRef) {\n // Stable binding names let projection slots share the same WGSL program.\n return N.storage(ref.value, \"uint\")\n .setName(ref.name)\n .onObjectUpdate(() => ref.value);\n}\n\n/** Fixed compute graph. Source mappings and storage may change without rebuilding shaders. */\nexport class ProjectedSplats {\n // Only the instance count changes; the other indirect draw arguments are fixed.\n readonly indirect = new IndirectStorageBufferAttribute(\n new Uint32Array([SPLATS_PER_INSTANCE * 6, 0, 0, 0, 0]),\n 1,\n );\n /** Common kernels, the full sorter and the first slot are ready; remaining slots warm automatically. */\n readonly ready: Promise<void>;\n error: unknown = null;\n /**\n * Called when kernels for a new WebXR eye count can draw, or when a slot\n * fails to compile. Draws hide Splats until then, so on-demand hosts must\n * redraw.\n */\n onKernelsReady?: () => void;\n\n private readonly limits: DeviceLimits;\n private readonly cache = new ProjectionCache();\n private readonly visibleCount = new StorageBufferAttribute(\n new Uint32Array(1),\n 1,\n );\n private readonly keys = buffer(\"gslProjectionKeys\");\n private readonly seeds = buffer(\"gslProjectionSeeds\");\n private readonly sorter: WebGPURadixSort;\n // Slots for each eye count. One eye compiles at startup; WebXR eye counts\n // compile as a session starts or on first use, so other draws pay nothing.\n private readonly slotSets = new Map<number, SlotSet>();\n private readonly compilations: Promise<void>[] = [];\n private readonly onSessionStart = () => void this.getSlots(2);\n private shrinkViews = false;\n private readonly onSessionEnd = () => {\n this.shrinkViews = true;\n this.onKernelsReady?.();\n };\n private readonly resetCount: ComputeNode;\n private readonly finish: ComputeNode;\n private readonly state: Uniforms;\n private readonly matrix = new THREE.Matrix4();\n private readonly translation = new THREE.Matrix4();\n private readonly scale = new THREE.Vector3();\n private readonly viewPosition = new THREE.Vector3();\n private capacity = 0;\n private viewCapacity = 0;\n private disposed = false;\n private projectedInputs: unknown[] = [];\n\n constructor(\n private readonly renderer: WebGPURenderer,\n private readonly uniforms: Uniforms,\n ) {\n const computeRenderer = renderer as ComputeRenderer;\n this.limits = computeRenderer.backend.device.limits;\n this.state = {\n ...uniforms,\n projectionMatrix: { value: new THREE.Matrix4() },\n renderToViewQuat: { value: new THREE.Quaternion() },\n renderToViewPos: { value: new THREE.Vector3() },\n renderToViewScale: { value: 1 },\n near: { value: 0.1 },\n far: { value: 1000 },\n renderSize: { value: new THREE.Vector2() },\n // Projected records of each eye start one capacity after the last.\n viewStride: { value: 1 },\n sortDirection: { value: new THREE.Vector3() },\n sortOffset: { value: new THREE.Vector3() },\n sortRadial: { value: false },\n // RADIX_SORT_MODE_IDS value of the current key encoding.\n sortMode: { value: 0 },\n // NDC translation the draw applies to unjittered projections.\n projectionJitter: { value: new THREE.Vector2() },\n };\n // Every view, including each WebXR eye, draws one compact sorted order.\n const count = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toReadOnly()\n .element(0);\n this.sorter = new WebGPURadixSort(1, this.keys, {\n count,\n mode: uniformBinding(this.state, \"sortMode\", \"uint\"),\n maxComputeWorkgroupsPerDimension:\n this.limits.maxComputeWorkgroupsPerDimension,\n maxStorageBufferBindingSize: Math.min(\n this.limits.maxStorageBufferBindingSize,\n this.limits.maxBufferSize,\n ),\n });\n const drawCount = N.storage(this.indirect, \"uint\")\n .setName(\"gslDrawIndirect\")\n .element(1);\n const counter = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toAtomic();\n this.resetCount = N.Fn(() => {\n N.atomicStore(counter.element(0), N.uint(0));\n })()\n .compute(1, [1])\n .setName(\"Splat reset visible count\");\n this.finish = N.Fn(() => {\n drawCount.assign(\n count.add(SPLATS_PER_INSTANCE - 1).div(N.uint(SPLATS_PER_INSTANCE)),\n );\n })()\n .compute(1, [1])\n .setName(\"Splat visible draw arguments\");\n const mono = this.createSlotSet(1);\n this.ready = computeRenderer\n .compileComputeAsync([\n this.resetCount,\n this.finish,\n ...this.sorter.nodes,\n mono.slots[0].node,\n ])\n .then(() => {\n mono.compiled = 1;\n })\n .catch((error: unknown) => {\n this.error = error;\n });\n this.compilations.push(this.ready.then(() => this.compileSlots(mono)));\n renderer.xr.addEventListener(\"sessionstart\", this.onSessionStart);\n renderer.xr.addEventListener(\"sessionend\", this.onSessionEnd);\n }\n\n private createSlot(eyeCount = 1): ComputeSlot {\n this.ensureEyeUniforms(eyeCount);\n const uniforms = {\n ...this.state,\n ...makeGenerateUniforms(),\n };\n const u = <Type extends UniformType>(name: string, type: Type) =>\n uniformBinding(uniforms, name, type);\n const generate = createGenerateProgram({ uniforms });\n // Eye 0 reads the unsuffixed uniforms; later eyes append their index.\n const eyes = Array.from({ length: eyeCount }, (_, eye) =>\n eye ? `${eye}` : \"\",\n ).map((suffix) => ({\n project: createProjectionProgram(uniforms, {\n projectionMatrix: u(`projectionMatrix${suffix}`, \"mat4\"),\n renderToViewQuat: u(`renderToViewQuat${suffix}`, \"vec4\"),\n renderToViewPos: u(`renderToViewPos${suffix}`, \"vec3\"),\n renderToViewScale: u(`renderToViewScale${suffix}`, \"float\"),\n near: u(`near${suffix}`, \"float\"),\n far: u(`far${suffix}`, \"float\"),\n renderSize: u(`renderSize${suffix}`, \"vec2\"),\n }),\n pixelScale: u(`renderSize${suffix}`, \"vec2\")\n .mul(u(\"focalAdjustment\", \"float\"))\n .mul(0.5),\n }));\n const viewStride = u(\"viewStride\", \"uint\");\n const direction = u(\"sortDirection\", \"vec3\");\n const sortOffset = u(\"sortOffset\", \"vec3\");\n const radial = u(\"sortRadial\", \"bool\");\n const sortMode = u(\"sortMode\", \"uint\");\n const front = sortMode.equal(N.uint(RADIX_SORT_MODE_IDS.front));\n const stochastic = u(\"stochastic\", \"bool\");\n const centerRange = u(\"clipXY\", \"float\").abs().max(1).mul(1.000001);\n const keys = bindBuffer(this.keys);\n const seeds = bindBuffer(this.seeds);\n // Compact slot of each mapped Splat, read by the first sort pass.\n const sortValues = N.storage(this.sorter.inputValues, \"uint\")\n .setName(\"gslSortInputValues\")\n .onObjectUpdate(() => this.sorter.inputValues);\n const counter = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toAtomic();\n const node = N.Fn(() => {\n const index = N.uint(N.instanceIndex);\n // Sorted draws key each Splat at its mapping index, not its atomic slot.\n // The first radix pass compacts keys in mapping order, so equal keys\n // keep source order every frame.\n const sorted = stochastic\n .not()\n .or(u(\"stochasticOrdering\", \"bool\"))\n .toVar();\n const mappingIndex = u(\"targetBase\", \"uint\").add(index).toVar();\n // Decode, edit and evaluate color once, then project for each eye.\n const generated = generate.prepare(index);\n const projected = eyes.map(({ project }) => {\n const projection = project(generated, false);\n const extent = projection.axis1.abs().add(projection.axis2.abs());\n const ndc = projection.clipCenter.xy.div(projection.clipCenter.w);\n // Reject only quads wholly outside the viewport; clipXY and every\n // existing visual cutoff remain part of the shared projection math.\n const onscreen = N.all(ndc.abs().lessThanEqual(extent.add(1)));\n return { projection, ndc, visible: projection.valid.and(onscreen) };\n });\n // Shared culling keeps Splats any eye draws.\n const visible = projected\n .slice(1)\n .reduce((any, eye) => any.or(eye.visible), projected[0].visible);\n N.If(visible, () => {\n const rgb = generated.resolveRgb().toVar();\n // Compact survivors and their stable seeds into the same slots.\n const slot = N.atomicAdd(counter.element(0), N.uint(1)).toVar();\n projected.forEach(({ projection, ndc, visible: eyeVisible }, eye) => {\n const cacheIndex = viewStride.mul(eye).add(slot);\n const write = () => {\n projection.rgba.rgb.assign(rgb);\n this.cache.write(\n cacheIndex,\n projection,\n ndc,\n eyes[eye].pixelScale,\n centerRange,\n );\n };\n if (eyeCount > 1) {\n N.If(eyeVisible, write).Else(() => {\n this.cache.writeHidden(cacheIndex);\n });\n } else {\n write();\n }\n });\n N.If(stochastic, () => {\n seeds.element(slot).assign(generated.stochasticSeed);\n });\n // Sorted blending orders back to front by depth or distance;\n // stochastic ordering uses front-to-back depth.\n N.If(sorted, () => {\n const center = generated.center.add(sortOffset);\n const metric = N.select(\n radial.and(front.not()),\n center.dot(center),\n center.dot(direction),\n );\n const bits = N.floatBitsToUint(metric);\n // Non-finite metrics draw last; INVALID_SORT_KEY marks absence.\n const key = N.uint(INVALID_SORT_KEY - 1).toVar();\n N.If(\n bits.bitAnd(N.uint(0x7fffffff)).lessThan(N.uint(0x7f800000)),\n () => {\n // Signed float bits in ascending order, preserved across\n // negative view depths; inverted for back-to-front keys.\n const ascending = N.select(\n bits.bitAnd(N.uint(0x80000000)).notEqual(0),\n bits.bitXor(N.uint(0xffffffff)),\n bits.bitXor(N.uint(0x80000000)),\n );\n key.assign(\n ascending.bitXor(\n N.select(front, N.uint(0), N.uint(0xffffffff)),\n ),\n );\n },\n );\n // Discard low mantissa bits before storing the key: front keys keep\n // 16 bits and fast keys 24. Projection/depth cache precision is\n // independent of this sorting approximation.\n const shift = N.select(\n front,\n N.uint(16),\n N.select(\n sortMode.equal(N.uint(RADIX_SORT_MODE_IDS.fast)),\n N.uint(8),\n N.uint(0),\n ),\n );\n keys.element(mappingIndex).assign(key.shiftRight(shift));\n sortValues.element(mappingIndex).assign(slot);\n });\n }).Else(() => {\n N.If(sorted, () => {\n keys.element(mappingIndex).assign(N.uint(INVALID_SORT_KEY));\n });\n });\n })()\n .compute(1, [WORKGROUP_SIZE])\n .setName(\n eyeCount > 1\n ? `Splat generate project compact ${eyeCount} eyes`\n : \"Splat generate project compact\",\n );\n return { uniforms, node };\n }\n\n /** Projection uniforms of each eye after the first, created on demand. */\n private ensureEyeUniforms(eyeCount: number) {\n for (let eye = 1; eye < eyeCount; eye++) {\n if (this.state[`projectionMatrix${eye}`]) continue;\n Object.assign(this.state, {\n [`projectionMatrix${eye}`]: { value: new THREE.Matrix4() },\n [`renderToViewQuat${eye}`]: { value: new THREE.Quaternion() },\n [`renderToViewPos${eye}`]: { value: new THREE.Vector3() },\n [`renderToViewScale${eye}`]: { value: 1 },\n [`near${eye}`]: { value: 0.1 },\n [`far${eye}`]: { value: 1000 },\n [`renderSize${eye}`]: { value: new THREE.Vector2() },\n });\n }\n }\n\n private createSlotSet(eyeCount: number): SlotSet {\n const set: SlotSet = {\n slots: Array.from({ length: PROJECT_SLOTS }, () =>\n this.createSlot(eyeCount),\n ),\n compiled: 0,\n };\n this.slotSets.set(eyeCount, set);\n return set;\n }\n\n /**\n * Compiled slots that project this many eyes. One eye uses the startup\n * slots; WebXR eye counts build theirs on first request.\n */\n private getSlots(eyeCount: number) {\n let set = this.slotSets.get(eyeCount);\n if (!set) {\n set = this.createSlotSet(eyeCount);\n this.compilations.push(this.compileSlots(set));\n }\n return set.slots.slice(0, set.compiled);\n }\n\n private async compileSlots(set: SlotSet) {\n try {\n // A drawable set yields first, so readiness callbacks run before the\n // slots that only batch more meshes.\n if (set.compiled > 0)\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n while (!this.disposed && !this.error && set.compiled < set.slots.length) {\n await (this.renderer as ComputeRenderer).compileComputeAsync([\n set.slots[set.compiled].node,\n ]);\n set.compiled++;\n // The first slot is enough to draw; later ones only batch more meshes.\n if (set.compiled === 1 && !this.disposed) this.onKernelsReady?.();\n }\n } catch (error) {\n this.error = error;\n // The next draw throws the compilation error.\n if (!this.disposed) this.onKernelsReady?.();\n }\n }\n\n vertexData(camera: THREE.Camera, stochastic: boolean): ProjectedVertexData {\n const multiView = getViews(camera)[0] !== camera;\n const eye = multiView ? N.cameraIndex : N.uint(0);\n const stride = uniformBinding(this.state, \"viewStride\", \"uint\");\n // Compute the eye offset before looking up its order.\n const base = eye.mul(stride).toVar();\n const i = N.uint(N.instanceIndex)\n .mul(SPLATS_PER_INSTANCE)\n .add(N.uint(N.positionGeometry.z));\n const count = N.storage(this.visibleCount, \"uint\")\n .setName(\"gslVisibleCount\")\n .toReadOnly()\n .element(0);\n const clipPosition = N.vec4(0, 0, 2, 1).toVar();\n const rgba = N.vec4(0).toVar();\n const splatUv = N.vec2(0).toVar();\n const stochasticSeed = stochastic ? N.uint(0).toVar() : undefined;\n const supportRadiusSquared = N.float(0).toVar();\n const kernelPower = N.float(0).toVar();\n const view = splatViewportUniforms(this.uniforms, camera);\n const centerRange = uniformBinding(this.uniforms, \"clipXY\", \"float\")\n .abs()\n .max(1)\n .mul(1.000001);\n const renderSize = multiView\n ? view.renderSize\n : uniformBinding(this.state, \"renderSize\", \"vec2\");\n const pixelScale = renderSize\n .mul(uniformBinding(this.uniforms, \"focalAdjustment\", \"float\"))\n .mul(0.5);\n\n // Indirect draws round up to whole quad groups; trim before any index or\n // cache load, including the unused tail of the final instance.\n N.If(i.lessThan(count), () => {\n // Every eye draws the one shared order of compact slots.\n const cacheIndex = i.toVar();\n const loadOrdered = () => {\n cacheIndex.assign(\n N.storage(this.sorter.ordering, \"uint\")\n .onObjectUpdate(() => this.sorter.ordering)\n .toReadOnly()\n .element(i),\n );\n };\n if (stochastic) {\n // Unsorted stochastic draws read compacted slots directly.\n N.If(\n uniformBinding(this.uniforms, \"stochasticOrdering\", \"bool\"),\n loadOrdered,\n );\n } else {\n loadOrdered();\n }\n stochasticSeed?.assign(\n bindBuffer(this.seeds).toReadOnly().element(cacheIndex),\n );\n const projected = this.cache.read(\n base.add(cacheIndex),\n pixelScale,\n centerRange,\n uniformBinding(this.state, \"projectionJitter\", \"vec2\"),\n );\n clipPosition.assign(projected.clipPosition);\n rgba.assign(projected.rgba);\n splatUv.assign(projected.splatUv);\n supportRadiusSquared.assign(projected.supportRadiusSquared);\n kernelPower.assign(projected.kernelPower);\n });\n return {\n clipPosition,\n rgba,\n splatUv,\n stochasticSeed,\n supportRadiusSquared,\n kernelPower,\n viewportOrigin: view.viewportOrigin,\n };\n }\n\n private resizeBuffer(ref: BufferRef, count: number) {\n if (ref.value.count === count) return;\n const old = ref.value;\n ref.value = new StorageBufferAttribute(new Uint32Array(count), 1);\n old.dispose();\n }\n\n private resize(count: number, views: number, shrink = false) {\n const required = Math.max(1, count);\n const bytes = required * 4;\n const byteLimit = Math.min(\n this.limits.maxStorageBufferBindingSize,\n this.limits.maxBufferSize,\n );\n if (bytes > byteLimit) {\n throw new RangeError(\n `WebGPU sort requires ${bytes} bytes per index buffer; device binding limit is ${this.limits.maxStorageBufferBindingSize}. Request higher requiredLimits when creating WebGPURenderer or reduce resident Splats.`,\n );\n }\n const limit = Math.floor(byteLimit / 4);\n // Amortize small mapping changes without tying shader graphs to capacity.\n const capacity = shrink\n ? required\n : required <= this.capacity\n ? this.capacity\n : Math.min(\n limit,\n Math.max(\n required,\n 2048,\n Math.ceil((this.capacity * 1.5) / 2048) * 2048,\n ),\n );\n const viewCapacity =\n shrink || this.shrinkViews ? views : Math.max(views, this.viewCapacity);\n this.shrinkViews = false;\n if (capacity === this.capacity && viewCapacity === this.viewCapacity)\n return;\n const size = getProjectionCacheSize(capacity * viewCapacity, this.limits);\n this.resizeBuffer(this.keys, capacity);\n this.sorter.resize(capacity, shrink);\n this.cache.resize(size);\n this.capacity = capacity;\n this.viewCapacity = viewCapacity;\n this.state.viewStride.value = capacity;\n }\n\n render(\n accumulator: SplatAccumulator,\n camera: THREE.Camera,\n geometry: SplatGeometry,\n radial: boolean,\n fastSort: boolean,\n shrink = false,\n ) {\n if (this.error) throw this.error;\n const cameras = getViews(camera) as THREE.PerspectiveCamera[];\n const multiView = cameras[0] !== camera;\n // WebXR eyes share one generated, culled, compacted and sorted set, like\n // one head; each eye still gets its exact projection.\n const slots = this.disposed ? [] : this.getSlots(cameras.length);\n if (slots.length === 0) {\n // Draw nothing until the kernels for this eye count compile.\n geometry.setIndirect(null);\n geometry.instanceCount = 0;\n return false;\n }\n this.resize(accumulator.numSplats, cameras.length, shrink);\n const { uniforms } = this;\n const stochastic = uniforms.stochastic.value;\n // Only stochastic draws read seeds; sorted rendering keeps one entry.\n this.resizeBuffer(this.seeds, stochastic ? this.capacity : 1);\n // Unsorted stochastic draws need no keys or sort.\n const sortMode: RadixSortMode | null = !stochastic\n ? fastSort\n ? \"fast\"\n : \"full\"\n : uniforms.stochasticOrdering.value\n ? \"front\"\n : null;\n if (sortMode) this.state.sortMode.value = RADIX_SORT_MODE_IDS[sortMode];\n this.state.sortRadial.value = radial;\n // TAA exposes its unjittered projection during scene capture. Project and\n // sort without the jitter so a still view reuses the compute results;\n // drawing applies the jitter as an NDC translation.\n const jitter = this.state.projectionJitter.value as THREE.Vector2;\n jitter.set(0, 0);\n const unjittered = getTAAProjection(camera);\n const monoProjection =\n !multiView &&\n unjittered &&\n getProjectionJitter(camera.projectionMatrix, unjittered, jitter)\n ? unjittered\n : null;\n geometry.setIndirect(this.indirect);\n geometry.setSplatCount(Math.max(1, accumulator.numSplats));\n // The accumulator version covers source, mapping, transform, animation and\n // edit changes. Output color settings are draw-only.\n const inputs = [\n accumulator,\n accumulator.version,\n ...accumulator.viewOrigin.toArray(),\n cameras.length,\n stochastic,\n // Each mode keys only the sort options it reads.\n !stochastic && radial,\n sortMode,\n uniforms.maxStdDev.value,\n uniforms.minPixelRadius.value,\n uniforms.minAlpha.value,\n uniforms.preBlurAmount.value,\n uniforms.blurAmount.value,\n uniforms.clipXY.value,\n uniforms.focalAdjustment.value,\n ];\n for (const { node } of accumulator.mapping) inputs.push(node.layers.mask);\n for (const view of cameras) {\n inputs.push(\n ...view.matrixWorld.elements,\n ...(monoProjection ?? view.projectionMatrix).elements,\n view.near,\n view.far,\n view.layers.mask,\n view.viewport?.z ?? uniforms.renderSize.value.x,\n view.viewport?.w ?? uniforms.renderSize.value.y,\n );\n }\n if (\n !shrink &&\n inputs.length === this.projectedInputs.length &&\n inputs.every((value, index) => value === this.projectedInputs[index])\n )\n return true;\n // A failed or partially submitted update must not reuse the old snapshot.\n this.projectedInputs = [];\n cameras.forEach((view, eye) => {\n this.setEye(eye, view, monoProjection, accumulator);\n });\n this.setSortPose(cameras, accumulator);\n this.dispatch(slots, cameras, accumulator, sortMode);\n this.projectedInputs = inputs;\n return true;\n }\n\n /** Projection uniforms for one eye; eye 0 also serves mono draws. */\n private setEye(\n eye: number,\n view: THREE.PerspectiveCamera,\n projection: THREE.Matrix4 | null,\n accumulator: SplatAccumulator,\n ) {\n const state = this.state;\n const suffix = eye ? `${eye}` : \"\";\n // WebXR eye viewports are physical pixels; Three draws them as given.\n const viewport = view.viewport;\n state[`projectionMatrix${suffix}`].value.copy(\n projection ?? view.projectionMatrix,\n );\n state[`near${suffix}`].value = view.near;\n state[`far${suffix}`].value = view.far;\n const renderSize = state[`renderSize${suffix}`].value as THREE.Vector2;\n renderSize.copy(this.uniforms.renderSize.value);\n if (viewport) renderSize.set(viewport.z, viewport.w);\n this.matrix\n .copy(view.matrixWorld)\n .invert()\n .multiply(this.translation.makeTranslation(accumulator.viewOrigin))\n .decompose(\n state[`renderToViewPos${suffix}`].value,\n state[`renderToViewQuat${suffix}`].value,\n this.scale,\n );\n state[`renderToViewScale${suffix}`].value =\n (this.scale.x + this.scale.y + this.scale.z) / 3;\n }\n\n /** Sort from the views' mean pose: the camera, or the WebXR head. */\n private setSortPose(\n views: THREE.PerspectiveCamera[],\n accumulator: SplatAccumulator,\n ) {\n // Read the views at each draw: after a manual update, the accumulator's\n // pose may be stale and only places the render origin.\n getMeanViewPose(\n views,\n this.viewPosition,\n this.state.sortDirection.value as THREE.Vector3,\n );\n (this.state.sortOffset.value as THREE.Vector3).subVectors(\n accumulator.viewOrigin,\n this.viewPosition,\n );\n }\n\n /**\n * Generates, projects, compacts and sorts the meshes any view draws. Sorted\n * modes also visit hidden meshes, which only mark their keys absent.\n */\n private dispatch(\n slots: ComputeSlot[],\n views: THREE.Camera[],\n accumulator: SplatAccumulator,\n sortMode: RadixSortMode | null,\n ) {\n const pending: ComputeNode[] = [this.resetCount];\n let slotCount = 0;\n for (const { node, base, count, matrixWorld } of accumulator.mapping) {\n const drawn = views.some((view) => view.layers.test(node.layers));\n // Sorting reads a key for every mapped Splat, including hidden meshes.\n if (!drawn && !sortMode) continue;\n // A slot's uniforms can only be changed after its preceding batch has\n // been submitted. Keep the last batch open for draw arguments and sorting.\n if (slotCount === slots.length) {\n this.renderer.compute(pending);\n pending.length = 0;\n slotCount = 0;\n }\n const slot = slots[slotCount++];\n if (drawn) accumulator.prepareUniforms(node, slot.uniforms, matrixWorld);\n slot.uniforms.targetBase.value = base;\n // Hidden meshes read no source data; each Splat fails visibility.\n slot.uniforms.targetCount.value = drawn ? count : 0;\n slot.node.count = count;\n pending.push(slot.node);\n }\n pending.push(this.finish);\n if (sortMode)\n pending.push(...this.sorter.prepare(accumulator.numSplats, sortMode));\n this.renderer.compute(pending);\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.projectedInputs = [];\n this.renderer.xr.removeEventListener(\"sessionstart\", this.onSessionStart);\n this.renderer.xr.removeEventListener(\"sessionend\", this.onSessionEnd);\n void Promise.all(this.compilations).then(() => this.disposeResources());\n }\n\n private disposeResources() {\n for (const { slots } of this.slotSets.values())\n for (const slot of slots) slot.node.dispose();\n for (const node of [this.resetCount, this.finish]) node.dispose();\n this.sorter.dispose();\n this.cache.dispose();\n this.visibleCount.dispose();\n this.keys.value.dispose();\n this.seeds.value.dispose();\n this.indirect.dispose();\n }\n}\n","import type { WebGPURenderer } from \"three/webgpu\";\nimport type { SplatMaterialOptions } from \"../backend\";\nimport { NodeSplatBackend } from \"../tsl/SplatBackend\";\nimport type { Uniforms } from \"../uniforms\";\nimport { ProjectedSplats } from \"./ProjectedSplats\";\n\n/** Native WebGPU: fixed compute projection, visible compaction, GPU sort and indirect draw. */\nexport class WebGPUSplatBackend extends NodeSplatBackend {\n readonly kind = \"webgpu\";\n readonly projection: ProjectedSplats;\n precompile: Promise<void> | null;\n\n constructor(\n renderer: WebGPURenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n ) {\n const projection = new ProjectedSplats(renderer, uniforms);\n super(renderer, uniforms, options, undefined, (camera, stochastic) =>\n projection.vertexData(camera, stochastic),\n );\n this.projection = projection;\n this.precompile = projection.ready.finally(() => {\n this.precompile = null;\n });\n }\n\n get sortError() {\n return this.projection.error;\n }\n getOrderingCapacity(count: number) {\n return Math.max(1, count);\n }\n\n dispose() {\n super.dispose();\n this.projection.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport {\n type GaussianSplatCompatibleRenderer,\n isWebGPURenderer,\n isXRRenderTarget,\n usesNativeWebGPU,\n} from \"./rendererUtils\";\nimport type { SplatNodeMaterial } from \"./tsl/SplatMaterial\";\nimport type { Uniforms } from \"./uniforms\";\nimport { WebGLFallbackSplatBackend } from \"./webgl-fallback/SplatBackend\";\nimport { WebGLSplatBackend } from \"./webgl/SplatBackend\";\nimport { WebGPUSplatBackend } from \"./webgpu/SplatBackend\";\n\nexport type SplatBackend =\n | WebGLSplatBackend\n | WebGPUSplatBackend\n | WebGLFallbackSplatBackend;\n\nexport function createSplatBackend(\n renderer: GaussianSplatCompatibleRenderer,\n uniforms: Uniforms,\n options: SplatMaterialOptions,\n): SplatBackend {\n if (!isWebGPURenderer(renderer)) {\n return new WebGLSplatBackend(renderer, uniforms, options);\n }\n return usesNativeWebGPU(renderer)\n ? new WebGPUSplatBackend(renderer, uniforms, options)\n : new WebGLFallbackSplatBackend(renderer, uniforms, options);\n}\n\nexport function configureSplatOutput(\n renderer: GaussianSplatCompatibleRenderer,\n target: THREE.RenderTarget | null,\n uniforms: Uniforms,\n encodeLinear?: boolean,\n) {\n let blendSpace = THREE.ColorManagement.workingColorSpace;\n if (!isWebGPURenderer(renderer)) {\n if (target === null) blendSpace = renderer.outputColorSpace;\n else if (isXRRenderTarget(target)) blendSpace = target.texture.colorSpace;\n }\n uniforms.encodeLinear.value =\n encodeLinear ?? blendSpace !== THREE.SRGBColorSpace;\n}\n\nexport type CPUOrderingUpdate = {\n ordering: Uint32Array;\n activeSplats: number;\n requiredCapacity: number;\n shrink: boolean;\n};\n\nexport type SplatMaterial = THREE.ShaderMaterial | SplatNodeMaterial;\n\nexport type SplatMaterialOptions = {\n premultipliedAlpha: boolean;\n transparent: boolean;\n depthTest: boolean;\n depthWrite: boolean;\n};\n","import * as THREE from \"three\";\nimport { SplatWorker } from \"../runtime/SplatWorker\";\nimport { resolveTimer } from \"../utils/three\";\nimport { SortCenterCache } from \"./SortCenterCache\";\nimport { SplatAccumulator } from \"./SplatAccumulator\";\nimport { SplatGeometry } from \"./SplatGeometry\";\nimport {\n type SplatBackend,\n type SplatMaterial,\n configureSplatOutput,\n createSplatBackend,\n} from \"./backend\";\nimport {\n type GaussianSplatCompatibleRenderer,\n assertSupportedRenderer,\n getMeanViewPose,\n getRenderFrame,\n getViews,\n} from \"./rendererUtils\";\nimport { DEFAULT_MIN_ALPHA, makeSplatUniforms } from \"./uniforms\";\n\nconst renderToViewScaleTmp = new THREE.Vector3();\nconst renderToViewMatrixTmp = new THREE.Matrix4();\nconst renderTranslationTmp = new THREE.Matrix4();\nconst headPositionTmp = new THREE.Vector3();\nconst headTargetTmp = new THREE.Vector3();\ntype UpdateRequest = {\n scene: THREE.Scene;\n camera: THREE.Camera;\n shrinkResources: boolean;\n};\n\n// Back-to-front for blending, front-to-back for stochastic overdraw, or\n// source order for unsorted stochastic draws.\ntype SortMode = \"back\" | \"front\" | \"identity\";\n\nconst UNSUPPORTED_CAMERA =\n \"GaussianSplatRenderer draws ArrayCamera only for WebXR; render other views with separate cameras\";\n\n/**\n * Whether the camera is the WebXR camera or one of its eyes. Presenting alone\n * is not enough: Three draws render targets with the caller's camera when\n * xr.enabled is off, and WebGPURenderer whenever the target is not its output.\n */\nfunction isXRCamera(\n camera: THREE.Camera,\n renderer: GaussianSplatCompatibleRenderer,\n) {\n if (!renderer.xr.isPresenting) return false;\n const xrCamera = renderer.xr.getCamera();\n return (\n camera === xrCamera || (xrCamera.cameras as THREE.Camera[]).includes(camera)\n );\n}\n\n/**\n * Multiple views are drawn only as WebXR eyes. Classic WebGL draws each view\n * of an ArrayCamera separately, as a camera with a viewport.\n */\nfunction isSupportedCamera(\n camera: THREE.Camera,\n renderer: GaussianSplatCompatibleRenderer,\n) {\n return (\n isXRCamera(camera, renderer) ||\n (!(camera as THREE.ArrayCamera).isArrayCamera &&\n (camera as THREE.PerspectiveCamera).viewport === undefined)\n );\n}\n\nfunction assertSupportedCamera(\n camera: THREE.Camera,\n renderer: GaussianSplatCompatibleRenderer,\n) {\n if (!isSupportedCamera(camera, renderer)) throw new Error(UNSUPPORTED_CAMERA);\n}\n\n// Average (uniform) world scale of a camera, read without updating it.\nfunction getCameraWorldScale(camera: THREE.Camera): number {\n const scale = renderToViewScaleTmp.setFromMatrixScale(camera.matrixWorld);\n return (scale.x + scale.y + scale.z) / 3;\n}\n\nexport interface GaussianSplatRendererOptions {\n /**\n * Pass in a THREE.WebGLRenderer or an initialized THREE.WebGPURenderer so\n * Gaussian Splat Lite can perform work outside the usual render loop. Both\n * native WebGPU and the WebGL2 fallback are supported. The renderer\n * should be created with antialias: false (the default) because MSAA does not\n * improve Gaussian Splatting and significantly reduces performance.\n */\n renderer: GaussianSplatCompatibleRenderer;\n /**\n * Callback function to be called when GaussianSplatRenderer needs to re-render,\n * for example when a splat sort completes.\n */\n onDirty?: () => void;\n /**\n * Whether to use premultiplied alpha when accumulating splat RGB\n * @default true\n */\n premultipliedAlpha?: boolean;\n /**\n * Decode stored sRGB Splat colors to linear before blending. When omitted,\n * conversion follows the active blend space automatically.\n * @default undefined\n */\n encodeLinear?: boolean;\n /**\n * Pass in a THREE.Timer to synchronize time-based effects across different\n * systems. A supplied timer remains owned and updated by the caller.\n * @default new THREE.Timer()\n */\n timer?: THREE.Timer;\n /**\n * Controls whether to check and automatically update Gsplat collection\n * each frame render.\n * @default true\n */\n autoUpdate?: boolean;\n /**\n * Controls whether to update the Gsplats before or after rendering. For WebXR\n * this is set to false in order to complete rendering as soon as possible.\n * @default true (if not WebXR)\n */\n preUpdate?: boolean;\n /**\n * Maximum standard deviations from the center to render Gaussians. Values\n * Math.sqrt(4)..Math.sqrt(9) produce acceptable results and can be tweaked for\n * performance. A Gaussian still above minAlpha at this distance fades to\n * minAlpha there instead of ending in a step.\n * @default Math.sqrt(8)\n */\n maxStdDev?: number;\n /**\n * Minimum screen-pixel radius for splat rendering, independent of the\n * internal projection scale used by focalAdjustment.\n * @default 1.0\n */\n minPixelRadius?: number;\n /**\n * Minimum alpha value for splat rendering.\n * @default 0.5 / 255\n */\n minAlpha?: number;\n /**\n * Scalar value to add to 2D splat covariance diagonal, effectively blurring +\n * enlarging splats. In scenes trained without the Gsplat anti-aliasing tweak\n * this value was typically 0.3, but with anti-aliasing it is 0.0\n * @default 0.3\n */\n preBlurAmount?: number;\n /**\n * Scalar value to add to the projected 2D splat covariance diagonal, with\n * opacity adjustment for anti-aliasing. Set to 0.3 with preBlurAmount = 0\n * to enable compensated blur. Its screen-space scale depends on focalAdjustment.\n * @default 0.0\n */\n blurAmount?: number;\n /**\n * X/Y clipping boundary factor for Gsplat centers against view frustum.\n * 1.0 clips any centers that are exactly out of bounds, while 1.25 clips\n * centers that are 25% beyond the bounds.\n * @default 1.25\n */\n clipXY?: number;\n /**\n * Parameter to adjust projected splat scale calculation to match other renderers,\n * similar to the same parameter in the MKellogg 3DGS renderer. Higher values will\n * tend to sharpen the splats. A value 2.0 can be used to match the behavior of\n * the PlayCanvas renderer.\n * @default 2.0\n */\n focalAdjustment?: number;\n /**\n * Whether to sort splats radially (geometric distance) from the viewpoint (true)\n * or by Z-depth (false). Most scenes are trained with the Z-depth sort metric\n * and will render more accurately at certain viewpoints. However, radial sorting\n * is more stable under viewpoint rotations.\n * @default false\n */\n sortRadial?: boolean;\n /**\n * Lower-precision sorting for faster sorted rendering.\n * Has no effect on stochastic rendering.\n * @default true\n */\n fastSort?: boolean;\n /**\n * Minimum interval between WebGL sort calls in milliseconds. Native WebGPU\n * projects and sorts each draw without CPU throttling.\n * @default 0\n */\n minSortIntervalMs?: number;\n /**\n * Enables stochastic transparency. Also applies to WebXR.\n * @default false\n */\n stochastic?: boolean;\n /**\n * Increment stochasticSample once per scene render while stochastic\n * coverage is active, including WebXR. All views in that render share the\n * same sample.\n * @default true\n */\n autoAdvanceStochasticSample?: boolean;\n /**\n * 16-bit front-to-back ordering for stochastic frames.\n * WebXR eyes share one order based on their mean position and direction.\n * WebGL and WebGL fallback sort asynchronously; native WebGPU sorts on the GPU.\n * Disable to draw in source/compacted order.\n * @default true\n */\n stochasticSort?: boolean;\n /**\n * Set the splat shader material to be transparent which determines if the\n * splats are rendered during the first opaque THREE.js render pass or the\n * second transparent render pass. Stochastic rendering keeps the\n * material in the opaque list, with depth testing and writing enabled.\n * @default undefined = true\n */\n transparent?: boolean;\n /**\n * Set the splat shader material to enable depth testing which determines if the\n * splats respect the Z depth buffer and blend with other opaque objects in the scene.\n * @default undefined = true\n */\n depthTest?: boolean;\n /**\n * Set the splat shader material to enable depth writing which determines if the\n * splats write to the Z depth buffer. Note that enabling this may produce\n * undesirable results because most of the Gsplat is transparent.\n * @default undefined = false\n */\n depthWrite?: boolean;\n}\n\nexport class GaussianSplatRenderer extends THREE.Mesh<\n SplatGeometry,\n SplatMaterial\n> {\n readonly renderer: GaussianSplatCompatibleRenderer;\n readonly uniforms: ReturnType<typeof GaussianSplatRenderer.makeUniforms>;\n\n autoUpdate: boolean;\n preUpdate: boolean;\n /** @internal False for a second renderer on the same scene, so each `onFrame` runs once per frame. */\n frameCallbacks = true;\n\n renderSize = new THREE.Vector2();\n maxStdDev: number;\n minPixelRadius: number;\n minAlpha: number;\n preBlurAmount: number;\n blurAmount: number;\n clipXY: number;\n focalAdjustment: number;\n sortRadial: boolean;\n private _fastSort: boolean;\n minSortIntervalMs: number;\n /**\n * Noise pattern index, wrapped to uint32. Each value selects an independent\n * pattern. Disable autoAdvanceStochasticSample for manual control.\n */\n stochasticSample = 0;\n autoAdvanceStochasticSample: boolean;\n private _stochastic: boolean;\n private stochasticFrame: boolean;\n private _stochasticSort: boolean;\n private _premultipliedAlpha: boolean;\n private _encodeLinear: boolean | undefined;\n private _transparent: boolean;\n private readonly sortedBlending: THREE.Blending;\n private _depthTest: boolean;\n private _depthWrite: boolean;\n\n readonly timer: THREE.Timer;\n private readonly ownsTimer: boolean;\n lastFrame = -1;\n updateTimeoutId = -1;\n onDirty?: () => void;\n dirty: boolean;\n\n private readonly backend: SplatBackend;\n private orderingBuffer: Uint32Array = new Uint32Array(0);\n // A CPU ordering matching the displayed accumulator; unsorted stochastic\n // updates display without one.\n private orderingReady = false;\n // Mean pose of the WebXR eyes; see getGenerationCamera().\n private readonly headCamera = new THREE.PerspectiveCamera();\n maxSplats = 0;\n activeSplats = 0;\n\n display: SplatAccumulator;\n current: SplatAccumulator;\n accumulators: SplatAccumulator[] = [];\n\n sorting = false;\n sortDirty = false;\n lastSortTime = 0;\n sortWorker: SplatWorker | null = null;\n sortedCenter = new THREE.Vector3().setScalar(Number.NEGATIVE_INFINITY);\n sortedDir = new THREE.Vector3().setScalar(0);\n private sortedRadial: boolean | undefined;\n private sortedFastSort: boolean | undefined;\n private sortedMode: SortMode | undefined;\n private sortCenterCache = new SortCenterCache();\n private sortStateRevision = 0;\n private uploadedSortStateRevision = -1;\n private updateRunning = false;\n private updatePromise: Promise<void> = Promise.resolve();\n private queuedUpdate: UpdateRequest | null = null;\n private disposed = false;\n private pendingProjectionShrink = false;\n private unsupportedCameraReported = false;\n\n constructor(options: GaussianSplatRendererOptions) {\n if (!options?.renderer) {\n throw new Error(\"renderer is required in GaussianSplatRenderer options\");\n }\n assertSupportedRenderer(options.renderer);\n\n const uniforms = GaussianSplatRenderer.makeUniforms();\n\n const premultipliedAlpha = options.premultipliedAlpha ?? true;\n const stochastic = options.stochastic ?? false;\n const backend = createSplatBackend(options.renderer, uniforms, {\n premultipliedAlpha,\n transparent: options.transparent ?? true,\n depthTest: options.depthTest ?? true,\n depthWrite: options.depthWrite ?? false,\n });\n const geometry = new SplatGeometry();\n const material = backend.selectMaterial(stochastic);\n\n super(geometry, material);\n this.renderer = options.renderer;\n this.backend = backend;\n this.uniforms = uniforms;\n this.sortedBlending = material.blending;\n this._depthTest = options.depthTest ?? true;\n this._depthWrite = options.depthWrite ?? false;\n this._premultipliedAlpha = premultipliedAlpha;\n this._encodeLinear = options.encodeLinear;\n this._transparent = options.transparent ?? true;\n this._stochastic = stochastic;\n this.autoAdvanceStochasticSample =\n options.autoAdvanceStochasticSample ?? true;\n this._stochasticSort = options.stochasticSort ?? true;\n this.stochasticFrame = stochastic;\n this.applyMaterialState(this.stochasticFrame);\n // Disable frustum culling because we want to always draw them all\n // and cull Gsplats individually in the shader\n this.frustumCulled = false;\n\n // By default GaussianSplatRenderer will only render for layer 0\n // this.layers.enableAll();\n\n // gaussianSplatRendererInstance = this;\n this.onDirty = options.onDirty;\n this.dirty = true;\n this.autoUpdate = options.autoUpdate ?? true;\n this.preUpdate = options.preUpdate ?? true;\n\n this.maxStdDev = options.maxStdDev ?? Math.sqrt(8.0);\n this.minPixelRadius = options.minPixelRadius ?? 1.0;\n this.minAlpha = options.minAlpha ?? DEFAULT_MIN_ALPHA;\n this.preBlurAmount = options.preBlurAmount ?? 0.3;\n this.blurAmount = options.blurAmount ?? 0.0;\n this.clipXY = options.clipXY ?? 1.25;\n this.focalAdjustment = options.focalAdjustment ?? 2.0;\n this.sortRadial = options.sortRadial ?? false;\n this._fastSort = options.fastSort ?? true;\n this.minSortIntervalMs = options.minSortIntervalMs ?? 0;\n\n const { timer, ownsTimer } = resolveTimer(options.timer);\n this.timer = timer;\n this.ownsTimer = ownsTimer;\n\n this.display = new SplatAccumulator();\n this.current = this.display;\n if (backend.kind !== \"webgpu\") {\n this.accumulators.push(new SplatAccumulator());\n }\n\n if (backend.kind === \"webgpu\") {\n backend.precompile?.then(() => {\n if (!this.disposed) this.setDirty();\n });\n // WebXR eye kernels compile on first use or session start; draws hide\n // Splats until they are ready, so request a redraw.\n backend.projection.onKernelsReady = () => {\n if (!this.disposed) this.setDirty();\n };\n }\n }\n\n raycast(_raycaster: THREE.Raycaster, _intersects: THREE.Intersection[]) {}\n\n static makeUniforms() {\n return makeSplatUniforms();\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.queuedUpdate = null;\n clearTimeout(this.updateTimeoutId);\n this.updateTimeoutId = -1;\n\n super.dispose();\n\n this.backend.dispose();\n this.uniforms.stochasticNoise.value.dispose();\n\n const accumulators = new Set<SplatAccumulator>();\n accumulators.add(this.display);\n accumulators.add(this.current);\n for (const accumulator of this.accumulators) {\n accumulators.add(accumulator);\n }\n for (const accumulator of accumulators) {\n accumulator.dispose();\n }\n this.accumulators.length = 0;\n\n this.resetSortWorker();\n this.orderingBuffer = new Uint32Array(0);\n this.orderingReady = false;\n this.maxSplats = 0;\n this.activeSplats = 0;\n\n this.geometry.dispose();\n }\n\n /** Native WebGPU sorts on the GPU before drawing; WebGL sorts in a worker. */\n get synchronousSort() {\n return this.backend.kind === \"webgpu\";\n }\n\n setDirty() {\n if (!this.dirty) {\n this.dirty = true;\n this.onDirty?.();\n }\n }\n\n private resetSortWorker() {\n this.sortWorker?.dispose();\n this.sortWorker = null;\n this.sortCenterCache.dispose();\n this.uploadedSortStateRevision = -1;\n }\n\n /**\n * Frees the worker, its sort state and the ordering, which unsorted draws\n * never read. Re-enabling sorting reallocates them and uploads centers.\n */\n private releaseOrdering() {\n this.resetSortWorker();\n if (this.backend.kind !== \"webgpu\") this.backend.releaseOrdering();\n this.orderingBuffer = new Uint32Array(0);\n this.maxSplats = 0;\n }\n\n private takeAccumulator() {\n return this.accumulators.pop() ?? new SplatAccumulator();\n }\n\n private releaseAccumulator(accumulator: SplatAccumulator) {\n this.accumulators.push(accumulator);\n }\n\n private disposeOversizedAccumulators(maxSplats: number) {\n for (const accumulator of this.accumulators) {\n if (accumulator.maxSplats > maxSplats) accumulator.dispose();\n }\n }\n\n /**\n * Draw stochastically exactly while the displayed accumulator was generated\n * for it: only stochastic accumulators carry sampling seeds, and only\n * sorted ones a back-to-front order. WebGL backends therefore switch modes\n * once an update for the new mode is displayed. Native WebGPU switches at\n * the update boundary too, keeping mode changes outside an active draw.\n */\n private syncStochasticFrame() {\n const active =\n this.backend.kind === \"webgpu\" || this.display.numSplats === 0\n ? this._stochastic\n : this.display.hasStochasticSeeds;\n if (active === this.stochasticFrame) return;\n this.stochasticFrame = active;\n this.material = this.backend.selectMaterial(active);\n this.applyMaterialState(active);\n this.setDirty();\n }\n\n private applyMaterialState(stochasticActive: boolean) {\n const { material } = this;\n const wasOpaque = isOpaqueMaterial(material);\n material.transparent = stochasticActive ? false : this._transparent;\n material.blending = stochasticActive\n ? THREE.NoBlending\n : this.sortedBlending;\n material.depthTest = stochasticActive ? true : this._depthTest;\n material.depthWrite = stochasticActive ? true : this._depthWrite;\n if (\n material.premultipliedAlpha !== this._premultipliedAlpha ||\n wasOpaque !== isOpaqueMaterial(material)\n ) {\n material.premultipliedAlpha = this._premultipliedAlpha;\n material.needsUpdate = true;\n }\n }\n\n private reportedRenderError = \"\";\n private runAutomaticUpdate(request: UpdateRequest) {\n try {\n void this.updateInternal(request).catch((error) =>\n this.reportRenderError(error),\n );\n } catch (error) {\n this.reportRenderError(error);\n }\n }\n private readonly viewportSize = new THREE.Vector4();\n\n private reportRenderError(error: unknown) {\n const message = String(error);\n if (message !== this.reportedRenderError) {\n this.reportedRenderError = message;\n console.error(\"Gaussian Splat render failed\", error);\n }\n }\n\n onBeforeRender(\n renderer: GaussianSplatCompatibleRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n ) {\n try {\n this.prepareDraw(renderer, scene, camera);\n } catch (error) {\n this.reportRenderError(error);\n this.geometry.setIndirect(null);\n this.geometry.instanceCount = 0;\n } finally {\n // Generation can render nested quads, advancing Three's render counter.\n this.lastFrame = getRenderFrame(renderer);\n }\n }\n\n private prepareDraw(\n renderer: GaussianSplatCompatibleRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n ) {\n if (!isSupportedCamera(camera, renderer)) {\n // Throwing here would leave Three.js mid-render; skip this draw instead.\n if (!this.unsupportedCameraReported) {\n this.unsupportedCameraReported = true;\n console.error(UNSUPPORTED_CAMERA);\n }\n this.geometry.setIndirect(null);\n this.geometry.instanceCount = 0;\n return;\n }\n const frame = getRenderFrame(renderer);\n const isNewFrame = frame !== this.lastFrame;\n this.lastFrame = frame;\n if (isNewFrame) {\n if (this.autoAdvanceStochasticSample && this.stochasticFrame) {\n this.stochasticSample = (this.stochasticSample + 1) >>> 0;\n }\n }\n\n const currentRenderTarget = renderer.getRenderTarget();\n if (currentRenderTarget) {\n this.renderSize.set(\n currentRenderTarget.viewport.z,\n currentRenderTarget.viewport.w,\n );\n } else {\n renderer.getViewport(this.viewportSize);\n this.renderSize\n .set(this.viewportSize.z, this.viewportSize.w)\n .multiplyScalar(renderer.getPixelRatio());\n }\n\n const xrView = isXRCamera(camera, renderer);\n const updateCamera = xrView ? renderer.xr.getCamera() : camera;\n // Classic WebGL draws each eye separately; node backends select viewport\n // uniforms per eye in the shader. XR preparation uses the first eye's size.\n const viewport =\n (camera as THREE.PerspectiveCamera).viewport ??\n (xrView\n ? (getViews(updateCamera)[0] as THREE.PerspectiveCamera).viewport\n : undefined);\n this.uniforms.viewportOrigin.value.set(viewport?.x ?? 0, viewport?.y ?? 0);\n if (viewport) this.renderSize.set(viewport.z, viewport.w);\n this.uniforms.renderSize.value.copy(this.renderSize);\n // Accumulator generation inside this draw would reset a classic WebGL\n // eye viewport and must not delay XR frames.\n const renderNested =\n this.backend.kind !== \"webgpu\" && this.preUpdate && !xrView && !viewport;\n\n // Trigger update after refreshing renderSize but before any uniforms that\n // depend on the active accumulator, avoiding both size and display latency.\n if (this.autoUpdate && isNewFrame) {\n // Native preparation only updates mappings and edit metadata. Its GPU\n // projection runs below, so it can prepare before XR draws as well.\n // Three has already selected this draw's material and render list.\n // Mode changes must finish outside the draw; onDirty then requests\n // a frame with the matching material, ordering and accumulator.\n const preUpdate =\n this.stochasticFrame === this._stochastic &&\n (this.backend.kind === \"webgpu\" || renderNested);\n const updateRequest = {\n scene,\n camera: updateCamera,\n shrinkResources: false,\n };\n if (preUpdate) {\n this.runAutomaticUpdate(updateRequest);\n } else if (this.updateTimeoutId === -1) {\n this.updateTimeoutId = setTimeout(() => {\n this.updateTimeoutId = -1;\n this.runAutomaticUpdate(updateRequest);\n }, 0);\n }\n }\n\n const typedCamera = camera as\n | THREE.PerspectiveCamera\n | THREE.OrthographicCamera;\n\n this.uniforms.near.value = typedCamera.near;\n this.uniforms.far.value = typedCamera.far;\n\n const display = this.display;\n // Native WebGPU prepares current poses before every draw.\n if (this.autoUpdate && renderNested) {\n display.refreshTransforms(renderer);\n }\n this.uniforms.renderOrigin.value.copy(display.viewOrigin);\n const geometry = this.geometry;\n // CPU orderings exist only while they match the displayed accumulator.\n this.uniforms.stochasticOrdering.value =\n this.stochasticSort &&\n (this.backend.kind === \"webgpu\" || this.orderingReady);\n const splatCount =\n this.stochasticFrame && !this.uniforms.stochasticOrdering.value\n ? display.numSplats\n : this.activeSplats;\n geometry.setSplatCount(splatCount);\n this.uniforms.splatCount.value = splatCount;\n\n // Keep rig scale: Camera.matrixWorldInverse can strip it in Three.js.\n renderToViewMatrixTmp\n .copy(camera.matrixWorld)\n .invert()\n .multiply(renderTranslationTmp.makeTranslation(display.viewOrigin))\n .decompose(\n this.uniforms.renderToViewPos.value,\n this.uniforms.renderToViewQuat.value,\n renderToViewScaleTmp,\n );\n this.uniforms.renderToViewScale.value =\n (renderToViewScaleTmp.x +\n renderToViewScaleTmp.y +\n renderToViewScaleTmp.z) /\n 3;\n this.uniforms.maxStdDev.value = this.maxStdDev;\n this.uniforms.minPixelRadius.value = this.minPixelRadius;\n // Negative thresholds hide nothing, like zero.\n const minAlpha = Math.max(0, this.minAlpha);\n this.uniforms.minAlpha.value = minAlpha;\n // A Gaussian's kernel where maxStdDev ends it. One still flat there cannot\n // fade; bound the slope instead.\n const edgeKernel = Math.exp(-0.5 * Math.fround(this.maxStdDev) ** 2);\n const edgeScale = 1 / Math.max(1 - edgeKernel, 0.001);\n this.uniforms.edgeFade.value.set(\n edgeKernel * edgeScale,\n minAlpha * edgeScale,\n );\n this.uniforms.preBlurAmount.value = this.preBlurAmount;\n this.uniforms.blurAmount.value = this.blurAmount;\n this.uniforms.clipXY.value = this.clipXY;\n this.uniforms.focalAdjustment.value = this.focalAdjustment;\n this.uniforms.stochastic.value = this.stochasticFrame;\n this.uniforms.stochasticSample.value = this.stochasticSample >>> 0;\n configureSplatOutput(\n renderer,\n currentRenderTarget,\n this.uniforms,\n this._encodeLinear,\n );\n\n if (this.backend.kind === \"webgpu\") {\n if (this.backend.sortError) throw this.backend.sortError;\n if (this.backend.precompile) {\n geometry.instanceCount = 0;\n } else {\n const projected = this.backend.projection.render(\n display,\n camera,\n geometry,\n this.sortRadial,\n this.fastSort,\n this.pendingProjectionShrink,\n );\n if (projected) this.pendingProjectionShrink = false;\n }\n } else {\n const splatTextures = display.getTextures();\n this.uniforms.splats.value = splatTextures[0];\n this.uniforms.splats2.value = splatTextures[1];\n this.uniforms.stochasticSeeds.value = display.getStochasticSeeds();\n }\n\n this.dirty = false;\n }\n\n clearSplats() {\n this.activeSplats = 0;\n this.display.numSplats = 0;\n this.display.mapping = [];\n this.syncStochasticFrame();\n this.setDirty();\n }\n\n async update({\n scene,\n camera,\n }: {\n scene: THREE.Scene;\n camera: THREE.Camera;\n }) {\n assertSupportedCamera(camera, this.renderer);\n this.reportedRenderError = \"\";\n if (this.backend.kind === \"webgpu\") {\n await this.backend.precompile;\n if (this.backend.sortError) throw this.backend.sortError;\n }\n await this.updateInternal({\n scene,\n camera,\n shrinkResources: false,\n });\n }\n\n /** Updates the current scene and shrinks renderer work resources to their current allocation tiers. */\n async shrinkResources({\n scene,\n camera,\n }: {\n scene: THREE.Scene;\n camera: THREE.Camera;\n }) {\n assertSupportedCamera(camera, this.renderer);\n this.reportedRenderError = \"\";\n await this.updateInternal({\n scene,\n camera,\n shrinkResources: true,\n });\n }\n\n private updateInternal(request: UpdateRequest): Promise<void> {\n if (this.disposed) return Promise.resolve();\n\n if (this.backend.kind === \"webgpu\") {\n const { scene, shrinkResources } = request;\n if (scene.matrixWorldAutoUpdate) scene.updateMatrixWorld();\n if (!(request.camera as THREE.ArrayCamera).isArrayCamera)\n request.camera.updateWorldMatrix(true, false);\n const camera = this.getGenerationCamera(request.camera);\n if (this.ownsTimer) this.timer.update();\n if (shrinkResources) this.pendingProjectionShrink = true;\n const previousVersion = this.current.version;\n const viewChanged =\n !this.current.viewOrigin.equals(\n renderToViewScaleTmp.setFromMatrixPosition(camera.matrixWorld),\n ) ||\n !this.current.viewDirection.equals(\n renderToViewScaleTmp\n .setFromMatrixColumn(camera.matrixWorld, 2)\n .normalize()\n .negate(),\n );\n const { requiredMaxSplats } = this.current.prepareGenerate({\n renderer: this.renderer,\n scene,\n timer: this.timer,\n camera,\n layerCamera: request.camera,\n previous: this.current,\n frameCallbacks: this.frameCallbacks,\n });\n // The accumulator only carries source mappings and the camera-relative\n // origin here. Projection, compaction and ordering happen on the GPU\n // immediately before each draw.\n this.display = this.current;\n this.activeSplats = this.current.numSplats;\n this.maxSplats = requiredMaxSplats;\n this.sortDirty = false;\n this.syncStochasticFrame();\n if (\n shrinkResources ||\n viewChanged ||\n previousVersion !== this.current.version\n ) {\n this.setDirty();\n }\n return Promise.resolve();\n }\n\n const pending = this.queuedUpdate;\n const shrinkResources =\n request.shrinkResources || (pending?.shrinkResources ?? false);\n this.queuedUpdate = {\n scene: request.scene,\n camera: request.camera,\n shrinkResources,\n };\n\n if (!this.updateRunning) {\n this.updateRunning = true;\n this.updatePromise = this.drainUpdates();\n }\n return this.updatePromise;\n }\n\n private async drainUpdates() {\n try {\n while (this.queuedUpdate) {\n const request = this.queuedUpdate;\n this.queuedUpdate = null;\n await this.performUpdate(request);\n }\n } finally {\n this.queuedUpdate = null;\n this.updateRunning = false;\n }\n }\n\n private async performUpdate({\n scene,\n camera: updateCamera,\n shrinkResources,\n }: UpdateRequest) {\n const next = this.takeAccumulator();\n\n const renderer = this.renderer;\n if (scene.matrixWorldAutoUpdate) scene.updateMatrixWorld();\n if (!(updateCamera as THREE.ArrayCamera).isArrayCamera)\n updateCamera.updateWorldMatrix(true, false);\n if (this.ownsTimer) {\n this.timer.update();\n }\n\n // Read the mode when the update runs; queued requests may predate a switch.\n const mode: SortMode = !this._stochastic\n ? \"back\"\n : this.stochasticSort\n ? \"front\"\n : \"identity\";\n // One viewpoint generates and sorts: the camera, or the WebXR head.\n const camera = this.getGenerationCamera(updateCamera);\n const center = new THREE.Vector3().setFromMatrixPosition(\n camera.matrixWorld,\n );\n const direction = new THREE.Vector3()\n .setFromMatrixColumn(camera.matrixWorld, 2)\n .normalize()\n .negate();\n const moveTolerance =\n 0.001 * getCameraWorldScale(getViews(updateCamera)[0]);\n const viewChanged =\n mode !== this.sortedMode ||\n (mode === \"back\" &&\n (this.sortRadial !== this.sortedRadial ||\n this.fastSort !== this.sortedFastSort)) ||\n center.distanceTo(this.sortedCenter) > moveTolerance ||\n (mode !== \"identity\" &&\n (mode === \"front\" || !this.sortRadial) &&\n direction.dot(this.sortedDir) < 0.999);\n\n const previousVersion = this.current.version;\n let preparation: ReturnType<SplatAccumulator[\"prepareGenerate\"]>;\n try {\n preparation = next.prepareGenerate({\n renderer,\n scene,\n timer: this.timer,\n camera,\n layerCamera: updateCamera,\n previous: this.current,\n frameCallbacks: this.frameCallbacks,\n });\n } catch (error) {\n this.releaseAccumulator(next);\n throw error;\n }\n const { version, sortUpdated, requiredMaxSplats, generate } = preparation;\n const orderingNeedsShrink =\n shrinkResources &&\n this.backend.getOrderingCapacity(requiredMaxSplats) < this.maxSplats;\n const doUpdate =\n shrinkResources ||\n mode !== this.sortedMode ||\n center.distanceTo(this.current.viewOrigin) > moveTolerance ||\n version !== previousVersion;\n const needsSort = orderingNeedsShrink || viewChanged || sortUpdated;\n // Unsorted stochastic draws read source indices directly.\n const skipSort = mode === \"identity\";\n\n if (!doUpdate) {\n this.current.viewDirection.copy(direction);\n this.sortDirty ||= needsSort;\n this.releaseAccumulator(next);\n } else {\n try {\n generate(shrinkResources, mode !== \"back\");\n } catch (error) {\n this.releaseAccumulator(next);\n throw error;\n }\n\n if (sortUpdated) {\n this.sortStateRevision += 1;\n }\n\n if (skipSort) {\n this.releaseAccumulator(this.display);\n if (this.current !== this.display) {\n this.releaseAccumulator(this.current);\n }\n // The stochastic shader reads identity indices, so the latest generated\n // accumulator is immediately displayable without a matching ordering.\n this.display = next;\n } else if (\n this.display.mappingVersion === next.mappingVersion &&\n !needsSort\n ) {\n // Appearance-only update: the mapping and existing sort order are\n // still valid, so display the new accumulator immediately.\n this.releaseAccumulator(this.display);\n this.display = next;\n } else {\n if (this.display !== this.current) {\n // The previous current is not being displayed, so replace it\n this.releaseAccumulator(this.current);\n }\n }\n\n this.current = next;\n // Appearance-only updates can reuse the current ordering. Preserve an\n // already pending sort, but do not enqueue a new one unless depth or the\n // mapping may have changed.\n this.sortDirty ||= needsSort;\n this.setDirty();\n }\n\n if (skipSort) {\n // No ordering matches the displayed accumulator. Record the view it\n // was generated for, so later frames compare against it as they do\n // against a sort and only real view or mode changes regenerate it.\n this.sortDirty = false;\n this.activeSplats = this.display.numSplats;\n this.orderingReady = false;\n if (doUpdate) {\n this.sortedMode = mode;\n this.sortedCenter.copy(center);\n this.sortedDir.copy(direction);\n }\n if (shrinkResources) {\n this.releaseOrdering();\n this.disposeOversizedAccumulators(this.current.maxSplats);\n }\n this.syncStochasticFrame();\n return;\n }\n\n await this.driveSort(\n orderingNeedsShrink,\n // Switch modes without waiting for the sort interval.\n shrinkResources || this.stochasticFrame !== this._stochastic,\n mode,\n );\n\n this.syncStochasticFrame();\n if (shrinkResources) {\n this.disposeOversizedAccumulators(this.current.maxSplats);\n }\n }\n\n /**\n * Viewpoint for generation, spherical harmonics, the render origin and\n * sorting: the camera, or for WebXR eyes their mean pose, the shared head.\n */\n private getGenerationCamera(camera: THREE.Camera) {\n const views = getViews(camera);\n if (views.length < 2 || !isXRCamera(camera, this.renderer)) return views[0];\n const position = headPositionTmp;\n const target = headTargetTmp;\n getMeanViewPose(views, position, target);\n target.add(position);\n const head = this.headCamera;\n head.matrixAutoUpdate = false;\n head.matrix\n .lookAt(\n position,\n target,\n renderToViewScaleTmp.setFromMatrixColumn(views[0].matrixWorld, 1),\n )\n .setPosition(position);\n head.updateMatrixWorld(true);\n return head;\n }\n\n private async driveSort(\n shrinkOrdering: boolean,\n forceSort: boolean,\n mode: SortMode,\n ) {\n // WebGL updates await each sort before draining the next queued update.\n if (this.disposed || this.backend.kind === \"webgpu\" || !this.sortDirty)\n return;\n\n const now = performance.now();\n const nextSortTime = this.lastSortTime\n ? this.lastSortTime + this.minSortIntervalMs\n : now;\n\n this.sorting = true;\n this.sortDirty = false;\n this.lastSortTime = performance.now();\n const current = this.current;\n const previousActiveSplats = this.activeSplats;\n\n try {\n const sortRadial = this.sortRadial;\n const fastSort = this.fastSort;\n if (shrinkOrdering || this.sortWorker?.disposed) this.resetSortWorker();\n this.sortWorker ??= new SplatWorker();\n const sortWorker = this.sortWorker;\n\n const { numSplats, maxSplats } = current;\n const orderingMaxSplats = this.backend.getOrderingCapacity(maxSplats);\n this.maxSplats = shrinkOrdering\n ? orderingMaxSplats\n : Math.max(this.maxSplats, orderingMaxSplats);\n\n if (this.orderingBuffer.length !== this.maxSplats) {\n this.orderingBuffer = new Uint32Array(this.maxSplats);\n }\n\n const stateRevision = this.sortStateRevision;\n const stateUpdate =\n this.uploadedSortStateRevision !== stateRevision\n ? this.sortCenterCache.prepare(current)\n : undefined;\n const cameraPosition = current.viewOrigin.toArray() as [\n number,\n number,\n number,\n ];\n const direction = current.viewDirection.toArray() as [\n number,\n number,\n number,\n ];\n if (!forceSort && now < nextSortTime) {\n await new Promise((resolve) => setTimeout(resolve, nextSortTime - now));\n if (this.disposed) return;\n }\n this.lastSortTime = performance.now();\n if (stateUpdate) {\n const { payload, commit } = stateUpdate;\n await sortWorker.call(\"setSortCenterState\", payload);\n if (this.disposed) return;\n commit();\n this.uploadedSortStateRevision = stateRevision;\n }\n\n // Every view, including both WebXR eyes, draws this one order.\n const { ordering, activeSplats } = await sortWorker.call(\n \"sortCenters32\",\n {\n numSplats,\n cameraPosition,\n direction,\n radial: sortRadial,\n fastSort,\n frontSort: mode !== \"back\",\n ordering: this.orderingBuffer,\n },\n );\n if (this.disposed) return;\n\n this.activeSplats = activeSplats;\n const previousOrdering = this.backend.cpuOrdering;\n this.backend.setCPUOrdering({\n ordering,\n activeSplats,\n requiredCapacity: this.maxSplats,\n shrink: shrinkOrdering,\n });\n\n // Keep the displayed texture's CPU source attached while transferring\n // the other buffer to the worker for the next sort.\n this.orderingBuffer =\n previousOrdering?.length === this.maxSplats\n ? previousOrdering\n : new Uint32Array(this.maxSplats);\n\n this.sortedCenter.fromArray(cameraPosition);\n this.sortedDir.fromArray(direction);\n this.sortedRadial = sortRadial;\n this.sortedFastSort = fastSort;\n this.sortedMode = mode;\n this.orderingReady = true;\n if (this.display !== current) {\n this.releaseAccumulator(this.display);\n this.display = current;\n }\n this.setDirty();\n } catch (error) {\n if (this.disposed) return;\n this.sortDirty = true;\n if (current !== this.display && this.accumulators.length === 0) {\n // A candidate waiting on a new ordering cannot be displayed. Roll back\n // to the still-valid display accumulator and free the failed one.\n this.current = this.display;\n this.releaseAccumulator(current);\n this.activeSplats = previousActiveSplats;\n this.sortDirty = false;\n this.uploadedSortStateRevision = -1;\n }\n throw error;\n } finally {\n this.sorting = false;\n }\n }\n\n /** Decode sRGB before blending; undefined follows the active blend space. */\n get encodeLinear(): boolean | undefined {\n return this._encodeLinear;\n }\n\n set encodeLinear(value: boolean | undefined) {\n if (value === this._encodeLinear) return;\n this._encodeLinear = value;\n this.setDirty();\n }\n\n get premultipliedAlpha(): boolean {\n return this._premultipliedAlpha;\n }\n\n set premultipliedAlpha(value: boolean) {\n const nextValue = Boolean(value);\n if (this._premultipliedAlpha !== nextValue) {\n this._premultipliedAlpha = nextValue;\n this.applyMaterialState(this.stochasticFrame);\n }\n }\n\n get transparent(): boolean {\n return this._transparent;\n }\n\n set transparent(value: boolean) {\n const nextValue = Boolean(value);\n if (this._transparent !== nextValue) {\n this._transparent = nextValue;\n this.applyMaterialState(this.stochasticFrame);\n }\n }\n\n get fastSort(): boolean {\n return this._fastSort;\n }\n\n set fastSort(value: boolean) {\n const nextValue = Boolean(value);\n if (nextValue === this._fastSort) return;\n this._fastSort = nextValue;\n // Stochastic orderings sort front to back and ignore it.\n if (!this._stochastic && this.backend.kind !== \"webgpu\") {\n this.sortDirty = true;\n }\n this.setDirty();\n }\n\n get stochasticSort(): boolean {\n return this._stochasticSort;\n }\n\n set stochasticSort(value: boolean) {\n const nextValue = Boolean(value);\n if (nextValue === this._stochasticSort) return;\n this._stochasticSort = nextValue;\n if (this._stochastic && this.backend.kind !== \"webgpu\") {\n this.sortDirty = true;\n }\n this.setDirty();\n }\n\n get stochastic(): boolean {\n return this._stochastic;\n }\n\n /**\n * Whether Splats currently draw stochastically. It follows `stochastic`\n * once an update for the new mode is displayed.\n */\n get stochasticActive(): boolean {\n return this.stochasticFrame;\n }\n\n set stochastic(value: boolean) {\n const nextValue = Boolean(value);\n if (nextValue === this._stochastic) return;\n this._stochastic = nextValue;\n if (this.display.numSplats === 0) this.syncStochasticFrame();\n this.sortDirty = true;\n this.setDirty();\n }\n\n get depthTest(): boolean {\n return this._depthTest;\n }\n\n set depthTest(value: boolean) {\n this._depthTest = Boolean(value);\n this.applyMaterialState(this.stochasticFrame);\n }\n\n get depthWrite(): boolean {\n return this._depthWrite;\n }\n\n set depthWrite(value: boolean) {\n this._depthWrite = Boolean(value);\n this.applyMaterialState(this.stochasticFrame);\n }\n}\n\nfunction isOpaqueMaterial(material: THREE.Material) {\n return (\n material.transparent === false &&\n material.blending === THREE.NormalBlending &&\n material.alphaToCoverage === false\n );\n}\n","import {\n Color,\n ColorManagement,\n DepthTexture,\n FloatType,\n GLSL3,\n HalfFloatType,\n type Matrix4,\n NoBlending,\n NoToneMapping,\n type OrthographicCamera,\n type PerspectiveCamera,\n SRGBTransfer,\n type Scene,\n ShaderMaterial,\n WebGLRenderTarget,\n type WebGLRenderer,\n} from \"three\";\nimport { FullScreenQuad, Pass } from \"three/addons/postprocessing/Pass.js\";\nimport { createTAAState } from \"./taaShared\";\n\nconst vertexShader = /* glsl */ `\nout vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = vec4(position.xy, 0.0, 1.0);\n}\n`;\n\n// TRAANode's resolve, with camera/depth reprojection in place of velocity.\nconst fragmentShader = /* glsl */ `\nprecision highp float;\nprecision highp int;\nuniform sampler2D source;\nuniform sampler2D sourceDepth;\nuniform sampler2D history;\nuniform sampler2D historyDepth;\nuniform vec2 renderSize;\nuniform mat4 projection;\nuniform mat4 unjitteredProjection;\nuniform mat4 previousProjection;\nuniform mat4 viewToPreviousClip;\nuniform mat4 previousViewToView;\nuniform bool valid;\nuniform bool reversed;\nuniform bool logarithmic;\nuniform vec2 logFar;\nuniform float depthThreshold;\nuniform float edgeDepthDiff;\nuniform float maxMotionLength;\nuniform bool useSubpixelCorrection;\nuniform vec3 luminanceCoefficients;\nin vec2 vUv;\nout vec4 fragColor;\n\nivec2 bounded(ivec2 p) {\n return clamp(p, ivec2(0), ivec2(renderSize) - 1);\n}\n\n// Homogeneous view coordinates retain far-depth precision and avoid a\n// world-space round trip.\nvec4 viewPosition(vec2 uv, float depth, mat4 p, float logFarValue) {\n float z = reversed ? depth : depth * 2.0 - 1.0;\n float orientation = reversed ? -1.0 : 1.0;\n float viewZ = (p[3][2] - z * p[3][3]) * orientation;\n float viewW = (z * p[2][3] - p[2][2]) * orientation;\n if (logarithmic) {\n viewZ = 1.0 - exp2(depth * logFarValue);\n viewW = 1.0;\n }\n float clipW = p[2][3] * viewZ + p[3][3] * viewW;\n vec2 viewXY = ((uv * 2.0 - 1.0) * clipW - p[2].xy * viewZ\n - p[3].xy * viewW) / vec2(p[0][0], p[1][1]);\n return vec4(viewXY, viewZ, viewW);\n}\n\nfloat forwardDepth(vec4 positionView) {\n vec4 clip = projection * positionView;\n float depth = clip.z / clip.w;\n return reversed ? 1.0 - depth : depth * 0.5 + 0.5;\n}\n\nvec4 clipAABB(vec4 center, vec4 historyColor, vec4 extent) {\n vec4 delta = historyColor - center;\n vec3 unit = abs(delta.rgb / (extent.rgb + 1e-7));\n float maxUnit = max(unit.r, max(unit.g, unit.b));\n return maxUnit > 1.0 ? center + delta / maxUnit : historyColor;\n}\n\nvec4 flickerReduction(vec4 currentColor, vec4 historyColor, float currentWeight) {\n vec3 compressedCurrent = currentColor.rgb / (max(currentColor.r, max(currentColor.g, currentColor.b)) + 1.0);\n vec3 compressedHistory = historyColor.rgb / (max(historyColor.r, max(historyColor.g, historyColor.b)) + 1.0);\n float weightCurrent = currentWeight / (dot(compressedCurrent, luminanceCoefficients) + 1.0);\n float weightHistory = (1.0 - currentWeight) / (dot(compressedHistory, luminanceCoefficients) + 1.0);\n return (currentColor * weightCurrent + historyColor * weightHistory)\n / max(weightCurrent + weightHistory, 0.00001);\n}\n\nvoid main() {\n ivec2 pixel = ivec2(gl_FragCoord.xy);\n vec4 currentColor = texelFetch(source, pixel, 0);\n fragColor = currentColor;\n gl_FragDepth = texelFetch(sourceDepth, pixel, 0).r;\n if (!valid) return;\n\n float closestDepth = 2.0;\n float farthestDepth = -1.0;\n float closestRawDepth = gl_FragDepth;\n ivec2 closestPixel = pixel;\n vec4 moment1 = currentColor;\n vec4 moment2 = currentColor * currentColor;\n for (int x = -1; x <= 1; ++x) {\n for (int y = -1; y <= 1; ++y) {\n ivec2 p = bounded(pixel + ivec2(x, y));\n float rawDepth = texelFetch(sourceDepth, p, 0).r;\n float depth = reversed && !logarithmic ? 1.0 - rawDepth : rawDepth;\n if (depth < closestDepth) {\n closestDepth = depth;\n closestRawDepth = rawDepth;\n closestPixel = p;\n }\n farthestDepth = max(farthestDepth, depth);\n if (x != 0 || y != 0) {\n vec4 neighbor = max(texelFetch(source, p, 0), vec4(0.0));\n moment1 += neighbor;\n moment2 += neighbor * neighbor;\n }\n }\n }\n\n vec2 closestUV = (vec2(closestPixel) + 0.5) / renderSize;\n vec4 positionView = viewPosition(closestUV, closestRawDepth, projection, logFar.x);\n vec4 previousClip = viewToPreviousClip * positionView;\n if (previousClip.w <= 0.0) return;\n vec4 currentClip = unjitteredProjection * positionView;\n // Exclude projection jitter from camera motion.\n vec2 offsetUV = (currentClip.xy / currentClip.w - previousClip.xy / previousClip.w) * 0.5;\n vec2 historyUV = vUv - offsetUV;\n if (any(lessThan(historyUV, vec2(0.0))) || any(greaterThanEqual(historyUV, vec2(1.0)))) return;\n\n float oldDepth = texture(historyDepth, historyUV).r;\n vec4 previousView = viewPosition(historyUV, oldDepth, previousProjection, logFar.y);\n float previousDepth = forwardDepth(previousViewToView * previousView);\n if (logarithmic) {\n // Log depth is monotonic; convert only the extrema for depth thresholds.\n closestDepth = forwardDepth(positionView);\n float farthestZ = 1.0 - exp2(farthestDepth * logFar.x);\n farthestDepth = forwardDepth(vec4(0.0, 0.0, farthestZ, 1.0));\n }\n bool isEdge = farthestDepth - closestDepth > edgeDepthDiff;\n bool isDisocclusion = closestDepth - previousDepth > depthThreshold;\n if (!isEdge && isDisocclusion) return;\n\n float motionFactor = clamp(length(offsetUV * renderSize) / maxMotionLength, 0.0, 1.0);\n float currentWeight = 0.05;\n if (useSubpixelCorrection) {\n vec2 phase = fract(offsetUV * renderSize);\n vec2 weight = max(phase, 1.0 - phase);\n currentWeight += (1.0 - weight.x * weight.y) / 0.75 * 0.25;\n }\n currentWeight = clamp(currentWeight + motionFactor, 0.0, 1.0);\n float gamma = mix(0.5, 1.0, pow(1.0 - motionFactor, 2.0));\n vec4 mean = moment1 / 9.0;\n vec4 extent = sqrt(max(moment2 / 9.0 - mean * mean, vec4(0.0))) * gamma;\n vec4 historyColor = clipAABB(mean, texture(history, historyUV), extent);\n fragColor = flickerReduction(currentColor, historyColor, currentWeight);\n}\n`;\n\nfunction makeTarget(name: string) {\n const target = new WebGLRenderTarget(1, 1, {\n type: HalfFloatType,\n depthTexture: new DepthTexture(1, 1, FloatType),\n });\n target.texture.name = name;\n return target;\n}\n\n/**\n * Temporal reprojection for WebGLRenderer, using depth and camera motion.\n * Object motion is not tracked; no velocity texture is required.\n * Owns scene capture, camera jitter, and history. It blends and accumulates\n * in the output color space, like direct canvas rendering, then hands the\n * composer a working-space result. Use EffectComposer with OutputPass for\n * output.\n */\nexport class TAAPass extends Pass {\n /** Depth difference above which non-edge history is rejected. */\n depthThreshold = 0.0005;\n /** Depth range within the 3x3 neighborhood that identifies an edge. */\n edgeDepthDiff = 0.001;\n /** Camera motion in pixels at which history loses all weight. */\n maxMotionLength = 128;\n /** Increase current-frame weight for subpixel camera motion. */\n useSubpixelCorrection = true;\n // Three uses this flag to honor the target's output color space for both\n // ordinary materials and splats, matching direct canvas blending.\n private readonly _source = Object.assign(makeTarget(\"TAAPass.scene\"), {\n isXRRenderTarget: true,\n });\n private readonly _history = [\n makeTarget(\"TAAPass.history0\"),\n makeTarget(\"TAAPass.history1\"),\n ];\n private readonly _clearColor = new Color();\n private readonly _state = createTAAState(\n <T>(value: T) => ({ value }),\n [this._source, ...this._history],\n );\n private readonly _uniforms;\n private readonly _resolveMaterial: ShaderMaterial;\n private readonly _copyMaterial: ShaderMaterial;\n private readonly _quad: FullScreenQuad;\n\n constructor(\n public scene: Scene,\n public camera: PerspectiveCamera | OrthographicCamera,\n ) {\n super();\n\n this._uniforms = {\n source: { value: this._source.texture },\n sourceDepth: { value: this._source.depthTexture },\n history: { value: this._history[0].texture },\n historyDepth: { value: this._history[0].depthTexture },\n ...this._state.uniforms,\n };\n this._resolveMaterial = new ShaderMaterial({\n name: \"TAAPass.resolve\",\n uniforms: this._uniforms,\n vertexShader,\n fragmentShader,\n glslVersion: GLSL3,\n blending: NoBlending,\n depthTest: true,\n depthWrite: true,\n toneMapped: false,\n });\n this._copyMaterial = new ShaderMaterial({\n name: \"TAAPass.copy\",\n uniforms: { source: { value: null }, decode: { value: false } },\n vertexShader,\n // Inverts OutputPass's transfer, so the two round-trip at any alpha.\n fragmentShader: /* glsl */ `\n uniform sampler2D source;\n uniform bool decode;\n in vec2 vUv;\n out vec4 fragColor;\n void main() {\n fragColor = texture(source, vUv);\n if (decode) {\n vec4 color = vec4(max(fragColor.rgb, 0.0), 1.0);\n fragColor.rgb = sRGBTransferEOTF(color).rgb;\n }\n }\n `,\n glslVersion: GLSL3,\n blending: NoBlending,\n depthTest: false,\n depthWrite: false,\n toneMapped: false,\n });\n this._quad = new FullScreenQuad(this._resolveMaterial);\n }\n\n /** Current scene depth, before temporal accumulation. Owned by this pass. */\n get depthTexture(): DepthTexture {\n return this._source.depthTexture as DepthTexture;\n }\n\n /** Jittered projection used to capture depthTexture. Treat as read-only. */\n get projectionMatrix(): Matrix4 {\n return this._uniforms.projection.value;\n }\n\n /** Resize all internal targets in physical pixels; a size change clears history. */\n override setSize(width: number, height: number): void {\n this._state.setSize(width, height);\n }\n\n /** Discard history after a camera cut, scene replacement, or color-space change. */\n reset(): void {\n this._state.reset();\n }\n\n /** Render the scene and resolve TAA into the composer's working-space buffer. */\n override render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n ): void {\n const { camera, _state: state, _uniforms: uniforms } = this;\n this.setSize(writeBuffer.width, writeBuffer.height);\n const colorSpace = renderer.outputColorSpace;\n if (this._source.texture.colorSpace !== colorSpace) {\n this._source.texture.colorSpace = colorSpace;\n this.reset();\n }\n // The attributes are null while the WebGL context is lost.\n state.setStencil(\n renderer.getContextAttributes()?.stencil === true,\n FloatType,\n );\n const previousTarget = renderer.getRenderTarget();\n const autoClear = renderer.autoClear;\n const xrEnabled = renderer.xr.enabled;\n const toneMapping = renderer.toneMapping;\n try {\n renderer.xr.enabled = false;\n renderer.autoClear = false;\n // The output pass tone-maps the resolved image.\n renderer.toneMapping = NoToneMapping;\n const reversedDepth = camera.reversedDepth;\n state.beginCapture(camera);\n try {\n renderer.setRenderTarget(this._source);\n // Refresh the clear color in the capture target's color space.\n renderer.setClearColor(\n renderer.getClearColor(this._clearColor),\n renderer.getClearAlpha(),\n );\n renderer.clear();\n renderer.render(this.scene, camera);\n } finally {\n state.endCapture(camera);\n // Three may initialize reversed depth during the first draw. Keep its\n // new depth convention when restoring the unjittered projection.\n if (camera.reversedDepth !== reversedDepth)\n camera.updateProjectionMatrix();\n }\n\n const input = this._history[state.historyIndex];\n const output = this._history[1 - state.historyIndex];\n if (!uniforms.valid.value) {\n // Allocate depth attachments before either is bound as a sampler.\n for (const target of this._history) renderer.initRenderTarget(target);\n }\n uniforms.history.value = input.texture;\n uniforms.historyDepth.value = input.depthTexture;\n uniforms.reversed.value = renderer.capabilities.reversedDepthBuffer;\n uniforms.logarithmic.value =\n renderer.capabilities.logarithmicDepthBuffer &&\n \"isPerspectiveCamera\" in camera &&\n camera.isPerspectiveCamera;\n this._resolveMaterial.depthFunc = state.prepareResolve(camera, this);\n renderer.setRenderTarget(output);\n this._quad.material = this._resolveMaterial;\n this._quad.render(renderer);\n\n this._copyMaterial.uniforms.source.value = output.texture;\n // As the last pass, present the output-space image as it is.\n this._copyMaterial.uniforms.decode.value =\n !this.renderToScreen &&\n ColorManagement.getTransfer(colorSpace) === SRGBTransfer;\n renderer.setRenderTarget(this.renderToScreen ? null : writeBuffer);\n this._quad.material = this._copyMaterial;\n this._quad.render(renderer);\n\n state.advance(camera);\n } finally {\n renderer.setRenderTarget(previousTarget);\n renderer.autoClear = autoClear;\n renderer.xr.enabled = xrEnabled;\n renderer.toneMapping = toneMapping;\n }\n }\n\n override dispose(): void {\n this._source.dispose();\n for (const target of this._history) target.dispose();\n this._resolveMaterial.dispose();\n this._copyMaterial.dispose();\n this._quad.dispose();\n }\n}\n","import {\n ColorManagement,\n DepthTexture,\n FloatType,\n HalfFloatType,\n type Matrix4,\n NoBlending,\n type OrthographicCamera,\n type PerspectiveCamera,\n type Scene,\n type Texture,\n UnsignedInt248Type,\n Vector2,\n type Vector3,\n WebGLCoordinateSystem,\n} from \"three\";\nimport {\n Node,\n type NodeBuilder,\n type NodeFrame,\n NodeMaterial,\n NodeUpdateType,\n QuadMesh,\n RenderTarget,\n RendererUtils,\n type TextureNode,\n type UniformNode,\n type WebGPURenderer,\n} from \"three/webgpu\";\nimport { usesNativeWebGPU } from \"../rendering/rendererUtils\";\nimport { N } from \"../rendering/tsl/tslCompat\";\nimport { createTAAState } from \"./taaShared\";\n\n/** Camera/depth TAA for WebGPURenderer, including its WebGL2 fallback. */\nexport class TAANode extends Node<\"vec4\"> {\n static get type() {\n return \"TAANode\";\n }\n\n depthThreshold = 0.0005;\n edgeDepthDiff = 0.001;\n maxMotionLength = 128;\n useSubpixelCorrection = true;\n\n private readonly source = this.makeTarget(\"TAA.scene\");\n private readonly history = [\n this.makeTarget(\"TAA.history0\"),\n this.makeTarget(\"TAA.history1\"),\n ];\n private readonly historyColor = N.texture(\n this.history[0].texture,\n N.screenUV,\n );\n private readonly historyDepth = N.texture(\n this.history[0].depthTexture,\n N.screenUV,\n );\n private readonly textureNode = (\n N.passTexture as unknown as (pass: TAANode, texture: Texture) => TextureNode\n )(this, this.history[0].texture);\n private readonly material = new NodeMaterial();\n private readonly quad = new QuadMesh(this.material);\n private readonly state = createTAAState<\n UniformNode<\"float\", number>,\n UniformNode<\"bool\", boolean>,\n UniformNode<\"vec2\", Vector2>,\n UniformNode<\"vec3\", Vector3>,\n UniformNode<\"mat4\", Matrix4>\n >(N.uniform, [this.source, ...this.history], true);\n private readonly zeroToOne = N.uniform(true);\n private readonly drawingSize = new Vector2();\n private workingColorSpace = ColorManagement.workingColorSpace;\n private readonly pipelineStates = new WeakSet<object>();\n private pipelineRendering = false;\n private capturePending = true;\n\n constructor(\n public scene: Scene,\n public camera: PerspectiveCamera | OrthographicCamera,\n ) {\n super(\"vec4\");\n this.updateBeforeType = NodeUpdateType.RENDER;\n this.material.name = \"TAA.resolve\";\n this.material.blending = NoBlending;\n this.material.depthTest = true;\n this.material.depthWrite = true;\n this.material.toneMapped = false;\n this.quad.name = \"TAA.resolve\";\n }\n\n private makeTarget(name: string) {\n const target = new RenderTarget(1, 1, {\n type: HalfFloatType,\n depthTexture: new DepthTexture(1, 1, FloatType),\n samples: 0,\n });\n target.texture.name = name;\n return target as RenderTarget & { depthTexture: DepthTexture };\n }\n\n get depthTexture(): DepthTexture {\n return this.source.depthTexture;\n }\n\n get projectionMatrix(): Matrix4 {\n return this.state.uniforms.projection.value;\n }\n\n getTextureNode() {\n return this.textureNode;\n }\n\n setSize(width: number, height: number) {\n this.state.setSize(width, height);\n }\n\n reset() {\n this.state.reset();\n }\n\n override updateBefore(frame: NodeFrame) {\n if (this.pipelineRendering && !this.capturePending) return;\n const renderer = frame.renderer as WebGPURenderer;\n if (this.workingColorSpace !== ColorManagement.workingColorSpace) {\n this.workingColorSpace = ColorManagement.workingColorSpace;\n this.reset();\n }\n const rendererState = RendererUtils.saveRendererState(renderer);\n const xrEnabled = renderer.xr.enabled;\n const { camera, state } = this;\n const { uniforms } = state;\n if (this.pipelineRendering) {\n this.setSize(this.drawingSize.x, this.drawingSize.y);\n } else if (rendererState.renderTarget) {\n this.setSize(\n rendererState.renderTarget.width,\n rendererState.renderTarget.height,\n );\n } else {\n renderer.getDrawingBufferSize(this.drawingSize);\n this.setSize(this.drawingSize.x, this.drawingSize.y);\n }\n // Float depth with stencil is an optional WebGPU feature.\n state.setStencil(\n renderer.stencil,\n renderer.stencil &&\n !(\n usesNativeWebGPU(renderer) &&\n renderer.hasFeature(\"depth32float-stencil8\")\n )\n ? UnsignedInt248Type\n : FloatType,\n );\n try {\n renderer.xr.enabled = false;\n renderer.setMRT(null);\n renderer.setScissorTest(false);\n renderer.autoClear = true;\n const reversedDepth = camera.reversedDepth;\n const coordinateSystem = camera.coordinateSystem;\n state.beginCapture(camera);\n try {\n renderer.setRenderTarget(this.source);\n renderer.render(this.scene, camera);\n } finally {\n state.endCapture(camera);\n // Three may initialize the camera's depth convention on its first draw.\n if (\n camera.reversedDepth !== reversedDepth ||\n camera.coordinateSystem !== coordinateSystem\n )\n camera.updateProjectionMatrix();\n }\n uniforms.reversed.value = renderer.reversedDepthBuffer;\n this.zeroToOne.value =\n renderer.coordinateSystem !== WebGLCoordinateSystem ||\n renderer.reversedDepthBuffer;\n uniforms.logarithmic.value =\n renderer.logarithmicDepthBuffer &&\n \"isPerspectiveCamera\" in camera &&\n camera.isPerspectiveCamera;\n this.material.depthFunc = state.prepareResolve(camera, this);\n if (!uniforms.valid.value)\n for (const target of this.history) renderer.initRenderTarget(target);\n const previous = this.history[state.historyIndex];\n this.historyColor.value = previous.texture;\n this.historyDepth.value = previous.depthTexture;\n const output = this.history[1 - state.historyIndex];\n renderer.setRenderObjectFunction(null);\n renderer.setRenderTarget(output);\n this.quad.render(renderer);\n this.textureNode.value = output.texture;\n state.advance(camera);\n this.capturePending = false;\n } finally {\n RendererUtils.restoreRendererState(renderer, rendererState);\n renderer.xr.enabled = xrEnabled;\n }\n return undefined;\n }\n\n override setup(builder: NodeBuilder) {\n const pipelineState = (builder.context as { renderPipelineState?: object })\n .renderPipelineState;\n if (pipelineState && !this.pipelineStates.has(pipelineState)) {\n this.pipelineStates.add(pipelineState);\n const begin = () => {\n this.pipelineRendering = true;\n this.capturePending = true;\n const renderer = builder.renderer;\n const target =\n renderer.getRenderTarget() ?? renderer.getOutputRenderTarget();\n if (target) this.drawingSize.set(target.width, target.height);\n else renderer.getDrawingBufferSize(this.drawingSize);\n };\n // The first pipeline render builds its callbacks after the before phase.\n begin();\n N.OnBeforeRenderPipeline(begin);\n N.OnAfterRenderPipeline(() => {\n this.pipelineRendering = false;\n });\n }\n const u = this.state.uniforms;\n // Explicit screen UVs avoid identity texture matrices on every sample/load.\n const source = N.texture(this.source.texture, N.screenUV);\n const sourceDepth = N.texture(this.depthTexture, N.screenUV);\n const history = this.historyColor;\n const historyDepth = this.historyDepth;\n const bounded = (p: Node<\"ivec2\">) =>\n p.clamp(N.ivec2(0), N.ivec2(u.renderSize).sub(1));\n // TSL texture coordinates have a top-left origin on both backends.\n const viewPosition = (\n uv: Node<\"vec2\">,\n depth: Node<\"float\">,\n p: Node<\"mat4\">,\n far: Node<\"float\">,\n near: Node<\"float\">,\n ) => {\n const z = N.select(this.zeroToOne, depth, depth.mul(2).sub(1));\n const orientation = N.select(u.reversed, -1, 1);\n const viewZ = p\n .element(3)\n .z.sub(z.mul(p.element(3).w))\n .mul(orientation)\n .toVar();\n const viewW = z\n .mul(p.element(2).w)\n .sub(p.element(2).z)\n .mul(orientation)\n .toVar();\n N.If(u.logarithmic, () => {\n viewZ.assign(near.mul(depth.mul(far).exp2()).negate());\n viewW.assign(1);\n });\n const clipW = p.element(2).w.mul(viewZ).add(p.element(3).w.mul(viewW));\n const xy = uv\n .mul(2)\n .sub(1)\n .mul(N.vec2(1, -1))\n .mul(clipW)\n .sub(p.element(2).xy.mul(viewZ))\n .sub(p.element(3).xy.mul(viewW))\n .div(N.vec2(p.element(0).x, p.element(1).y));\n return N.vec4(xy, viewZ, viewW);\n };\n const forwardDepth = (position: Node<\"vec4\">) => {\n const clip = u.projection.mul(position).toVar();\n const depth = clip.z.div(clip.w);\n return N.select(\n u.reversed,\n N.float(1).sub(depth),\n N.select(this.zeroToOne, depth, depth.mul(0.5).add(0.5)),\n );\n };\n const pixel = N.ivec2(N.screenCoordinate.xy);\n this.material.depthNode = sourceDepth.load(pixel).r;\n this.material.colorNode = N.Fn(() => {\n const currentColor = source.load(pixel).toVar();\n const result = currentColor.toVar();\n N.If(u.valid, () => {\n const closestDepth = N.float(2).toVar();\n const farthestDepth = N.float(-1).toVar();\n const closestRawDepth = sourceDepth.load(pixel).r.toVar();\n const closestPixel = pixel.toVar();\n const moment1 = currentColor.toVar();\n const moment2 = currentColor.mul(currentColor).toVar();\n for (let x = -1; x <= 1; x++) {\n for (let y = -1; y <= 1; y++) {\n const p = bounded(pixel.add(N.ivec2(x, y))).toVar();\n const rawDepth = sourceDepth.load(p).r.toVar();\n const depth = N.select(\n u.reversed.and(u.logarithmic.not()),\n N.float(1).sub(rawDepth),\n rawDepth,\n ).toVar();\n N.If(depth.lessThan(closestDepth), () => {\n closestDepth.assign(depth);\n closestRawDepth.assign(rawDepth);\n closestPixel.assign(p);\n });\n farthestDepth.assign(farthestDepth.max(depth));\n if (x !== 0 || y !== 0) {\n const neighbor = source.load(p).max(0).toVar();\n moment1.addAssign(neighbor);\n moment2.addAssign(neighbor.mul(neighbor));\n }\n }\n }\n const closestUV = N.vec2(closestPixel).add(0.5).div(u.renderSize);\n const positionView = viewPosition(\n closestUV,\n closestRawDepth,\n u.projection,\n u.logFar.x,\n u.logNear.x,\n );\n const previousClip = u.viewToPreviousClip.mul(positionView).toVar();\n N.If(previousClip.w.greaterThan(0), () => {\n const currentClip = u.unjitteredProjection.mul(positionView).toVar();\n const offsetUV = currentClip.xy\n .div(currentClip.w)\n .sub(previousClip.xy.div(previousClip.w))\n .mul(N.vec2(0.5, -0.5))\n .toVar();\n const historyUV = N.screenUV.sub(offsetUV).toVar();\n N.If(\n historyUV\n .greaterThanEqual(0)\n .all()\n .and(historyUV.lessThan(1).all()),\n () => {\n const oldDepth = historyDepth.sample(historyUV).r.toVar();\n const previousView = viewPosition(\n historyUV,\n oldDepth,\n u.previousProjection,\n u.logFar.y,\n u.logNear.y,\n );\n const previousDepth = forwardDepth(\n u.previousViewToView.mul(previousView),\n );\n N.If(u.logarithmic, () => {\n closestDepth.assign(forwardDepth(positionView));\n const farthestZ = u.logNear.x\n .mul(farthestDepth.mul(u.logFar.x).exp2())\n .negate();\n farthestDepth.assign(forwardDepth(N.vec4(0, 0, farthestZ, 1)));\n });\n const isEdge = farthestDepth\n .sub(closestDepth)\n .greaterThan(u.edgeDepthDiff);\n const isDisocclusion = closestDepth\n .sub(previousDepth)\n .greaterThan(u.depthThreshold);\n N.If(isEdge.or(isDisocclusion.not()), () => {\n const motionFactor = offsetUV\n .mul(u.renderSize)\n .length()\n .div(u.maxMotionLength)\n .clamp(0, 1)\n .toVar();\n const currentWeight = N.float(0.05).toVar();\n N.If(u.useSubpixelCorrection, () => {\n const phase = offsetUV.mul(u.renderSize).fract();\n const weight = phase.max(N.vec2(1).sub(phase));\n currentWeight.addAssign(\n N.float(1).sub(weight.x.mul(weight.y)).div(0.75).mul(0.25),\n );\n });\n currentWeight.assign(\n currentWeight.add(motionFactor).clamp(0, 1),\n );\n const gamma = N.mix(\n 0.5,\n 1,\n N.float(1).sub(motionFactor).pow(2),\n );\n const mean = moment1.div(9).toVar();\n const extent = moment2\n .div(9)\n .sub(mean.mul(mean))\n .max(0)\n .sqrt()\n .mul(gamma);\n const historyColor = history.sample(historyUV).toVar();\n const delta = historyColor.sub(mean).toVar();\n const unit = delta.rgb.div(extent.rgb.add(1e-7)).abs();\n const maxUnit = unit.x.max(unit.y).max(unit.z);\n N.If(maxUnit.greaterThan(1), () => {\n historyColor.assign(mean.add(delta.div(maxUnit)));\n });\n const compressedCurrent = currentColor.rgb.div(\n currentColor.r.max(currentColor.g).max(currentColor.b).add(1),\n );\n const compressedHistory = historyColor.rgb.div(\n historyColor.r.max(historyColor.g).max(historyColor.b).add(1),\n );\n const weightCurrent = currentWeight.div(\n compressedCurrent.dot(u.luminanceCoefficients).add(1),\n );\n const weightHistory = N.float(1)\n .sub(currentWeight)\n .div(compressedHistory.dot(u.luminanceCoefficients).add(1));\n result.assign(\n currentColor\n .mul(weightCurrent)\n .add(historyColor.mul(weightHistory))\n .div(weightCurrent.add(weightHistory).max(0.00001)),\n );\n });\n },\n );\n });\n });\n return result;\n })();\n return this.textureNode;\n }\n\n override dispose() {\n super.dispose();\n this.source.dispose();\n for (const target of this.history) target.dispose();\n this.material.dispose();\n }\n}\n","import * as THREE from \"three\";\n\n/** Blend in output space like the canvas, then convert to texture storage. */\nexport class WebGLCapture {\n private readonly depthTexture = new THREE.DepthTexture(\n 1,\n 1,\n THREE.UnsignedIntType,\n );\n private readonly target = Object.assign(\n new THREE.WebGLRenderTarget(1, 1, {\n type: THREE.UnsignedByteType,\n internalFormat: \"RGBA8\",\n generateMipmaps: false,\n depthTexture: this.depthTexture,\n }),\n // Output/XR semantics enable per-material display conversion before blending.\n // Plain RGBA8 stores those output-space values without an sRGB attachment.\n { isXRRenderTarget: true },\n );\n private readonly camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n private readonly material = new THREE.ShaderMaterial({\n uniforms: {\n colorBuffer: { value: this.target.texture },\n depthBuffer: { value: this.target.depthTexture },\n decodeSRGB: { value: true },\n encodeSRGB: { value: false },\n },\n vertexShader: `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = vec4(position.xy, 0.0, 1.0);\n }\n `,\n fragmentShader: `\n uniform sampler2D colorBuffer;\n uniform sampler2D depthBuffer;\n uniform bool decodeSRGB;\n uniform bool encodeSRGB;\n varying vec2 vUv;\n void main() {\n vec4 color = texture2D(colorBuffer, vUv);\n color.rgb = color.a > 0.0 ? color.rgb / color.a : vec3(0.0);\n if (decodeSRGB) color = sRGBTransferEOTF(color);\n if (encodeSRGB) color = sRGBTransferOETF(color);\n color.rgb *= color.a;\n gl_FragColor = color;\n gl_FragDepth = texture2D(depthBuffer, vUv).r;\n }\n `,\n blending: THREE.NoBlending,\n depthFunc: THREE.AlwaysDepth,\n toneMapped: false,\n });\n private readonly quad = new THREE.Mesh(\n new THREE.PlaneGeometry(2, 2),\n this.material,\n );\n\n constructor(private readonly renderer: THREE.WebGLRenderer) {\n this.quad.frustumCulled = false;\n }\n\n render(scene: THREE.Scene, camera: THREE.Camera) {\n const { renderer, target, material } = this;\n const output = renderer.getRenderTarget();\n if (!output) throw new Error(\"WebGL capture requires a render target\");\n const face = renderer.getActiveCubeFace();\n const mip = renderer.getActiveMipmapLevel();\n // Keep float outputs unclamped; other types blend in 8 bits like the canvas.\n const type =\n output.texture.type === THREE.HalfFloatType ||\n output.texture.type === THREE.FloatType\n ? output.texture.type\n : THREE.UnsignedByteType;\n if (\n target.texture.type !== type ||\n target.depthBuffer !== output.depthBuffer ||\n target.stencilBuffer !== output.stencilBuffer ||\n target.samples !== output.samples\n ) {\n target.dispose();\n target.texture.type = type;\n // An sRGB 8-bit target would otherwise allocate as SRGB8_ALPHA8 and\n // blend in linear space.\n target.texture.internalFormat =\n type === THREE.UnsignedByteType ? \"RGBA8\" : null;\n target.depthBuffer = output.depthBuffer;\n target.stencilBuffer = output.stencilBuffer;\n this.depthTexture.format = output.stencilBuffer\n ? THREE.DepthStencilFormat\n : THREE.DepthFormat;\n this.depthTexture.type = output.stencilBuffer\n ? THREE.UnsignedInt248Type\n : THREE.UnsignedIntType;\n // Antialias the scene here; the output only receives a full-screen quad.\n target.samples = output.samples;\n }\n target.setSize(output.width, output.height);\n target.texture.colorSpace = renderer.outputColorSpace;\n material.uniforms.decodeSRGB.value =\n target.texture.colorSpace === THREE.SRGBColorSpace;\n material.uniforms.encodeSRGB.value =\n output.texture.colorSpace === THREE.SRGBColorSpace &&\n output.texture.type !== THREE.UnsignedByteType;\n material.depthTest = output.depthBuffer;\n material.depthWrite = output.depthBuffer;\n try {\n renderer.setRenderTarget(target);\n renderer.render(scene, camera);\n renderer.setRenderTarget(output, face, mip);\n // Three also reverses AlwaysDepth/NeverDepth when reversing depth. Read\n // its live state: resetState() clears it while the capability stays set.\n material.depthFunc = renderer.state.buffers.depth.getReversed()\n ? THREE.NeverDepth\n : THREE.AlwaysDepth;\n renderer.render(this.quad, this.camera);\n } finally {\n renderer.setRenderTarget(output, face, mip);\n }\n }\n\n dispose() {\n this.target.dispose();\n this.quad.geometry.dispose();\n this.material.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport { NodeMaterial, QuadMesh, type WebGPURenderer } from \"three/webgpu\";\nimport { usesNativeWebGPU } from \"../rendering/rendererUtils\";\nimport { N } from \"../rendering/tsl/tslCompat\";\n\n/** Blend in working space, then convert to texture storage. */\nexport class WebGPUCapture {\n private readonly depthTexture = new THREE.DepthTexture(1, 1, THREE.FloatType);\n private readonly target = new THREE.RenderTarget(1, 1, {\n generateMipmaps: false,\n depthTexture: this.depthTexture,\n });\n private readonly material = new NodeMaterial();\n private readonly quad = new QuadMesh(this.material);\n private workingColorSpace = \"\";\n private outputColorSpace = \"\";\n private storageColorSpace = \"\";\n private toneMapping: THREE.ToneMapping | null = null;\n\n constructor(private readonly renderer: WebGPURenderer) {\n this.material.blending = THREE.NoBlending;\n this.material.toneMapped = false;\n this.material.depthNode = N.texture(this.depthTexture).load(\n N.ivec2(N.screenCoordinate.xy),\n ).r;\n }\n\n render(scene: THREE.Scene, camera: THREE.Camera) {\n const { renderer, target, material } = this;\n const output = renderer.getRenderTarget();\n if (!output) throw new Error(\"WebGPU capture requires a render target\");\n const face = renderer.getActiveCubeFace();\n const mip = renderer.getActiveMipmapLevel();\n const workingColorSpace = THREE.ColorManagement.workingColorSpace;\n const native = usesNativeWebGPU(renderer);\n const depthFormat = output.stencilBuffer\n ? THREE.DepthStencilFormat\n : THREE.DepthFormat;\n // r186's WebGL fallback allocates MSAA depth renderbuffers as DEPTH_COMPONENT24.\n let depthType: THREE.TextureDataType =\n !native && output.samples > 0 ? THREE.UnsignedIntType : THREE.FloatType;\n if (output.stencilBuffer) {\n const float = output.depthTexture\n ? output.depthTexture.type === THREE.FloatType\n : renderer.reversedDepthBuffer;\n // Float depth with stencil is an optional WebGPU feature.\n depthType =\n native && float && renderer.hasFeature(\"depth32float-stencil8\")\n ? THREE.FloatType\n : THREE.UnsignedInt248Type;\n }\n // Keep float outputs unclamped; otherwise match the display's\n // intermediate precision when it needs an output pass.\n const type =\n output.texture.type === THREE.HalfFloatType ||\n output.texture.type === THREE.FloatType\n ? output.texture.type\n : renderer.outputColorSpace !== workingColorSpace ||\n renderer.toneMapping !== THREE.NoToneMapping\n ? renderer.getOutputBufferType()\n : THREE.UnsignedByteType;\n if (\n target.texture.type !== type ||\n target.depthBuffer !== output.depthBuffer ||\n target.stencilBuffer !== output.stencilBuffer ||\n this.depthTexture.type !== depthType ||\n this.depthTexture.format !== depthFormat ||\n target.samples !== output.samples\n ) {\n target.dispose();\n target.texture.type = type;\n this.depthTexture.type = depthType;\n this.depthTexture.format = depthFormat;\n target.depthBuffer = output.depthBuffer;\n target.stencilBuffer = output.stencilBuffer;\n target.depthTexture = output.depthBuffer ? this.depthTexture : null;\n // Antialias the scene here; the output only receives a full-screen quad.\n // Native WebGPU binds a multisampled depth texture as a different type.\n if (target.samples !== output.samples) material.needsUpdate = true;\n target.samples = output.samples;\n }\n target.setSize(output.width, output.height);\n\n // RGBA8 sRGB attachments encode linear fragment output in hardware.\n const storageColorSpace =\n output.texture.type === THREE.UnsignedByteType &&\n output.texture.colorSpace === THREE.SRGBColorSpace\n ? THREE.LinearSRGBColorSpace\n : output.texture.colorSpace || THREE.LinearSRGBColorSpace;\n if (\n this.workingColorSpace !== workingColorSpace ||\n this.outputColorSpace !== renderer.outputColorSpace ||\n this.storageColorSpace !== storageColorSpace ||\n this.toneMapping !== renderer.toneMapping\n ) {\n const color = N.texture(target.texture).load(\n N.ivec2(N.screenCoordinate.xy),\n );\n const outputColor = N.renderOutput(\n color,\n renderer.toneMapping,\n renderer.outputColorSpace,\n );\n material.fragmentNode = N.premultiplyAlpha(\n N.convertColorSpace(\n N.unpremultiplyAlpha(outputColor),\n renderer.outputColorSpace,\n storageColorSpace,\n ),\n );\n material.needsUpdate = true;\n this.workingColorSpace = workingColorSpace;\n this.outputColorSpace = renderer.outputColorSpace;\n this.storageColorSpace = storageColorSpace;\n this.toneMapping = renderer.toneMapping;\n }\n material.depthTest = output.depthBuffer;\n material.depthWrite = output.depthBuffer;\n material.depthFunc = renderer.reversedDepthBuffer\n ? THREE.NeverDepth\n : THREE.AlwaysDepth;\n try {\n renderer.setRenderTarget(target);\n renderer.render(scene, camera);\n renderer.setRenderTarget(output, face, mip);\n this.quad.render(renderer);\n } finally {\n renderer.setRenderTarget(output, face, mip);\n }\n }\n\n dispose() {\n this.target.dispose();\n this.material.dispose();\n }\n}\n","import * as THREE from \"three\";\nimport {\n type GaussianSplatCompatibleRenderer,\n isWebGPURenderer,\n usesNativeWebGPU,\n} from \"../rendering/rendererUtils\";\n\n/** Packed RGBA8, with the bottom row first on every backend. */\nexport async function readPixels(\n renderer: GaussianSplatCompatibleRenderer,\n target: THREE.RenderTarget,\n pixels: Uint8Array,\n face = 0,\n) {\n if (\n target.texture.format !== THREE.RGBAFormat ||\n target.texture.type !== THREE.UnsignedByteType\n ) {\n throw new Error(\n \"Splat capture readback requires an RGBA UnsignedByte target\",\n );\n }\n\n const { width, height } = target;\n if (!isWebGPURenderer(renderer)) {\n await renderer.readRenderTargetPixelsAsync(\n target as THREE.WebGLRenderTarget,\n 0,\n 0,\n width,\n height,\n pixels,\n face,\n );\n return;\n }\n\n const readback = await renderer.readRenderTargetPixelsAsync(\n target,\n 0,\n 0,\n width,\n height,\n 0,\n face,\n );\n const source = new Uint8Array(\n readback.buffer,\n readback.byteOffset,\n readback.byteLength,\n );\n if (!usesNativeWebGPU(renderer)) {\n pixels.set(source);\n return;\n }\n\n // Native WebGPU pads rows to 256 bytes and reads from the top left.\n const rowBytes = width * 4;\n const rowStride = Math.ceil(rowBytes / 256) * 256;\n for (let y = 0; y < height; y++) {\n const start = (height - y - 1) * rowStride;\n pixels.set(source.subarray(start, start + rowBytes), y * rowBytes);\n }\n}\n\nexport function downsamplePixels(\n source: Uint8Array,\n width: number,\n height: number,\n superXY: number,\n output: Uint8Array,\n) {\n const subWidth = width / superXY;\n const subHeight = height / superXY;\n const samples = superXY * superXY;\n for (let y = 0; y < subHeight; y++) {\n for (let x = 0; x < subWidth; x++) {\n const outputIndex = (y * subWidth + x) * 4;\n for (let channel = 0; channel < 4; channel++) {\n let sum = 0;\n for (let sy = 0; sy < superXY; sy++) {\n const row = (y * superXY + sy) * width;\n for (let sx = 0; sx < superXY; sx++) {\n sum += source[(row + x * superXY + sx) * 4 + channel];\n }\n }\n output[outputIndex + channel] = Math.round(sum / samples);\n }\n }\n }\n}\n","import {\n type GaussianSplatCompatibleRenderer,\n isWebGPURenderer,\n setRendererRenderTarget,\n} from \"../rendering/rendererUtils\";\n\n/** Wrap synchronous drawing only; output state must never survive an await. */\nexport function withCaptureState<T>(\n renderer: GaussianSplatCompatibleRenderer,\n draw: () => T,\n): T {\n const target = renderer.getRenderTarget();\n const cubeFace = renderer.getActiveCubeFace();\n const mipmapLevel = renderer.getActiveMipmapLevel();\n const xrEnabled = renderer.xr.enabled;\n const autoClear = renderer.autoClear;\n const nodeRenderer = isWebGPURenderer(renderer) ? renderer : null;\n const mrt = nodeRenderer?.getMRT() ?? null;\n\n renderer.xr.enabled = false;\n renderer.autoClear = true;\n nodeRenderer?.setMRT(null);\n try {\n return draw();\n } finally {\n renderer.xr.enabled = xrEnabled;\n renderer.autoClear = autoClear;\n nodeRenderer?.setMRT(mrt);\n setRendererRenderTarget(renderer, target, cubeFace, mipmapLevel);\n }\n}\n","import * as THREE from \"three\";\nimport { SplatEdit } from \"../scene/SplatEdit\";\n\n/** Filter capture data without changing visibility while sorting is pending. */\nexport function captureSceneView(\n scene: THREE.Scene,\n hideObjects: readonly THREE.Object3D[],\n): THREE.Scene {\n if (hideObjects.length === 0) return scene;\n\n const hidden = new Set(hideObjects);\n const view = new THREE.Scene();\n view.matrixWorldAutoUpdate = scene.matrixWorldAutoUpdate;\n view.updateMatrixWorld = (force) => scene.updateMatrixWorld(force);\n\n const filter =\n (callback: (object: THREE.Object3D) => void) =>\n (object: THREE.Object3D) => {\n // Captures use the same visible edits as the display.\n if (!(object instanceof SplatEdit)) {\n let ancestor: THREE.Object3D | null = object;\n while (ancestor) {\n if (hidden.has(ancestor)) return;\n ancestor = ancestor.parent;\n }\n }\n callback(object);\n };\n view.traverse = (callback) => scene.traverse(filter(callback));\n view.traverseVisible = (callback) => scene.traverseVisible(filter(callback));\n return view;\n}\n","import * as THREE from \"three\";\nimport { CubeRenderTarget, PMREMGenerator } from \"three/webgpu\";\nimport { GaussianSplatRenderer } from \"../rendering/GaussianSplatRenderer\";\nimport {\n isWebGPURenderer,\n setRendererRenderTarget,\n usesNativeWebGPU,\n} from \"../rendering/rendererUtils\";\nimport { WebGLCapture } from \"./WebGLCapture\";\nimport { WebGPUCapture } from \"./WebGPUCapture\";\nimport { downsamplePixels, readPixels } from \"./pixels\";\nimport { withCaptureState } from \"./rendererState\";\nimport { captureSceneView } from \"./sceneView\";\n\nexport type SplatCaptureTargetOptions = {\n width: number;\n height: number;\n doubleBuffer?: boolean;\n superXY?: number;\n} & Omit<THREE.RenderTargetOptions, \"stencilBuffer\">;\n\nexport interface SplatCaptureOptions {\n splatRenderer: GaussianSplatRenderer;\n target?: SplatCaptureTargetOptions;\n}\n\nexport interface SplatCaptureCubeOptions {\n scene: THREE.Scene;\n worldCenter: THREE.Vector3;\n size?: number;\n near?: number;\n far?: number;\n hideObjects?: THREE.Object3D[];\n filter?: boolean;\n}\n\nexport type SplatCaptureEnvOptions = Omit<SplatCaptureCubeOptions, \"filter\">;\n\ntype SceneView = { scene: THREE.Scene; camera: THREE.Camera };\n\ntype CubeRender = {\n target: THREE.WebGLCubeRenderTarget | CubeRenderTarget;\n camera: THREE.CubeCamera;\n near: number;\n far: number;\n};\n\n/** Optional offscreen capture and environment maps, independent of core rendering. */\nexport class SplatCapture {\n readonly splatRenderer: GaussianSplatRenderer;\n readonly superXY: number;\n target?: THREE.RenderTarget;\n backTarget?: THREE.RenderTarget;\n superPixels?: Uint8Array;\n targetPixels?: Uint8Array;\n\n private disposed = false;\n private readonly captureRenderer: GaussianSplatRenderer;\n private readonly capturePass: WebGLCapture | WebGPUCapture;\n // Captures share one Splat renderer and its sort, so they run one at a time.\n private pending: Promise<unknown> = Promise.resolve();\n // Keyed by `filter`: an environment capture keeps an earlier cube texture valid.\n private readonly cubeRenders = new Map<boolean, CubeRender>();\n private lastCube: CubeRender | null = null;\n private pmrem: THREE.PMREMGenerator | PMREMGenerator | null = null;\n\n constructor({ splatRenderer, target }: SplatCaptureOptions) {\n this.splatRenderer = splatRenderer;\n this.capturePass = isWebGPURenderer(this.renderer)\n ? new WebGPUCapture(this.renderer)\n : new WebGLCapture(this.renderer);\n this.superXY = target?.superXY ?? 1;\n if (\n !Number.isInteger(this.superXY) ||\n this.superXY < 1 ||\n this.superXY > 4\n ) {\n throw new Error(\"Splat capture superXY must be an integer from 1 to 4\");\n }\n if (target) this.initializeTarget(target);\n this.captureRenderer = new GaussianSplatRenderer({\n renderer: this.renderer,\n timer: splatRenderer.timer,\n autoUpdate: false,\n stochastic: false,\n });\n // The display renderer already runs each model's onFrame.\n this.captureRenderer.frameCallbacks = false;\n }\n\n private initializeTarget(target: SplatCaptureTargetOptions) {\n const {\n width,\n height,\n doubleBuffer,\n superXY: _superXY,\n ...options\n } = target;\n if (\n !Number.isInteger(width) ||\n !Number.isInteger(height) ||\n width < 1 ||\n height < 1 ||\n width * this.superXY > 8192 ||\n height * this.superXY > 8192\n ) {\n throw new Error(\n \"Splat capture dimensions must be positive integers up to 8192 / superXY\",\n );\n }\n const targetOptions = {\n format: THREE.RGBAFormat,\n type: THREE.UnsignedByteType,\n colorSpace: THREE.SRGBColorSpace,\n ...options,\n // Three.js attaches stencil only together with depth.\n stencilBuffer: options.depthBuffer !== false && this.stencilBuffer,\n };\n const superWidth = width * this.superXY;\n const superHeight = height * this.superXY;\n this.target = isWebGPURenderer(this.renderer)\n ? new THREE.RenderTarget(superWidth, superHeight, targetOptions)\n : new THREE.WebGLRenderTarget(superWidth, superHeight, targetOptions);\n if (doubleBuffer) {\n this.backTarget = this.target.clone();\n }\n }\n\n get renderer() {\n return this.splatRenderer.renderer;\n }\n\n private get stencilBuffer() {\n const { renderer } = this;\n // The attributes are null while the WebGL context is lost.\n return isWebGPURenderer(renderer)\n ? renderer.stencil\n : renderer.getContextAttributes()?.stencil === true;\n }\n\n private assertActive() {\n if (this.disposed) throw new Error(\"Splat capture is disposed\");\n }\n\n private enqueue<T>(task: () => Promise<T>): Promise<T> {\n const result = this.pending.then(task);\n this.pending = result.catch(() => {});\n return result;\n }\n\n private async renderCapture(\n { scene, camera }: SceneView,\n draw: () => void,\n radial = false,\n hideObjects: THREE.Object3D[] = [],\n ) {\n this.assertActive();\n const { splatRenderer: source, captureRenderer } = this;\n\n Object.assign(captureRenderer, {\n maxStdDev: source.maxStdDev,\n minPixelRadius: source.minPixelRadius,\n minAlpha: source.minAlpha,\n preBlurAmount: source.preBlurAmount,\n blurAmount: source.blurAmount,\n clipXY: source.clipXY,\n focalAdjustment: source.focalAdjustment,\n fastSort: source.fastSort,\n premultipliedAlpha: source.premultipliedAlpha,\n transparent: source.transparent,\n depthTest: source.depthTest,\n depthWrite: source.depthWrite,\n encodeLinear: source.encodeLinear,\n sortRadial: radial || source.sortRadial,\n });\n // Stencil masking is set on the Splat material, not on the renderer.\n const sourceMaterial = source.material;\n const captureMaterial = captureRenderer.material;\n captureMaterial.stencilWrite = sourceMaterial.stencilWrite;\n captureMaterial.stencilWriteMask = sourceMaterial.stencilWriteMask;\n captureMaterial.stencilFunc = sourceMaterial.stencilFunc;\n captureMaterial.stencilRef = sourceMaterial.stencilRef;\n captureMaterial.stencilFuncMask = sourceMaterial.stencilFuncMask;\n captureMaterial.stencilFail = sourceMaterial.stencilFail;\n captureMaterial.stencilZFail = sourceMaterial.stencilZFail;\n captureMaterial.stencilZPass = sourceMaterial.stencilZPass;\n captureRenderer.layers.mask = camera.layers.mask;\n const view = { scene: captureSceneView(scene, hideObjects), camera };\n // Models and their edits are shared with the display, so every capture\n // checks them. Version checks reuse generated data and ordering while valid.\n await captureRenderer.update(view);\n // The display can update shared models while a WebGL sort is pending.\n // Appearance changes refresh the data without repeating that sort.\n if (\n captureRenderer.display.mapping.some(\n ({ node, version }) => node.version !== version,\n )\n ) {\n await captureRenderer.update(view);\n }\n this.assertActive();\n\n // Suppress only other Splat draws, preserving their children's visibility.\n const layers = new Map<THREE.Layers, number>();\n scene.traverse((object) => {\n if (object instanceof GaussianSplatRenderer) {\n layers.set(object.layers, object.layers.mask);\n }\n });\n const visibility = new Map(\n hideObjects.map((object) => [object, object.visible]),\n );\n try {\n for (const layer of layers.keys()) layer.mask = 0;\n for (const object of visibility.keys()) object.visible = false;\n scene.add(captureRenderer);\n withCaptureState(this.renderer, draw);\n } finally {\n scene.remove(captureRenderer);\n for (const [layer, mask] of layers) layer.mask = mask;\n for (const [object, visible] of visibility) object.visible = visible;\n }\n }\n\n /** Snapshots the camera now; the capture may wait for earlier ones. */\n private targetCapture({ scene, camera }: SceneView) {\n this.assertActive();\n camera.updateWorldMatrix(true, false);\n const Camera = camera.constructor as new () => THREE.Camera;\n const captureCamera = new Camera().copy(camera, false);\n captureCamera.matrixAutoUpdate = false;\n captureCamera.matrix.copy(camera.matrixWorld);\n return async () => {\n this.assertActive();\n const target = this.backTarget ?? this.target;\n if (!target)\n throw new Error(\"Initialize SplatCapture with target options\");\n const stencilBuffer = target.depthBuffer && this.stencilBuffer;\n if (target.stencilBuffer !== stencilBuffer) {\n target.dispose();\n target.stencilBuffer = stencilBuffer;\n }\n await this.renderCapture({ scene, camera: captureCamera }, () => {\n setRendererRenderTarget(this.renderer, target);\n this.capturePass.render(scene, captureCamera);\n });\n if (target !== this.target) {\n [this.target, this.backTarget] = [this.backTarget, this.target];\n }\n return target;\n };\n }\n\n async renderTarget(view: SceneView): Promise<THREE.RenderTarget> {\n return this.enqueue(this.targetCapture(view));\n }\n\n /** Reuses the returned buffer; copy it if a later read must not overwrite it. */\n async readTarget(): Promise<Uint8Array> {\n this.assertActive();\n const target = this.target;\n if (!target) throw new Error(\"Initialize SplatCapture with target options\");\n const { width, height } = target;\n if (width % this.superXY !== 0 || height % this.superXY !== 0) {\n throw new Error(\n \"Splat capture target dimensions must be divisible by superXY\",\n );\n }\n const byteSize = width * height * 4;\n if (this.superPixels?.length !== byteSize) {\n this.superPixels = new Uint8Array(byteSize);\n }\n const pixels = this.superPixels;\n await readPixels(this.renderer, target, pixels);\n this.assertActive();\n if (this.superXY === 1) return pixels;\n\n const subSize = byteSize / (this.superXY * this.superXY);\n if (this.targetPixels?.length !== subSize) {\n this.targetPixels = new Uint8Array(subSize);\n }\n downsamplePixels(pixels, width, height, this.superXY, this.targetPixels);\n return this.targetPixels;\n }\n\n async renderReadTarget(view: SceneView): Promise<Uint8Array> {\n const capture = this.targetCapture(view);\n // Read in the same turn, before a queued capture can redraw the target.\n return this.enqueue(async () => {\n await capture();\n return this.readTarget();\n });\n }\n\n private renderCube(scene: THREE.Scene, camera: THREE.CubeCamera) {\n const { renderer } = this;\n camera.updateMatrixWorld();\n if (camera.coordinateSystem !== renderer.coordinateSystem) {\n camera.coordinateSystem = renderer.coordinateSystem;\n camera.updateCoordinateSystem();\n }\n const target = camera.renderTarget;\n const generateMipmaps = target.texture.generateMipmaps;\n target.texture.generateMipmaps = false;\n try {\n for (let face = 0; face < 6; face++) {\n // Generate cube mipmaps only after all six resolved faces are ready.\n if (face === 5) target.texture.generateMipmaps = generateMipmaps;\n setRendererRenderTarget(\n renderer,\n target,\n face,\n camera.activeMipmapLevel,\n );\n this.capturePass.render(scene, camera.children[face] as THREE.Camera);\n }\n target.texture.needsPMREMUpdate = true;\n } finally {\n target.texture.generateMipmaps = generateMipmaps;\n }\n }\n\n /** Validates and snapshots the center now; the capture may wait for earlier ones. */\n private cubeCapture({\n scene,\n worldCenter,\n size = 256,\n near = 0.1,\n far = 1000,\n hideObjects = [],\n filter = false,\n }: SplatCaptureCubeOptions) {\n this.assertActive();\n if (!Number.isInteger(size) || size < 1 || size > 8192) {\n throw new Error(\n \"Splat capture cube size must be a positive integer up to 8192\",\n );\n }\n if (!(near > 0 && far > near && Number.isFinite(far))) {\n throw new Error(\"Splat capture cube requires 0 < near < far < Infinity\");\n }\n const center = worldCenter.clone();\n return async () => {\n this.assertActive();\n const stencilBuffer = this.stencilBuffer;\n let cubeRender = this.cubeRenders.get(filter);\n if (\n !cubeRender ||\n cubeRender.target.width !== size ||\n cubeRender.target.stencilBuffer !== stencilBuffer ||\n cubeRender.near !== near ||\n cubeRender.far !== far\n ) {\n cubeRender?.target.dispose();\n if (this.lastCube === cubeRender) this.lastCube = null;\n const Target = isWebGPURenderer(this.renderer)\n ? CubeRenderTarget\n : THREE.WebGLCubeRenderTarget;\n const target = new Target(size, {\n format: THREE.RGBAFormat,\n type: THREE.UnsignedByteType,\n stencilBuffer,\n generateMipmaps: filter,\n minFilter: filter\n ? THREE.LinearMipmapLinearFilter\n : THREE.LinearFilter,\n colorSpace: filter\n ? THREE.LinearSRGBColorSpace\n : THREE.SRGBColorSpace,\n });\n const camera = new THREE.CubeCamera(near, far, target);\n cubeRender = { target, camera, near, far };\n this.cubeRenders.set(filter, cubeRender);\n }\n\n const { target, camera } = cubeRender;\n camera.position.copy(center);\n const updateCamera = new THREE.PerspectiveCamera(90, 1, near, far);\n updateCamera.position.copy(center);\n await this.renderCapture(\n { scene, camera: updateCamera },\n () => this.renderCube(scene, camera),\n true,\n hideObjects,\n );\n this.lastCube = cubeRender;\n return target.texture;\n };\n }\n\n async renderCubeMap(\n options: SplatCaptureCubeOptions,\n ): Promise<THREE.CubeTexture> {\n return this.enqueue(this.cubeCapture(options));\n }\n\n /** Faces of the latest cube capture, in the WebGL layout on every backend. */\n async readCubeTargets(): Promise<Uint8Array[]> {\n // Queued with captures: the six reads span awaits.\n return this.enqueue(async () => {\n this.assertActive();\n if (!this.lastCube)\n throw new Error(\"Render a cube map before reading its faces\");\n const { target } = this.lastCube;\n const native = usesNativeWebGPU(this.renderer);\n const faces: Uint8Array[] = [];\n // Keep WebGL framebuffer readback sequential, including its async cleanup.\n for (let face = 0; face < 6; face++) {\n const pixels = new Uint8Array(target.width * target.height * 4);\n // Native WebGPU stores +X and -X swapped, and each face reads back\n // rotated 180 degrees from the WebGL layout.\n const source = native && face < 2 ? 1 - face : face;\n await readPixels(this.renderer, target, pixels, source);\n if (native) new Uint32Array(pixels.buffer).reverse();\n faces.push(pixels);\n }\n this.assertActive();\n return faces;\n });\n }\n\n /** The caller owns the result; texture.dispose() also releases its render target. */\n async renderEnvMap(options: SplatCaptureEnvOptions): Promise<THREE.Texture> {\n const capture = this.cubeCapture({ ...options, filter: true });\n // Filter in the same turn, before a queued capture can redraw the cube.\n return this.enqueue(async () => {\n const cube = await capture();\n this.assertActive();\n this.pmrem ??= isWebGPURenderer(this.renderer)\n ? new PMREMGenerator(this.renderer)\n : new THREE.PMREMGenerator(this.renderer);\n const pmrem = this.pmrem;\n const target = withCaptureState(this.renderer, () =>\n pmrem.fromCubemap(cube),\n );\n const disposeTarget = () => {\n target.texture.removeEventListener(\"dispose\", disposeTarget);\n target.dispose();\n };\n target.texture.addEventListener(\"dispose\", disposeTarget);\n return target.texture;\n });\n }\n\n recurseSetEnvMap(root: THREE.Object3D, envMap: THREE.Texture) {\n root.traverse((node) => {\n if (!(node instanceof THREE.Mesh)) return;\n const materials = Array.isArray(node.material)\n ? node.material\n : [node.material];\n for (const material of materials) {\n if (material instanceof THREE.MeshStandardMaterial) {\n // Shaders depend on the map's presence and mapping, not its contents.\n if (material.envMap?.mapping !== envMap.mapping) {\n material.needsUpdate = true;\n }\n material.envMap = envMap;\n }\n }\n });\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.captureRenderer.dispose();\n this.capturePass.dispose();\n this.target?.dispose();\n this.backTarget?.dispose();\n for (const { target } of this.cubeRenders.values()) target.dispose();\n this.pmrem?.dispose();\n this.target = undefined;\n this.backTarget = undefined;\n this.superPixels = undefined;\n this.targetPixels = undefined;\n this.cubeRenders.clear();\n this.lastCube = null;\n this.pmrem = null;\n }\n}\n","/** Response URLs such as blob: and data: cannot resolve relative assets. */\nexport function getAssetBaseUrl(url?: string): string | undefined {\n if (!url) return undefined;\n try {\n new URL(\".\", url);\n return url;\n } catch {\n return undefined;\n }\n}\n","/** @internal */\nexport enum Opcode {\n Constant = 1,\n InputField = 2,\n InputAttribute = 3,\n Negate = 10,\n Abs = 11,\n Sqrt = 12,\n Log = 13,\n Exp = 14,\n Floor = 15,\n Ceil = 16,\n Round = 17,\n Normalize = 18,\n Length = 19,\n IsFinite = 20,\n Not = 22,\n Sin = 23,\n Cos = 24,\n Acos = 25,\n Tan = 26,\n Asin = 27,\n Atan = 28,\n Add = 30,\n Subtract = 31,\n Multiply = 32,\n Divide = 33,\n Min = 34,\n Max = 35,\n Pow = 36,\n Dot = 37,\n Cross = 38,\n Equal = 39,\n NotEqual = 40,\n Less = 41,\n LessEqual = 42,\n Greater = 43,\n GreaterEqual = 44,\n And = 45,\n Or = 46,\n QuaternionMultiply = 47,\n RotateVector = 48,\n Atan2 = 49,\n Select = 60,\n Clamp = 61,\n Mix = 62,\n // Preserve float32 rounding between the two operations (not hardware FMA).\n MultiplyAdd = 63,\n AddMultiply = 64,\n Vec2 = 70,\n Vec3 = 71,\n Vec4 = 72,\n Component = 74,\n MaxComponentIndex = 75,\n}\n\n/** @internal */\nexport enum InputField {\n Position = 1,\n Scale = 2,\n Quaternion = 3,\n Opacity = 4,\n Alpha = 5,\n Color = 6,\n Sh0 = 7,\n}\n\n/** @internal */\nexport const SH_COEFFICIENT_COUNT = 15;\n\n/** @internal */\nexport type SplatPostDecodeValueType =\n | \"float\"\n | \"bool\"\n | \"vec2\"\n | \"vec3\"\n | \"vec4\"\n | \"quaternion\";\n\n/** @internal */\nexport const TYPE_WIDTHS: Record<SplatPostDecodeValueType, number> = {\n float: 1,\n bool: 1,\n vec2: 2,\n vec3: 3,\n vec4: 4,\n quaternion: 4,\n};\n\n/** @internal */\nexport type SplatPostDecodeInstruction = {\n opcode: Opcode;\n type: SplatPostDecodeValueType;\n args: readonly number[];\n immediate: number;\n};\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_OPCODE = 0;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_WIDTH = 1;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE = 2;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 = 3;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT = 4;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_INSTRUCTION_STRIDE = 7;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_MISSING_ARGUMENT = 0xffff;\n\n/** @internal */\nexport type SplatPostDecodeAttributeFormat =\n | \"f32\"\n | \"f16\"\n | \"u8\"\n | \"unorm8\"\n | \"i8\"\n | \"snorm8\"\n | \"u16\"\n | \"unorm16\"\n | \"i16\"\n | \"snorm16\"\n | \"u32\"\n | \"i32\";\n\n/** @internal */\nexport const ATTRIBUTE_FORMAT_BYTES: Record<\n SplatPostDecodeAttributeFormat,\n number\n> = {\n f32: 4,\n f16: 2,\n u8: 1,\n unorm8: 1,\n i8: 1,\n snorm8: 1,\n u16: 2,\n unorm16: 2,\n i16: 2,\n snorm16: 2,\n u32: 4,\n i32: 4,\n};\n\nexport type AttributeComponents = 1 | 2 | 3 | 4;\n\nexport type AttributeBinding = {\n data: ArrayBufferView;\n format: SplatPostDecodeAttributeFormat;\n count: number;\n components: AttributeComponents;\n byteOffset: number;\n byteStride: number;\n};\n\n/** @internal */\nexport type SerializedSplatPostDecodeAttribute = {\n format: SplatPostDecodeAttributeFormat;\n components: AttributeComponents;\n byteOffset: number;\n byteStride: number;\n count: number;\n};\n\n/** @internal */\nexport type SplatPostDecodeOutputs = {\n when?: number;\n position?: number;\n scale?: number;\n quaternion?: number;\n opacity?: number;\n alpha?: number;\n color?: number;\n sh?: readonly number[];\n};\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_START = 0;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION = 1;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_REGISTER = 2;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE = 3;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE = 4;\n\n/** @internal */\nexport const SPLAT_POST_DECODE_FLOW_STAGE_STRIDE = 5;\n\n/** @internal */\nexport type SerializedSplatPostDecodeCondition = {\n /** Packed start/instruction/register/onTrue/onFalse Uint16 records. */\n stages: Uint16Array;\n};\n\n/** @internal */\nexport type SerializedSplatPostDecode = {\n /** Packed opcode/width/immediate/arg0/arg1/arg2/arg3 Uint16 records. */\n instructions: Uint16Array;\n constants: Float32Array;\n outputs: Omit<SplatPostDecodeOutputs, \"when\">;\n condition?: SerializedSplatPostDecodeCondition;\n attributeData: Uint8Array;\n attributes: readonly SerializedSplatPostDecodeAttribute[];\n};\n\nexport type PostDecodeSource = {\n instructions: readonly SplatPostDecodeInstruction[];\n constants: readonly number[];\n attributes: readonly AttributeBinding[];\n};\n\nexport type PostDecodeSplatData = {\n numSplats: number;\n splat0: Uint32Array;\n splat1: Uint32Array;\n sortCenters: Float32Array;\n sourceIds?: Uint32Array;\n sh1?: Uint32Array;\n sh2?: Uint32Array;\n sh3a?: Uint32Array;\n sh3b?: Uint32Array;\n};\n","import {\n ATTRIBUTE_FORMAT_BYTES,\n type AttributeBinding,\n type AttributeComponents,\n InputField,\n Opcode,\n SH_COEFFICIENT_COUNT,\n type SplatPostDecodeAttributeFormat,\n type SplatPostDecodeInstruction,\n type SplatPostDecodeOutputs,\n type SplatPostDecodeValueType,\n TYPE_WIDTHS,\n} from \"./protocol\";\n\ntype NumericValueType = \"float\" | \"vec2\" | \"vec3\" | \"vec4\";\n\ntype VectorValueType = \"vec2\" | \"vec3\" | \"vec4\";\n\nclass SplatPostDecodeValue<T extends SplatPostDecodeValueType> {\n /** @internal */\n constructor(\n readonly type: T,\n /** @internal */ readonly register: number,\n /** @internal */ readonly owner: ProgramBuilder,\n ) {}\n}\n\ntype FloatValue = SplatPostDecodeValue<\"float\">;\n\ntype BoolValue = SplatPostDecodeValue<\"bool\">;\n\ntype Vec2Value = SplatPostDecodeValue<\"vec2\">;\n\ntype Vec3Value = SplatPostDecodeValue<\"vec3\">;\n\ntype Vec4Value = SplatPostDecodeValue<\"vec4\">;\n\ntype QuaternionValue = SplatPostDecodeValue<\"quaternion\">;\n\ntype FloatLike = number | FloatValue;\n\ntype BoolLike = boolean | BoolValue;\n\ntype Vec2Literal = readonly [number, number];\n\ntype Vec3Literal = readonly [number, number, number];\n\ntype Vec4Literal = readonly [number, number, number, number];\n\ntype Vec2Like = Vec2Literal | Vec2Value;\n\ntype Vec3Like = Vec3Literal | Vec3Value;\n\ntype Vec4Like = Vec4Literal | Vec4Value;\n\ntype QuaternionLike = Vec4Literal | QuaternionValue;\n\ntype LiteralFor<T extends SplatPostDecodeValueType> = T extends \"float\"\n ? number\n : T extends \"bool\"\n ? boolean\n : T extends \"vec2\"\n ? Vec2Literal\n : T extends \"vec3\"\n ? Vec3Literal\n : Vec4Literal;\n\ntype ValueLike<T extends SplatPostDecodeValueType> =\n | LiteralFor<T>\n | SplatPostDecodeValue<T>;\n\ntype AnyValueLike = ValueLike<SplatPostDecodeValueType>;\n\ntype BroadcastLike<T extends NumericValueType> = ValueLike<T> | FloatLike;\n\ntype SplatPostDecodeAttributeOptions<\n Components extends AttributeComponents = 1,\n> = {\n data: ArrayBufferView;\n format: SplatPostDecodeAttributeFormat;\n count: number;\n components?: Components;\n /** Byte offset relative to the supplied data view. */\n byteOffset?: number;\n byteStride?: number;\n};\n\ntype AttributeValue<Components extends AttributeComponents> =\n Components extends 1\n ? FloatValue\n : Components extends 2\n ? Vec2Value\n : Components extends 3\n ? Vec3Value\n : Vec4Value;\n\ntype SplatShCoefficientContext = {\n index: number;\n degree: 1 | 2 | 3;\n order: number;\n};\n\nclass SplatPostDecodeShPatch {\n /** @internal */\n constructor(\n /** @internal */ readonly owner: ProgramBuilder,\n /** @internal */ readonly coefficients: readonly Vec3Value[],\n ) {}\n}\n\nclass SplatPostDecodeShValue {\n /** @internal */\n constructor(private readonly owner: ProgramBuilder) {}\n\n coefficient(index: number): Vec3Value {\n if (\n !Number.isInteger(index) ||\n index < 0 ||\n index >= SH_COEFFICIENT_COUNT\n ) {\n throw new Error(\"SH coefficient index must be between 0 and 14\");\n }\n return this.owner.inputField(\"vec3\", InputField.Sh0 + index);\n }\n\n map(\n transform: (\n coefficient: Vec3Value,\n context: SplatShCoefficientContext,\n ) => Vec3Like,\n ): SplatPostDecodeShPatch {\n const coefficients: Vec3Value[] = [];\n let index = 0;\n for (let degree = 1 as 1 | 2 | 3; degree <= 3; degree += 1) {\n for (let order = -degree; order <= degree; order += 1) {\n coefficients.push(\n this.owner.coerce(\n transform(this.coefficient(index), { index, degree, order }),\n \"vec3\",\n ),\n );\n index += 1;\n }\n }\n return new SplatPostDecodeShPatch(this.owner, coefficients);\n }\n}\n\ntype SplatPostDecodeInput = {\n readonly position: Vec3Value;\n readonly scale: Vec3Value;\n readonly quaternion: QuaternionValue;\n /** Semantic opacity in [0, exp(24/e)] (approximately 6830.182). */\n readonly opacity: FloatValue;\n /** Standard alpha in the [0, 1] range. */\n readonly alpha: FloatValue;\n readonly color: Vec3Value;\n readonly sh: SplatPostDecodeShValue;\n};\n\nexport type SplatPostDecodePatch = {\n /** If false, this splat's packed values are left byte-for-byte unchanged. */\n when?: BoolLike;\n position?: Vec3Like;\n scale?: Vec3Like;\n quaternion?: QuaternionLike;\n /** Semantic opacity, encoded within the renderer's shape range [0, 1]. */\n opacity?: FloatLike;\n /**\n * Standard alpha, clamped to [0, 1] and independent from semantic opacity.\n * Cannot be output with opacity in the same patch.\n */\n alpha?: FloatLike;\n color?: Vec3Like;\n sh?: SplatPostDecodeShPatch;\n};\n\ntype VariadicNumericOperation = <T extends NumericValueType>(\n first: ValueLike<T>,\n ...rest: BroadcastLike<T>[]\n) => SplatPostDecodeValue<T>;\n\ntype BinaryNumericOperation = <T extends NumericValueType>(\n left: ValueLike<T>,\n right: BroadcastLike<T>,\n) => SplatPostDecodeValue<T>;\n\ntype UnaryNumericOperation = <T extends NumericValueType>(\n value: ValueLike<T>,\n) => SplatPostDecodeValue<T>;\n\ntype SplatPostDecodeOperations = {\n add: VariadicNumericOperation;\n sub: BinaryNumericOperation;\n mul: VariadicNumericOperation;\n div: BinaryNumericOperation;\n min: BinaryNumericOperation;\n max: BinaryNumericOperation;\n pow: BinaryNumericOperation;\n clamp<T extends NumericValueType>(\n value: ValueLike<T>,\n min: BroadcastLike<T>,\n max: BroadcastLike<T>,\n ): SplatPostDecodeValue<T>;\n mix<T extends NumericValueType>(\n left: ValueLike<T>,\n right: ValueLike<T>,\n amount: BroadcastLike<T>,\n ): SplatPostDecodeValue<T>;\n neg: UnaryNumericOperation;\n abs: UnaryNumericOperation;\n sqrt: UnaryNumericOperation;\n log: UnaryNumericOperation;\n exp: UnaryNumericOperation;\n floor: UnaryNumericOperation;\n ceil: UnaryNumericOperation;\n round: UnaryNumericOperation;\n sin: UnaryNumericOperation;\n cos: UnaryNumericOperation;\n acos: UnaryNumericOperation;\n tan: UnaryNumericOperation;\n asin: UnaryNumericOperation;\n atan: UnaryNumericOperation;\n atan2: BinaryNumericOperation;\n normalize<T extends VectorValueType | \"quaternion\">(\n value: ValueLike<T>,\n ): SplatPostDecodeValue<T>;\n length(value: Vec2Like | Vec3Like | Vec4Like): FloatValue;\n isFinite(\n value: FloatLike | Vec2Like | Vec3Like | Vec4Like | QuaternionLike,\n ): BoolValue;\n not(value: BoolLike): BoolValue;\n eq<T extends SplatPostDecodeValueType>(\n left: ValueLike<T>,\n right: ValueLike<T>,\n ): BoolValue;\n ne<T extends SplatPostDecodeValueType>(\n left: ValueLike<T>,\n right: ValueLike<T>,\n ): BoolValue;\n lt(left: FloatLike, right: FloatLike): BoolValue;\n lte(left: FloatLike, right: FloatLike): BoolValue;\n gt(left: FloatLike, right: FloatLike): BoolValue;\n gte(left: FloatLike, right: FloatLike): BoolValue;\n and(first: BoolLike, ...rest: BoolLike[]): BoolValue;\n or(first: BoolLike, ...rest: BoolLike[]): BoolValue;\n select<T extends SplatPostDecodeValueType>(\n condition: BoolLike,\n whenTrue: ValueLike<T>,\n whenFalse: ValueLike<T>,\n ): SplatPostDecodeValue<T>;\n dot(\n left: Vec2Like | Vec3Like | Vec4Like,\n right: Vec2Like | Vec3Like | Vec4Like,\n ): FloatValue;\n cross(left: Vec3Like, right: Vec3Like): Vec3Value;\n vec2(x: FloatLike, y: FloatLike): Vec2Value;\n vec3(x: FloatLike, y: FloatLike, z: FloatLike): Vec3Value;\n vec4(x: FloatLike, y: FloatLike, z: FloatLike, w: FloatLike): Vec4Value;\n quaternion(\n x: FloatLike,\n y: FloatLike,\n z: FloatLike,\n w: FloatLike,\n ): QuaternionValue;\n component(\n value: Vec2Like | Vec3Like | Vec4Like | QuaternionLike,\n index: number,\n ): FloatValue;\n maxComponentIndex(value: Vec2Like | Vec3Like | Vec4Like): FloatValue;\n quatMul(left: QuaternionLike, right: QuaternionLike): QuaternionValue;\n rotateVector(quaternion: QuaternionLike, vector: Vec3Like): Vec3Value;\n};\n\nexport type SplatPostDecodeContext = {\n splat: SplatPostDecodeInput;\n op: SplatPostDecodeOperations;\n attribute<Components extends AttributeComponents = 1>(\n options: SplatPostDecodeAttributeOptions<Components>,\n ): AttributeValue<Components>;\n};\n\nconst COMPONENT_TYPES = [\"float\", \"vec2\", \"vec3\", \"vec4\"] as const;\n\nfunction inferLiteralType(value: unknown): SplatPostDecodeValueType {\n if (typeof value === \"boolean\") return \"bool\";\n if (typeof value === \"number\") return \"float\";\n if (Array.isArray(value) && value.length >= 2 && value.length <= 4) {\n return COMPONENT_TYPES[value.length - 1];\n }\n throw new Error(\"Unsupported postDecode literal\");\n}\n\nfunction constantKey(\n type: SplatPostDecodeValueType,\n values: readonly number[],\n) {\n return `${type}:${values\n .map((value) => (Object.is(value, -0) ? \"-0\" : value))\n .join(\":\")}`;\n}\n\nexport class ProgramBuilder {\n readonly instructions: SplatPostDecodeInstruction[] = [];\n readonly constants: number[] = [];\n readonly attributes: AttributeBinding[] = [];\n readonly op: SplatPostDecodeOperations;\n readonly splat: SplatPostDecodeInput;\n\n readonly constantRegisters = new Map<\n string,\n SplatPostDecodeValue<SplatPostDecodeValueType>\n >();\n readonly inputRegisters = new Map<\n number,\n SplatPostDecodeValue<SplatPostDecodeValueType>\n >();\n\n constructor() {\n this.op = this.createOperations();\n const builder = this;\n const sh = new SplatPostDecodeShValue(this);\n this.splat = {\n get position() {\n return builder.inputField(\"vec3\", InputField.Position);\n },\n get scale() {\n return builder.inputField(\"vec3\", InputField.Scale);\n },\n get quaternion() {\n return builder.inputField(\"quaternion\", InputField.Quaternion);\n },\n get opacity() {\n return builder.inputField(\"float\", InputField.Opacity);\n },\n get alpha() {\n return builder.inputField(\"float\", InputField.Alpha);\n },\n get color() {\n return builder.inputField(\"vec3\", InputField.Color);\n },\n sh,\n };\n }\n\n private instruction<T extends SplatPostDecodeValueType>(\n type: T,\n opcode: Opcode,\n args: readonly number[] = [],\n immediate = 0,\n ): SplatPostDecodeValue<T> {\n if (this.instructions.length >= 4096) {\n throw new Error(\"postDecode program exceeds 4096 instructions\");\n }\n const register = this.instructions.length;\n this.instructions.push({ opcode, type, args, immediate });\n return new SplatPostDecodeValue(type, register, this);\n }\n\n inputField<T extends SplatPostDecodeValueType>(\n type: T,\n field: InputField,\n ): SplatPostDecodeValue<T> {\n const existing = this.inputRegisters.get(field);\n if (existing) return existing as SplatPostDecodeValue<T>;\n const value = this.instruction(type, Opcode.InputField, [], field);\n this.inputRegisters.set(field, value);\n return value;\n }\n\n attribute<Components extends AttributeComponents = 1>(\n options: SplatPostDecodeAttributeOptions<Components>,\n ): AttributeValue<Components> {\n if (!ArrayBuffer.isView(options.data)) {\n throw new Error(\"postDecode attribute data must be an ArrayBuffer view\");\n }\n const componentBytes = ATTRIBUTE_FORMAT_BYTES[options.format];\n if (!componentBytes) {\n throw new Error(`Unknown postDecode format: ${options.format}`);\n }\n const count = options.count;\n const components = options.components ?? 1;\n const byteOffset = options.byteOffset ?? 0;\n const packedBytes = componentBytes * components;\n const byteStride = options.byteStride ?? packedBytes;\n if (!Number.isSafeInteger(count) || count < 0) {\n throw new Error(\"postDecode attribute count must be non-negative\");\n }\n if (!Number.isInteger(components) || components < 1 || components > 4) {\n throw new Error(\n \"postDecode attribute components must be between 1 and 4\",\n );\n }\n if (\n !Number.isSafeInteger(byteOffset) ||\n byteOffset < 0 ||\n !Number.isSafeInteger(byteStride) ||\n byteStride < packedBytes\n ) {\n throw new Error(\"Invalid postDecode attribute byteOffset or byteStride\");\n }\n const requiredBytes =\n count === 0\n ? byteOffset\n : byteOffset + (count - 1) * byteStride + packedBytes;\n if (\n !Number.isSafeInteger(requiredBytes) ||\n requiredBytes > options.data.byteLength\n ) {\n throw new Error(\"postDecode attribute data is too small\");\n }\n\n const index = this.attributes.length;\n this.attributes.push({\n data: options.data,\n format: options.format,\n count,\n components,\n byteOffset,\n byteStride,\n });\n return this.instruction(\n COMPONENT_TYPES[components - 1],\n Opcode.InputAttribute,\n [],\n index,\n ) as AttributeValue<Components>;\n }\n\n coerce<T extends SplatPostDecodeValueType>(\n value: ValueLike<T>,\n expectedType?: T,\n ): SplatPostDecodeValue<T> {\n if (value instanceof SplatPostDecodeValue) {\n if (value.owner !== this) {\n throw new Error(\n \"Cannot combine values from different postDecode programs\",\n );\n }\n if (expectedType && value.type !== expectedType) {\n const vec4Quaternion =\n (expectedType === \"quaternion\" && value.type === \"vec4\") ||\n (expectedType === \"vec4\" && value.type === \"quaternion\");\n if (!vec4Quaternion) {\n throw new Error(`Expected ${expectedType}, received ${value.type}`);\n }\n }\n return value as SplatPostDecodeValue<T>;\n }\n\n const type = expectedType ?? inferLiteralType(value);\n const numeric =\n typeof value === \"boolean\"\n ? [value ? 1 : 0]\n : typeof value === \"number\"\n ? [value]\n : [...(value as readonly number[])];\n const width = TYPE_WIDTHS[type];\n if (numeric.length !== width) {\n throw new Error(`Expected ${width} values for ${type}`);\n }\n const values = numeric.map(Math.fround);\n if (!values.every(Number.isFinite)) {\n throw new Error(\"postDecode constants must be finite\");\n }\n const key = constantKey(type, values);\n const existing = this.constantRegisters.get(key);\n if (existing) return existing as SplatPostDecodeValue<T>;\n\n const immediate = this.constants.length;\n this.constants.push(...values);\n const result = this.instruction(type as T, Opcode.Constant, [], immediate);\n this.constantRegisters.set(key, result);\n return result;\n }\n\n private unary(\n opcode: Opcode,\n value: AnyValueLike,\n outputType?: SplatPostDecodeValueType,\n ) {\n const input = this.coerce(value);\n return this.instruction(outputType ?? input.type, opcode, [input.register]);\n }\n\n private binary(\n opcode: Opcode,\n leftValue: AnyValueLike,\n rightValue: AnyValueLike,\n outputType?: SplatPostDecodeValueType,\n ) {\n const left = this.coerce(leftValue);\n const right = this.coerceForBinary(rightValue, left.type);\n return this.instruction(outputType ?? left.type, opcode, [\n left.register,\n right.register,\n ]);\n }\n\n private ternary(\n opcode: Opcode,\n firstValue: AnyValueLike,\n secondValue: AnyValueLike,\n thirdValue: AnyValueLike,\n ) {\n const first = this.coerce(firstValue);\n const second = this.coerceForBinary(secondValue, first.type);\n const third = this.coerceForBinary(thirdValue, first.type);\n return this.instruction(first.type, opcode, [\n first.register,\n second.register,\n third.register,\n ]);\n }\n\n private coerceForBinary(\n value: AnyValueLike,\n targetType: SplatPostDecodeValueType,\n ) {\n if (value instanceof SplatPostDecodeValue) {\n return value.type === \"float\" && TYPE_WIDTHS[targetType] > 1\n ? this.coerce(value)\n : this.coerce(value, targetType);\n }\n return this.coerce(\n value,\n typeof value === \"number\" && TYPE_WIDTHS[targetType] > 1\n ? \"float\"\n : targetType,\n );\n }\n\n private createOperations(): SplatPostDecodeOperations {\n const reduceNumeric =\n (opcode: Opcode): VariadicNumericOperation =>\n <T extends NumericValueType>(\n first: ValueLike<T>,\n ...rest: BroadcastLike<T>[]\n ) => {\n let result = this.coerce(first);\n for (const right of rest) {\n result = this.binary(\n opcode,\n result,\n right,\n ) as SplatPostDecodeValue<T>;\n }\n return result;\n };\n const binaryNumeric =\n (opcode: Opcode): BinaryNumericOperation =>\n <T extends NumericValueType>(\n left: ValueLike<T>,\n right: BroadcastLike<T>,\n ) =>\n this.binary(opcode, left, right) as SplatPostDecodeValue<T>;\n const unaryNumeric =\n (opcode: Opcode): UnaryNumericOperation =>\n <T extends NumericValueType>(value: ValueLike<T>) =>\n this.unary(opcode, value) as SplatPostDecodeValue<T>;\n const compare =\n (opcode: Opcode) => (left: AnyValueLike, right: AnyValueLike) => {\n const a = this.coerce(left);\n const scalar = opcode !== Opcode.Equal && opcode !== Opcode.NotEqual;\n if (scalar && a.type !== \"float\")\n throw new Error(\"Ordered comparisons require scalars\");\n const b = this.coerce(right, a.type);\n return this.instruction(\"bool\", opcode, [\n a.register,\n b.register,\n ]) as BoolValue;\n };\n const vectorBinary = (\n opcode: Opcode,\n left: AnyValueLike,\n right: AnyValueLike,\n ) => {\n const a = this.coerce(left);\n if (\n !(a.type === \"vec2\" || a.type === \"vec3\" || a.type === \"vec4\") ||\n (opcode === Opcode.Cross && a.type !== \"vec3\")\n )\n throw new Error(\"dot/cross require matching vectors\");\n const b = this.coerce(right, a.type);\n return this.instruction(\n opcode === Opcode.Dot ? \"float\" : a.type,\n opcode,\n [a.register, b.register],\n );\n };\n const reduceBoolean =\n (opcode: Opcode) =>\n (first: BoolLike, ...rest: BoolLike[]): BoolValue => {\n let result = this.coerce(first, \"bool\");\n for (const right of rest) {\n result = this.binary(opcode, result, right, \"bool\") as BoolValue;\n }\n return result;\n };\n const construct = <T extends VectorValueType | \"quaternion\">(\n opcode: Opcode,\n type: T,\n values: FloatLike[],\n ) =>\n this.instruction(\n type,\n opcode,\n values.map((value) => this.coerce(value, \"float\").register),\n );\n\n return {\n add: reduceNumeric(Opcode.Add),\n sub: binaryNumeric(Opcode.Subtract),\n mul: reduceNumeric(Opcode.Multiply),\n div: binaryNumeric(Opcode.Divide),\n min: binaryNumeric(Opcode.Min),\n max: binaryNumeric(Opcode.Max),\n pow: binaryNumeric(Opcode.Pow),\n clamp: (value, min, max) =>\n this.ternary(Opcode.Clamp, value, min, max) as never,\n mix: (left, right, amount) =>\n this.ternary(Opcode.Mix, left, right, amount) as never,\n neg: unaryNumeric(Opcode.Negate),\n abs: unaryNumeric(Opcode.Abs),\n sqrt: unaryNumeric(Opcode.Sqrt),\n log: unaryNumeric(Opcode.Log),\n exp: unaryNumeric(Opcode.Exp),\n floor: unaryNumeric(Opcode.Floor),\n ceil: unaryNumeric(Opcode.Ceil),\n round: unaryNumeric(Opcode.Round),\n sin: unaryNumeric(Opcode.Sin),\n cos: unaryNumeric(Opcode.Cos),\n acos: unaryNumeric(Opcode.Acos),\n tan: unaryNumeric(Opcode.Tan),\n asin: unaryNumeric(Opcode.Asin),\n atan: unaryNumeric(Opcode.Atan),\n atan2: binaryNumeric(Opcode.Atan2),\n normalize: (value) => this.unary(Opcode.Normalize, value) as never,\n length: (value) =>\n this.unary(Opcode.Length, value, \"float\") as FloatValue,\n isFinite: (value) =>\n this.unary(Opcode.IsFinite, value, \"bool\") as BoolValue,\n not: (value) =>\n this.unary(Opcode.Not, this.coerce(value, \"bool\"), \"bool\") as BoolValue,\n eq: compare(Opcode.Equal),\n ne: compare(Opcode.NotEqual),\n lt: compare(Opcode.Less),\n lte: compare(Opcode.LessEqual),\n gt: compare(Opcode.Greater),\n gte: compare(Opcode.GreaterEqual),\n and: reduceBoolean(Opcode.And),\n or: reduceBoolean(Opcode.Or),\n select: (condition, whenTrue, whenFalse) => {\n const trueValue = this.coerce(whenTrue);\n const falseValue = this.coerce(whenFalse, trueValue.type);\n return this.instruction(trueValue.type, Opcode.Select, [\n this.coerce(condition, \"bool\").register,\n trueValue.register,\n falseValue.register,\n ]) as never;\n },\n dot: (left, right) => vectorBinary(Opcode.Dot, left, right) as FloatValue,\n cross: (left, right) =>\n vectorBinary(Opcode.Cross, left, right) as Vec3Value,\n vec2: (x, y) => construct(Opcode.Vec2, \"vec2\", [x, y]),\n vec3: (x, y, z) => construct(Opcode.Vec3, \"vec3\", [x, y, z]),\n vec4: (x, y, z, w) => construct(Opcode.Vec4, \"vec4\", [x, y, z, w]),\n quaternion: (x, y, z, w) =>\n construct(Opcode.Vec4, \"quaternion\", [x, y, z, w]),\n component: (value, index) => {\n const input = this.coerce(value as AnyValueLike);\n if (\n !Number.isInteger(index) ||\n index < 0 ||\n index >= TYPE_WIDTHS[input.type]\n ) {\n throw new Error(\"postDecode component index is out of bounds\");\n }\n return this.instruction(\n \"float\",\n Opcode.Component,\n [input.register],\n index,\n );\n },\n maxComponentIndex: (value) =>\n this.unary(Opcode.MaxComponentIndex, value, \"float\") as FloatValue,\n quatMul: (left, right) => {\n const a = this.coerce(left, \"quaternion\");\n const b = this.coerce(right, \"quaternion\");\n return this.instruction(\"quaternion\", Opcode.QuaternionMultiply, [\n a.register,\n b.register,\n ]);\n },\n rotateVector: (quaternion, vector) => {\n const q = this.coerce(quaternion, \"quaternion\");\n const v = this.coerce(vector, \"vec3\");\n return this.instruction(\"vec3\", Opcode.RotateVector, [\n q.register,\n v.register,\n ]);\n },\n };\n }\n}\n\nexport function buildOutputs(\n builder: ProgramBuilder,\n patch: SplatPostDecodePatch,\n) {\n if (patch.opacity !== undefined && patch.alpha !== undefined) {\n throw new Error(\"postDecode opacity cannot be combined with alpha\");\n }\n const output = <T extends SplatPostDecodeValueType>(\n value: ValueLike<T> | undefined,\n type: T,\n ) => (value === undefined ? undefined : builder.coerce(value, type).register);\n const outputs: SplatPostDecodeOutputs = {\n when: output(patch.when, \"bool\"),\n position: output(patch.position, \"vec3\"),\n scale: output(patch.scale, \"vec3\"),\n quaternion: output(patch.quaternion, \"quaternion\"),\n opacity: output(patch.opacity, \"float\"),\n alpha: output(patch.alpha, \"float\"),\n color: output(patch.color, \"vec3\"),\n };\n if (patch.sh !== undefined) {\n if (\n !(patch.sh instanceof SplatPostDecodeShPatch) ||\n patch.sh.owner !== builder\n ) {\n throw new Error(\n \"postDecode SH output must be created from splat.sh.map()\",\n );\n }\n outputs.sh = patch.sh.coefficients.map((value) => value.register);\n }\n return outputs;\n}\n","import {\n Opcode,\n type PostDecodeSource,\n type SplatPostDecodeOutputs,\n} from \"./protocol\";\n\n/** Fuse only single-use intermediates; shared values must still run once. */\nexport function fuseArithmetic(\n source: PostDecodeSource,\n outputs: SplatPostDecodeOutputs,\n): PostDecodeSource {\n const uses = new Uint32Array(source.instructions.length);\n for (const instruction of source.instructions) {\n for (const argument of instruction.args) uses[argument] += 1;\n }\n for (const register of [\n outputs.when,\n outputs.position,\n outputs.scale,\n outputs.quaternion,\n outputs.opacity,\n outputs.alpha,\n outputs.color,\n ...(outputs.sh ?? []),\n ]) {\n if (register !== undefined) uses[register] += 1;\n }\n\n const instructions = source.instructions.slice();\n for (let index = 0; index < instructions.length; index += 1) {\n const outer = instructions[index];\n if (outer.opcode !== Opcode.Add && outer.opcode !== Opcode.Multiply) {\n continue;\n }\n const innerOpcode =\n outer.opcode === Opcode.Add ? Opcode.Multiply : Opcode.Add;\n for (let side = 0; side < 2; side += 1) {\n const register = outer.args[side];\n const inner = instructions[register];\n if (uses[register] !== 1 || inner.opcode !== innerOpcode) continue;\n instructions[index] = {\n ...outer,\n opcode:\n outer.opcode === Opcode.Add ? Opcode.MultiplyAdd : Opcode.AddMultiply,\n args: [...inner.args, outer.args[1 - side]],\n // Keep the outer operand order as well as its rounding boundary.\n immediate: side,\n };\n break;\n }\n }\n // The compiler's dependency walk removes the bypassed intermediates.\n return { ...source, instructions };\n}\n","import { fuseArithmetic } from \"./optimizer\";\nimport {\n ATTRIBUTE_FORMAT_BYTES,\n type AttributeBinding,\n Opcode,\n type PostDecodeSource,\n SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION,\n SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE,\n SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE,\n SPLAT_POST_DECODE_FLOW_STAGE_REGISTER,\n SPLAT_POST_DECODE_FLOW_STAGE_START,\n SPLAT_POST_DECODE_FLOW_STAGE_STRIDE,\n SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0,\n SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE,\n SPLAT_POST_DECODE_INSTRUCTION_OPCODE,\n SPLAT_POST_DECODE_INSTRUCTION_STRIDE,\n SPLAT_POST_DECODE_INSTRUCTION_WIDTH,\n SPLAT_POST_DECODE_MISSING_ARGUMENT,\n type SerializedSplatPostDecodeAttribute,\n type SerializedSplatPostDecodeCondition,\n type SplatPostDecodeInstruction,\n type SplatPostDecodeOutputs,\n TYPE_WIDTHS,\n} from \"./protocol\";\n\nclass GenerationRegisterMap {\n private readonly values: Int32Array;\n private readonly generations: Uint32Array;\n private generation = 1;\n\n constructor(size: number) {\n this.values = new Int32Array(size);\n this.generations = new Uint32Array(size);\n }\n\n clear() {\n // A map lives for one compilation, capped at 4096 condition stages.\n this.generation += 1;\n }\n\n has(source: number) {\n return this.generations[source] === this.generation;\n }\n\n get(source: number) {\n return this.values[source];\n }\n\n set(source: number, target: number) {\n this.generations[source] = this.generation;\n this.values[source] = target;\n }\n\n delete(source: number) {\n this.generations[source] = 0;\n }\n}\n\ntype CompiledProgram = {\n instructions: SplatPostDecodeInstruction[];\n constants: number[];\n outputs: Omit<SplatPostDecodeOutputs, \"when\">;\n condition?: SerializedSplatPostDecodeCondition;\n attributes: AttributeBinding[];\n};\n\nfunction markDependencies(\n builder: PostDecodeSource,\n roots: readonly (number | undefined)[],\n marked: Uint8Array,\n) {\n const pending: number[] = [];\n for (const root of roots) {\n if (root === undefined || marked[root]) continue;\n marked[root] = 1;\n pending.push(root);\n }\n while (pending.length !== 0) {\n const register = pending.pop() as number;\n for (const argument of builder.instructions[register].args) {\n if (marked[argument]) continue;\n marked[argument] = 1;\n pending.push(argument);\n }\n }\n}\n\n/**\n * Serializes source instructions while remapping only live registers. A\n * generation map represents the current straight-line path. Branch merges\n * advance its generation in O(1), while unique predecessors reuse it. One\n * generation array is also shared by every dependency walk.\n */\nclass InstructionSerializer {\n readonly instructions: SplatPostDecodeInstruction[] = [];\n readonly constants: number[] = [];\n readonly attributes: AttributeBinding[] = [];\n\n private readonly constantMap = new Map<number, number>();\n private readonly attributeMap = new Map<number, number>();\n private readonly dependencyMarks: Uint32Array;\n private dependencyGeneration = 0;\n\n constructor(private readonly builder: PostDecodeSource) {\n this.dependencyMarks = new Uint32Array(builder.instructions.length);\n }\n\n appendDependencies(\n roots: readonly (number | undefined)[],\n registers: GenerationRegisterMap,\n forceRoots = false,\n ) {\n if (forceRoots) {\n for (const root of roots) {\n if (\n root !== undefined &&\n this.builder.instructions[root].opcode !== Opcode.Constant\n ) {\n registers.delete(root);\n }\n }\n }\n\n this.dependencyGeneration += 1;\n const generation = this.dependencyGeneration;\n const pending: number[] = [];\n const sourceOrder: number[] = [];\n for (const root of roots) {\n if (root !== undefined && !registers.has(root)) pending.push(root);\n }\n while (pending.length !== 0) {\n const source = pending.pop() as number;\n if (\n registers.has(source) ||\n this.dependencyMarks[source] === generation\n ) {\n continue;\n }\n this.dependencyMarks[source] = generation;\n sourceOrder.push(source);\n for (const argument of this.builder.instructions[source].args) {\n if (!registers.has(argument)) pending.push(argument);\n }\n }\n\n sourceOrder.sort((left, right) => left - right);\n this.append(sourceOrder, registers);\n return registers;\n }\n\n append(sourceOrder: readonly number[], registers: GenerationRegisterMap) {\n for (const sourceIndex of sourceOrder) {\n const source = this.builder.instructions[sourceIndex];\n if (source.opcode === Opcode.Constant) {\n let target = this.constantMap.get(sourceIndex);\n if (target === undefined) {\n this.reserveInstruction();\n target = this.instructions.length;\n this.constantMap.set(sourceIndex, target);\n const immediate = this.constants.length;\n this.constants.push(\n ...this.builder.constants.slice(\n source.immediate,\n source.immediate + TYPE_WIDTHS[source.type],\n ),\n );\n this.instructions.push({ ...source, immediate });\n }\n registers.set(sourceIndex, target);\n continue;\n }\n\n this.reserveInstruction();\n let immediate = source.immediate;\n if (source.opcode === Opcode.InputAttribute) {\n let target = this.attributeMap.get(immediate);\n if (target === undefined) {\n target = this.attributes.length;\n this.attributeMap.set(immediate, target);\n this.attributes.push(this.builder.attributes[immediate]);\n }\n immediate = target;\n }\n const args = source.args.map((argument) => registers.get(argument));\n registers.set(sourceIndex, this.instructions.length);\n this.instructions.push({ ...source, args, immediate });\n }\n }\n\n private reserveInstruction() {\n if (this.instructions.length >= 4096) {\n throw new Error(\"postDecode compiled program exceeds 4096 instructions\");\n }\n }\n}\n\nfunction emptyCompiledProgram(): CompiledProgram {\n return {\n instructions: [],\n constants: [],\n outputs: {},\n condition: undefined,\n attributes: [],\n };\n}\n\nfunction remapOutputs(\n outputs: SplatPostDecodeOutputs,\n registers: GenerationRegisterMap,\n): Omit<SplatPostDecodeOutputs, \"when\"> {\n const remap = (register: number | undefined) =>\n register === undefined ? undefined : registers.get(register);\n return {\n position: remap(outputs.position),\n scale: remap(outputs.scale),\n quaternion: remap(outputs.quaternion),\n opacity: remap(outputs.opacity),\n alpha: remap(outputs.alpha),\n color: remap(outputs.color),\n sh: outputs.sh?.map((register) => registers.get(register)),\n };\n}\n\ntype FlowNode = {\n register: number;\n onTrue: number;\n onFalse: number;\n};\n\nfunction compileConditionFlow(\n builder: PostDecodeSource,\n outputs: SplatPostDecodeOutputs,\n outputRoots: readonly (number | undefined)[],\n whenRegister: number,\n): CompiledProgram | undefined {\n const FLOW_ACCEPT = -1;\n const FLOW_REJECT = -2;\n const FLOW_DYNAMIC = 0;\n const FLOW_CONSTANT_FALSE = 1;\n const FLOW_CONSTANT_TRUE = 2;\n const constantValues = new Uint8Array(whenRegister + 1);\n for (let register = 0; register <= whenRegister; register += 1) {\n const instruction = builder.instructions[register];\n if (instruction.opcode === Opcode.Constant && instruction.type === \"bool\") {\n constantValues[register] = builder.constants[instruction.immediate]\n ? FLOW_CONSTANT_TRUE\n : FLOW_CONSTANT_FALSE;\n continue;\n }\n const left = constantValues[instruction.args[0]];\n if (instruction.opcode === Opcode.Not) {\n constantValues[register] =\n left === FLOW_CONSTANT_TRUE\n ? FLOW_CONSTANT_FALSE\n : left === FLOW_CONSTANT_FALSE\n ? FLOW_CONSTANT_TRUE\n : FLOW_DYNAMIC;\n } else if (instruction.opcode === Opcode.And) {\n const right = constantValues[instruction.args[1]];\n constantValues[register] =\n left === FLOW_CONSTANT_FALSE || right === FLOW_CONSTANT_FALSE\n ? FLOW_CONSTANT_FALSE\n : left === FLOW_CONSTANT_TRUE && right === FLOW_CONSTANT_TRUE\n ? FLOW_CONSTANT_TRUE\n : FLOW_DYNAMIC;\n } else if (instruction.opcode === Opcode.Or) {\n const right = constantValues[instruction.args[1]];\n constantValues[register] =\n left === FLOW_CONSTANT_TRUE || right === FLOW_CONSTANT_TRUE\n ? FLOW_CONSTANT_TRUE\n : left === FLOW_CONSTANT_FALSE && right === FLOW_CONSTANT_FALSE\n ? FLOW_CONSTANT_FALSE\n : FLOW_DYNAMIC;\n }\n }\n\n const reverseNodes: FlowNode[] = [];\n const FLOW_AND_LEFT = 0;\n const FLOW_OR_LEFT = 1;\n const FLOW_CONTINUATION_SIZE = 3;\n const continuations = new Int32Array(\n (whenRegister + 1) * FLOW_CONTINUATION_SIZE,\n );\n let continuationEnd = 0;\n let register = whenRegister;\n let onTrue = FLOW_ACCEPT;\n let onFalse = FLOW_REJECT;\n let compiledTarget = FLOW_REJECT;\n while (true) {\n const constant = constantValues[register];\n if (constant !== FLOW_DYNAMIC) {\n compiledTarget = constant === FLOW_CONSTANT_TRUE ? onTrue : onFalse;\n } else {\n const instruction = builder.instructions[register];\n if (instruction.opcode === Opcode.Not) {\n register = instruction.args[0];\n const target = onTrue;\n onTrue = onFalse;\n onFalse = target;\n continue;\n }\n if (\n instruction.opcode === Opcode.And ||\n instruction.opcode === Opcode.Or\n ) {\n const isAnd = instruction.opcode === Opcode.And;\n continuations[continuationEnd] = isAnd ? FLOW_AND_LEFT : FLOW_OR_LEFT;\n continuations[continuationEnd + 1] = instruction.args[0];\n continuations[continuationEnd + 2] = isAnd ? onFalse : onTrue;\n continuationEnd += FLOW_CONTINUATION_SIZE;\n register = instruction.args[1];\n continue;\n }\n if (reverseNodes.length >= 4096) {\n throw new Error(\"postDecode condition exceeds 4096 flow nodes\");\n }\n compiledTarget = reverseNodes.length;\n reverseNodes.push({ register, onTrue, onFalse });\n }\n\n if (continuationEnd === 0) break;\n continuationEnd -= FLOW_CONTINUATION_SIZE;\n const type = continuations[continuationEnd];\n register = continuations[continuationEnd + 1];\n const target = continuations[continuationEnd + 2];\n if (type === FLOW_AND_LEFT) {\n onTrue = compiledTarget;\n onFalse = target;\n } else {\n onTrue = target;\n onFalse = compiledTarget;\n }\n }\n\n const entry = compiledTarget;\n if (entry === FLOW_REJECT) return emptyCompiledProgram();\n if (entry === FLOW_ACCEPT) {\n outputs.when = undefined;\n return undefined;\n }\n\n const stageCount = reverseNodes.length;\n\n const acceptTarget = stageCount;\n const rejectTarget = acceptTarget + 1;\n const stages = new Uint16Array(\n stageCount * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE,\n );\n const predecessors = new Int32Array(stageCount).fill(-1);\n let acceptPredecessor = -1;\n const recordPredecessor = (target: number, predecessor: number) => {\n if (target === rejectTarget) return;\n if (target === acceptTarget) {\n acceptPredecessor =\n acceptPredecessor === -1\n ? predecessor\n : acceptPredecessor === predecessor\n ? predecessor\n : -2;\n return;\n }\n predecessors[target] =\n predecessors[target] === -1\n ? predecessor\n : predecessors[target] === predecessor\n ? predecessor\n : -2;\n };\n const remapTarget = (target: number) =>\n target === FLOW_ACCEPT\n ? acceptTarget\n : target === FLOW_REJECT\n ? rejectTarget\n : stageCount - 1 - target;\n\n for (let stage = 0; stage < stageCount; stage += 1) {\n const node = reverseNodes[stageCount - 1 - stage];\n const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;\n const onTrue = remapTarget(node.onTrue);\n const onFalse = remapTarget(node.onFalse);\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE] = onTrue;\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE] = onFalse;\n recordPredecessor(onTrue, stage);\n recordPredecessor(onFalse, stage);\n }\n\n const serializer = new InstructionSerializer(builder);\n const pathRegisters = new GenerationRegisterMap(builder.instructions.length);\n for (let stage = 0; stage < stageCount; stage += 1) {\n if (stage === 0 || predecessors[stage] !== stage - 1) {\n pathRegisters.clear();\n }\n const node = reverseNodes[stageCount - 1 - stage];\n const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_START] =\n serializer.instructions.length;\n serializer.appendDependencies([node.register], pathRegisters, true);\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION] =\n serializer.instructions.length - 1;\n stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_REGISTER] = pathRegisters.get(\n node.register,\n );\n }\n\n if (acceptPredecessor !== stageCount - 1) pathRegisters.clear();\n serializer.appendDependencies(outputRoots, pathRegisters);\n return {\n instructions: serializer.instructions,\n constants: serializer.constants,\n outputs: remapOutputs(outputs, pathRegisters),\n condition: { stages },\n attributes: serializer.attributes,\n };\n}\n\nexport function compileProgram(\n builder: PostDecodeSource,\n sourceOutputs: SplatPostDecodeOutputs,\n): CompiledProgram {\n return compileSource(fuseArithmetic(builder, sourceOutputs), sourceOutputs);\n}\n\nfunction compileSource(\n builder: PostDecodeSource,\n sourceOutputs: SplatPostDecodeOutputs,\n): CompiledProgram {\n const outputs = { ...sourceOutputs };\n if (outputs.when !== undefined) {\n const condition = builder.instructions[outputs.when];\n if (condition.opcode === Opcode.Constant) {\n if (builder.constants[condition.immediate] === 0) {\n return emptyCompiledProgram();\n }\n outputs.when = undefined;\n }\n }\n\n const outputRoots = [\n outputs.position,\n outputs.scale,\n outputs.quaternion,\n outputs.opacity,\n outputs.alpha,\n outputs.color,\n ...(outputs.sh ?? []),\n ];\n if (outputs.when !== undefined) {\n const flow = compileConditionFlow(\n builder,\n outputs,\n outputRoots,\n outputs.when,\n );\n if (flow) return flow;\n }\n\n const live = new Uint8Array(builder.instructions.length);\n markDependencies(builder, outputRoots, live);\n const instructionOrder: number[] = [];\n for (let register = 0; register < live.length; register += 1) {\n if (live[register]) instructionOrder.push(register);\n }\n\n const serializer = new InstructionSerializer(builder);\n const registers = new GenerationRegisterMap(builder.instructions.length);\n serializer.append(instructionOrder, registers);\n return {\n instructions: serializer.instructions,\n constants: serializer.constants,\n outputs: remapOutputs(outputs, registers),\n attributes: serializer.attributes,\n };\n}\n\nexport function packInstructions(\n instructions: readonly SplatPostDecodeInstruction[],\n): Uint16Array {\n // The builder and compiler cap programs at 4096 instructions with at most\n // four arguments/components each, so registers and immediates fit Uint16.\n const packed = new Uint16Array(\n instructions.length * SPLAT_POST_DECODE_INSTRUCTION_STRIDE,\n );\n packed.fill(SPLAT_POST_DECODE_MISSING_ARGUMENT);\n for (let index = 0; index < instructions.length; index += 1) {\n const instruction = instructions[index];\n const offset = index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_OPCODE] = instruction.opcode;\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_WIDTH] =\n TYPE_WIDTHS[instruction.type];\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE] =\n instruction.immediate;\n for (let argument = 0; argument < instruction.args.length; argument += 1) {\n packed[offset + SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 + argument] =\n instruction.args[argument];\n }\n }\n return packed;\n}\n\ntype AttributeRegion = {\n buffer: ArrayBufferLike;\n start: number;\n end: number;\n outputOffset: number;\n};\n\nexport function snapshotAttributes(bindings: readonly AttributeBinding[]) {\n const attributes: SerializedSplatPostDecodeAttribute[] = bindings.map(\n ({ format, components, byteStride, count }) => ({\n format,\n components,\n byteOffset: 0,\n byteStride,\n count,\n }),\n );\n const rangesByBuffer = new Map<\n ArrayBufferLike,\n {\n start: number;\n end: number;\n attribute: SerializedSplatPostDecodeAttribute;\n }[]\n >();\n for (const [index, binding] of bindings.entries()) {\n if (binding.count === 0) continue;\n const packedBytes =\n ATTRIBUTE_FORMAT_BYTES[binding.format] * binding.components;\n const start = binding.data.byteOffset + binding.byteOffset;\n const end = start + (binding.count - 1) * binding.byteStride + packedBytes;\n const ranges = rangesByBuffer.get(binding.data.buffer) ?? [];\n ranges.push({ start, end, attribute: attributes[index] });\n rangesByBuffer.set(binding.data.buffer, ranges);\n }\n\n const regions: AttributeRegion[] = [];\n let byteLength = 0;\n for (const [buffer, ranges] of rangesByBuffer) {\n ranges.sort((left, right) => left.start - right.start);\n let region: AttributeRegion | undefined;\n for (const { start, end, attribute } of ranges) {\n if (region && start <= region.end) {\n byteLength += Math.max(0, end - region.end);\n region.end = Math.max(region.end, end);\n } else {\n region = { buffer, start, end, outputOffset: byteLength };\n regions.push(region);\n byteLength += end - start;\n }\n attribute.byteOffset = region.outputOffset + start - region.start;\n }\n }\n\n const data = new Uint8Array(byteLength);\n for (const region of regions) {\n data.set(\n new Uint8Array(region.buffer, region.start, region.end - region.start),\n region.outputOffset,\n );\n }\n\n return { data, attributes };\n}\n","import {\n ProgramBuilder,\n type SplatPostDecodeContext,\n type SplatPostDecodePatch,\n buildOutputs,\n} from \"./builder\";\nimport {\n compileProgram,\n packInstructions,\n snapshotAttributes,\n} from \"./compiler\";\nimport type {\n SerializedSplatPostDecode,\n SplatPostDecodeOutputs,\n} from \"./protocol\";\n\nconst SPLAT_POST_DECODE_PROGRAM = Symbol(\"SplatPostDecodeProgram\");\n\nexport type SplatPostDecodeProgram = {\n readonly [SPLAT_POST_DECODE_PROGRAM]: true;\n};\n\nclass SplatPostDecodeProgramImpl implements SplatPostDecodeProgram {\n readonly [SPLAT_POST_DECODE_PROGRAM] = true as const;\n\n private readonly compiled: ReturnType<typeof compileProgram>;\n\n constructor(builder: ProgramBuilder, outputs: SplatPostDecodeOutputs) {\n this.compiled = compileProgram(builder, outputs);\n }\n\n static serialize(program: SplatPostDecodeProgram): SerializedSplatPostDecode {\n if (!(program instanceof SplatPostDecodeProgramImpl)) {\n throw new Error(\"Invalid postDecode program\");\n }\n const compiled = program.compiled;\n const snapshot = snapshotAttributes(compiled.attributes);\n return {\n instructions: packInstructions(compiled.instructions),\n constants: new Float32Array(compiled.constants),\n outputs: compiled.outputs,\n condition: compiled.condition,\n attributeData: snapshot.data,\n attributes: snapshot.attributes,\n };\n }\n}\n\n/** @internal */\nexport function serializeSplatPostDecode(\n program: SplatPostDecodeProgram,\n): SerializedSplatPostDecode {\n return SplatPostDecodeProgramImpl.serialize(program);\n}\n\nfunction defineSplatPostDecode(\n build: (context: SplatPostDecodeContext) => SplatPostDecodePatch,\n): SplatPostDecodeProgram {\n const builder = new ProgramBuilder();\n const patch = build({\n splat: builder.splat,\n op: builder.op,\n attribute: (options) => builder.attribute(options),\n });\n if (!patch || typeof patch !== \"object\") {\n throw new Error(\"postDecode builder must return a splat patch object\");\n }\n return new SplatPostDecodeProgramImpl(builder, buildOutputs(builder, patch));\n}\n\nexport const postDecode = {\n define: defineSplatPostDecode,\n};\n","import { DefaultLoadingManager, type Loader } from \"three\";\nimport type { ReorderedSplatResult, SplatFileType } from \"../data/defines\";\nimport { workerPool } from \"../runtime/SplatWorker\";\nimport { abortable, linkedAbortController } from \"../runtime/abort\";\nimport { getAssetBaseUrl } from \"./assetUrl\";\nimport type {\n SplatFileResolver,\n SplatLoadStatus,\n SplatProgressEvent,\n} from \"./loadTypes\";\nimport {\n type SplatPostDecodeProgram,\n serializeSplatPostDecode,\n} from \"./postDecode/program\";\n\nexport type SplatDataLoadOptions = {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n resolveFile?: SplatFileResolver;\n postDecode?: SplatPostDecodeProgram;\n signal?: AbortSignal;\n onProgress?: (event: SplatProgressEvent) => void;\n onLoad?: (decoded: ReorderedSplatResult) => void;\n onError?: (error: unknown) => void;\n};\n\ntype SplatLoadContext = Pick<\n Loader,\n \"manager\" | \"path\" | \"requestHeader\" | \"withCredentials\"\n>;\n\n/** Loads packed data without constructing scene objects or GPU textures. */\nexport async function loadSplatData(\n {\n url,\n file,\n fileBytes,\n fileType,\n fileName,\n resolveFile,\n postDecode,\n signal,\n onLoad,\n onProgress,\n onError,\n }: SplatDataLoadOptions,\n context: SplatLoadContext = {\n manager: DefaultLoadingManager,\n path: \"\",\n requestHeader: {},\n withCredentials: false,\n },\n): Promise<ReorderedSplatResult> {\n let resolvedURL: string | undefined;\n let started = false;\n const request = linkedAbortController(signal);\n const { controller } = request;\n try {\n signal?.throwIfAborted();\n // Snapshot application attributes at the load call, before waiting for a worker.\n const serializedPostDecode = postDecode\n ? serializeSplatPostDecode(postDecode)\n : undefined;\n if (\n [url, file, fileBytes].filter((input) => input !== undefined).length !== 1\n ) {\n throw new Error(\"Provide exactly one of url, file, or fileBytes\");\n }\n fileName ??= (file as File | undefined)?.name;\n const byteArray =\n fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;\n const resourcePath = url === undefined ? undefined : context.path + url;\n resolvedURL =\n resourcePath === undefined\n ? undefined\n : context.manager.resolveURL(resourcePath);\n started = true;\n context.manager.itemStart(resolvedURL ?? \"\");\n\n const pathName = resolvedURL || fileName;\n const requestUrl = new URL(pathName || \"\", window.location.href).href;\n const resourceUrl = new URL(\n resourcePath || fileName || \"\",\n window.location.href,\n ).href;\n const memoryHeavy =\n fileType === \"sog\" ||\n (!fileType && !/\\.(ply|spz)(?:[?#]|$)/i.test(pathName ?? \"\"));\n const decoded = await workerPool.withWorker(\n (worker) =>\n worker.call(\n \"loadSplats\",\n {\n url: resolvedURL ? requestUrl : undefined,\n requestHeader: context.requestHeader,\n withCredentials: context.withCredentials,\n file,\n fileBytes: byteArray?.slice(),\n fileType,\n pathName,\n hasFileResolver: resolveFile !== undefined,\n reportProcessingProgress: onProgress !== undefined,\n baseUrl: getAssetBaseUrl(requestUrl) ?? resourceUrl,\n postDecode: serializedPostDecode,\n },\n {\n signal: controller.signal,\n onStatus: async (data) => {\n const status = data as SplatLoadStatus;\n if (\"assetRequest\" in status) {\n return worker.call(\"resolveAsset\", {\n requestId: status.assetRequest,\n url: new URL(\n context.manager.resolveURL(status.url),\n window.location.href,\n ).href,\n });\n }\n if (\"fileRequest\" in status) {\n if (!resolveFile) throw new Error(\"No external file resolver\");\n const input = await abortable(\n Promise.resolve(\n resolveFile(status.filename, controller.signal),\n ),\n controller.signal,\n );\n controller.signal.throwIfAborted();\n return worker.call(\"resolveFile\", {\n requestId: status.fileRequest,\n input:\n input instanceof Uint8Array\n ? input.slice()\n : input instanceof ArrayBuffer\n ? input.slice(0)\n : input,\n });\n }\n if (onProgress) {\n try {\n onProgress(\n Object.assign(\n new ProgressEvent(\"progress\", {\n lengthComputable: status.total !== 0,\n loaded: status.loaded,\n total: status.total,\n }),\n { stage: status.stage ?? \"download\" },\n ),\n );\n } catch (error) {\n console.error(\"Progress callback failed\", error);\n }\n }\n },\n },\n ),\n memoryHeavy,\n controller.signal,\n );\n signal?.throwIfAborted();\n onLoad?.(decoded);\n return decoded;\n } catch (error) {\n if (started) context.manager.itemError(resolvedURL ?? \"\");\n onError?.(error);\n throw error;\n } finally {\n request.cleanup();\n controller.abort();\n if (started) context.manager.itemEnd(resolvedURL ?? \"\");\n }\n}\n","import { Loader } from \"three\";\nimport { Splats } from \"../data/Splats\";\nimport { linkedAbortController } from \"../runtime/abort\";\nimport { SplatMesh } from \"../scene/SplatMesh\";\nimport { type SplatDataLoadOptions, loadSplatData } from \"./loadSplatData\";\nimport type { SplatProgressEvent } from \"./loadTypes\";\n\ntype SplatLoadOptions = Omit<SplatDataLoadOptions, \"onLoad\"> & {\n splats?: Splats;\n onLoad?: (decoded: Splats) => void;\n};\n\n// SplatLoader implements the THREE.Loader interface for PLY, SPZ, SOG and RAD.\nexport class SplatLoader extends Loader {\n private readonly requests = new Set<AbortController>();\n\n override abort() {\n for (const request of this.requests)\n request.abort(new DOMException(\"Splat load aborted\", \"AbortError\"));\n return this;\n }\n\n load(\n url: string,\n onLoad?: (decoded: Splats) => void,\n onProgress?: (event: SplatProgressEvent) => void,\n onError?: (error: unknown) => void,\n ) {\n return this.loadInternal({ url, onLoad, onProgress, onError });\n }\n\n loadAsync(\n url: string,\n onProgress?: (event: SplatProgressEvent) => void,\n signal?: AbortSignal,\n ): Promise<Splats> {\n return this.loadInternalAsync({ url, onProgress, signal });\n }\n\n parse(splats: Splats): SplatMesh {\n return new SplatMesh({ splats });\n }\n\n loadInternal(options: SplatLoadOptions) {\n void this.loadInternalAsync(options).catch(() => {});\n }\n\n async loadInternalAsync({\n splats,\n onLoad,\n ...options\n }: SplatLoadOptions): Promise<Splats> {\n const request = linkedAbortController(options.signal);\n this.requests.add(request.controller);\n try {\n let result!: Splats;\n await loadSplatData(\n {\n ...options,\n signal: request.signal,\n onLoad: (decoded) => {\n result = splats ?? new Splats();\n result.initializeDecoded(decoded);\n onLoad?.(result);\n },\n },\n this,\n );\n return result;\n } finally {\n this.requests.delete(request.controller);\n request.cleanup();\n }\n }\n}\n","import * as THREE from \"three\";\nimport { SPLAT_TEX_HEIGHT, SPLAT_TEX_WIDTH } from \"./defines\";\n\nconst GROUP_LAYER_SIZE = SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT;\n\ntype OpacityRange = { first: number; last: number; refs: number };\n\n/** Source blocks hold group IDs; a small float32 table holds their opacities. */\nexport class SplatOpacityTable {\n private blocks: Uint32Array;\n private readonly blockSize: number;\n private readonly blocksPerLayer: number;\n private readonly blockTexture: THREE.DataArrayTexture;\n private dirtyLayers: Uint8Array;\n private dirty = false;\n // Transparent, stable, RAD incoming and RAD outgoing groups.\n private values = new Float32Array([0, 1, 0, 1]);\n private valueTexture = this.createValueTexture();\n private valuesDirty = false;\n private readonly ranges = new Map<number, OpacityRange>();\n private readonly freeGroups: number[] = [];\n private nextGroup = 4;\n\n constructor(capacity: number, layerSize: number, blockBits: number) {\n this.blockSize = 2 ** blockBits;\n this.blocksPerLayer = layerSize / this.blockSize;\n this.blocks = new Uint32Array(capacity / this.blockSize);\n const width = Math.min(SPLAT_TEX_WIDTH, this.blocksPerLayer);\n this.blockTexture = this.createTexture(\n this.blocks,\n width,\n this.blocksPerLayer / width,\n capacity / layerSize,\n );\n this.dirtyLayers = new Uint8Array(capacity / layerSize);\n }\n\n private createTexture(\n data: Uint32Array,\n width: number,\n height: number,\n depth: number,\n ) {\n const texture = new THREE.DataArrayTexture(data, width, height, depth);\n texture.format = THREE.RedIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n }\n\n private createValueTexture() {\n const count = this.values.length;\n return this.createTexture(\n new Uint32Array(this.values.buffer),\n Math.min(SPLAT_TEX_WIDTH, count),\n Math.min(SPLAT_TEX_HEIGHT, Math.ceil(count / SPLAT_TEX_WIDTH)),\n Math.ceil(count / GROUP_LAYER_SIZE),\n );\n }\n\n /** CPU arrays and GPU storage each occupy this many bytes. */\n get byteLength() {\n return this.blocks.byteLength + this.values.byteLength;\n }\n\n getOpacity(source: number) {\n return this.values[this.blocks[Math.floor(source / this.blockSize)]];\n }\n\n setGroupOpacity(group: number, opacity: number) {\n const value = Math.fround(opacity);\n if (this.values[group] === value) return false;\n this.values[group] = value;\n this.valuesDirty = true;\n return true;\n }\n\n private releaseBlock(group: number) {\n if (group < 4) return;\n const range = this.ranges.get(group) as OpacityRange;\n if (--range.refs === 0) {\n this.ranges.delete(group);\n this.freeGroups.push(group);\n }\n }\n\n /** Validated ranges retain their group while only its coefficient changes. */\n setOpacity(start: number, count: number, opacity: number) {\n const first = Math.floor(start / this.blockSize);\n const last = Math.ceil((start + count) / this.blockSize);\n const previous = this.blocks[first];\n const range = this.ranges.get(previous);\n if (\n range?.first === first &&\n range.last === last &&\n range.refs === last - first\n )\n return this.setGroupOpacity(previous, opacity);\n\n const value = Math.fround(opacity);\n let block = first;\n while (block < last && this.values[this.blocks[block]] === value) block++;\n if (block === last) return false;\n const group = this.freeGroups.pop() ?? this.nextGroup++;\n if (group >= this.values.length) {\n const values = new Float32Array(this.values.length * 2);\n values.set(this.values);\n this.values = values;\n this.valueTexture.dispose();\n this.valueTexture = this.createValueTexture();\n }\n this.ranges.set(group, { first, last, refs: last - first });\n this.values[group] = value;\n this.valuesDirty = true;\n for (let index = first; index < last; index++) {\n this.releaseBlock(this.blocks[index]);\n this.blocks[index] = group;\n }\n this.dirtyLayers.fill(\n 1,\n Math.floor(first / this.blocksPerLayer),\n Math.ceil(last / this.blocksPerLayer),\n );\n this.dirty = true;\n return true;\n }\n\n copyBlocks() {\n return this.blocks.slice();\n }\n\n /** Adopt a prepared RAD table, retaining any uploads still pending. */\n commitBlocks(blocks: Uint32Array, dirtyLayers: Uint8Array) {\n this.blocks = blocks;\n this.blockTexture.image.data = blocks;\n for (let layer = 0; layer < dirtyLayers.length; layer++) {\n if (!dirtyLayers[layer]) continue;\n this.dirtyLayers[layer] = 1;\n this.dirty = true;\n }\n }\n\n get texture() {\n if (this.dirty) {\n for (let layer = 0; layer < this.dirtyLayers.length; layer++) {\n if (!this.dirtyLayers[layer]) continue;\n this.blockTexture.addLayerUpdate(layer);\n this.dirtyLayers[layer] = 0;\n }\n this.blockTexture.needsUpdate = true;\n this.dirty = false;\n }\n return this.blockTexture;\n }\n\n get opacityTexture() {\n if (this.valuesDirty) {\n this.valueTexture.needsUpdate = true;\n this.valuesDirty = false;\n }\n return this.valueTexture;\n }\n\n dispose() {\n this.blockTexture.dispose();\n this.valueTexture.dispose();\n this.blockTexture.image.data = new Uint32Array(0);\n this.valueTexture.image.data = new Uint32Array(0);\n this.blocks = new Uint32Array(0);\n this.values = new Float32Array(0);\n this.dirtyLayers = new Uint8Array(0);\n this.ranges.clear();\n this.freeGroups.length = 0;\n this.dirty = this.valuesDirty = false;\n }\n}\n","import * as THREE from \"three\";\nimport { SplatOpacityTable } from \"./SplatOpacityTable\";\nimport { Splats, type SplatsOptions } from \"./Splats\";\nimport {\n type ReorderedSplatResult,\n SPLAT_BOUNDS_BLOCK_SIZE,\n SPLAT_TEX_WIDTH,\n type SplatResult,\n} from \"./defines\";\nimport type { RaycastRangeCallback, SplatRaycastQuery } from \"./raycast\";\nimport { decodeShRgbToArray } from \"./splatCodec\";\nimport { SH_ARRAY_COUNTS, SH_KEYS } from \"./splatData\";\nimport { getTextureSize } from \"./textureLayout\";\nimport { decodeSplat } from \"./unpack\";\n\ntype IndexedSplatsOptions = {\n capacity: number;\n layerSize: number;\n numSh: number;\n blockBits: number;\n};\n\nfunction makeTexture(\n data: Uint32Array,\n width: number,\n height: number,\n depth: number,\n) {\n const texture = new THREE.DataArrayTexture(data, width, height, depth);\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n return texture;\n}\n\ntype DecodedSplat = ReturnType<typeof decodeSplat>;\ntype DecodedSplatWithSh = DecodedSplat & { sh: THREE.Color[] };\n\n/** Fixed packed storage with one visible-index contract for rendering and CPU reads.\n * Fades affect display only: records returned to picking retain their source opacity. */\nexport abstract class IndexedSplats extends Splats {\n readonly layerSize: number;\n readonly numSh: 0 | 1 | 2 | 3;\n protected readonly opacities: SplatOpacityTable;\n protected sourceIndices = new Uint32Array(0);\n protected visibleIndices: Uint32Array;\n private sourceArrays: Uint32Array[];\n private sourceCenters: Float32Array;\n private sourceTextures: THREE.DataArrayTexture[];\n private indexTexture = Splats.emptyTexture;\n private readonly blockBits: number;\n private disposed = false;\n private readonly spatialChunks = new Map<\n number,\n { count: number; bounds: Float32Array }\n >();\n private spatialBoundsBytes = 0;\n\n constructor({ capacity, layerSize, numSh, blockBits }: IndexedSplatsOptions) {\n // RAD and SOG layout helpers supply aligned power-of-two layers.\n if (capacity > 0x1_0000_0000)\n throw new Error(\"Indexed Splat capacity exceeds 32-bit addressing\");\n super();\n this.maxSplats = capacity;\n this.layerSize = layerSize;\n this.numSh = numSh as 0 | 1 | 2 | 3;\n this.blockBits = blockBits;\n this.opacities = new SplatOpacityTable(capacity, layerSize, blockBits);\n this.sourceArrays = Array.from(\n { length: 2 + SH_ARRAY_COUNTS[numSh] },\n () => new Uint32Array(capacity * 4),\n );\n this.sourceCenters = new Float32Array(this.sourceArrays[0].buffer);\n this.sourceIds = new Uint32Array(capacity);\n this.visibleIndices = new Uint32Array(capacity);\n this.sourceTextures = this.sourceArrays.map((array) =>\n makeTexture(\n array,\n SPLAT_TEX_WIDTH,\n layerSize / SPLAT_TEX_WIDTH,\n capacity / layerSize,\n ),\n );\n }\n\n protected assertLive() {\n if (this.disposed) throw new Error(\"Streaming Splat source is disposed\");\n }\n\n override initialize(options: SplatsOptions = {}) {\n // Splats calls initialize once during super(); fixed storage is installed next.\n if (this.sourceArrays !== undefined)\n throw new Error(\"Streaming sources cannot be reinitialized\");\n return super.initialize(options);\n }\n\n /** Range-based sources can materialize their visible map lazily. */\n protected ensureIndices() {}\n\n /** Each source updates its bounds independently of the visible-index map. */\n protected commitIndices(indices: Uint32Array) {\n const target = this.prepareIndices(indices.length);\n for (let index = 0; index < indices.length; index++) {\n const source = indices[index];\n target[index] = source;\n this.visibleIndices[source] = index;\n }\n }\n\n /** Reserve index storage and mark it for upload; fill the first count entries synchronously. */\n protected prepareIndices(count: number) {\n this.assertLive();\n if (\n count > this.sourceIndices.length ||\n count < this.sourceIndices.length / 4\n ) {\n const layout = getTextureSize(Math.max(1, Math.ceil(count / 4)), 1);\n const capacity = layout.maxSplats * 4;\n if (capacity !== this.sourceIndices.length) {\n if (this.indexTexture !== Splats.emptyTexture)\n this.indexTexture.dispose();\n this.sourceIndices = new Uint32Array(capacity);\n this.indexTexture = makeTexture(\n this.sourceIndices,\n layout.width,\n layout.height,\n layout.depth,\n );\n }\n }\n this.numSplats = count;\n if (this.indexTexture !== Splats.emptyTexture)\n this.indexTexture.needsUpdate = true;\n this.needsUpdate = true;\n return this.sourceIndices;\n }\n\n /** Copies packed records. Input buffers remain caller-owned for both formats. */\n protected writeRecords(\n start: number,\n data: ReorderedSplatResult,\n allocation: number,\n ) {\n this.assertLive();\n const count = data.numSplats;\n if (\n !Number.isSafeInteger(start) ||\n start < 0 ||\n !Number.isSafeInteger(count) ||\n count < 0 ||\n !Number.isSafeInteger(allocation) ||\n allocation < count ||\n start + allocation > this.maxSplats\n )\n throw new Error(\"Invalid streaming Splat write range\");\n const arrays = [\n ...data.splatArrays,\n ...SH_KEYS.slice(0, SH_ARRAY_COUNTS[this.numSh]).map(\n (key) => data.extra[key],\n ),\n ];\n if (\n arrays.length !== this.sourceArrays.length ||\n data.sourceIds.length < count ||\n arrays.some(\n (array) =>\n count > 0 &&\n (!(array instanceof Uint32Array) || array.length < count * 4),\n )\n )\n throw new Error(\"Incomplete packed Splat or SH records\");\n if (\n data.spatialBounds?.length !==\n Math.ceil(count / SPLAT_BOUNDS_BLOCK_SIZE) * 6\n )\n throw new Error(\"Incorrect spatial bounds block length\");\n this.releaseSpatialBounds(start);\n // Packed data remains caller-owned, as do its spatial bounds.\n const bounds = data.spatialBounds.slice();\n this.spatialChunks.set(start, { count, bounds });\n this.spatialBoundsBytes += bounds.byteLength;\n this.sourceIds.set(data.sourceIds.subarray(0, count), start);\n this.sourceIds.fill(0, start + count, start + allocation);\n const firstLayer = Math.floor(start / this.layerSize);\n const lastLayer = Math.ceil((start + allocation) / this.layerSize);\n for (let index = 0; index < this.sourceArrays.length; index++) {\n const target = this.sourceArrays[index];\n const source = arrays[index];\n if (source) target.set(source.subarray(0, count * 4), start * 4);\n target.fill(0, (start + count) * 4, (start + allocation) * 4);\n for (let layer = firstLayer; layer < lastLayer; layer++)\n this.sourceTextures[index].addLayerUpdate(layer);\n this.sourceTextures[index].needsUpdate = true;\n }\n this.needsUpdate = true;\n }\n\n private getStorageIndex(index: number) {\n this.assertLive();\n this.ensureIndices();\n this.checkVisibleRange(index, 1);\n return this.sourceIndices[index];\n }\n\n override getSourceIndex(index: number) {\n return this.sourceIds[this.getStorageIndex(index)];\n }\n\n private checkVisibleRange(start: number, count: number) {\n if (\n !Number.isSafeInteger(start) ||\n start < 0 ||\n !Number.isSafeInteger(count) ||\n count < 0 ||\n start + count > this.numSplats\n )\n throw new Error(\"Invalid visible Splat range\");\n }\n\n override getNumSh() {\n return this.numSh;\n }\n\n private get textureByteLength() {\n return (\n this.sourceArrays.reduce((bytes, array) => bytes + array.byteLength, 0) +\n this.sourceIndices.byteLength +\n this.opacities.byteLength\n );\n }\n\n override getByteLength() {\n return (\n this.textureByteLength +\n this.sourceIds.byteLength +\n this.centerOnlyBounds.byteLength +\n this.bounds.byteLength +\n this.spatialBoundsBytes +\n this.visibleIndices.byteLength\n );\n }\n\n get residentBytes() {\n return this.getByteLength() + this.textureByteLength;\n }\n\n private center(source: number, axis: number) {\n const second = this.sourceArrays[1];\n const base = source * 4;\n return second[base + 1] >>> 16 === 0xfc00 && second[base + 2] === 0xfc00fc00\n ? Number.NaN\n : this.sourceCenters[base + axis];\n }\n\n override copySortCenters(\n target: Float32Array,\n targetStart: number,\n count: number,\n ) {\n this.assertLive();\n this.ensureIndices();\n this.checkVisibleRange(0, count);\n if (\n !Number.isSafeInteger(targetStart) ||\n targetStart < 0 ||\n targetStart + count * 3 > target.length\n )\n throw new Error(\"Invalid sort center target range\");\n for (let index = 0; index < count; index++)\n for (let axis = 0; axis < 3; axis++)\n target[targetStart + index * 3 + axis] = this.center(\n this.sourceIndices[index],\n axis,\n );\n }\n\n protected releaseSpatialBounds(start: number) {\n const chunk = this.spatialChunks.get(start);\n if (chunk) {\n this.spatialBoundsBytes -= chunk.bounds.byteLength;\n this.spatialChunks.delete(start);\n }\n }\n\n override forEachRaycastRange(\n query: SplatRaycastQuery,\n callback: RaycastRangeCallback,\n ) {\n this.assertLive();\n this.ensureIndices();\n let rangeStart = -1;\n let rangeEnd = -1;\n for (const [start, { count, bounds }] of this.spatialChunks) {\n query.forEachRange(bounds, count, (base, length) => {\n for (\n let source = start + base;\n source < start + base + length;\n source++\n ) {\n const index = this.visibleIndices[source];\n // Validate against the current cut so hidden slots need no clearing.\n if (index >= this.numSplats || this.sourceIndices[index] !== source)\n continue;\n if (index !== rangeEnd) {\n if (rangeStart >= 0) callback(rangeStart, rangeEnd - rangeStart);\n rangeStart = index;\n }\n rangeEnd = index + 1;\n }\n });\n }\n if (rangeStart >= 0) callback(rangeStart, rangeEnd - rangeStart);\n }\n\n override copySplatRecords(\n firstTarget: Uint32Array,\n secondTarget: Uint32Array,\n sourceStart: number,\n count: number,\n ) {\n this.assertLive();\n this.ensureIndices();\n this.checkVisibleRange(sourceStart, count);\n if (firstTarget.length < count * 4 || secondTarget.length < count * 4)\n throw new Error(\"Splat record target is too small\");\n for (let index = 0; index < count; index++) {\n const source = this.sourceIndices[sourceStart + index] * 4;\n for (let word = 0; word < 4; word++) {\n firstTarget[index * 4 + word] = this.sourceArrays[0][source + word];\n secondTarget[index * 4 + word] = this.sourceArrays[1][source + word];\n }\n }\n }\n\n override getSplat(index: number): DecodedSplatWithSh;\n override getSplat(index: number, includeSh: true): DecodedSplatWithSh;\n override getSplat(index: number, includeSh: false): DecodedSplat;\n override getSplat(index: number, includeSh: boolean): DecodedSplat;\n override getSplat(index: number, includeSh = true) {\n const source = this.getStorageIndex(index);\n const splat = decodeSplat(\n [this.sourceArrays[0], this.sourceArrays[1]],\n source,\n );\n if (!includeSh) return splat;\n const rgb = [0, 0, 0];\n const sh = Array.from(\n { length: [0, 3, 8, 15][this.numSh] },\n (_, coefficient) => {\n const word =\n this.sourceArrays[2 + (coefficient >> 2)][\n source * 4 + (coefficient & 3)\n ];\n decodeShRgbToArray(word, rgb);\n return new THREE.Color(rgb[0], rgb[1], rgb[2]);\n },\n );\n return { ...splat, sh };\n }\n\n override forEachCenter(\n callback: (index: number, x: number, y: number, z: number) => void,\n ) {\n this.assertLive();\n this.ensureIndices();\n for (let index = 0; index < this.numSplats; index++) {\n const source = this.sourceIndices[index];\n callback(\n index,\n this.center(source, 0),\n this.center(source, 1),\n this.center(source, 2),\n );\n }\n }\n\n override forEachSplat(callback: Parameters<Splats[\"forEachSplat\"]>[0]) {\n this.assertLive();\n this.ensureIndices();\n let splat: ReturnType<typeof decodeSplat> | undefined;\n const records: [Uint32Array, Uint32Array] = [\n this.sourceArrays[0],\n this.sourceArrays[1],\n ];\n for (let index = 0; index < this.numSplats; index++) {\n splat = decodeSplat(records, this.sourceIndices[index], splat);\n callback(\n index,\n splat.center,\n splat.scales,\n splat.quaternion,\n splat.opacity,\n splat.color,\n );\n }\n }\n\n override takeData(): SplatResult & { sourceIds: Uint32Array } {\n this.assertLive();\n this.ensureIndices();\n const count = this.numSplats;\n const sourceIds = new Uint32Array(count);\n for (let i = 0; i < count; i++)\n sourceIds[i] = this.sourceIds[this.sourceIndices[i]];\n const arrays = this.sourceArrays.map((source) => {\n const target = new Uint32Array(count * 4);\n for (let index = 0; index < count; index++) {\n const offset = this.sourceIndices[index] * 4;\n for (let word = 0; word < 4; word++)\n target[index * 4 + word] = source[offset + word];\n }\n return target;\n });\n const data = {\n numSplats: count,\n splatArrays: [arrays[0], arrays[1]],\n sourceIds,\n extra: Object.fromEntries(\n arrays.slice(2).map((array, index) => [SH_KEYS[index], array]),\n ),\n } satisfies SplatResult;\n this.dispose();\n return data;\n }\n\n override setTextureUniforms(uniforms: Record<string, THREE.IUniform>) {\n this.assertLive();\n this.ensureIndices();\n uniforms.sourceSplats.value = this.sourceTextures[0];\n uniforms.sourceSplats2.value = this.sourceTextures[1];\n uniforms.sh1Texture.value = this.sourceTextures[2] ?? Splats.emptyTexture;\n uniforms.sh2Texture.value = this.sourceTextures[3] ?? Splats.emptyTexture;\n uniforms.sh3TextureA.value = this.sourceTextures[4] ?? Splats.emptyTexture;\n uniforms.sh3TextureB.value = this.sourceTextures[5] ?? Splats.emptyTexture;\n uniforms.sourceLayerBits.value = Math.log2(this.layerSize);\n uniforms.sourceLayerMask.value = this.layerSize - 1;\n uniforms.sourceBlockBits.value = this.blockBits;\n uniforms.sourceBlocks.value = this.opacities.texture;\n uniforms.sourceOpacities.value = this.opacities.opacityTexture;\n uniforms.sourceIndexed.value = true;\n uniforms.sourceIndices.value = this.indexTexture;\n this.needsUpdate = false;\n }\n\n override dispose() {\n if (this.disposed) return;\n super.dispose();\n for (const texture of this.sourceTextures) texture.dispose();\n if (this.indexTexture !== Splats.emptyTexture) this.indexTexture.dispose();\n this.opacities.dispose();\n this.sourceArrays = [];\n this.sourceTextures = [];\n this.sourceCenters = new Float32Array(0);\n this.sourceIndices = new Uint32Array(0);\n this.visibleIndices = new Uint32Array(0);\n this.indexTexture = Splats.emptyTexture;\n this.spatialChunks.clear();\n this.spatialBoundsBytes = 0;\n this.disposed = true;\n }\n}\n","import { IndexedSplats } from \"./IndexedSplats\";\nimport {\n type ReorderedSplatResult,\n SPLAT_TEX_HEIGHT,\n SPLAT_TEX_WIDTH,\n} from \"./defines\";\nimport { resetSplatBounds } from \"./splatData\";\n\nexport type RadPagedSplatsOptions = {\n /** Maximum records in one decoded chunk. Defaults to Spark's 65,536. */\n pageSize?: number;\n pageCount: number;\n numSh: number;\n /** Pass the device limit when known. WebGL2 guarantees at least 256. */\n maxArrayLayers?: number;\n};\n\n/** Page ranges in a sorted, file-global cut; used only by RAD streaming. */\nexport type RadSelectionRange = {\n start: number;\n end: number;\n slot: number;\n pageStart: number;\n chunkIndex: number;\n sourceBase: number;\n};\n\nexport type RadSelectionSnapshot = {\n pageCount: number;\n opacityBlocks: Uint32Array;\n ranges: RadSelectionRange[];\n};\n\ntype RadPreparedCut = {\n indices: Uint32Array;\n selectedPages: Uint32Array;\n centerOnlyBoundingBox: Float32Array;\n boundingBox: Float32Array;\n};\n\nexport type RadPreparedSelection = RadPreparedCut & {\n opacityBlocks: Uint32Array;\n dirtyLayers: Uint8Array;\n fadeKinds: number;\n final?: RadPreparedCut;\n};\n\nconst EMPTY_INDICES = new Uint32Array(0);\n\n/** One power-of-two texture layer per page, with no shared upload layers. */\nexport function radPageTextureLayout({\n pageSize = 65_536,\n pageCount,\n maxArrayLayers = 256,\n}: Omit<RadPagedSplatsOptions, \"numSh\">) {\n if (\n !Number.isSafeInteger(pageSize) ||\n pageSize < 1 ||\n pageSize > SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT\n )\n throw new Error(\"RAD pageSize must be between 1 and 4,194,304\");\n if (\n !Number.isSafeInteger(maxArrayLayers) ||\n maxArrayLayers < 1 ||\n !Number.isSafeInteger(pageCount) ||\n pageCount < 1 ||\n pageCount > maxArrayLayers\n )\n throw new Error(\"RAD pageCount exceeds the texture array layer limit\");\n const pageStride =\n 2 ** Math.ceil(Math.log2(Math.max(SPLAT_TEX_WIDTH, pageSize)));\n const capacity = pageStride * pageCount;\n if (capacity > 0x1_0000_0000)\n throw new Error(\"RAD page pool exceeds the 32-bit source index limit\");\n return {\n pageSize,\n pageStride,\n pageCount,\n capacity,\n width: SPLAT_TEX_WIDTH,\n height: pageStride / SPLAT_TEX_WIDTH,\n depth: pageCount,\n };\n}\n\n/** Fixed RAD page slots; shared IndexedSplats owns rendering and CPU access. */\nexport class RadPagedSplats extends IndexedSplats {\n readonly pageSize: number;\n readonly pageStride: number;\n readonly pageCount: number;\n private selectedPages: Uint32Array;\n private finalSelection?: RadPreparedCut;\n private fadeProgress = 1;\n private fadeKinds = 0;\n\n constructor(options: RadPagedSplatsOptions) {\n const layout = radPageTextureLayout(options);\n super({\n capacity: layout.capacity,\n layerSize: layout.pageStride,\n numSh: options.numSh,\n blockBits: 0,\n });\n this.pageSize = layout.pageSize;\n this.pageStride = layout.pageStride;\n this.pageCount = layout.pageCount;\n this.selectedPages = new Uint32Array(this.pageCount);\n }\n\n pageStart(slot: number) {\n return slot * this.pageStride;\n }\n\n /** Copies data; callers retain ownership of the packed buffers. */\n writePage(slot: number, data: ReorderedSplatResult) {\n const start = this.pageStart(slot);\n if (data.numSplats > this.pageSize)\n throw new Error(\"RAD chunk does not fit its page slot\");\n this.writeRecords(start, data, this.pageStride);\n }\n\n /** Remove the displayed cut when its scheduler becomes hidden. */\n clearSelection() {\n this.assertLive();\n if (!this.numSplats) return false;\n this.commitIndices(EMPTY_INDICES);\n this.selectedPages.fill(0);\n resetSplatBounds(this.centerOnlyBounds);\n resetSplatBounds(this.bounds);\n this.finalSelection = undefined;\n this.fadeKinds = 0;\n this.fadeProgress = 1;\n this.opacities.setGroupOpacity(2, 1);\n this.opacities.setGroupOpacity(3, 1);\n return true;\n }\n\n /** Snapshot only changed pools; never transfer live texture storage. */\n snapshotSelection(ranges: RadSelectionRange[]): RadSelectionSnapshot {\n this.assertLive();\n return {\n pageCount: this.pageCount,\n opacityBlocks: this.opacities.copyBlocks(),\n ranges,\n };\n }\n\n /** Internal commit of worker-prepared data; the caller gives up the arrays. */\n commitSelection(prepared: RadPreparedSelection) {\n this.commitCut(prepared);\n this.finalSelection = prepared.final;\n this.fadeKinds = prepared.fadeKinds;\n this.fadeProgress = this.fadeKinds ? 0 : 1;\n this.opacities.setGroupOpacity(2, this.fadeKinds ? 0 : 1);\n this.opacities.setGroupOpacity(3, 1);\n this.opacities.commitBlocks(prepared.opacityBlocks, prepared.dirtyLayers);\n }\n\n /** Keep record indices, page occupancy and bounds on the same cut. */\n private commitCut(cut: RadPreparedCut) {\n this.commitIndices(cut.indices);\n this.selectedPages = cut.selectedPages;\n this.centerOnlyBounds = cut.centerOnlyBoundingBox;\n this.bounds = cut.boundingBox;\n }\n\n /** A normal streaming fade changes only two group coefficients. */\n setFadeProgress(progress: number) {\n this.assertLive();\n if (progress === this.fadeProgress) return false;\n this.fadeProgress = progress;\n if (!this.fadeKinds) return false;\n const fadeIn = this.opacities.setGroupOpacity(2, progress);\n const fadeOut = this.opacities.setGroupOpacity(3, 1 - progress);\n return (\n (!!(this.fadeKinds & 1) && fadeIn) || (!!(this.fadeKinds & 2) && fadeOut)\n );\n }\n\n isPageSelected(slot: number) {\n return this.selectedPages[slot] > 0;\n }\n\n /** Complete opacity changes without removing outgoing records. */\n finishFadeIn() {\n const changed = this.setFadeProgress(1);\n this.finalSelection = undefined;\n this.fadeKinds = 0;\n return changed;\n }\n\n /** The worker already removed outgoing records from the final cut. */\n finishFade() {\n if (!this.finalSelection) return this.finishFadeIn();\n this.commitCut(this.finalSelection);\n this.finishFadeIn();\n return true;\n }\n\n override getByteLength() {\n return (\n super.getByteLength() +\n (this.finalSelection?.indices.byteLength ?? 0) +\n (this.finalSelection?.selectedPages.byteLength ?? 0) +\n (this.finalSelection?.centerOnlyBoundingBox.byteLength ?? 0) +\n (this.finalSelection?.boundingBox.byteLength ?? 0) +\n this.selectedPages.byteLength\n );\n }\n\n override dispose() {\n super.dispose();\n this.selectedPages = new Uint32Array(0);\n this.finalSelection = undefined;\n }\n}\n","/** Exponential backoff for temporary streaming failures. */\nexport function retryDelay(failures: number) {\n return Math.min(30_000, 1000 * 2 ** failures);\n}\n\n/** Wake on-demand render loops at the next retry, without polling idle scenes. */\nexport class RetryTimer {\n private timer?: ReturnType<typeof setTimeout>;\n private deadline = Number.POSITIVE_INFINITY;\n\n constructor(private readonly wake: () => void) {}\n\n update(deadlines: Iterable<number>) {\n const now = performance.now();\n let next = Number.POSITIVE_INFINITY;\n for (const at of deadlines) if (at > now) next = Math.min(next, at);\n if (next === this.deadline) return;\n this.dispose();\n this.deadline = next;\n if (Number.isFinite(next))\n this.timer = setTimeout(() => {\n this.dispose();\n this.wake();\n }, next - now);\n }\n\n dispose() {\n clearTimeout(this.timer);\n this.timer = undefined;\n this.deadline = Number.POSITIVE_INFINITY;\n }\n}\n","import type { ReorderedSplatResult, SplatResult } from \"../../data/defines\";\nimport type { PostDecodeSplatData } from \"../postDecode/protocol\";\n\nexport type RadChunkRange = {\n offset: number;\n bytes: number;\n base?: number;\n count?: number;\n filename?: string;\n};\n\n/** Spark RAD version 1 directory. Child references use file-global indices. */\nexport type RadMeta = {\n version: number;\n type: \"gsplat\";\n count: number;\n maxSh?: number;\n lodTree?: boolean;\n chunkSize?: number;\n allChunkBytes: number;\n chunks: RadChunkRange[];\n shCodeCount?: number;\n splatEncoding?: Record<string, unknown>;\n comment?: string;\n};\n\nexport type RadHeader = { meta: RadMeta; chunksStart: number };\n\nexport type RadChunkData = SplatResult & {\n base: number;\n childStart?: Uint32Array;\n childCount?: Uint16Array;\n lodRadii?: Float32Array;\n};\n\n/** Render records for streaming; tree arrays are transferred to the LOD worker. */\nexport type RadStreamChunk = Omit<ReorderedSplatResult, \"sortCenters\"> & {\n /** Root-page radius used when its initial bounds collapse to one point. */\n rootRadius?: number;\n};\n\nexport type RadDecodedChunk = PostDecodeSplatData & {\n base: number;\n childStart?: Uint32Array;\n childCount?: Uint16Array;\n lodRadii?: Float32Array;\n};\n\nexport function unpackRadChunk(decoded: RadDecodedChunk): RadChunkData {\n return {\n base: decoded.base,\n numSplats: decoded.numSplats,\n splatArrays: [decoded.splat0, decoded.splat1],\n sortCenters: decoded.sortCenters,\n extra: {\n sh1: decoded.sh1,\n sh2: decoded.sh2,\n sh3a: decoded.sh3a,\n sh3b: decoded.sh3b,\n },\n childStart: decoded.childStart,\n childCount: decoded.childCount,\n lodRadii: decoded.lodRadii,\n };\n}\n\n/** Without chunkSize, Spark treats the dataset as one chunk. */\nexport function getRadChunkSpan(meta: RadMeta, index: number) {\n const chunk = meta.chunks[index];\n const base = chunk.base ?? index * (meta.chunkSize ?? meta.count);\n const count =\n chunk.count ?? Math.min(meta.chunkSize ?? meta.count, meta.count - base);\n return { base, count };\n}\n\nexport function isRadPrefix(bytes: Uint8Array) {\n return (\n bytes[0] === 0x52 &&\n bytes[1] === 0x41 &&\n bytes[2] === 0x44 &&\n bytes[3] === 0x30\n );\n}\n\nexport function getRadHeaderSize(prefix: Uint8Array) {\n if (!isRadPrefix(prefix)) throw new Error(\"RAD: missing RAD0 magic\");\n const jsonLength = new DataView(\n prefix.buffer,\n prefix.byteOffset,\n prefix.byteLength,\n ).getUint32(4, true);\n return { jsonLength, headerLength: 8 + Math.ceil(jsonLength / 8) * 8 };\n}\n\n/** Validate the header as soon as a full-response fallback supplies it. */\nexport function collectRadHeader(complete: (bytes: Uint8Array) => void) {\n let header = new Uint8Array(8);\n let received = 0;\n let done = false;\n return (bytes: Uint8Array) => {\n if (done) return;\n let offset = 0;\n if (received < 8) {\n const count = Math.min(bytes.length, 8 - received);\n header.set(bytes.subarray(0, count), received);\n received += count;\n offset += count;\n }\n if (received === 8 && header.length === 8) {\n const expanded = new Uint8Array(getRadHeaderSize(header).headerLength);\n expanded.set(header);\n header = expanded;\n }\n if (received >= 8) {\n const count = Math.min(bytes.length - offset, header.length - received);\n header.set(bytes.subarray(offset, offset + count), received);\n received += count;\n if (received === header.length) {\n done = true;\n complete(header);\n }\n }\n };\n}\n","/** Bound pending copies while allowing one oversized item to make progress. */\nexport class StreamByteBudget {\n constructor(\n readonly limit: number,\n public used = 0,\n ) {}\n\n reserve(bytes: number) {\n if (bytes === 0) return true;\n if (this.used > 0 && this.used + bytes > this.limit) return false;\n this.used += bytes;\n return true;\n }\n}\n","import * as THREE from \"three\";\n\n/** A renderer whose size, in CSS pixels, sets a camera's resolution. */\nexport type StreamResolutionSource = {\n getSize(target: THREE.Vector2): THREE.Vector2;\n};\n\nconst size = new THREE.Vector2();\nconst identity = new THREE.Matrix4();\n\n/**\n * Bring a registered camera's world matrices up to date and report whether it\n * can select detail. WebXR uses the eye matrices supplied by Three, preserving\n * their rig transforms. Wait until the eyes have a projection and viewport.\n */\nfunction prepareStreamCamera(camera: THREE.Camera) {\n const array = camera as THREE.ArrayCamera;\n if (array.isArrayCamera) {\n return (\n array.cameras.length > 0 &&\n array.cameras.every(\n (eye) =>\n (eye.viewport?.z ?? 0) > 0 &&\n (eye.viewport?.w ?? 0) > 0 &&\n !eye.projectionMatrix.equals(identity) &&\n !(eye.matrixWorld.equals(identity) && !eye.matrix.equals(identity)),\n )\n );\n }\n camera.updateWorldMatrix(true, false);\n return true;\n}\n\n/** Capture actual eye poses; the ArrayCamera rig can be unset on its first frame. */\nexport function streamViews(cameras: readonly THREE.Camera[]) {\n const views: THREE.Camera[] = [];\n for (const camera of cameras) {\n if (!prepareStreamCamera(camera)) continue;\n const array = camera as THREE.ArrayCamera;\n if (array.isArrayCamera) views.push(...array.cameras);\n else views.push(camera);\n }\n return views;\n}\n\n/** Cameras that select a streamed model's detail, with their resolutions. */\nexport class StreamCameras {\n // Keys keep registration order.\n private readonly resolutions = new Map<THREE.Camera, THREE.Vector2>();\n\n /** Registered cameras, in registration order. */\n get cameras() {\n return [...this.resolutions.keys()];\n }\n\n has(camera: THREE.Camera) {\n return this.resolutions.has(camera);\n }\n\n add(camera: THREE.Camera) {\n if (this.resolutions.has(camera)) return false;\n this.resolutions.set(camera, new THREE.Vector2());\n return true;\n }\n\n delete(camera: THREE.Camera) {\n return this.resolutions.delete(camera);\n }\n\n setResolution(\n camera: THREE.Camera,\n xOrVec: number | THREE.Vector2,\n y?: number,\n ) {\n const resolution = this.resolutions.get(camera);\n if (!resolution) return false;\n const width = typeof xOrVec === \"number\" ? xOrVec : xOrVec.x;\n const height = typeof xOrVec === \"number\" ? (y ?? Number.NaN) : xOrVec.y;\n if (!(width > 0 && height > 0) || !Number.isFinite(width + height))\n throw new Error(\"Camera resolution must be positive and finite\");\n resolution.set(width, height);\n return true;\n }\n\n setResolutionFromRenderer(\n camera: THREE.Camera,\n renderer: StreamResolutionSource,\n ) {\n return this.setResolution(camera, renderer.getSize(size));\n }\n\n /** The camera's resolution, or undefined until one is set. */\n getResolution(camera: THREE.Camera) {\n const resolution = this.resolutions.get(camera);\n return resolution && resolution.x > 0 ? resolution : undefined;\n }\n\n /**\n * Registered cameras that see `layers`. Throws when none are registered,\n * since nothing could select detail.\n */\n seeing(layers: THREE.Layers) {\n if (!this.resolutions.size)\n throw new Error(\"Register a camera with setCamera() before update()\");\n const cameras: THREE.Camera[] = [];\n for (const camera of this.resolutions.keys())\n if (camera.layers.test(layers)) cameras.push(camera);\n return cameras;\n }\n}\n","import type { Group, LoadingManager } from \"three\";\nimport { retryDelay } from \"../../runtime/retry\";\nimport type { SplatRequestOptions } from \"../loadTypes\";\n\nexport type StreamRequestOptions = SplatRequestOptions & {\n manager?: LoadingManager;\n};\n\nexport type StreamSchedulerOptions = {\n group?: Group;\n /** Initial Splat budget; update scheduler.splatBudget to change it at runtime. */\n splatBudget?: number;\n /** Milliseconds to retain unused data after fade-out; defaults to 2000. */\n cooldownMs?: number;\n fadeDurationMs?: number;\n /** Active downloads/decodes. Ready copies use a separate bounded byte queue. */\n maxConcurrentLoads?: number;\n onChange?: () => void;\n onError?: (error: unknown, url: string) => void;\n};\n\nexport type StreamStats = {\n visibleSplats: number;\n visibleMeshes: number;\n residentMeshes: number;\n /** Decoded chunks, including cached chunks that are not currently drawn. */\n residentChunks: number;\n /** Retained CPU and estimated GPU bytes, excluding pending copies and WASM. */\n residentBytes: number;\n /** Reserved or ready copies awaiting publication into source storage. */\n pendingBytes: number;\n loadingChunks: number;\n downloadedBytes: number;\n peakWasmMemoryBytes: number;\n};\n\nexport function positiveInteger(value: number, name: string) {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new Error(`${name} must be a positive safe integer`);\n return value;\n}\n\nexport function streamSettings(options: StreamSchedulerOptions) {\n const splatBudget = positiveInteger(\n options.splatBudget ?? 3_000_000,\n \"splatBudget\",\n );\n const cooldownMs = options.cooldownMs ?? 2000;\n if (!Number.isFinite(cooldownMs) || cooldownMs < 0)\n throw new Error(\"cooldownMs must be finite and nonnegative\");\n const fadeDurationMs = options.fadeDurationMs ?? 200;\n if (!Number.isFinite(fadeDurationMs) || fadeDurationMs < 0)\n throw new Error(\"fadeDurationMs must be finite and nonnegative\");\n const maxConcurrentLoads = positiveInteger(\n options.maxConcurrentLoads ?? 4,\n \"maxConcurrentLoads\",\n );\n return {\n splatBudget,\n cooldownMs,\n fadeDurationMs,\n maxConcurrentLoads,\n };\n}\n\n/** Bound queued decode/extraction copies independently of per-update publication. */\nexport function streamPendingLimit(concurrency: number, unitBytes = 0) {\n const pendingBytesPerLoad = 8 * 1024 * 1024;\n return concurrency * Math.max(pendingBytesPerLoad, unitBytes);\n}\n\n/** Format errors are permanent; transient failures retry with capped backoff. */\nexport function streamRetryAt(error: unknown, failures: number) {\n const failure = error as { fatal?: boolean } | undefined;\n if (failure?.fatal) return Number.POSITIVE_INFINITY;\n const message = error instanceof Error ? error.message : String(error);\n const status = /\\bHTTP (\\d{3})\\b/.exec(message)?.[1];\n const retryable = status\n ? [408, 425, 429].includes(Number(status)) || Number(status) >= 500\n : error instanceof TypeError ||\n (error instanceof Error && error.name === \"NetworkError\");\n const workerLost =\n error instanceof Error && error.name === \"WorkerTerminatedError\";\n return retryable || workerLost\n ? performance.now() + retryDelay(failures)\n : Number.POSITIVE_INFINITY;\n}\n\nexport function notifyStreamChange(options: StreamSchedulerOptions) {\n try {\n options.onChange?.();\n } catch (error) {\n console.error(\"Stream onChange failed\", error);\n }\n}\n\nexport function notifyStreamError(\n options: StreamSchedulerOptions,\n error: unknown,\n url: string,\n) {\n try {\n if (options.onError) options.onError(error, url);\n else console.error(\"Streaming load failed\", url, error);\n } catch (callbackError) {\n console.error(\"Stream onError failed\", callbackError);\n }\n}\n","import {\n RadPagedSplats,\n type RadPagedSplatsOptions,\n type RadPreparedSelection,\n} from \"../../../data/RadPagedSplats\";\nimport { SplatMesh } from \"../../../scene/SplatMesh\";\n\n/** A fixed pool of RAD pages sharing one scene node and accumulator call. */\nexport class RadStreamBatch extends SplatMesh {\n readonly source: RadPagedSplats;\n\n constructor(options: RadPagedSplatsOptions) {\n const source = new RadPagedSplats(options);\n super({ splats: source });\n this.source = source;\n this.name = \"rad-batch\";\n this.maxSh = source.numSh;\n }\n\n clearSelection() {\n if (!this.source.clearSelection()) return false;\n this.numSplats = 0;\n this.updateMappingVersion();\n return true;\n }\n\n setFadeProgress(progress: number) {\n if (!this.source.setFadeProgress(progress)) return false;\n this.updateVersion({ sort: false });\n return true;\n }\n\n commitSelection(prepared: RadPreparedSelection) {\n this.source.commitSelection(prepared);\n this.numSplats = this.source.getNumSplats();\n this.updateMappingVersion();\n }\n\n finishFade() {\n if (!this.source.finishFade()) return false;\n if (this.numSplats !== this.source.getNumSplats()) {\n this.numSplats = this.source.getNumSplats();\n this.updateMappingVersion();\n } else this.updateVersion({ sort: false });\n return true;\n }\n\n override dispose() {\n this.removeFromParent();\n super.dispose();\n this.numSplats = 0;\n }\n}\n","import { abortable } from \"../runtime/abort\";\nimport type { SplatRequestOptions } from \"./loadTypes\";\n\nexport type ByteSource = {\n size: number;\n url?: string;\n read(offset: number, length: number, retain?: boolean): Promise<Uint8Array>;\n};\n\nexport function checkRange(offset: number, length: number, size?: number) {\n if (\n !Number.isSafeInteger(offset) ||\n !Number.isSafeInteger(length) ||\n !Number.isSafeInteger(offset + length) ||\n offset < 0 ||\n length < 0 ||\n (size !== undefined && offset + length > size)\n )\n throw new Error(\"Source byte range is out of bounds\");\n}\n\nexport function joinBytes(chunks: Uint8Array[], length: number) {\n if (chunks.length === 1) return chunks[0];\n const bytes = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n}\n\nexport async function collectBytes(\n read: () => Promise<Uint8Array | undefined>,\n maxBytes: number,\n progress: (bytes: number) => void,\n signal?: AbortSignal,\n validateChunk?: (chunk: Uint8Array, size: number) => void,\n) {\n const chunks: Uint8Array[] = [];\n let size = 0;\n for (;;) {\n signal?.throwIfAborted();\n const bytes = await abortable(read(), signal);\n if (bytes === undefined) break;\n size += bytes.byteLength;\n if (size > maxBytes)\n throw new Error(\"Source response exceeds its byte limit\");\n validateChunk?.(bytes, size);\n if (bytes.byteLength) chunks.push(bytes);\n progress(bytes.byteLength);\n }\n return { chunks, size };\n}\n\nexport async function readResponse(\n response: Response,\n maxBytes: number,\n progress: (bytes: number) => void,\n signal?: AbortSignal,\n validateChunk?: (chunk: Uint8Array, size: number) => void,\n) {\n const reader = response.body?.getReader();\n try {\n if (!response.ok)\n throw new Error(`HTTP ${response.status} loading ${response.url}`);\n const announced = Number(response.headers.get(\"Content-Length\"));\n if (Number.isFinite(announced) && announced > maxBytes)\n throw new Error(\"Source response exceeds its byte limit\");\n return await collectBytes(\n async () => {\n const chunk = await reader?.read();\n return chunk?.done ? undefined : chunk?.value;\n },\n maxBytes,\n progress,\n signal,\n validateChunk,\n );\n } catch (error) {\n await reader?.cancel(error).catch(() => {});\n throw error;\n } finally {\n reader?.releaseLock();\n }\n}\n\n/** Each reader owns its Range header. Credentials only follow the original origin. */\nexport function requestOptions(\n args: SplatRequestOptions,\n url: string,\n base?: string,\n): RequestInit & { headers: Headers } {\n const sameOrigin = !base || new URL(url).origin === new URL(base).origin;\n const headers = new Headers(sameOrigin ? args.requestHeader : undefined);\n headers.delete(\"Range\");\n headers.delete(\"If-Range\");\n return {\n headers,\n credentials: sameOrigin && args.withCredentials ? \"include\" : \"same-origin\",\n };\n}\n\n/** Bounded ordered prefetch: consume in decoder order while later reads overlap. */\nexport async function* prefetchOrdered<T>(\n count: number,\n concurrency: number,\n read: (index: number) => Promise<T>,\n signal?: AbortSignal,\n) {\n signal?.throwIfAborted();\n const pending = new Map<number, Promise<T>>();\n let next = 0;\n const fill = () => {\n while (next < count && pending.size < concurrency) {\n const index = next++;\n const task = Promise.resolve().then(() => read(index));\n void task.catch(() => {});\n pending.set(index, task);\n }\n };\n fill();\n try {\n for (let index = 0; index < count; index++) {\n signal?.throwIfAborted();\n const value = await abortable(pending.get(index) as Promise<T>, signal);\n pending.delete(index);\n fill();\n yield value;\n }\n } finally {\n pending.clear();\n }\n}\n","import type { LoadingManager } from \"three\";\nimport { abortable, linkedAbortController } from \"../../runtime/abort\";\nimport { getAssetBaseUrl } from \"../assetUrl\";\nimport type {\n SplatFileInput,\n SplatFileResolver,\n SplatRequestOptions,\n} from \"../loadTypes\";\nimport { checkRange, joinBytes, readResponse, requestOptions } from \"../source\";\nimport {\n type RadHeader,\n collectRadHeader,\n getRadHeaderSize,\n} from \"./radFormat\";\n\nexport type RadSourceOptions = SplatRequestOptions & {\n url?: string;\n file?: Blob;\n fileBytes?: Uint8Array | ArrayBuffer;\n baseUrl?: string;\n manager?: LoadingManager;\n resolveFile?: SplatFileResolver;\n /** Internal bridge for LoadingManager URL modifiers in a decode worker. */\n resolveAsset?: (url: string) => Promise<string>;\n onProgress?: (downloadedBytes: number) => void;\n /** Validate ordinary metadata as soon as the full-response header arrives. */\n validateHeader?: (bytes: Uint8Array) => void;\n};\n\ntype Remote = {\n url: string;\n resolved?: string;\n responseUrl?: string;\n total?: number;\n validator?: string;\n validatorHeader?: \"ETag\" | \"Last-Modified\";\n full?: Blob;\n};\n\n/** Small response snapshot shared across a dataset's download workers. */\nexport type RadResourceState = Pick<\n Remote,\n \"responseUrl\" | \"total\" | \"validator\" | \"validatorHeader\"\n>;\n\n/** Resolved page input. Local inputs contain only the requested Blob slice. */\nexport type RadReadRequest = {\n input: string | Blob;\n offset: number;\n length: number;\n wholeFile: boolean;\n resourceUrl?: string;\n state?: RadResourceState;\n requestHeader?: Record<string, string>;\n withCredentials?: boolean;\n};\n\nfunction baseUrl() {\n return typeof document === \"undefined\" ? undefined : document.baseURI;\n}\n\n/** Slice without copying; callers choose how to take ownership of page bytes. */\nfunction sliceLocalInput(\n input: Exclude<SplatFileInput, string>,\n offset: number,\n length: number,\n) {\n if (input instanceof Blob) {\n checkRange(offset, length, input.size);\n return input.slice(offset, offset + length);\n }\n const bytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\n if (!(bytes instanceof Uint8Array))\n throw new Error(\"RAD: chunk resolver returned an unsupported input\");\n checkRange(offset, length, bytes.length);\n return bytes.subarray(offset, offset + length);\n}\n\n/** Validated byte reads shared by ordinary RAD loading and paged loading. */\nexport class RadSource {\n readonly stats = { downloadedBytes: 0, activeRequests: 0, cachedBytes: 0 };\n private readonly controller = new AbortController();\n private readonly remotes = new Map<string, Remote>();\n private readonly root: SplatFileInput;\n private readonly origin?: string;\n\n constructor(\n readonly options: RadSourceOptions,\n private readonly allowFullDownload = false,\n ) {\n const inputs = [options.url, options.file, options.fileBytes].filter(\n (input) => input !== undefined,\n );\n if (inputs.length !== 1)\n throw new Error(\"RAD: provide exactly one of url, file, or fileBytes\");\n this.root = inputs[0];\n const initialUrl = options.url ?? options.baseUrl;\n if (initialUrl) this.origin = new URL(initialUrl, baseUrl()).origin;\n }\n\n get url() {\n if (typeof this.root !== \"string\") return this.options.baseUrl;\n return this.remotes.get(this.root)?.responseUrl ?? this.root;\n }\n\n async readHeader(signal?: AbortSignal) {\n const prefix = await this.read(this.root, 0, 8, signal);\n const { headerLength } = getRadHeaderSize(prefix);\n const tail = await this.read(this.root, 8, headerLength - 8, signal);\n const bytes = new Uint8Array(headerLength);\n bytes.set(prefix);\n bytes.set(tail, 8);\n return bytes;\n }\n\n async readChunk(header: RadHeader, index: number, signal?: AbortSignal) {\n const { input, offset, length, wholeFile } = await this.chunkRead(\n header,\n index,\n signal,\n );\n return this.read(input, offset, length, signal, wholeFile);\n }\n\n private async chunkRead(\n header: RadHeader,\n index: number,\n signal?: AbortSignal,\n ) {\n signal?.throwIfAborted();\n this.controller.signal.throwIfAborted();\n const chunk = header.meta.chunks[index];\n if (!chunk) throw new Error(`RAD: missing chunk ${index}`);\n let input = this.root;\n let offset = header.chunksStart + chunk.offset;\n if (chunk.filename !== undefined) {\n offset = chunk.offset;\n if (this.options.resolveFile) {\n const controller = this.requestController(signal);\n try {\n input = await abortable(\n Promise.resolve(\n this.options.resolveFile(chunk.filename, controller.signal),\n ),\n controller.signal,\n );\n } finally {\n controller.cleanup();\n }\n } else {\n const sourceBase = getAssetBaseUrl(this.url) ?? this.options.baseUrl;\n if (!sourceBase)\n throw new Error(\n `RAD: external chunk \"${chunk.filename}\" requires resolveFile or baseUrl`,\n );\n input = new URL(chunk.filename, sourceBase).href;\n }\n if (typeof input === \"string\")\n input = new URL(\n input,\n getAssetBaseUrl(this.url) ?? this.options.baseUrl ?? baseUrl(),\n ).href;\n }\n return {\n input,\n offset,\n length: chunk.bytes,\n wholeFile: chunk.filename !== undefined && offset === 0,\n };\n }\n\n /** Resolve callbacks on their owning thread; workers read and validate bodies. */\n async prepareChunk(\n header: RadHeader,\n index: number,\n signal?: AbortSignal,\n ): Promise<RadReadRequest> {\n const read = await this.chunkRead(header, index, signal);\n signal?.throwIfAborted();\n this.controller.signal.throwIfAborted();\n const { input, offset, length } = read;\n if (typeof input === \"string\") {\n const remote = this.remote(input);\n const controller = this.requestController(signal);\n try {\n const url = await this.resolveRemote(remote, controller.signal);\n controller.signal.throwIfAborted();\n checkRange(offset, length, remote.total);\n const options = requestOptions(this.options, url, this.origin);\n const requestHeader: Record<string, string> = {};\n options.headers.forEach((value, name) => {\n requestHeader[name] = value;\n });\n return {\n ...read,\n input: url,\n resourceUrl: input,\n state: this.resourceState(remote),\n requestHeader,\n withCredentials: options.credentials === \"include\",\n };\n } finally {\n controller.cleanup();\n }\n }\n const slice = sliceLocalInput(input, offset, length);\n // Snapshot only this page, never copy/detach the full file per worker.\n const file = slice instanceof Blob ? slice : new Blob([slice as BlobPart]);\n return { input: file, offset: 0, length, wholeFile: true };\n }\n\n /** Worker transport reuses all ordinary Range, size and encoding validation. */\n static async readPreparedChunk(\n request: RadReadRequest,\n signal: AbortSignal,\n onProgress?: (downloadedBytes: number) => void,\n ) {\n const { input, offset, length, wholeFile } = request;\n const source = new RadSource({\n ...(typeof input === \"string\" ? { url: input } : { file: input }),\n requestHeader: request.requestHeader,\n withCredentials: request.withCredentials,\n onProgress,\n });\n try {\n if (typeof input === \"string\")\n Object.assign(source.remote(input), request.state, { resolved: input });\n const bytes = await source.read(input, offset, length, signal, wholeFile);\n const state =\n typeof input === \"string\"\n ? source.resourceState(source.remote(input))\n : undefined;\n return { bytes, state };\n } finally {\n source.dispose();\n }\n }\n\n /** Reconcile parallel responses before publishing a decoded page. */\n acceptChunkResponse(request: RadReadRequest, state?: RadResourceState) {\n this.controller.signal.throwIfAborted();\n if (request.resourceUrl === undefined) return;\n if (!state) throw new Error(\"RAD: missing worker response metadata\");\n const remote = this.remote(request.resourceUrl);\n if (\n remote.validator &&\n (state.validator !== remote.validator ||\n state.validatorHeader !== remote.validatorHeader)\n )\n throw new Error(\"RAD: resource version changed during loading\");\n if (\n remote.total !== undefined &&\n state.total !== undefined &&\n remote.total !== state.total\n )\n throw new Error(\"RAD: resource length changed during loading\");\n remote.responseUrl = state.responseUrl ?? remote.responseUrl;\n remote.total ??= state.total;\n if (!remote.validator && state.validator) {\n remote.validator = state.validator;\n remote.validatorHeader = state.validatorHeader;\n }\n }\n\n private resourceState(remote: Remote): RadResourceState {\n const { responseUrl, total, validator, validatorHeader } = remote;\n return { responseUrl, total, validator, validatorHeader };\n }\n\n private remote(url: string) {\n let remote = this.remotes.get(url);\n if (!remote) {\n remote = { url };\n this.remotes.set(url, remote);\n }\n return remote;\n }\n\n private async resolveRemote(remote: Remote, signal: AbortSignal) {\n remote.resolved ??= new URL(\n this.options.resolveAsset\n ? await abortable(this.options.resolveAsset(remote.url), signal)\n : (this.options.manager?.resolveURL(remote.url) ?? remote.url),\n this.options.baseUrl ?? baseUrl(),\n ).href;\n return remote.resolved;\n }\n\n private requestController(signal?: AbortSignal) {\n return linkedAbortController(this.controller.signal, signal);\n }\n\n private async read(\n input: SplatFileInput,\n offset: number,\n length: number,\n signal?: AbortSignal,\n wholeFile = false,\n ): Promise<Uint8Array> {\n signal?.throwIfAborted();\n this.controller.signal.throwIfAborted();\n if (typeof input === \"string\") {\n return this.readRemote(\n this.remote(input),\n offset,\n length,\n signal,\n wholeFile,\n );\n }\n const slice = sliceLocalInput(input, offset, length);\n if (slice instanceof Blob) {\n return new Uint8Array(await abortable(slice.arrayBuffer(), signal));\n }\n // Workers transfer buffers; never detach the caller's source bytes.\n return new Uint8Array(slice);\n }\n\n private async readRemote(\n remote: Remote,\n offset: number,\n length: number,\n signal?: AbortSignal,\n wholeFile = false,\n ): Promise<Uint8Array> {\n checkRange(offset, length, remote.total);\n if (!length) return new Uint8Array();\n if (remote.full)\n return new Uint8Array(\n await abortable(\n remote.full.slice(offset, offset + length).arrayBuffer(),\n signal,\n ),\n );\n const controller = this.requestController(signal);\n const manager = this.options.manager;\n let started = false;\n let response: Response | undefined;\n try {\n const resolved = await this.resolveRemote(remote, controller.signal);\n controller.signal.throwIfAborted();\n const options = requestOptions(this.options, resolved, this.origin);\n const { headers } = options;\n if (!wholeFile)\n headers.set(\"Range\", `bytes=${offset}-${offset + length - 1}`);\n // A single byte range can be fetched without a CORS preflight. Adding\n // If-Range would require server opt-in even when Range itself works.\n // Compare response validators below to detect resource changes instead.\n manager?.itemStart(resolved);\n started = true;\n this.stats.activeRequests++;\n response = await fetch(resolved, {\n headers,\n credentials: options.credentials,\n signal: controller.signal,\n });\n remote.responseUrl = response.url || remote.resolved;\n const encoding = response.headers.get(\"Content-Encoding\");\n if (\n encoding &&\n encoding.toLowerCase() !== \"identity\" &&\n response.status === 206\n )\n throw new Error(\n \"RAD: byte-range resources must use identity Content-Encoding\",\n );\n const etag = response.headers.get(\"ETag\");\n const modified = response.headers.get(\"Last-Modified\");\n const validatorHeader =\n etag && !etag.startsWith(\"W/\")\n ? \"ETag\"\n : modified\n ? \"Last-Modified\"\n : undefined;\n const validator = validatorHeader\n ? (response.headers.get(validatorHeader) ?? undefined)\n : undefined;\n if (\n remote.validator &&\n response.headers.get(remote.validatorHeader ?? \"ETag\") !==\n remote.validator\n )\n throw new Error(\"RAD: resource version changed during loading\");\n if (!remote.validator && validator) {\n remote.validator = validator;\n remote.validatorHeader = validatorHeader;\n }\n if (response.status === 206) {\n const contentRange = response.headers.get(\"Content-Range\");\n // Some public storage hosts serve correct ranges but do not expose\n // Content-Range to browser JavaScript. In that case the bounded body\n // and RAD/RADC container checks still validate the returned data.\n if (contentRange !== null) {\n const range = /^bytes (\\d+)-(\\d+)\\/(\\d+)$/.exec(contentRange);\n if (!range) throw new Error(\"RAD: invalid Content-Range header\");\n const [start, end, total] = range.slice(1).map(Number);\n if (\n !Number.isSafeInteger(total) ||\n start !== offset ||\n end !== offset + length - 1 ||\n end >= total ||\n (remote.total !== undefined && remote.total !== total)\n )\n throw new Error(\n \"RAD: Content-Range does not match the requested bytes\",\n );\n remote.total = total;\n }\n const bytes = await this.readResponse(\n response,\n length,\n controller.signal,\n );\n if (bytes.length !== length)\n throw new Error(\"RAD: truncated range response\");\n return bytes;\n }\n if (response.status !== 200)\n throw new Error(\n `RAD: HTTP ${response.status} loading ${remote.resolved}`,\n );\n if (\n this.allowFullDownload &&\n remote.url === this.root &&\n offset === 0 &&\n length === 8\n ) {\n const { chunks, size } = await readResponse(\n response,\n Number.POSITIVE_INFINITY,\n (bytes) => this.progress(bytes),\n controller.signal,\n collectRadHeader((bytes) => this.options.validateHeader?.(bytes)),\n );\n const full = new Blob(chunks as BlobPart[]);\n remote.total = size;\n checkRange(offset, length, size);\n this.cacheFullResponse(remote, full);\n return new Uint8Array(await full.slice(0, 8).arrayBuffer());\n }\n const limit = wholeFile\n ? length\n : this.allowFullDownload\n ? Number.POSITIVE_INFINITY\n : 0;\n if (!limit && offset === 0 && length === 8) {\n // A split dataset's .rad contains only its bounded header. Allow that\n // complete response even when its server cannot serve byte ranges.\n const bytes = await this.readHeaderOnlyResponse(\n response,\n controller.signal,\n );\n remote.total = bytes.length;\n this.cacheFullResponse(remote, bytes);\n return bytes.slice(0, 8);\n }\n if (!limit)\n throw new Error(\n \"RAD: server ignored Range; streaming requires byte-range support\",\n );\n if (remote.total !== undefined && remote.total > limit)\n throw new Error(\"RAD: full response exceeds its byte limit\");\n const bytes = await this.readResponse(response, limit, controller.signal);\n if (wholeFile && bytes.length !== length)\n throw new Error(\n \"RAD: external chunk length does not match its directory entry\",\n );\n if (remote.total !== undefined && remote.total !== bytes.length)\n throw new Error(\"RAD: resource length changed during loading\");\n remote.total = bytes.length;\n checkRange(offset, length, bytes.length);\n return bytes.slice(offset, offset + length);\n } catch (error) {\n await response?.body?.cancel().catch(() => {});\n if (started) manager?.itemError(remote.resolved ?? remote.url);\n throw error;\n } finally {\n controller.cleanup();\n if (started) {\n this.stats.activeRequests--;\n manager?.itemEnd(remote.resolved ?? remote.url);\n }\n }\n }\n\n private cacheFullResponse(remote: Remote, bytes: Uint8Array | Blob) {\n remote.full = bytes instanceof Blob ? bytes : new Blob([bytes as BlobPart]);\n this.stats.cachedBytes = [...this.remotes.values()].reduce(\n (sum, entry) => sum + (entry.full?.size ?? 0),\n 0,\n );\n }\n\n private async readHeaderOnlyResponse(\n response: Response,\n signal: AbortSignal,\n ) {\n const failure = () =>\n new Error(\n \"RAD: server ignored Range for a monolithic file; streaming requires byte-range support\",\n );\n const prefix = new Uint8Array(8);\n let headerLength: number | undefined;\n let jsonLength = 0;\n // The prefix establishes the byte limit before response chunks are retained.\n const bytes = await this.readResponse(\n response,\n Number.POSITIVE_INFINITY,\n signal,\n (chunk, size) => {\n const offset = size - chunk.length;\n if (offset < 8) prefix.set(chunk.subarray(0, 8 - offset), offset);\n if (size >= 8 && headerLength === undefined)\n ({ jsonLength, headerLength } = getRadHeaderSize(prefix));\n if (size > (headerLength ?? 8)) throw failure();\n },\n );\n if (bytes.length !== headerLength)\n throw new Error(\"RAD: truncated header-only response\");\n const meta = JSON.parse(\n new TextDecoder(\"utf-8\", { fatal: true }).decode(\n bytes.subarray(8, 8 + jsonLength),\n ),\n ) as { chunks?: unknown };\n if (\n !Array.isArray(meta.chunks) ||\n !meta.chunks.every(\n (chunk) =>\n chunk &&\n typeof chunk.filename === \"string\" &&\n chunk.filename.length > 0,\n )\n )\n throw failure();\n return bytes;\n }\n\n private async readResponse(\n response: Response,\n limit: number,\n signal: AbortSignal,\n validateChunk?: (chunk: Uint8Array, size: number) => void,\n ) {\n const { chunks, size } = await readResponse(\n response,\n limit,\n (bytes) => this.progress(bytes),\n signal,\n validateChunk,\n );\n return joinBytes(chunks, size);\n }\n\n private progress(bytes: number) {\n this.stats.downloadedBytes += bytes;\n this.options.onProgress?.(this.stats.downloadedBytes);\n }\n\n dispose() {\n this.controller.abort(\n new DOMException(\"RAD source disposed\", \"AbortError\"),\n );\n this.remotes.clear();\n this.stats.cachedBytes = 0;\n }\n}\n","import type { LoadingManager } from \"three\";\nimport { abortable, linkedAbortController } from \"../../runtime/abort\";\n\ntype StreamWorker = {\n disposed: boolean;\n peakWasmMemoryBytes: number;\n dispose(reason?: unknown): void;\n};\ntype Slot<W> = {\n worker: W;\n busy: boolean;\n references: number;\n};\n\ntype WorkerLease<W> = {\n worker: W;\n /** The retained cache handle releases this reference once on disposal. */\n retain: () => () => void;\n release: () => void;\n};\n\ntype LoadTask<W> = WorkerLease<W> & {\n id: number;\n signal: AbortSignal;\n start: (url: string) => void;\n progress: (loaded: number) => void;\n};\n\n/** Bounded worker leases. Cache handles retain slots; cancellation never kills unrelated work. */\nexport class StreamWorkerPool<W extends StreamWorker> {\n private readonly slots: Slot<W>[] = [];\n private readonly waiters = new Set<() => void>();\n private readonly controller = new AbortController();\n private peakBytes = 0;\n private nextTaskId = 0;\n downloadedBytes = 0;\n\n constructor(\n private readonly createWorker: () => W,\n readonly concurrency: number,\n private readonly retainIdle = false,\n ) {}\n\n get workers() {\n return this.slots.map(({ worker }) => worker);\n }\n\n get peakWasmMemoryBytes() {\n this.peakBytes = Math.max(\n this.peakBytes,\n this.slots.reduce(\n (bytes, { worker }) => bytes + worker.peakWasmMemoryBytes,\n 0,\n ),\n );\n return this.peakBytes;\n }\n\n private retire(slot: Slot<W>) {\n this.peakBytes = this.peakWasmMemoryBytes;\n if (!this.retainIdle && !slot.busy && !slot.references)\n slot.worker.dispose();\n }\n\n /** Shared RAD/SOG task lifecycle; format RPCs and cache ownership stay local. */\n async run<T>(\n options: {\n signal?: AbortSignal;\n manager: LoadingManager;\n cancel: (worker: W, id: number) => Promise<unknown>;\n },\n load: (task: LoadTask<W>) => Promise<T>,\n ): Promise<T> {\n const id = ++this.nextTaskId;\n const request = linkedAbortController(\n this.controller.signal,\n options.signal,\n );\n let lease: WorkerLease<W> | undefined;\n let cancel: (() => void) | undefined;\n let url: string | undefined;\n let loaded = 0;\n try {\n lease = await this.acquire(request.signal);\n const { worker } = lease;\n cancel = () => {\n if (!worker.disposed) void options.cancel(worker, id).catch(() => {});\n };\n request.signal.addEventListener(\"abort\", cancel, { once: true });\n request.signal.throwIfAborted();\n // Do not race load() against abort: synchronous decoding keeps its slot\n // until the worker replies. The format also checks before publishing.\n return await load({\n ...lease,\n id,\n signal: request.signal,\n start: (value) => {\n url = value;\n options.manager.itemStart(value);\n request.signal.throwIfAborted();\n },\n progress: (next) => {\n this.downloadedBytes += next - loaded;\n loaded = next;\n },\n });\n } catch (error) {\n cancel?.();\n if (url !== undefined) options.manager.itemError(url);\n throw error;\n } finally {\n if (cancel) request.signal.removeEventListener(\"abort\", cancel);\n request.cleanup();\n lease?.release();\n if (url !== undefined) options.manager.itemEnd(url);\n }\n }\n\n private async acquire(signal: AbortSignal): Promise<WorkerLease<W>> {\n for (;;) {\n signal.throwIfAborted();\n let slot = this.slots.find((candidate) => !candidate.busy);\n if (!slot && this.slots.length < this.concurrency) {\n slot = {\n worker: this.createWorker(),\n busy: false,\n references: 0,\n };\n this.slots.push(slot);\n }\n if (slot) {\n if (slot.worker.disposed) {\n this.peakBytes = this.peakWasmMemoryBytes;\n slot.worker = this.createWorker();\n slot.references = 0;\n }\n const owner = slot;\n const worker = owner.worker;\n owner.busy = true;\n let released = false;\n return {\n worker,\n retain: () => {\n owner.references++;\n return () => {\n if (owner.worker === worker) {\n owner.references--;\n this.retire(owner);\n }\n };\n },\n release: () => {\n if (released) return;\n released = true;\n owner.busy = false;\n this.retire(owner);\n this.wake();\n },\n };\n }\n let wake!: () => void;\n const available = new Promise<void>((resolve) => {\n wake = resolve;\n this.waiters.add(wake);\n });\n try {\n await abortable(available, signal);\n } finally {\n this.waiters.delete(wake);\n }\n }\n }\n\n private wake() {\n for (const wake of this.waiters) wake();\n this.waiters.clear();\n }\n\n dispose(\n reason: unknown = new DOMException(\n \"Streaming worker pool disposed\",\n \"AbortError\",\n ),\n ) {\n if (this.controller.signal.aborted) return;\n this.controller.abort(reason);\n this.peakBytes = this.peakWasmMemoryBytes;\n for (const { worker } of this.slots) worker.dispose(reason);\n this.wake();\n }\n}\n","import { WorkerRpc } from \"../../../runtime/WorkerRpc\";\nimport type { RadStreamRpcHandlers } from \"./worker\";\nimport BundledWorker from \"./worker?worker&inline\";\n\n/** Worker assigned either LOD ownership or a persistent page decoder. */\nexport class RadStreamWorker extends WorkerRpc<RadStreamRpcHandlers> {\n constructor(onDispose?: () => void) {\n super(new BundledWorker(), onDispose);\n }\n}\n","import { DefaultLoadingManager } from \"three\";\nimport { abortable } from \"../../../runtime/abort\";\nimport { RadSource, type RadSourceOptions } from \"../../rad/RadSource\";\nimport type { RadHeader, RadStreamChunk } from \"../../rad/radFormat\";\nimport { StreamWorkerPool } from \"../StreamWorkerPool\";\nimport type { RadSelectionRequest } from \"./RadSelectionState\";\nimport { RadStreamWorker } from \"./RadStreamWorker\";\nimport type { prepareRadSelection } from \"./prepareRadSelection\";\nimport type { RadStreamSelection } from \"./radFade\";\n\nexport type RadStreamLoaderOptions = Pick<\n RadSourceOptions,\n | \"url\"\n | \"file\"\n | \"fileBytes\"\n | \"resolveFile\"\n | \"manager\"\n | \"requestHeader\"\n | \"withCredentials\"\n>;\n\n/** Dedicated LOD traversal with a separate bounded pool of parallel decoders. */\nexport class RadStreamLoader {\n readonly source: RadSource;\n private readonly lodWorker: RadStreamWorker;\n private readonly pool: StreamWorkerPool<RadStreamWorker>;\n private readonly decoderReady = new WeakMap<RadStreamWorker, Promise<void>>();\n private readonly controller = new AbortController();\n private initialization?: Promise<RadHeader>;\n private header?: RadHeader;\n private rootReady?: Promise<void>;\n private initialRoot?: RadStreamChunk;\n private rootBytes?: Uint8Array;\n private pending = new Map<\n number,\n { task: Promise<RadStreamChunk>; signal?: AbortSignal }\n >();\n private estimatedCodebookBytes = 0;\n private selectionBytes = 0;\n\n constructor(\n private readonly options: RadStreamLoaderOptions,\n maxConcurrentLoads = 4,\n ) {\n this.source = new RadSource({\n ...options,\n manager: options.manager ?? DefaultLoadingManager,\n });\n this.lodWorker = new RadStreamWorker();\n this.pool = new StreamWorkerPool(\n () => new RadStreamWorker(),\n maxConcurrentLoads,\n true,\n );\n }\n\n get stats() {\n return {\n cachedBytes: this.source.stats.cachedBytes,\n downloadedBytes:\n this.source.stats.downloadedBytes + this.pool.downloadedBytes,\n peakWasmMemoryBytes:\n this.pool.peakWasmMemoryBytes + this.lodWorker.peakWasmMemoryBytes,\n estimatedCodebookBytes:\n this.estimatedCodebookBytes *\n this.pool.workers.filter((worker) => !worker.disposed).length,\n bootstrapBytes: this.rootBytes?.byteLength ?? 0,\n selectionBytes: this.selectionBytes,\n };\n }\n\n get lodWorkerLost() {\n return this.lodWorker.disposed && !this.controller.signal.aborted;\n }\n\n private assertActive() {\n this.controller.signal.throwIfAborted();\n if (this.lodWorker.disposed) throw new Error(\"RAD LOD worker terminated\");\n }\n\n initialize(signal?: AbortSignal) {\n signal?.throwIfAborted();\n this.assertActive();\n this.initialization ??= this.source\n .readHeader(this.controller.signal)\n .then(async (bytes) => {\n const header = await this.lodWorker.call(\"initializeRad\", {\n bytes,\n });\n this.assertActive();\n this.header = header;\n const degree = header.meta.maxSh ?? 0;\n // Float codebooks plus packed caches for every degree up to maxSh.\n this.estimatedCodebookBytes =\n (header.meta.shCodeCount ?? 0) * [0, 52, 144, 292][degree];\n return header;\n });\n return abortable(this.initialization, signal);\n }\n\n async loadChunk(\n index: number,\n signal?: AbortSignal,\n onDecoded?: () => void,\n ): Promise<RadStreamChunk> {\n signal?.throwIfAborted();\n this.assertActive();\n let pending = this.pending.get(index);\n if (!pending || pending.signal?.aborted) {\n const task = this.loadChunkInternal(index, signal, onDecoded).finally(\n () => {\n if (this.pending.get(index) === pending) this.pending.delete(index);\n },\n );\n pending = { task, signal };\n this.pending.set(index, pending);\n }\n // Keep cancelled synchronous work reserved until its worker reply arrives.\n return pending.task;\n }\n\n private async loadChunkInternal(\n index: number,\n signal?: AbortSignal,\n onDecoded?: () => void,\n ): Promise<RadStreamChunk> {\n const header = await this.initialize(signal);\n // Codebooks live in chunk zero. Its initial geometry is held only until the\n // caller requests that page, avoiding a duplicate fetch during races.\n this.rootReady ??= this.decode(\n 0,\n header,\n this.controller.signal,\n index === 0 ? onDecoded : undefined,\n )\n .then((data) => {\n this.initialRoot = data;\n })\n .catch((error) => {\n this.rootReady = undefined;\n throw error;\n });\n await abortable(this.rootReady, signal);\n if (index === 0 && this.initialRoot) {\n const root = this.initialRoot;\n this.initialRoot = undefined;\n return root;\n }\n return this.decode(index, header, signal, onDecoded);\n }\n\n private async decode(\n index: number,\n header: RadHeader,\n signal?: AbortSignal,\n onDecoded?: () => void,\n ) {\n this.assertActive();\n return this.pool.run(\n {\n signal,\n manager: this.options.manager ?? DefaultLoadingManager,\n cancel: (worker, generation) =>\n worker.call(\"cancelRadLoad\", { generation }),\n },\n async ({ worker, id: generation, signal, release, start, progress }) => {\n this.assertActive();\n let ready = this.decoderReady.get(worker);\n if (!ready) {\n ready = worker\n .call(\"initializeRadDecoder\", {\n header,\n rootBytes: this.rootBytes?.slice(),\n })\n .catch((error) => {\n worker.dispose(error);\n throw error;\n });\n this.decoderReady.set(worker, ready);\n }\n // Resolve application callbacks here; page bodies stay inside the worker.\n const [request] = await Promise.all([\n this.source.prepareChunk(header, index, signal),\n ready,\n ]);\n signal.throwIfAborted();\n this.assertActive();\n if (typeof request.input === \"string\") start(request.input);\n const result = await worker.call(\n \"loadRadChunk\",\n { index, generation, request },\n {\n onStatus: (status) =>\n progress((status as { loaded: number }).loaded),\n },\n );\n this.assertActive();\n signal.throwIfAborted();\n try {\n this.source.acceptChunkResponse(request, result.state);\n } catch (error) {\n // A response rejected against another worker must not seed future jobs.\n worker.dispose(error);\n throw error;\n }\n const registration = this.lodWorker.call(\"retainRadChunk\", {\n index,\n generation,\n tree: result.tree,\n });\n // Registration owns no decoder state; release the slot before awaiting it.\n release();\n try {\n onDecoded?.();\n await registration;\n this.assertActive();\n signal.throwIfAborted();\n if (result.rootBytes) this.rootBytes = result.rootBytes;\n return result.data;\n } catch (error) {\n // A throwing callback must still observe registration before rollback.\n await registration.catch(() => {});\n this.releaseChunk(index, generation);\n throw error;\n }\n },\n );\n }\n\n getChunkUrl(index: number) {\n const filename = this.header?.meta.chunks[index]?.filename;\n const root = this.source.url;\n if (filename) return root ? new URL(filename, root).href : filename;\n return root ?? (this.options.file as File | undefined)?.name ?? \"RAD\";\n }\n\n async selectLod(request: RadSelectionRequest): Promise<RadStreamSelection> {\n this.assertActive();\n const { retainedBytes, ...selection } = await this.lodWorker.call(\n \"selectRadLod\",\n request,\n );\n this.assertActive();\n this.selectionBytes = retainedBytes;\n return selection;\n }\n\n async prepareSelection(request: Parameters<typeof prepareRadSelection>[0]) {\n this.assertActive();\n const result = await this.lodWorker.call(\"prepareRadSelection\", request);\n this.assertActive();\n return result;\n }\n\n releaseChunk(index: number, generation?: number) {\n if (index === 0 && generation === undefined) this.initialRoot = undefined;\n if (!this.lodWorker.disposed)\n void this.lodWorker\n .call(\"releaseRadChunk\", { index, generation })\n .catch(() => {});\n }\n\n dispose() {\n if (this.controller.signal.aborted) return;\n this.controller.abort(\n new DOMException(\"RAD loader disposed\", \"AbortError\"),\n );\n this.source.dispose();\n this.pool.dispose(this.controller.signal.reason);\n this.lodWorker.dispose(this.controller.signal.reason);\n this.pending.clear();\n this.initialRoot = undefined;\n this.rootBytes = undefined;\n this.estimatedCodebookBytes = 0;\n this.selectionBytes = 0;\n this.header = undefined;\n }\n}\n","import type { RadMeta } from \"../../rad/radFormat\";\nimport { getRadChunkSpan } from \"../../rad/radFormat\";\n\n/** CPU-only data retained in the dataset worker, never GPU source storage. */\nexport type RadLodChunk = {\n centers: Float32Array;\n radii: Float32Array;\n childStart: Uint32Array;\n childCount: Uint16Array;\n /** Original page index to Morton storage; tree arrays keep file order. */\n sourceToStorage: Uint32Array;\n /** Center and scale/rotation bounds per Morton storage block. */\n boundsBlocks: Float32Array;\n};\n\nexport type RadLodView = {\n /** Object-to-camera transform; doubles preserve large scene translations. */\n viewFromObject: number[];\n /** Camera projection's X/Y rows (8 values), including zoom and view offsets. */\n projectionRows: number[];\n /** Pixels per camera-space unit at depth 1, including projection zoom. */\n pixelScale: number;\n orthographic: boolean;\n};\n\nexport type RadLodRequest = {\n views: RadLodView[];\n splatBudget: number;\n pixelThreshold: number;\n residentChunks: number[];\n hysteresis?: number;\n};\n\nexport type RadLodSelection = {\n /** Stable file indices. The scheduler maps these to occupied GPU slots. */\n indices: Uint32Array;\n wantedChunks: Uint32Array;\n /** Ancestor and selected pages required by this cut. */\n touchedChunks: Uint32Array;\n};\n\n/** Resolve validated LOD indices without assuming that chunks are 64K records. */\nexport function radChunkIndex(meta: RadMeta, index: number): number {\n const size = meta.chunkSize ?? meta.count;\n const candidate = Math.floor(index / size);\n if (candidate < meta.chunks.length) {\n const range = getRadChunkSpan(meta, candidate);\n if (index >= range.base && index < range.base + range.count)\n return candidate;\n }\n // Header validation guarantees contiguous, ordered spans covering every index.\n let low = 0;\n let high = meta.chunks.length;\n while (low < high) {\n const middle = (low + high) >>> 1;\n if (getRadChunkSpan(meta, middle).base <= index) low = middle + 1;\n else high = middle;\n }\n return low - 1;\n}\n","import * as THREE from \"three\";\nimport {\n type RadSelectionRange,\n radPageTextureLayout,\n} from \"../../../data/RadPagedSplats\";\nimport { SPLAT_BOUNDS_BLOCK_SIZE } from \"../../../data/defines\";\nimport {\n getSplatByteLength,\n getSplatTextureBytes,\n} from \"../../../data/splatData\";\nimport { RetryTimer } from \"../../../runtime/retry\";\nimport type { RadMeta, RadStreamChunk } from \"../../rad/radFormat\";\nimport { getRadChunkSpan } from \"../../rad/radFormat\";\nimport { StreamByteBudget } from \"../StreamByteBudget\";\nimport {\n StreamCameras,\n type StreamResolutionSource,\n streamViews,\n} from \"../StreamCameras\";\nimport {\n type StreamSchedulerOptions,\n type StreamStats,\n notifyStreamChange,\n notifyStreamError,\n positiveInteger,\n streamPendingLimit,\n streamRetryAt,\n streamSettings,\n} from \"../streamOptions\";\nimport { RadStreamBatch } from \"./RadStreamBatch\";\nimport {\n RadStreamLoader,\n type RadStreamLoaderOptions,\n} from \"./RadStreamLoader\";\nimport type { RadSelectionPreparation } from \"./prepareRadSelection\";\nimport type { RadStreamSelection, RadVersionedSelection } from \"./radFade\";\nimport { type RadLodView, radChunkIndex } from \"./radLod\";\n\nexport type RadStreamSchedulerOptions = RadStreamLoaderOptions &\n StreamSchedulerOptions;\nexport type RadStreamStats = StreamStats & {\n pageBudget: number;\n lodTimeMs: number;\n};\n\ntype Pool = {\n batch: RadStreamBatch;\n /** The scheduler owns slot allocation and retirement. */\n slots: (Page | undefined)[];\n};\ntype PageSlot = { pool: Pool; slot: number };\ntype PageLoad = {\n controller: AbortController;\n phase: \"decoding\" | \"registering\";\n /** Kept until tree registration settles, including after cancellation. */\n reservedBytes: number;\n};\ntype PageStorage =\n | { phase: \"decoded\"; data: RadStreamChunk; allocation?: PageSlot }\n | { phase: \"resident\"; allocation: PageSlot };\n\ntype Page = {\n index: number;\n base: number;\n count: number;\n load?: PageLoad;\n /** Decoded buffers stay owned here until written to the reserved slot. */\n storage?: PageStorage;\n failures: number;\n retryAt: number;\n expiresAt?: number;\n};\n\ntype DisplayedCut = {\n selection: RadVersionedSelection;\n pages: Set<number>;\n transition?: { startedAt: number; pools: Pool[] };\n};\n\ntype ReadyCut = {\n selection: RadStreamSelection;\n pages: Set<number>;\n reselect: boolean;\n};\n\ntype Traversal = {\n pages: Set<number>;\n previous?: RadVersionedSelection;\n splatBudget: number;\n};\n\ntype Preparation = {\n /** Same order as the worker's pool snapshots and results. */\n pools: Pool[];\n pages: Set<number>;\n cancelled: boolean;\n bytes: number;\n result?: RadSelectionPreparation;\n};\n\nfunction pendingPageBytes(page: Page) {\n return page.storage?.phase === \"decoded\"\n ? getSplatByteLength(page.storage.data)\n : (page.load?.reservedBytes ?? 0);\n}\n\n/** Camera-driven RAD tree cuts with crossfades, on-demand pages and cooldown. */\nexport class RadStreamScheduler {\n readonly group: THREE.Group;\n readonly initialized: Promise<this>;\n readonly firstRenderable: Promise<this>;\n readonly cooldownMs: number;\n readonly fadeDurationMs: number;\n readonly maxConcurrentLoads: number;\n private _splatBudget: number;\n private readonly loader: RadStreamLoader;\n private readonly abort = new AbortController();\n private readonly streamCameras = new StreamCameras();\n private readonly pages = new Map<number, Page>();\n private readonly pools: Pool[] = [];\n private readonly bounds = new THREE.Box3();\n private readonly matrix = new THREE.Matrix4();\n private meta?: RadMeta;\n private pageSize = 0;\n private pageBudget = 0;\n private numSh = 0;\n private maxPagePendingBytes = 0;\n private disposed = false;\n private shown = true;\n private displayed?: DisplayedCut;\n private ready?: ReadyCut;\n private traversal?: Traversal;\n private preparation?: Preparation;\n private wanted = new Set<number>();\n private revision = 0;\n private lastRequestedRevision = -1;\n private refinementStopped = false;\n private lastViewKey = \"\";\n private views: RadLodView[] = [];\n private lodTimeMs = 0;\n private resolveFirst!: (value: this) => void;\n private rejectFirst!: (error: unknown) => void;\n\n constructor(private readonly options: RadStreamSchedulerOptions) {\n this.group = options.group ?? new THREE.Group();\n const settings = streamSettings(options);\n this._splatBudget = settings.splatBudget;\n this.cooldownMs = settings.cooldownMs;\n this.fadeDurationMs = settings.fadeDurationMs;\n this.maxConcurrentLoads = settings.maxConcurrentLoads;\n this.loader = new RadStreamLoader(options, this.maxConcurrentLoads);\n this.firstRenderable = new Promise((resolve, reject) => {\n this.resolveFirst = resolve;\n this.rejectFirst = reject;\n });\n this.initialized = this.initialize().catch((error) => {\n this.rejectFirst(error);\n this.loader.dispose();\n throw error;\n });\n void this.initialized.catch(() => {});\n void this.firstRenderable.catch(() => {});\n }\n\n /** Selected-node budget. Assigning a new value requests LOD selection. */\n get splatBudget(): number {\n return this._splatBudget;\n }\n\n set splatBudget(value: number) {\n if (value === this._splatBudget) return;\n this._splatBudget = positiveInteger(value, \"splatBudget\");\n this.invalidatePendingSelection();\n this.revision++;\n void this.requestSelection();\n }\n\n /** Cameras that select detail, in registration order. */\n get cameras(): readonly THREE.Camera[] {\n return this.streamCameras.cameras;\n }\n\n hasCamera(camera: THREE.Camera) {\n return this.streamCameras.has(camera);\n }\n\n /**\n * Select detail for this camera on each update; set its resolution too. For\n * WebXR register renderer.xr.getCamera(): it selects with its eyes' combined\n * frustum, sized by an eye's viewport. Returns whether the camera was newly\n * added.\n */\n setCamera(camera: THREE.Camera) {\n return this.streamCameras.add(camera);\n }\n\n /** Stop selecting detail for this camera. Returns whether it was registered. */\n deleteCamera(camera: THREE.Camera) {\n return this.streamCameras.delete(camera);\n }\n\n /**\n * Set a registered camera's render size in CSS pixels, without the device\n * pixel ratio. Returns whether the camera is registered.\n */\n setResolution(\n camera: THREE.Camera,\n xOrVec: number | THREE.Vector2,\n y?: number,\n ) {\n return this.streamCameras.setResolution(camera, xOrVec, y);\n }\n\n /** Set a registered camera's resolution from renderer.getSize(). */\n setResolutionFromRenderer(\n camera: THREE.Camera,\n renderer: StreamResolutionSource,\n ) {\n return this.streamCameras.setResolutionFromRenderer(camera, renderer);\n }\n\n get stats(): RadStreamStats {\n const loader = this.loader.stats;\n let pendingBytes = 0;\n let residentChunks = 0;\n let loadingChunks = 0;\n for (const page of this.pages.values()) {\n if (page.storage?.phase === \"resident\") residentChunks++;\n if (page.load?.phase === \"decoding\") loadingChunks++;\n pendingBytes += pendingPageBytes(page);\n }\n return {\n visibleSplats: this.shown\n ? this.pools.reduce((sum, { batch }) => sum + batch.numSplats, 0)\n : 0,\n visibleMeshes: this.shown\n ? this.pools.filter(({ batch }) => batch.numSplats > 0).length\n : 0,\n residentChunks,\n residentMeshes: this.pools.length,\n residentBytes:\n this.pools.reduce(\n (sum, { batch }) => sum + batch.source.residentBytes,\n 0,\n ) +\n loader.estimatedCodebookBytes +\n loader.bootstrapBytes +\n loader.cachedBytes +\n loader.selectionBytes +\n (this.displayed?.selection.indices.byteLength ?? 0),\n pendingBytes: pendingBytes + (this.preparation?.bytes ?? 0),\n loadingChunks,\n downloadedBytes: loader.downloadedBytes,\n peakWasmMemoryBytes: loader.peakWasmMemoryBytes,\n pageBudget: this.pageBudget,\n lodTimeMs: this.lodTimeMs,\n };\n }\n\n /** Group-local root bounds plus selected Gaussian extents; approximate while streaming. */\n getBoundingBox(): THREE.Box3 {\n const box = this.bounds.clone();\n // Coarse centers can cluster inside large Gaussians. Include their extent\n // here so callers can frame the scene without inspecting owned batches.\n for (const { batch } of this.pools) {\n if (!batch.numSplats) continue;\n if (batch.matrixAutoUpdate) batch.updateMatrix();\n box.union(batch.getBoundingBox(false).applyMatrix4(batch.matrix));\n }\n return box;\n }\n\n private async initialize() {\n const { meta } = await this.loader.initialize(this.abort.signal);\n this.abort.signal.throwIfAborted();\n if (meta.count && !meta.lodTree) {\n const error = new Error(\n \"RAD streaming requires a LOD tree; load this file with SplatMesh instead\",\n );\n error.name = \"RadLodRequiredError\";\n throw error;\n }\n this.meta = meta;\n this.numSh = meta.maxSh ?? 0;\n if (!meta.count) {\n this.resolveFirst(this);\n this.changed();\n return this;\n }\n this.pageSize = getRadChunkSpan(meta, 0).count;\n for (let index = 1; index < meta.chunks.length; index++)\n this.pageSize = Math.max(\n this.pageSize,\n getRadChunkSpan(meta, index).count,\n );\n // Validate the largest page against the texture layout limits.\n radPageTextureLayout({\n pageSize: this.pageSize,\n pageCount: 1,\n });\n const paddedCount = Math.ceil(this.pageSize / 2048) * 2048;\n this.maxPagePendingBytes =\n getSplatTextureBytes(paddedCount, this.numSh) +\n // Tree data, source IDs, Morton order and bounds awaiting LOD registration.\n this.pageSize * 30 +\n Math.ceil(this.pageSize / SPLAT_BOUNDS_BLOCK_SIZE) * (48 + 32);\n this.pageBudget = meta.chunks.length;\n this.wanted.add(0);\n this.pump();\n this.changed();\n return this;\n }\n\n /**\n * Call before rendering. Registered cameras share one cut at the greatest\n * detail any of them needs.\n */\n update(): boolean {\n if (this.disposed) return false;\n const cameras = this.streamCameras.seeing(this.group.layers);\n if (!this.meta) return false;\n const now = performance.now();\n if (this.refinementStopped) {\n for (const { batch } of this.pools)\n batch.layers.mask = this.group.layers.mask;\n let changed = this.updateFade(now);\n changed = this.releaseUnused(now, true) || changed;\n if (changed) this.changed();\n return changed;\n }\n this.group.updateWorldMatrix(true, false);\n let shown = cameras.length > 0;\n for (\n let object: THREE.Object3D | null = this.group;\n object;\n object = object.parent\n )\n shown &&= object.visible;\n let changed = false;\n if (shown !== this.shown) {\n this.shown = shown;\n this.revision++;\n if (!shown) {\n this.clearSelectionState();\n for (const { batch } of this.pools)\n changed = batch.clearSelection() || changed;\n this.cancelUnusedLoads();\n }\n }\n for (const { batch } of this.pools)\n batch.layers.mask = this.group.layers.mask;\n this.views = [];\n for (const camera of streamViews(cameras)) {\n // A WebXR camera is sized by an eye's viewport: a headset has only\n // physical pixels.\n const viewport = (camera as THREE.PerspectiveCamera).viewport;\n const resolution = this.streamCameras.getResolution(camera);\n const width = viewport?.z ?? resolution?.x;\n const height = viewport?.w ?? resolution?.y;\n if (width === undefined || height === undefined)\n throw new Error(\n \"RAD camera has no resolution; call setResolution() or setResolutionFromRenderer()\",\n );\n this.matrix\n .copy(camera.matrixWorld)\n .invert()\n .multiply(this.group.matrixWorld);\n const p = camera.projectionMatrix.elements;\n this.views.push({\n viewFromObject: this.matrix.elements.slice(),\n projectionRows: [p[0], p[4], p[8], p[12], p[1], p[5], p[9], p[13]],\n pixelScale:\n Math.max(Math.abs(p[0]) * width, Math.abs(p[5]) * height) / 2,\n orthographic:\n (camera as THREE.OrthographicCamera).isOrthographicCamera === true,\n });\n }\n const key = this.views\n .map(\n (view) =>\n `${view.viewFromObject.join(\",\")}/${view.projectionRows.join(\",\")}/${view.pixelScale}/${view.orthographic}`,\n )\n .join(\";\");\n if (key !== this.lastViewKey) {\n this.lastViewKey = key;\n this.revision++;\n }\n if (shown && this.meta.count && !this.pages.get(0)?.storage?.allocation)\n this.wanted.add(0);\n changed = this.updateFade(now) || changed;\n if (shown) {\n this.reservePages();\n changed = this.uploadPages() || changed;\n }\n const preparation = this.preparation;\n if (preparation?.result && !this.displayed?.transition) {\n this.preparation = undefined;\n if (!preparation.cancelled && shown)\n changed =\n this.applySelection(preparation.result, preparation.pools, now) ||\n changed;\n // Apply the latest view after publishing or discarding this snapshot.\n this.revision++;\n }\n // Keep drawing the old cut until its replacement is prepared.\n if (\n this.ready &&\n !this.preparation &&\n !this.displayed?.transition &&\n this.selectionPagesReady(this.ready.selection)\n ) {\n const { selection: selected, reselect } = this.ready;\n this.ready = undefined;\n if (selected.changedChunks.length) void this.prepareSelection(selected);\n else\n changed =\n this.applySelection(\n { selection: selected, fade: false, pools: [] },\n [],\n now,\n ) || changed;\n if (reselect) this.revision++;\n }\n // Keep expired caches until a pending view/budget decision can reuse them.\n const allowRelease = !shown || this.lastRequestedRevision === this.revision;\n changed = this.releaseUnused(now, allowRelease) || changed;\n if (shown) {\n void this.requestSelection();\n this.pump();\n }\n if (changed) this.changed();\n return changed;\n }\n\n private async requestSelection() {\n if (\n this.disposed ||\n this.refinementStopped ||\n !this.shown ||\n this.traversal ||\n this.preparation ||\n !this.meta?.count ||\n !this.views.length ||\n this.lastRequestedRevision === this.revision ||\n !this.pages.get(0)?.storage?.allocation\n )\n return;\n const residentChunks = [...this.pages.values()]\n .filter((page) => page.storage?.allocation)\n .map((page) => page.index);\n const traversal: Traversal = {\n pages: new Set(residentChunks),\n previous: this.displayed?.selection,\n splatBudget: this.splatBudget,\n };\n this.traversal = traversal;\n this.lastRequestedRevision = this.revision;\n const { previous, splatBudget } = traversal;\n const started = performance.now();\n let accepted = false;\n try {\n const selection = await this.loader.selectLod({\n views: this.views,\n splatBudget,\n pixelThreshold: 1,\n residentChunks,\n previousId: previous?.selectionId,\n readyId: this.ready?.selection.selectionId,\n fade: this.fadeDurationMs > 0,\n });\n if (this.disposed || !this.shown || splatBudget !== this.splatBudget)\n return;\n this.lodTimeMs = performance.now() - started;\n // Keep the selected tree path while its reserved pages await writing.\n this.wanted = new Set(selection.wantedChunks);\n for (const index of selection.touchedChunks) this.wanted.add(index);\n accepted = true;\n this.cancelUnusedLoads();\n this.pump();\n // A completed cut may be applied or hidden during traversal. Recompute\n // against its new fade baseline, but accept camera lag to avoid starvation.\n if (this.displayed?.selection !== previous || this.preparation) {\n this.lastRequestedRevision = -1;\n this.changed();\n return;\n }\n if (\n this.ready &&\n !this.displayed?.transition &&\n !this.selectionPagesReady(selection)\n ) {\n // Finish the waiting cut instead of chasing newly decoded pages forever.\n // Loading still follows the latest result; refresh after publication.\n this.ready.reselect = true;\n } else {\n this.ready = {\n selection,\n pages: new Set(selection.touchedChunks),\n reselect: false,\n };\n }\n this.changed();\n } catch (error) {\n if (!this.disposed) {\n this.stopRefinement(error);\n }\n } finally {\n if (this.traversal === traversal) this.traversal = undefined;\n // Each accepted decision retires unused caches before the next snapshot,\n // even if the camera kept moving while the worker was selecting.\n if (!this.disposed) {\n const revision = this.revision;\n this.cancelUnusedLoads();\n const released = this.releaseUnused(\n performance.now(),\n accepted || !this.shown,\n );\n if (released || revision !== this.revision) {\n this.changed();\n this.pump();\n }\n }\n // Updates overwrite views/revision while this task runs. Dispatch their\n // latest snapshot immediately; ready results never block the next task.\n void this.requestSelection();\n }\n }\n\n private selectionPagesReady(selection: RadStreamSelection) {\n // Shared and outgoing nodes are already displayed; only changed pages may\n // still be unwritten. Ancestors need not delay publishing the selected cut.\n return selection.changedChunks.every((index) => {\n const page = this.pages.get(index);\n return page?.storage?.phase === \"resident\";\n });\n }\n\n private async prepareSelection(selection: RadStreamSelection) {\n let preparation: Preparation | undefined;\n try {\n const rangesByPool = new Map<Pool, RadSelectionRange[]>();\n for (const index of selection.changedChunks) {\n const pool = this.pages.get(index)?.storage?.allocation?.pool;\n if (!pool) throw new Error(\"RAD transition references a retired page\");\n if (!rangesByPool.has(pool)) rangesByPool.set(pool, []);\n }\n const indices = selection.fade?.indices ?? selection.indices;\n const meta = this.meta as RadMeta;\n let selectedCount = 0;\n // Sorted file indices let us resolve each page once, without a per-node\n // scan on the main thread. Only changed pools need replacement data.\n for (let start = 0; start < indices.length; ) {\n const page = this.pages.get(radChunkIndex(meta, indices[start]));\n const allocation = page?.storage?.allocation;\n if (!page || !allocation)\n throw new Error(\"RAD cut references a retired page\");\n const { pool, slot } = allocation;\n const pageEnd = page.base + page.count;\n let end = start + 1;\n let high = indices.length;\n while (end < high) {\n const middle = Math.floor((end + high) / 2);\n if (indices[middle] < pageEnd) end = middle + 1;\n else high = middle;\n }\n const ranges = rangesByPool.get(pool);\n if (ranges) {\n ranges.push({\n start,\n end,\n slot,\n pageStart: pool.batch.source.pageStart(slot),\n chunkIndex: page.index,\n sourceBase: page.base,\n });\n selectedCount += end - start;\n }\n start = end;\n }\n const pools = Array.from(rangesByPool, ([pool, ranges]) =>\n pool.batch.source.snapshotSelection(ranges),\n );\n // Pin physical slots until the reply, even when cancelled or hidden.\n const pages = new Set<number>();\n for (const page of this.pages.values())\n if (page.storage?.allocation) pages.add(page.index);\n preparation = {\n pools: Array.from(rangesByPool.keys()),\n pages,\n cancelled: false,\n bytes:\n selection.indices.byteLength +\n (selection.fade?.indices.byteLength ?? 0) +\n (selection.fade?.fades.byteLength ?? 0) +\n selection.changedChunks.byteLength +\n selection.touchedChunks.byteLength +\n selection.wantedChunks.byteLength +\n selectedCount * 8 + // Render indices and post-fade indices.\n // Opacity tables, current/post-fade page counts and bounds, dirty flags.\n pools.reduce(\n (bytes, pool) =>\n bytes + pool.opacityBlocks.byteLength + pool.pageCount * 9 + 96,\n 0,\n ),\n };\n this.preparation = preparation;\n const result = await this.loader.prepareSelection({ selection, pools });\n if (this.preparation !== preparation) return;\n preparation.result = result;\n } catch (error) {\n if (this.disposed || this.preparation !== preparation) return;\n this.preparation = undefined;\n this.lastRequestedRevision = -1;\n if (!preparation?.cancelled) {\n this.stopRefinement(error);\n }\n }\n this.changed();\n }\n\n private applySelection(\n prepared: RadSelectionPreparation,\n affected: Pool[],\n now: number,\n ) {\n const { selection, fade } = prepared;\n const changed = affected.length > 0;\n let index = 0;\n for (const pool of affected) {\n pool.batch.commitSelection(prepared.pools[index++]);\n if (pool.batch.numSplats > 0 && pool.batch.parent !== this.group)\n this.group.add(pool.batch);\n else if (pool.batch.numSplats === 0) pool.batch.removeFromParent();\n }\n // Unchanged nodes keep the fade baseline valid for an in-flight decision.\n let displayedSelection: RadVersionedSelection = selection;\n if (this.displayed && !selection.changedChunks.length) {\n const previous = this.displayed.selection;\n previous.touchedChunks = selection.touchedChunks;\n previous.wantedChunks = selection.wantedChunks;\n displayedSelection = previous;\n }\n this.displayed = {\n selection: displayedSelection,\n pages: new Set(selection.touchedChunks),\n transition: fade ? { startedAt: now, pools: affected } : undefined,\n };\n this.cancelUnusedLoads();\n if (selection.indices.length && !fade) this.resolveFirst(this);\n return changed;\n }\n\n private invalidatePendingSelection() {\n this.ready = undefined;\n // A cancelled preparation still owns its physical slots until the reply.\n if (this.preparation) this.preparation.cancelled = true;\n }\n\n private clearSelectionState() {\n this.invalidatePendingSelection();\n this.displayed = undefined;\n this.wanted.clear();\n }\n\n /** Worker snapshots and waiting cuts pin pages without renewing cooldown. */\n private isPagePinned(index: number) {\n return (\n this.traversal?.pages.has(index) ||\n this.ready?.pages.has(index) ||\n this.preparation?.pages.has(index)\n );\n }\n\n private cancelUnusedLoads() {\n for (const page of this.pages.values()) {\n if (\n !this.wanted.has(page.index) &&\n !this.isPagePinned(page.index) &&\n page.index !== 0\n ) {\n page.load?.controller.abort();\n if (page.storage?.phase === \"decoded\") this.releasePage(page);\n }\n }\n }\n\n private updateFade(now: number) {\n const displayed = this.displayed;\n const transition = displayed?.transition;\n if (!displayed || !transition) return false;\n const progress = THREE.MathUtils.clamp(\n (now - transition.startedAt) / this.fadeDurationMs,\n 0,\n 1,\n );\n if (progress > 0 && displayed.selection.indices.length)\n this.resolveFirst(this);\n if (progress === 1) {\n displayed.transition = undefined;\n let changed = false;\n for (const { batch } of transition.pools) {\n changed = batch.finishFade() || changed;\n if (batch.numSplats === 0) batch.removeFromParent();\n }\n return changed;\n }\n let changed = false;\n for (const { batch } of transition.pools)\n if (batch.numSplats > 0)\n changed = batch.setFadeProgress(progress) || changed;\n return changed;\n }\n\n private page(index: number) {\n let page = this.pages.get(index);\n if (!page) {\n const range = getRadChunkSpan(this.meta as RadMeta, index);\n page = {\n index,\n base: range.base,\n count: range.count,\n failures: 0,\n retryAt: 0,\n };\n this.pages.set(index, page);\n }\n return page;\n }\n\n private pump() {\n if (this.disposed || this.refinementStopped || !this.meta) return;\n let loading = 0;\n let pendingBytes = 0;\n for (const page of this.pages.values()) {\n if (page.load?.phase === \"decoding\") loading++;\n pendingBytes += pendingPageBytes(page);\n }\n const pending = new StreamByteBudget(\n streamPendingLimit(this.maxConcurrentLoads, this.maxPagePendingBytes),\n pendingBytes,\n );\n const now = performance.now();\n for (const index of this.wanted) {\n const page = this.page(index);\n if (page.storage || page.load || now < page.retryAt) continue;\n if (\n loading >= this.maxConcurrentLoads ||\n !pending.reserve(this.maxPagePendingBytes)\n )\n break;\n const load: PageLoad = {\n controller: new AbortController(),\n phase: \"decoding\",\n reservedBytes: this.maxPagePendingBytes,\n };\n page.load = load;\n loading++;\n void this.loadPage(page, load);\n }\n }\n\n private async loadPage(page: Page, load: PageLoad) {\n const { signal } = load.controller;\n const active = () =>\n !this.disposed && !signal.aborted && page.load === load;\n try {\n const data = await this.loader.loadChunk(page.index, signal, () => {\n if (!active()) return;\n load.phase = \"registering\";\n this.pump();\n });\n if (!active()) return;\n page.storage = { phase: \"decoded\", data };\n page.failures = 0;\n if (page.index === 0) this.setInitialBounds(data);\n this.reservePages();\n } catch (error) {\n if (active()) {\n if (this.loader.lodWorkerLost) return this.stopRefinement(error);\n page.retryAt = streamRetryAt(error, page.failures++);\n if (page.index === 0 && page.retryAt === Number.POSITIVE_INFINITY)\n this.rejectFirst(error);\n this.failed(error, page.index);\n }\n } finally {\n if (page.load === load) page.load = undefined;\n this.scheduleRetry();\n if (!this.disposed) {\n void this.requestSelection();\n this.changed();\n this.pump();\n }\n }\n }\n\n private setInitialBounds(data: RadStreamChunk) {\n // The page worker computes these bounds during Morton reordering.\n const bounds = data.centerOnlyBoundingBox;\n this.bounds.min.fromArray(bounds);\n this.bounds.max.fromArray(bounds, 3);\n if (this.bounds.min.equals(this.bounds.max))\n this.bounds.expandByScalar(Math.max(0.001, data.rootRadius ?? 1));\n }\n\n private findSlot(): PageSlot {\n for (const pool of this.pools) {\n const slot = pool.slots.indexOf(undefined);\n if (slot !== -1) return { pool, slot };\n }\n const capacity = this.pools.reduce(\n (sum, pool) => sum + pool.slots.length,\n 0,\n );\n // Each chunk owns at most one slot. An unallocated page therefore leaves\n // room below pageBudget, which is the dataset's total chunk count.\n const count = Math.min(8, this.pageBudget - capacity);\n const batch = new RadStreamBatch({\n pageSize: this.pageSize,\n pageCount: count,\n numSh: this.numSh,\n });\n batch.layers.mask = this.group.layers.mask;\n const pool: Pool = {\n batch,\n slots: Array(count).fill(undefined),\n };\n this.pools.push(pool);\n return { pool, slot: 0 };\n }\n\n private reservePages() {\n for (const page of this.pages.values()) {\n const storage = page.storage;\n if (storage?.phase !== \"decoded\" || storage.allocation) continue;\n const available = this.findSlot();\n const { pool, slot } = available;\n pool.slots[slot] = page;\n storage.allocation = available;\n this.revision++;\n }\n }\n\n private uploadPages() {\n let changed = false;\n const pages = new Set([...(this.ready?.pages ?? []), ...this.wanted]);\n for (const index of pages) {\n const page = this.pages.get(index);\n const storage = page?.storage;\n if (!page || storage?.phase !== \"decoded\" || !storage.allocation)\n continue;\n const { pool, slot } = storage.allocation;\n pool.batch.source.writePage(slot, storage.data);\n page.storage = { phase: \"resident\", allocation: storage.allocation };\n page.expiresAt = undefined;\n changed = true;\n }\n return changed;\n }\n\n private releasePage(page: Page) {\n const allocation = page.storage?.allocation;\n if (allocation) {\n const { pool, slot } = allocation;\n pool.slots[slot] = undefined;\n }\n page.storage = undefined;\n page.expiresAt = undefined;\n this.loader.releaseChunk(page.index);\n this.revision++;\n }\n\n private releaseUnused(now: number, allowRelease: boolean) {\n let changed = false;\n for (const page of this.pages.values()) {\n const allocation = page.storage?.allocation;\n if (!allocation || page.index === 0) continue;\n const { pool, slot } = allocation;\n if (\n this.displayed?.pages.has(page.index) ||\n this.wanted.has(page.index) ||\n pool.batch.source.isPageSelected(slot)\n ) {\n page.expiresAt = undefined;\n continue;\n }\n page.expiresAt ??= now + this.cooldownMs;\n // A traversal snapshot delays release without renewing unused pages.\n if (\n !allowRelease ||\n now < page.expiresAt ||\n this.isPagePinned(page.index)\n )\n continue;\n this.releasePage(page);\n changed = true;\n }\n // Like streamed SOG, release source storage once its contents retire.\n for (let index = this.pools.length - 1; index >= 0; index--) {\n const pool = this.pools[index];\n if (pool.slots.every((page) => page === undefined)) {\n pool.batch.dispose();\n this.pools.splice(index, 1);\n changed = true;\n }\n }\n return changed;\n }\n\n /** Map a raycast hit's rendered index back to its stable file index. */\n getGlobalIndex(mesh: THREE.Object3D, renderedIndex: number) {\n const pool = this.pools.find(({ batch }) => batch === mesh);\n if (!pool) throw new Error(\"Mesh does not belong to this RAD dataset\");\n return pool.batch.source.getSourceIndex(renderedIndex);\n }\n\n private changed() {\n if (!this.disposed) notifyStreamChange(this.options);\n }\n\n private failed(error: unknown, index: number) {\n notifyStreamError(this.options, error, this.loader.getChunkUrl(index));\n }\n\n private stopRefinement(error: unknown) {\n this.refinementStopped = true;\n this.ready = undefined;\n this.preparation = undefined;\n this.wanted.clear();\n this.retryTimer.dispose();\n for (const page of this.pages.values()) page.load?.controller.abort(error);\n this.loader.dispose();\n for (const page of this.pages.values())\n if (page.storage?.phase === \"decoded\") this.releasePage(page);\n this.rejectFirst(error);\n this.failed(error, -1);\n this.changed();\n }\n\n private scheduleRetry() {\n if (!this.refinementStopped) this.retryTimer.update(this.retryDeadlines());\n }\n\n private *retryDeadlines() {\n for (const index of this.wanted) {\n const page = this.pages.get(index);\n if (page && !page.storage) yield page.retryAt;\n }\n }\n\n private readonly retryTimer = new RetryTimer(() => this.changed());\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.retryTimer.dispose();\n const reason = new DOMException(\"RAD scheduler disposed\", \"AbortError\");\n this.abort.abort(reason);\n this.rejectFirst(reason);\n for (const page of this.pages.values()) page.load?.controller.abort(reason);\n this.loader.dispose();\n this.preparation = undefined;\n for (const { batch } of this.pools) batch.dispose();\n this.pools.length = 0;\n this.pages.clear();\n this.clearSelectionState();\n this.traversal = undefined;\n this.meta = undefined;\n this.bounds.makeEmpty();\n this.views = [];\n }\n}\n","import type { Box3 } from \"three\";\nimport { IndexedSplats } from \"./IndexedSplats\";\nimport {\n type ReorderedSplatResult,\n SPLAT_TEX_HEIGHT,\n SPLAT_TEX_WIDTH,\n} from \"./defines\";\nimport { resetSplatBounds, unionSplatBounds } from \"./splatData\";\nimport { getTextureSize } from \"./textureLayout\";\n\n// Small allocation blocks avoid a separate 2048-Splat texture row per region.\nconst BLOCK_BITS = 6;\nconst BLOCK_SIZE = 1 << BLOCK_BITS;\nconst MIN_LAYER_SIZE = 8192;\n\nexport function sogBatchAllocationSize(count: number) {\n return Math.ceil(count / BLOCK_SIZE) * BLOCK_SIZE;\n}\n\nexport function sogBatchTextureLayout(count: number) {\n // Grow the layer dimensions instead of splitting a chunk into more Meshes.\n // Keep the same backing-array alignment as Splats to avoid a second copy.\n const aligned = getTextureSize(count).maxSplats;\n const layerSize = Math.min(\n SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT,\n Math.max(MIN_LAYER_SIZE, 2 ** Math.ceil(Math.log2(aligned / 256))),\n );\n return {\n capacity: Math.ceil(aligned / layerSize) * layerSize,\n layerSize,\n };\n}\n\n/** Independently visible regions in fixed source slots. */\nexport class SogRegionSplats extends IndexedSplats {\n private readonly activeRanges = new Map<number, number>();\n private indicesDirty = false;\n private boundsDirty = true;\n private readonly regionBounds = new Map<\n number,\n { centers: Float32Array; full: Float32Array }\n >();\n\n constructor(count: number, numSh: number) {\n const { capacity, layerSize } = sogBatchTextureLayout(count);\n super({ capacity, layerSize, numSh, blockBits: BLOCK_BITS });\n }\n\n write(start: number, data: ReorderedSplatResult) {\n if (\n data.centerOnlyBoundingBox?.length !== 6 ||\n data.boundingBox?.length !== 6\n )\n throw new Error(\"SOG region bounds must contain six values\");\n this.writeRecords(start, data, sogBatchAllocationSize(data.numSplats));\n this.regionBounds.set(start, {\n centers: data.centerOnlyBoundingBox.slice(),\n full: data.boundingBox.slice(),\n });\n if (this.activeRanges.has(start)) this.boundsDirty = true;\n }\n\n setOpacity(start: number, count: number, opacity: number) {\n this.assertLive();\n // The scheduler supplies block-aligned slots and clamped fade values.\n const previous = this.opacities.getOpacity(start);\n if (!this.opacities.setOpacity(start, count, opacity)) return;\n const visible = Math.fround(opacity) > 0;\n const visibilityChanged = previous > 0 !== visible;\n if (visibilityChanged) {\n if (visible) this.activeRanges.set(start, count);\n else this.activeRanges.delete(start);\n this.numSplats += visible ? count : -count;\n this.indicesDirty = true;\n this.boundsDirty = true;\n }\n return { visibilityChanged };\n }\n\n /** The batch hides the region before releasing its slot. */\n release(start: number) {\n this.assertLive();\n this.regionBounds.delete(start);\n this.releaseSpatialBounds(start);\n }\n\n override getBoundingBox(centersOnly = true, target?: Box3) {\n this.assertLive();\n if (this.boundsDirty) {\n resetSplatBounds(this.centerOnlyBounds);\n resetSplatBounds(this.bounds);\n for (const start of this.activeRanges.keys()) {\n const bounds = this.regionBounds.get(start);\n if (!bounds) throw new Error(\"Visible SOG region has no cached bounds\");\n unionSplatBounds(this.centerOnlyBounds, bounds.centers);\n unionSplatBounds(this.bounds, bounds.full);\n }\n this.boundsDirty = false;\n }\n return super.getBoundingBox(centersOnly, target);\n }\n\n override getByteLength() {\n return super.getByteLength() + this.regionBounds.size * 48;\n }\n\n protected override ensureIndices() {\n if (!this.indicesDirty) return;\n const indices = this.prepareIndices(this.numSplats);\n let target = 0;\n for (const [start, count] of this.activeRanges)\n for (let source = start; source < start + count; source++) {\n this.visibleIndices[source] = target;\n indices[target++] = source;\n }\n this.indicesDirty = false;\n }\n\n override dispose() {\n super.dispose();\n this.activeRanges.clear();\n this.regionBounds.clear();\n this.indicesDirty = false;\n }\n}\n","import type * as THREE from \"three\";\nimport { SogRegionSplats } from \"../../../data/SogRegionSplats\";\nimport type { ReorderedSplatResult } from \"../../../data/defines\";\nimport { SplatMesh } from \"../../../scene/SplatMesh\";\n\n/** Regions share one source, one scene node and one accumulator generation call. */\nexport class SogStreamBatch extends SplatMesh {\n private readonly source: SogRegionSplats;\n private readonly slots = new Map<number, number>();\n\n constructor(\n capacity: number,\n readonly numSh: number,\n private readonly group: THREE.Group,\n private readonly onEmpty: () => void,\n ) {\n const source = new SogRegionSplats(capacity, numSh);\n super({ splats: source });\n this.source = source;\n this.name = \"sog-batch\";\n }\n\n get residentBytes() {\n return this.source.residentBytes;\n }\n\n writeRegion(start: number, data: ReorderedSplatResult) {\n const count = data.numSplats;\n // The scheduler assigns disjoint fixed slots; only occupancy changes.\n this.source.write(start, data);\n this.slots.set(start, count);\n }\n\n setRegionOpacity(start: number, opacity: number) {\n const count = this.slots.get(start);\n if (count === undefined) return;\n const changed = this.source.setOpacity(start, count, opacity);\n if (!changed) return;\n if (changed.visibilityChanged) {\n this.numSplats = this.source.getNumSplats();\n this.updateMappingVersion();\n if (this.numSplats > 0 && this.parent !== this.group) {\n this.layers.mask = this.group.layers.mask;\n this.group.add(this);\n } else if (this.numSplats === 0) this.removeFromParent();\n } else this.updateVersion({ sort: false });\n }\n\n releaseRegion(start: number) {\n if (!this.slots.has(start)) return;\n this.setRegionOpacity(start, 0);\n this.source.release(start);\n this.slots.delete(start);\n if (!this.slots.size) {\n this.dispose();\n this.onEmpty();\n }\n }\n}\n","import { WorkerRpc } from \"../../../runtime/WorkerRpc\";\nimport type { SogStreamRpcHandlers } from \"./worker\";\nimport BundledWorker from \"./worker?worker&inline\";\n\n/** Worker assigned either LOD traversal or retained chunk decoding. */\nexport class SogStreamWorker extends WorkerRpc<SogStreamRpcHandlers> {\n constructor(onDispose?: () => void) {\n super(new BundledWorker(), onDispose);\n }\n}\n","import { DefaultLoadingManager } from \"three\";\nimport type { Splats } from \"../../../data/Splats\";\nimport { WorkerTerminatedError } from \"../../../runtime/WorkerRpc\";\nimport { abortable } from \"../../../runtime/abort\";\nimport { getAssetBaseUrl } from \"../../assetUrl\";\nimport type { SplatLoadStatus } from \"../../loadTypes\";\nimport { joinBytes, readResponse, requestOptions } from \"../../source\";\nimport { StreamWorkerPool } from \"../StreamWorkerPool\";\nimport type { StreamRequestOptions } from \"../streamOptions\";\nimport { SogStreamWorker } from \"./SogStreamWorker\";\nimport type { SogLodMetadata } from \"./sogLod\";\nimport type { SogView } from \"./sogVisibility\";\nimport type { SogChunkInfo } from \"./workerHandlers\";\n\nexport type SogStreamLoaderOptions = StreamRequestOptions & {\n url: string;\n /** Returns owned data in file order, or with a complete source ID map. */\n loadChunk?: (url: string, signal: AbortSignal) => Promise<Splats>;\n};\n\n/** A retained worker cache; extraction transfers owned packed arrays to the caller. */\nexport class SogChunkSource {\n private released = false;\n constructor(\n private readonly worker: SogStreamWorker,\n private readonly id: number,\n readonly info: SogChunkInfo,\n private readonly onRelease: () => void,\n ) {}\n\n get alive() {\n return !this.released && !this.worker.disposed;\n }\n\n async extract(ranges: { start: number; count: number }[]) {\n if (!this.alive)\n throw new WorkerTerminatedError(\"Streaming chunk is no longer cached\");\n return this.worker.call(\"extractSogRegions\", { id: this.id, ranges });\n }\n\n dispose() {\n if (this.released) return;\n this.released = true;\n if (!this.worker.disposed)\n void this.worker.call(\"releaseSogChunk\", { id: this.id }).catch(() => {});\n this.onRelease();\n }\n}\n\n/** Dedicated LOD worker, bounded decoders and retained chunk cache handles. */\nexport class SogStreamLoader {\n private readonly lodWorker: SogStreamWorker;\n private readonly pool: StreamWorkerPool<SogStreamWorker>;\n private readonly controller = new AbortController();\n private initialization?: Promise<SogLodMetadata>;\n private baseUrl = \"\";\n private downloadedBytes = 0;\n private retainedIndexBytes = 0;\n\n constructor(\n private readonly options: SogStreamLoaderOptions,\n maxConcurrentLoads: number,\n onChange: () => void,\n ) {\n this.pool = new StreamWorkerPool(\n () => new SogStreamWorker(() => queueMicrotask(onChange)),\n maxConcurrentLoads,\n );\n this.lodWorker = new SogStreamWorker(() => queueMicrotask(onChange));\n }\n\n get stats() {\n return {\n downloadedBytes: this.downloadedBytes + this.pool.downloadedBytes,\n peakWasmMemoryBytes:\n this.pool.peakWasmMemoryBytes + this.lodWorker.peakWasmMemoryBytes,\n retainedIndexBytes: this.lodWorker.disposed ? 0 : this.retainedIndexBytes,\n };\n }\n\n private assertActive() {\n this.controller.signal.throwIfAborted();\n if (this.lodWorker.disposed) throw new Error(\"SOG LOD worker terminated\");\n }\n\n initialize(signal?: AbortSignal) {\n signal?.throwIfAborted();\n this.assertActive();\n this.initialization ??= this.readIndex().catch((error) => {\n this.dispose();\n throw error;\n });\n return abortable(this.initialization, signal);\n }\n\n private async readIndex() {\n const signal = this.controller.signal;\n const manager = this.options.manager ?? DefaultLoadingManager;\n const resolveBase =\n typeof document === \"undefined\" ? undefined : document.baseURI;\n const url = new URL(manager.resolveURL(this.options.url), resolveBase).href;\n const resourceUrl = new URL(this.options.url, resolveBase ?? url).href;\n this.baseUrl = getAssetBaseUrl(url) ?? resourceUrl;\n manager.itemStart(url);\n try {\n const response = await fetch(url, {\n ...requestOptions(this.options, url, resourceUrl),\n signal,\n });\n const { chunks, size } = await readResponse(\n response,\n Number.POSITIVE_INFINITY,\n (bytes) => {\n this.downloadedBytes += bytes;\n },\n signal,\n );\n const bytes = new Uint8Array(joinBytes(chunks, size)).buffer;\n this.assertActive();\n const { retainedIndexBytes, ...index } = await this.lodWorker.call(\n \"parseSogIndex\",\n {\n bytes,\n baseUrl: getAssetBaseUrl(response.url || url) ?? resourceUrl,\n },\n );\n this.assertActive();\n this.retainedIndexBytes = retainedIndexBytes;\n return index;\n } catch (error) {\n manager.itemError(url);\n throw error;\n } finally {\n manager.itemEnd(url);\n }\n }\n\n async selectLod(view: SogView, budget: number): Promise<Uint32Array> {\n this.assertActive();\n return this.lodWorker.call(\"selectSogLod\", { view, budget });\n }\n\n async load(url: string, count: number, signal: AbortSignal) {\n this.assertActive();\n const manager = this.options.manager ?? DefaultLoadingManager;\n return this.pool.run(\n {\n signal,\n manager,\n cancel: (worker, id) => worker.call(\"releaseSogChunk\", { id }),\n },\n async ({ worker, id, signal, retain, start, progress }) => {\n this.assertActive();\n let info: SogChunkInfo;\n if (this.options.loadChunk) {\n const custom = await this.options.loadChunk(url, signal);\n try {\n signal.throwIfAborted();\n info = await worker.call(\"cacheSogChunk\", {\n id,\n data: custom.takeData(),\n });\n } finally {\n custom.dispose();\n }\n } else {\n const resolveBase =\n typeof document === \"undefined\" ? this.baseUrl : document.baseURI;\n const resourceUrl = new URL(url, resolveBase).href;\n const resolved = new URL(manager.resolveURL(url), resolveBase).href;\n start(resolved);\n const sameOrigin =\n new URL(getAssetBaseUrl(resolved) ?? resourceUrl).origin ===\n new URL(this.baseUrl).origin;\n info = await worker.call(\n \"loadSogChunk\",\n {\n id,\n url: resolved,\n baseUrl: resourceUrl,\n fileType: \"sog\",\n requestHeader: sameOrigin\n ? this.options.requestHeader\n : undefined,\n withCredentials: sameOrigin && this.options.withCredentials,\n expectedSogCount: count < 0 ? undefined : count,\n },\n {\n onStatus: (data) => {\n const status = data as SplatLoadStatus;\n if (\"assetRequest\" in status)\n return worker.call(\"resolveAsset\", {\n requestId: status.assetRequest,\n url: new URL(manager.resolveURL(status.url), resolveBase)\n .href,\n });\n if (\"loaded\" in status) progress(status.loaded);\n },\n },\n );\n }\n signal.throwIfAborted();\n this.assertActive();\n return new SogChunkSource(worker, id, info, retain());\n },\n );\n }\n\n dispose() {\n if (this.controller.signal.aborted) return;\n this.controller.abort(\n new DOMException(\"SOG loader disposed\", \"AbortError\"),\n );\n this.pool.dispose(this.controller.signal.reason);\n this.lodWorker.dispose(this.controller.signal.reason);\n this.initialization = undefined;\n this.retainedIndexBytes = 0;\n }\n}\n","import { Box3, Vector3 } from \"three\";\n\nexport type SogLodRange = {\n leaf: number;\n level: number;\n /** -1 for an empty LOD, which has no backing file. */\n file: number;\n offset: number;\n count: number;\n};\n\nexport type SogLodLeaf = {\n id: number;\n /** Coarse to fine, with strictly increasing counts and decreasing levels. */\n lods: SogLodRange[];\n};\n\nexport type SogLodNode = {\n bound: Box3;\n children?: SogLodNode[];\n leaf?: SogLodLeaf;\n};\n\nexport type SogLodFile = {\n url: string;\n count: number;\n ranges: SogLodRange[];\n};\n\nexport type SogLodManifest = {\n tree: SogLodNode;\n leaves: SogLodLeaf[];\n /** Flattened in leaf/LOD order; each leaf's first entry is unused. */\n upgradeRatios: number[];\n files: SogLodFile[];\n environment?: string;\n};\n\nexport const SOG_LOD_STRIDE = 4;\n\nconst DISTANCE_BAND_MULTIPLIER = 1.5;\n\n/** Packed worker index. Float64 preserves source bounds and safe-integer counts. */\nexport type SogLodIndex = {\n /** Preorder nodes: min XYZ, max XYZ, next index after the subtree, leaf ID (-1 for interiors). */\n nodes: Float64Array;\n leafOffsets: Uint32Array;\n /** Per level: level, file, offset, count. */\n lods: Float64Array;\n /** Best reachable distance-error reduction per added splat, in LOD order. */\n upgradeRatios: Float32Array;\n urls: string[];\n counts: Float64Array;\n environment?: string;\n};\n\n/** Scheduler metadata; the complete spatial tree stays in the LOD worker. */\nexport type SogLodMetadata = Omit<SogLodIndex, \"nodes\" | \"upgradeRatios\"> & {\n /** Root min XYZ and max XYZ. */\n bounds: Float64Array;\n};\n\n/** Flatten the tree and ranges into transferable typed arrays. */\nexport function packSogLodIndex(manifest: SogLodManifest): SogLodIndex {\n const { leaves, files, environment } = manifest;\n const nodes = new Float64Array((leaves.length * 2 - 1) * 8);\n let nextNode = 0;\n const writeNode = (node: SogLodNode) => {\n const offset = nextNode++ * 8;\n node.bound.min.toArray(nodes, offset);\n node.bound.max.toArray(nodes, offset + 3);\n nodes[offset + 7] = node.leaf?.id ?? -1;\n for (const child of node.children ?? []) writeNode(child);\n nodes[offset + 6] = nextNode;\n };\n writeNode(manifest.tree);\n const leafOffsets = new Uint32Array(leaves.length + 1);\n let count = 0;\n for (const leaf of leaves) {\n leafOffsets[leaf.id] = count;\n count += leaf.lods.length;\n }\n leafOffsets[leaves.length] = count;\n const lods = new Float64Array(count * SOG_LOD_STRIDE);\n for (const leaf of leaves) {\n leaf.lods.forEach((lod, index) => {\n lods.set(\n [lod.level, lod.file, lod.offset, lod.count],\n (leafOffsets[leaf.id] + index) * SOG_LOD_STRIDE,\n );\n });\n }\n return {\n nodes,\n leafOffsets,\n lods,\n upgradeRatios: Float32Array.from(manifest.upgradeRatios),\n urls: files.map((file) => file.url),\n counts: Float64Array.from(files, (file) => file.count),\n environment,\n };\n}\n\n/** Materialize only leaves visited by the camera, preserving stable range identities. */\nexport function readSogLodLeaf(\n index: Pick<SogLodIndex, \"leafOffsets\" | \"lods\">,\n id: number,\n): SogLodLeaf {\n const leaf: SogLodLeaf = { id, lods: [] };\n const data = index.lods;\n for (let i = index.leafOffsets[id]; i < index.leafOffsets[id + 1]; i++) {\n const offset = i * SOG_LOD_STRIDE;\n leaf.lods.push({\n leaf: id,\n level: data[offset],\n file: data[offset + 1],\n offset: data[offset + 2],\n count: data[offset + 3],\n });\n }\n return leaf;\n}\n\nfunction fail(message: string): never {\n throw new Error(`Streamed SOG: ${message}`);\n}\n\nfunction object(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n fail(\"expected an object\");\n return value as Record<string, unknown>;\n}\n\nfunction integer(value: unknown, name: string): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0)\n fail(`invalid ${name}`);\n return value;\n}\n\nfunction resolve(value: unknown, baseUrl: string): string {\n if (typeof value !== \"string\" || !value) fail(\"invalid asset path\");\n return new URL(value, baseUrl).href;\n}\n\n/** Streamed SOG v1, including the earlier unversioned manifests. */\nexport function parseSogLodManifest(\n value: unknown,\n baseUrl: string,\n): SogLodManifest {\n const root = object(value);\n if (root.version !== undefined && root.version !== 1)\n fail(`unsupported version ${root.version}`);\n const levels = integer(root.lodLevels, \"lodLevels\");\n if (levels < 1) fail(\"lodLevels must be positive\");\n if (!Array.isArray(root.filenames)) fail(\"filenames must be an array\");\n const files: SogLodFile[] = [];\n const urls = new Map<string, number>();\n const fileIndices = root.filenames.map((path) => {\n const url = resolve(path, baseUrl);\n const existing = urls.get(url);\n if (existing !== undefined) return existing;\n urls.set(url, files.length);\n files.push({ url, count: 0, ranges: [] });\n return files.length - 1;\n });\n const leaves: SogLodLeaf[] = [];\n const counts = Array<number>(levels).fill(0);\n const parseNode = (value: unknown): SogLodNode => {\n const node = object(value);\n const bounds = object(node.bound);\n const vector = (value: unknown) => {\n if (\n !Array.isArray(value) ||\n value.length !== 3 ||\n !value.every(Number.isFinite)\n )\n fail(\"invalid bounding box\");\n return new Vector3(value[0], value[1], value[2]);\n };\n const bound = new Box3(vector(bounds.min), vector(bounds.max));\n if (bound.isEmpty()) fail(\"bounding box min exceeds max\");\n if (node.children !== undefined) {\n if (\n node.lods !== undefined ||\n !Array.isArray(node.children) ||\n node.children.length !== 2\n )\n fail(\"interior nodes must have exactly two children and no lods\");\n const children = node.children.map(parseNode);\n // Include children despite rounding in older writers' parent bounds.\n for (const child of children) bound.union(child.bound);\n return { bound, children };\n }\n const leaf: SogLodLeaf = { id: leaves.length, lods: [] };\n leaves.push(leaf);\n for (const [key, value] of Object.entries(object(node.lods))) {\n const level = Number(key);\n if (!/^\\d+$/.test(key) || String(level) !== key || level >= levels)\n fail(`invalid LOD level ${key}`);\n const entry = object(value);\n const count = integer(entry.count, \"splat count\");\n if (count === 0) continue;\n const fileIndex = integer(entry.file, \"file index\");\n if (fileIndex >= fileIndices.length) fail(\"file index is out of bounds\");\n const range: SogLodRange = {\n leaf: leaf.id,\n level,\n file: fileIndices[fileIndex],\n offset: integer(entry.offset, \"splat offset\"),\n count,\n };\n integer(range.offset + range.count, \"range end\");\n counts[level] += range.count;\n files[range.file].ranges.push(range);\n leaf.lods.push(range);\n }\n return { bound, leaf };\n };\n const tree = parseNode(root.tree);\n const bandWeights = new Float64Array(levels);\n for (let level = 1; level < levels; level++)\n bandWeights[level] = DISTANCE_BAND_MULTIPLIER ** (2 * (level - 1));\n const distanceErrors = new Float64Array(levels);\n const upgradeRatios: number[] = [];\n for (const leaf of leaves) {\n leaf.lods.sort((a, b) => b.level - a.level);\n const coarsest = leaf.lods[0];\n // Missing coarser data means this region was decimated away. Price its\n // first nonempty level as an upgrade instead of forcing it into coverage.\n if (coarsest && coarsest.level < levels - 1) {\n leaf.lods.unshift({\n leaf: leaf.id,\n level: coarsest.level + 1,\n file: -1,\n offset: 0,\n count: 0,\n });\n }\n // Include every level before pruning, even with equal or inverted counts.\n let error = 0;\n for (let i = leaf.lods.length - 1; i >= 0; i--) {\n const lod = leaf.lods[i];\n const finer = leaf.lods[i + 1];\n if (finer)\n error += Math.max(finer.count - lod.count, 1) * bandWeights[lod.level];\n distanceErrors[lod.level] = error;\n }\n leaf.lods.sort(\n (a, b) =>\n a.count - b.count || distanceErrors[a.level] - distanceErrors[b.level],\n );\n let bestError = Number.POSITIVE_INFINITY;\n leaf.lods = leaf.lods.filter((lod) => {\n if (distanceErrors[lod.level] >= bestError) return false;\n bestError = distanceErrors[lod.level];\n return true;\n });\n // Include pruned levels' errors when finding the best reachable upgrade ratio.\n if (leaf.lods.length) upgradeRatios.push(0);\n for (let i = 1; i < leaf.lods.length; i++) {\n const coarse = leaf.lods[i - 1];\n let ratio = 0;\n for (let j = i; j < leaf.lods.length; j++) {\n const reach = leaf.lods[j];\n ratio = Math.max(\n ratio,\n (distanceErrors[coarse.level] - distanceErrors[reach.level]) /\n (reach.count - coarse.count),\n );\n }\n upgradeRatios.push(ratio);\n }\n }\n for (const file of files) {\n file.ranges.sort((a, b) => a.offset - b.offset || a.count - b.count);\n const level = file.ranges[0]?.level;\n for (const range of file.ranges) {\n if (range.offset !== file.count || range.level !== level)\n fail(\"chunk ranges must cover one LOD without gaps or overlaps\");\n file.count += range.count;\n }\n }\n const count = counts.reduce((sum, value) => sum + value, 0);\n integer(count, \"total count\");\n if (root.count !== undefined && root.count !== count) fail(\"count mismatch\");\n if (\n root.counts !== undefined &&\n (!Array.isArray(root.counts) ||\n root.counts.length !== levels ||\n root.counts.some((count, level) => count !== counts[level]))\n )\n fail(\"per-LOD counts mismatch\");\n const environment =\n root.environment == null ? undefined : resolve(root.environment, baseUrl);\n if (environment && files.some((file) => file.url === environment))\n fail(\"environment must be separate from LOD chunks\");\n return { tree, leaves, upgradeRatios, files, environment };\n}\n\nexport type SogVisibleLeaf = { leaf: SogLodLeaf; weight: number };\n\n/** Reuse cached refinements up to the target, then split gaps of four or more. */\nexport function resolveSogLod(\n leaf: SogLodLeaf,\n target: SogLodRange,\n current: SogLodRange | undefined,\n isLoaded: (range: SogLodRange) => boolean,\n): {\n range: SogLodRange | undefined;\n load?: SogLodRange;\n /** Wait until range is attached before requesting the next LOD. */\n refinement?: boolean;\n} {\n if (target.count === 0) return { range: undefined };\n if (current === target || isLoaded(target)) return { range: target };\n\n const targetIndex = leaf.lods.indexOf(target);\n const currentIndex = current ? leaf.lods.indexOf(current) : -1;\n // Prefer the finest cached refinement without going beyond the target.\n let index = targetIndex - 1;\n while (\n index > currentIndex &&\n (leaf.lods[index].count === 0 || !isLoaded(leaf.lods[index]))\n )\n index--;\n const range = index > currentIndex ? leaf.lods[index] : current;\n if (!range) return { range, load: leaf.lods.find((lod) => lod.count > 0) };\n\n let load = target;\n if (range.level - target.level >= 4) {\n const midpoint = Math.floor((range.level + target.level) / 2);\n let nextIndex = index + 1;\n // Missing or dominated levels advance to the finer side of the midpoint.\n while (nextIndex < targetIndex && leaf.lods[nextIndex].level > midpoint)\n nextIndex++;\n load = leaf.lods[nextIndex];\n }\n return { range, load, refinement: true };\n}\n\n/** Distance bands within a splat budget, using a small heap. */\nexport function selectSogLods(\n visible: SogVisibleLeaf[],\n budget: number,\n manifest: Pick<SogLodIndex, \"leafOffsets\" | \"upgradeRatios\">,\n): Map<number, SogLodRange> {\n const { leafOffsets, upgradeRatios } = manifest;\n let remaining = budget;\n type Upgrade = SogVisibleLeaf & { index: number; score: number };\n const selected = new Map<number, SogLodRange>();\n const heap: Upgrade[] = [];\n const better = (a: Upgrade, b: Upgrade) =>\n a.score > b.score || (a.score === b.score && a.leaf.id < b.leaf.id);\n const push = (item: Upgrade) => {\n let index = heap.length;\n heap.push(item);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (!better(item, heap[parent])) break;\n heap[index] = heap[parent];\n index = parent;\n }\n heap[index] = item;\n };\n const pop = () => {\n const first = heap[0];\n const last = heap.pop() as Upgrade;\n if (heap.length) {\n let index = 0;\n while (index * 2 + 1 < heap.length) {\n let child = index * 2 + 1;\n if (child + 1 < heap.length && better(heap[child + 1], heap[child]))\n child++;\n if (!better(heap[child], last)) break;\n heap[index] = heap[child];\n index = child;\n }\n heap[index] = last;\n }\n return first;\n };\n const upgrade = (\n leaf: SogLodLeaf,\n weight: number,\n index: number,\n ceiling = Number.POSITIVE_INFINITY,\n ) => {\n if (index >= leaf.lods.length) return;\n // A later step can have a higher ratio; keep it at the priority that opened it.\n const score = Math.min(\n weight * upgradeRatios[leafOffsets[leaf.id] + index],\n ceiling,\n );\n push({ leaf, weight, index, score });\n };\n for (const { leaf, weight } of visible) {\n const coarse = leaf.lods[0];\n if (!coarse) continue;\n selected.set(leaf.id, coarse);\n remaining -= coarse.count;\n upgrade(leaf, weight, 1);\n }\n while (heap.length) {\n const { leaf, weight, index, score } = pop();\n const coarse = leaf.lods[index - 1];\n const fine = leaf.lods[index];\n // Stop at the first unaffordable upgrade; skipping it makes unrelated\n // cheaper regions flicker as the camera moves. Coverage remains the floor.\n if (fine.count - coarse.count > remaining) break;\n remaining -= fine.count - coarse.count;\n selected.set(leaf.id, fine);\n upgrade(leaf, weight, index + 1, score);\n }\n return selected;\n}\n","import * as THREE from \"three\";\nimport { streamViews } from \"../StreamCameras\";\nimport {\n type SogLodIndex,\n type SogLodLeaf,\n type SogVisibleLeaf,\n readSogLodLeaf,\n selectSogLods,\n} from \"./sogLod\";\n\nexport type SogCamera = {\n modelView: number[];\n projection: number[];\n coordinateSystem: THREE.CoordinateSystem;\n reversedDepth: boolean;\n};\n\nexport type SogView = {\n /** The registered cameras that see the group; selection serves all of them. */\n cameras: SogCamera[];\n shown: boolean;\n};\n\ntype CameraState = {\n modelView: THREE.Matrix4;\n frustum: THREE.Frustum;\n cameraPosition: THREE.Vector3;\n fovScale: number;\n};\n\n/**\n * Capture the cameras that see the group without traversing the manifest or\n * reducing matrix precision. WebXR selects detail from each eye's current pose and frustum.\n */\nexport function captureSogView(\n cameras: readonly THREE.Camera[],\n group: THREE.Object3D,\n): SogView {\n group.updateWorldMatrix(true, false);\n const views: SogCamera[] = [];\n for (const camera of streamViews(cameras)) {\n views.push({\n // Invert matrixWorld like the splat projection: Camera.matrixWorldInverse\n // can omit rig scale.\n modelView: new THREE.Matrix4()\n .copy(camera.matrixWorld)\n .invert()\n .multiply(group.matrixWorld).elements,\n projection: camera.projectionMatrix.toArray(),\n coordinateSystem: camera.coordinateSystem,\n reversedDepth: camera.reversedDepth,\n });\n }\n let shown = cameras.length > 0;\n for (let node: THREE.Object3D | null = group; node; node = node.parent)\n shown &&= node.visible;\n return { cameras: views, shown };\n}\n\n/** Stable key of a view, for skipping unchanged selection requests. */\nexport function getSogViewKey(view: SogView) {\n return view.cameras\n .map(\n (camera) =>\n `${camera.modelView.join(\",\")}/${camera.projection.join(\",\")}/${camera.coordinateSystem}/${camera.reversedDepth}`,\n )\n .join(\";\");\n}\n\n/** Worker traversal state keeps leaf identities stable between selections. */\nexport class SogVisibility {\n private readonly leaves = new Map<number, SogLodLeaf>();\n private readonly cameras: CameraState[] = [];\n private readonly clip = new THREE.Matrix4();\n private readonly bound = new THREE.Box3();\n private readonly closest = new THREE.Vector3();\n private readonly inverseModelView = new THREE.Matrix4();\n\n constructor(\n private readonly manifest: Pick<\n SogLodIndex,\n \"nodes\" | \"leafOffsets\" | \"lods\" | \"upgradeRatios\"\n >,\n ) {}\n\n private prepareCameras(view: SogView) {\n const cameras = this.cameras;\n cameras.length = Math.min(cameras.length, view.cameras.length);\n view.cameras.forEach((camera, index) => {\n let state = cameras[index];\n if (!state) {\n state = {\n modelView: new THREE.Matrix4(),\n frustum: new THREE.Frustum(),\n cameraPosition: new THREE.Vector3(),\n fovScale: 1,\n };\n cameras[index] = state;\n }\n state.modelView.fromArray(camera.modelView);\n this.clip.fromArray(camera.projection).multiply(state.modelView);\n this.inverseModelView.copy(state.modelView).invert();\n state.cameraPosition.setFromMatrixPosition(this.inverseModelView);\n state.frustum.setFromProjectionMatrix(\n this.clip,\n camera.coordinateSystem,\n camera.reversedDepth,\n );\n const projection = camera.projection;\n state.fovScale =\n projection[11] === 0\n ? 1\n : 1 /\n (Math.max(Math.abs(projection[0]), Math.abs(projection[5])) *\n Math.tan(Math.PI / 8));\n });\n return cameras;\n }\n\n private collect(view: SogView) {\n const cameras = this.prepareCameras(view);\n const visible: SogVisibleLeaf[] = [];\n const { shown } = view;\n const nodes = this.manifest.nodes;\n for (let index = 0; shown && index < nodes.length / 8; ) {\n const offset = index * 8;\n this.bound.min.fromArray(nodes, offset);\n this.bound.max.fromArray(nodes, offset + 3);\n const id = nodes[offset + 7];\n if (id < 0) {\n // A branch only needs one view that sees it.\n if (cameras.some(({ frustum }) => frustum.intersectsBox(this.bound)))\n index++;\n else index = nodes[offset + 6];\n continue;\n }\n // A leaf tests each view once for visibility and detail together: the\n // nearest view that sees it decides its detail.\n let seen = false;\n let weight = 1e-12;\n for (const { modelView, frustum, cameraPosition, fovScale } of cameras) {\n if (!frustum.intersectsBox(this.bound)) continue;\n seen = true;\n this.bound\n .clampPoint(cameraPosition, this.closest)\n .applyMatrix4(modelView);\n // World-space distance to the box, without weighting by its radius.\n const distance = Math.max(this.closest.length() * fovScale, 1e-6);\n weight = Math.max(weight, 1 / distance ** 1.5);\n }\n if (!seen) {\n index = nodes[offset + 6];\n continue;\n }\n index++;\n let leaf = this.leaves.get(id);\n if (!leaf) {\n leaf = readSogLodLeaf(this.manifest, id);\n this.leaves.set(id, leaf);\n }\n visible.push({ leaf, weight });\n }\n return visible;\n }\n\n /** Transfer only [leaf ID, LOD ordinal] pairs in loading priority order. */\n select(view: SogView, budget: number): Uint32Array {\n const visible = this.collect(view);\n const targets = selectSogLods(visible, budget, this.manifest);\n visible.sort((a, b) => b.weight - a.weight || a.leaf.id - b.leaf.id);\n const result = new Uint32Array(targets.size * 2);\n let offset = 0;\n for (const { leaf } of visible) {\n const target = targets.get(leaf.id);\n if (!target) continue;\n result[offset++] = leaf.id;\n result[offset++] = leaf.lods.indexOf(target);\n }\n return result;\n }\n}\n","import * as THREE from \"three\";\nimport { sogBatchAllocationSize } from \"../../../data/SogRegionSplats\";\nimport type { ReorderedSplatResult } from \"../../../data/defines\";\nimport {\n getSplatByteLength,\n getSplatShDegree,\n getSplatTextureBytes,\n} from \"../../../data/splatData\";\nimport { RetryTimer } from \"../../../runtime/retry\";\nimport { StreamByteBudget } from \"../StreamByteBudget\";\nimport { StreamCameras } from \"../StreamCameras\";\nimport {\n type StreamSchedulerOptions,\n type StreamStats,\n notifyStreamChange,\n notifyStreamError,\n positiveInteger,\n streamPendingLimit,\n streamRetryAt,\n streamSettings,\n} from \"../streamOptions\";\nimport { SogStreamBatch } from \"./SogStreamBatch\";\nimport {\n type SogChunkSource,\n SogStreamLoader,\n type SogStreamLoaderOptions,\n} from \"./SogStreamLoader\";\nimport {\n SOG_LOD_STRIDE,\n type SogLodFile,\n type SogLodLeaf,\n type SogLodMetadata,\n type SogLodRange,\n readSogLodLeaf,\n resolveSogLod,\n} from \"./sogLod\";\nimport { type SogView, captureSogView, getSogViewKey } from \"./sogVisibility\";\n\nexport type SogStreamSchedulerOptions = SogStreamLoaderOptions &\n StreamSchedulerOptions;\nexport type SogStreamStats = StreamStats & { visibleRegions: number };\n\ntype Chunk = {\n file: SogLodFile;\n /** Stable slots keep a chunk together regardless of region arrival order. */\n batchSlots: Map<number, number>;\n batchCapacity: number;\n batch?: SogStreamBatch;\n data?: SogChunkSource;\n controller?: AbortController;\n expiresAt?: number;\n failures: number;\n retryAt: number;\n};\n\ntype Region = {\n batch: SogStreamBatch;\n start: number;\n range: SogLodRange;\n opacity: number;\n expiresAt?: number;\n};\n\ntype PendingRegion = {\n range: SogLodRange;\n chunk: Chunk;\n bytes: number;\n data?: ReorderedSplatResult;\n};\n\ntype LeafState = {\n target?: SogLodRange;\n current?: Region;\n /** Keep at most one previous LOD until its fade-out finishes. */\n outgoing?: Region;\n pending?: PendingRegion;\n};\n\nconst EMPTY_SELECTION = new Uint32Array(0);\n\nfunction* retryDeadlines(chunks: Iterable<Chunk>) {\n for (const chunk of chunks) yield chunk.retryAt;\n}\n\n/** Camera-driven Streamed SOG loading with per-chunk sources and region fades. */\nexport class SogStreamScheduler {\n readonly group: THREE.Group;\n readonly initialized: Promise<this>;\n readonly firstRenderable: Promise<this>;\n readonly cooldownMs: number;\n readonly fadeDurationMs: number;\n readonly maxConcurrentLoads: number;\n\n private _splatBudget: number;\n private readonly options: SogStreamSchedulerOptions;\n private readonly loader: SogStreamLoader;\n private readonly abort = new AbortController();\n private readonly streamCameras = new StreamCameras();\n private manifest?: SogLodMetadata;\n private readonly lodLeaves = new Map<number, SogLodLeaf>();\n private view?: SogView;\n private lastRequestedKey = \"\";\n private selecting = false;\n private selection: Uint32Array = EMPTY_SELECTION;\n private chunks: Chunk[] = [];\n /** Chunks with a batch, cached source or in-flight load. */\n private readonly activeChunks = new Set<Chunk>();\n private environment?: Chunk;\n private leaves = new Map<number, LeafState>();\n private wanted = new Set<Chunk>();\n private readonly fades = new Map<\n Region,\n { from: number; to: number; startedAt: number }\n >();\n private shown = true;\n private disposed = false;\n private resolveFirst!: (value: this) => void;\n private rejectFirst!: (error: unknown) => void;\n\n constructor(options: SogStreamSchedulerOptions) {\n this.options = { ...options };\n this.group = options.group ?? new THREE.Group();\n const settings = streamSettings(options);\n this._splatBudget = settings.splatBudget;\n this.cooldownMs = settings.cooldownMs;\n this.fadeDurationMs = settings.fadeDurationMs;\n this.maxConcurrentLoads = settings.maxConcurrentLoads;\n this.loader = new SogStreamLoader(\n this.options,\n this.maxConcurrentLoads,\n () => this.changed(),\n );\n this.firstRenderable = new Promise((resolve, reject) => {\n this.resolveFirst = resolve;\n this.rejectFirst = reject;\n });\n this.initialized = this.initialize().catch((error) => {\n this.rejectFirst(error);\n this.loader.dispose();\n throw error;\n });\n // Both readiness promises are optional to observe; errors remain available\n // to callers awaiting them and chunk failures go through onError.\n void this.initialized.catch(() => {});\n void this.firstRenderable.catch(() => {});\n }\n\n /** Visible-point target, including the environment. Reassign to reselect LODs. */\n get splatBudget(): number {\n return this._splatBudget;\n }\n\n set splatBudget(value: number) {\n if (value === this._splatBudget) return;\n this._splatBudget = positiveInteger(value, \"splatBudget\");\n void this.requestSelection();\n }\n\n get stats(): SogStreamStats {\n const { retainedIndexBytes, ...loaderStats } = this.loader.stats;\n const manifest = this.manifest;\n const stats: SogStreamStats = {\n visibleSplats: 0,\n visibleRegions: 0,\n visibleMeshes: 0,\n residentMeshes: 0,\n residentChunks: 0,\n residentBytes:\n retainedIndexBytes +\n (manifest\n ? manifest.bounds.byteLength +\n manifest.leafOffsets.byteLength +\n manifest.lods.byteLength +\n manifest.counts.byteLength\n : 0),\n pendingBytes: 0,\n loadingChunks: 0,\n ...loaderStats,\n };\n for (const { batch, data, controller } of this.activeChunks) {\n if (batch) {\n stats.residentMeshes++;\n stats.residentBytes += batch.residentBytes;\n if (this.shown && batch.numSplats > 0) {\n stats.visibleMeshes++;\n stats.visibleSplats += batch.numSplats;\n }\n }\n if (data?.alive) {\n stats.residentChunks++;\n stats.residentBytes += data.info.byteLength;\n }\n if (controller) stats.loadingChunks++;\n }\n for (const { current, outgoing, pending } of this.leaves.values()) {\n stats.pendingBytes += pending?.bytes ?? 0;\n if (this.shown) {\n if (current && Math.fround(current.opacity) > 0) stats.visibleRegions++;\n if (outgoing && Math.fround(outgoing.opacity) > 0)\n stats.visibleRegions++;\n }\n }\n return stats;\n }\n\n /** Group-local bounds from the index; available after initialized resolves. */\n getBoundingBox(): THREE.Box3 {\n const box = new THREE.Box3();\n if (this.manifest) {\n box.min.fromArray(this.manifest.bounds, 0);\n box.max.fromArray(this.manifest.bounds, 3);\n }\n return box;\n }\n\n private async initialize(): Promise<this> {\n const manifest = await this.loader.initialize(this.abort.signal);\n this.abort.signal.throwIfAborted();\n this.manifest = manifest;\n const files: SogLodFile[] = manifest.urls.map((url, index) => ({\n url,\n count: manifest.counts[index],\n ranges: [],\n }));\n if (this.manifest.environment)\n files.push({ url: this.manifest.environment, count: -1, ranges: [] });\n this.chunks = files.map((file) => ({\n file,\n batchSlots: new Map(),\n batchCapacity: 0,\n failures: 0,\n retryAt: 0,\n }));\n for (\n let offset = 0;\n offset < manifest.lods.length;\n offset += SOG_LOD_STRIDE\n ) {\n if (manifest.lods[offset + 3] === 0) continue;\n this.addBatchRange(\n this.chunks[manifest.lods[offset + 1]],\n manifest.lods[offset + 2],\n manifest.lods[offset + 3],\n );\n }\n if (this.manifest.environment)\n this.environment = this.chunks[this.chunks.length - 1];\n if (!this.environment && !this.manifest.lods.length)\n this.resolveFirst(this);\n this.changed();\n return this;\n }\n\n /** Cameras that select detail, in registration order. */\n get cameras(): readonly THREE.Camera[] {\n return this.streamCameras.cameras;\n }\n\n hasCamera(camera: THREE.Camera) {\n return this.streamCameras.has(camera);\n }\n\n /**\n * Select detail for this camera on each update. Detail follows distance,\n * so it needs no resolution. For WebXR register renderer.xr.getCamera(): it\n * selects the greatest detail needed by any eye that sees the region. Returns whether the camera was\n * newly added.\n */\n setCamera(camera: THREE.Camera) {\n return this.streamCameras.add(camera);\n }\n\n /** Stop selecting detail for this camera. Returns whether it was registered. */\n deleteCamera(camera: THREE.Camera) {\n return this.streamCameras.delete(camera);\n }\n\n /**\n * Call before rendering. Returns whether the displayed data changed. Each\n * leaf uses the distance of the nearest registered camera that sees it.\n */\n update(): boolean {\n if (this.disposed) return false;\n const cameras = this.streamCameras.seeing(this.group.layers);\n if (!this.manifest) return false;\n for (const chunk of this.activeChunks) {\n this.pruneChunk(chunk);\n if (chunk.batch) chunk.batch.layers.mask = this.group.layers.mask;\n }\n const view = captureSogView(cameras, this.group);\n // Three can register the XR rig before it supplies the first eye poses.\n // Preserve displayed regions and in-flight loads until those poses arrive.\n if (view.shown && !view.cameras.length) return false;\n this.view = view;\n const { shown } = this.view;\n this.shown = shown;\n if (!shown) {\n this.selection = EMPTY_SELECTION;\n this.lastRequestedKey = \"\";\n }\n const now = performance.now();\n const { selected, refinements } = this.selectRegions();\n const changed = this.applySelection(selected, now);\n this.updateRequests(refinements, now);\n // Start the new view's decision before retiring caches it may reuse.\n void this.requestSelection();\n this.releaseUnused(now, !shown || !this.selecting);\n if (\n shown &&\n [...this.leaves.values()].some(\n ({ current, outgoing }) =>\n (current?.opacity ?? 0) > 0 || (outgoing?.opacity ?? 0) > 0,\n )\n )\n this.resolveFirst(this);\n if (changed) this.changed();\n return changed;\n }\n\n private async requestSelection() {\n const view = this.view;\n if (\n this.disposed ||\n !this.shown ||\n this.selecting ||\n !this.manifest?.lods.length ||\n !view\n )\n return;\n const splatBudget = this.splatBudget;\n const budget = Math.max(\n 0,\n splatBudget - Math.max(0, this.environment?.file.count ?? 0),\n );\n const key = `${getSogViewKey(view)}/${splatBudget}/${budget}`;\n if (key === this.lastRequestedKey) return;\n this.lastRequestedKey = key;\n this.selecting = true;\n try {\n const selection = await this.loader.selectLod(view, budget);\n if (this.disposed || !this.shown || splatBudget !== this.splatBudget)\n return;\n // Keep one completed result; accepting camera lag avoids starving motion.\n // Resolve it against current caches, never worker-time resource snapshots.\n this.selection = selection;\n const { selected, refinements } = this.selectRegions();\n const now = performance.now();\n this.queueExtractions(selected, now);\n this.updateRequests(refinements, now);\n // Retire after every accepted decision so motion cannot postpone cleanup.\n this.releaseUnused(now, true);\n this.changed();\n } catch (error) {\n if (!this.disposed) {\n this.rejectFirst(error);\n this.failed(error, this.options.url);\n this.dispose();\n }\n } finally {\n this.selecting = false;\n // Updates replace the latest view while this task runs; no request queue.\n void this.requestSelection();\n }\n }\n\n private updateRequests(refinements: [LeafState, Chunk][], now: number) {\n // Establish coverage before starting the next LOD request.\n for (const [leaf, chunk] of refinements) {\n if (leaf.current?.range === leaf.target) this.wanted.add(chunk);\n }\n for (const chunk of this.activeChunks) {\n if (chunk.controller && !this.wanted.has(chunk)) chunk.controller.abort();\n }\n this.pump(now);\n }\n\n private selectRegions() {\n for (const leaf of this.leaves.values()) leaf.target = undefined;\n const selected: LeafState[] = [];\n this.wanted.clear();\n const show = (range: SogLodRange) => {\n const leaf = this.leafState(range.leaf);\n leaf.target = range;\n selected.push(leaf);\n if (leaf.current?.range !== range) this.wanted.add(this.chunkFor(range));\n };\n if (this.shown && this.environment) {\n const current = this.leaves.get(-1)?.current;\n const range = current?.range ?? this.environment.file.ranges[0];\n if (range && (current || this.environment.data?.alive)) show(range);\n else if (this.environment.file.count !== 0)\n this.wanted.add(this.environment);\n }\n const refinements: [LeafState, Chunk][] = [];\n for (\n let offset = 0;\n this.shown && offset < this.selection.length;\n offset += 2\n ) {\n const id = this.selection[offset];\n let leaf = this.lodLeaves.get(id);\n if (!leaf) {\n leaf = readSogLodLeaf(this.manifest as SogLodMetadata, id);\n this.lodLeaves.set(id, leaf);\n }\n const target = leaf.lods[this.selection[offset + 1]];\n const state = this.leafState(leaf.id);\n const { range, load, refinement } = resolveSogLod(\n leaf,\n target,\n state.current?.range,\n (lod) => this.chunks[lod.file].data?.alive === true,\n );\n if (range) show(range);\n if (load) {\n const chunk = this.chunks[load.file];\n if (range && refinement) refinements.push([state, chunk]);\n else this.wanted.add(chunk);\n }\n }\n for (const leaf of this.leaves.values()) {\n if (leaf.pending?.data && leaf.target !== leaf.pending.range)\n leaf.pending = undefined;\n }\n return { selected, refinements };\n }\n\n private leafState(id: number) {\n let leaf = this.leaves.get(id);\n if (!leaf) {\n leaf = {};\n this.leaves.set(id, leaf);\n }\n return leaf;\n }\n\n private chunkFor(range: SogLodRange) {\n return range.file < 0\n ? (this.environment as Chunk)\n : this.chunks[range.file];\n }\n\n private applySelection(selected: LeafState[], now: number) {\n // Advance an existing fade before reversing it to avoid opacity jumps.\n let changed = this.updateFades(now);\n changed = this.updateRegionVisibility(now) || changed;\n changed = this.attachPendingRegions(selected, now) || changed;\n this.queueExtractions(selected, now);\n // Complete zero-duration fades in this update as well.\n return this.updateFades(now) || changed;\n }\n\n private updateRegionVisibility(now: number) {\n let changed = false;\n for (const leaf of this.leaves.values()) {\n const { current, outgoing, target } = leaf;\n if (current) changed = this.fadeRegion(current, !!target, now) || changed;\n if (outgoing) changed = this.fadeRegion(outgoing, false, now) || changed;\n }\n return changed;\n }\n\n private attachPendingRegions(selected: LeafState[], now: number) {\n let changed = false;\n for (const leaf of selected) {\n const { current, pending, target: range } = leaf;\n // Finish a crossfade before admitting another LOD for this region.\n if (\n !range ||\n current?.range === range ||\n leaf.outgoing ||\n pending?.range !== range ||\n !pending.data\n )\n continue;\n\n const { data, chunk } = pending;\n const start = chunk.batchSlots.get(range.offset);\n if (start === undefined) throw new Error(\"Missing chunk region slot\");\n const numSh = getSplatShDegree(data.extra);\n let batch = chunk.batch;\n if (!batch) {\n batch = new SogStreamBatch(\n chunk.batchCapacity,\n numSh,\n this.group,\n () => {\n chunk.batch = undefined;\n this.pruneChunk(chunk);\n },\n );\n batch.name =\n range.file < 0 ? \"sog-environment\" : `sog-chunk-${range.file}`;\n chunk.batch = batch;\n this.activeChunks.add(chunk);\n }\n batch.writeRegion(start, data);\n leaf.pending = undefined;\n if (current) {\n leaf.outgoing = current;\n this.fadeRegion(current, false, now);\n }\n leaf.current = { batch, start, range, opacity: 0 };\n this.fadeRegion(leaf.current, true, now);\n changed = true;\n }\n return changed;\n }\n\n private queueExtractions(selected: LeafState[], now: number) {\n // Bound both in-flight and ready copies by their compact packed byte size.\n // One indivisible oversized region may occupy the queue on its own.\n let pendingBytes = 0;\n for (const leaf of this.leaves.values())\n pendingBytes += leaf.pending?.bytes ?? 0;\n const budget = new StreamByteBudget(\n streamPendingLimit(this.maxConcurrentLoads),\n pendingBytes,\n );\n const batches = new Map<\n Chunk,\n { source: SogChunkSource; regions: PendingRegion[] }\n >();\n for (const leaf of selected) {\n const range = leaf.target;\n if (!range || leaf.current?.range === range || leaf.pending) continue;\n const chunk = this.chunkFor(range);\n const source = chunk.data;\n if (!source?.alive || now < chunk.retryAt) continue;\n const bytes =\n getSplatTextureBytes(range.count, source.info.numSh) + range.count * 4;\n if (!budget.reserve(bytes)) continue;\n const pending = { range, chunk, bytes };\n leaf.pending = pending;\n const batch = batches.get(chunk) ?? { source, regions: [] };\n batch.regions.push(pending);\n batches.set(chunk, batch);\n }\n for (const [chunk, { source, regions }] of batches)\n void this.extract(chunk, source, regions);\n }\n\n private addBatchRange(chunk: Chunk, offset: number, count: number) {\n if (!count || chunk.batchSlots.has(offset)) return;\n chunk.batchSlots.set(offset, chunk.batchCapacity);\n chunk.batchCapacity += sogBatchAllocationSize(count);\n }\n\n private fadeRegion(region: Region, visible: boolean, now: number) {\n const to = visible ? 1 : 0;\n if ((this.fades.get(region)?.to ?? region.opacity) === to) return false;\n this.fades.set(region, { from: region.opacity, to, startedAt: now });\n return true;\n }\n\n private updateFades(now: number) {\n let changed = false;\n for (const [region, fade] of this.fades) {\n const progress =\n this.fadeDurationMs === 0 || fade.from === fade.to\n ? 1\n : THREE.MathUtils.clamp(\n (now - fade.startedAt) / this.fadeDurationMs,\n 0,\n 1,\n );\n const opacity = THREE.MathUtils.lerp(fade.from, fade.to, progress);\n if (region.opacity !== opacity) {\n region.opacity = opacity;\n region.batch.setRegionOpacity(region.start, opacity);\n changed = true;\n }\n if (progress === 1) {\n this.fades.delete(region);\n if (this.leaves.get(region.range.leaf)?.outgoing === region)\n this.releaseRegion(region);\n changed = true;\n }\n }\n return changed;\n }\n\n private async extract(\n chunk: Chunk,\n source: SogChunkSource,\n batch: PendingRegion[],\n ) {\n try {\n const results = await source.extract(\n batch.map(({ range }) => ({\n start: range.offset,\n count: range.count,\n })),\n );\n for (let index = 0; index < batch.length; index++) {\n const pending = batch[index];\n const { range } = pending;\n const data = results[index];\n const leaf = this.leaves.get(range.leaf);\n if (\n !this.disposed &&\n leaf?.pending === pending &&\n leaf.target === range\n ) {\n pending.data = data;\n pending.bytes = getSplatByteLength(data);\n } else if (leaf?.pending === pending) leaf.pending = undefined;\n }\n } catch (error) {\n for (const pending of batch) {\n const leaf = this.leaves.get(pending.range.leaf);\n if (leaf?.pending === pending) leaf.pending = undefined;\n }\n if (!this.disposed) {\n chunk.retryAt = streamRetryAt(error, chunk.failures++);\n if (!source.alive) {\n source.dispose();\n this.pruneChunk(chunk);\n }\n this.rejectFirstIfUnavailable(error);\n this.failed(error, chunk.file.url);\n }\n } finally {\n if (!this.disposed) {\n this.pump(performance.now());\n this.changed();\n }\n }\n }\n\n private releaseUnused(now: number, allowRelease: boolean) {\n const referenced = new Set(this.wanted);\n for (const [id, leaf] of this.leaves) {\n const { current, outgoing, pending } = leaf;\n if (pending) referenced.add(pending.chunk);\n if (outgoing) referenced.add(this.chunkFor(outgoing.range));\n if (current) {\n if (\n leaf.target ||\n current.opacity > 0 ||\n this.fades.has(current) ||\n outgoing\n ) {\n current.expiresAt = undefined;\n referenced.add(this.chunkFor(current.range));\n } else {\n current.expiresAt ??= now + this.cooldownMs;\n if (allowRelease && now >= current.expiresAt)\n this.releaseRegion(current);\n }\n }\n if (!leaf.target && !leaf.current && !leaf.outgoing && !leaf.pending)\n this.leaves.delete(id);\n }\n for (const chunk of this.activeChunks) {\n if (referenced.has(chunk) || chunk.controller || !chunk.data) {\n chunk.expiresAt = undefined;\n } else {\n chunk.expiresAt ??= now + this.cooldownMs;\n if (allowRelease && now >= chunk.expiresAt) {\n chunk.data.dispose();\n this.pruneChunk(chunk);\n }\n }\n }\n }\n\n private pump(now: number) {\n if (this.disposed) return;\n let loading = 0;\n for (const chunk of this.activeChunks) {\n this.pruneChunk(chunk);\n if (chunk.controller) loading++;\n }\n for (const chunk of this.wanted) {\n if (loading >= this.maxConcurrentLoads) break;\n if (chunk.data || chunk.controller || now < chunk.retryAt) continue;\n chunk.controller = new AbortController();\n this.activeChunks.add(chunk);\n loading++;\n void this.load(chunk, chunk.controller);\n }\n this.retryTimer.update(retryDeadlines(this.wanted));\n }\n\n private async load(chunk: Chunk, controller: AbortController) {\n let decoded: SogChunkSource | undefined;\n try {\n decoded = await this.loader.load(\n chunk.file.url,\n chunk.file.count,\n controller.signal,\n );\n controller.signal.throwIfAborted();\n if (chunk.batch && decoded.info.numSh !== chunk.batch.numSh)\n throw new Error(\n `Chunk SH degree mismatch: expected ${chunk.batch.numSh}, received ${decoded.info.numSh}`,\n );\n if (chunk === this.environment) {\n chunk.file.count = decoded.info.numSplats;\n this.addBatchRange(chunk, 0, chunk.file.count);\n chunk.file.ranges = chunk.file.count\n ? [\n {\n leaf: -1,\n level: 0,\n file: -1,\n offset: 0,\n count: chunk.file.count,\n },\n ]\n : [];\n } else if (decoded.info.numSplats !== chunk.file.count) {\n throw new Error(\n `Chunk count mismatch: expected ${chunk.file.count}, received ${decoded.info.numSplats}`,\n );\n }\n chunk.data = decoded;\n decoded = undefined;\n chunk.expiresAt = undefined;\n chunk.failures = 0;\n chunk.retryAt = 0;\n if (\n chunk === this.environment &&\n !chunk.file.count &&\n !this.manifest?.lods.length\n )\n this.resolveFirst(this);\n } catch (error) {\n if (!controller.signal.aborted && !this.disposed) {\n chunk.retryAt = streamRetryAt(error, chunk.failures++);\n this.rejectFirstIfUnavailable(error);\n this.failed(error, chunk.file.url);\n }\n } finally {\n decoded?.dispose();\n chunk.controller = undefined;\n this.pruneChunk(chunk);\n if (!this.disposed) {\n this.pump(performance.now());\n // Loading the environment changes the budget available to LOD.\n if (chunk === this.environment) void this.requestSelection();\n this.changed();\n }\n }\n }\n\n private pruneChunk(chunk: Chunk) {\n if (chunk.data && !chunk.data.alive) chunk.data = undefined;\n if (!chunk.data) chunk.expiresAt = undefined;\n if (!chunk.batch && !chunk.data && !chunk.controller)\n this.activeChunks.delete(chunk);\n }\n\n private releaseRegion(region: Region) {\n this.fades.delete(region);\n region.batch.releaseRegion(region.start);\n const leaf = this.leaves.get(region.range.leaf);\n if (leaf?.current === region) leaf.current = undefined;\n if (leaf?.outgoing === region) leaf.outgoing = undefined;\n }\n\n private changed() {\n if (!this.disposed) notifyStreamChange(this.options);\n }\n\n private failed(error: unknown, url: string) {\n notifyStreamError(this.options, error, url);\n }\n\n private readonly retryTimer = new RetryTimer(() => this.changed());\n\n private rejectFirstIfUnavailable(error: unknown) {\n // A failed refinement does not invalidate already renderable coverage.\n if ([...this.leaves.values()].some((leaf) => leaf.current || leaf.pending))\n return;\n if (\n this.wanted.size > 0 &&\n [...this.wanted].every(\n (chunk) => chunk.retryAt === Number.POSITIVE_INFINITY,\n )\n )\n this.rejectFirst(error);\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.retryTimer.dispose();\n this.abort.abort();\n this.rejectFirst(this.abort.signal.reason);\n this.loader.dispose();\n for (const chunk of this.activeChunks) {\n chunk.controller?.abort();\n chunk.data?.dispose();\n chunk.data = undefined;\n }\n for (const leaf of this.leaves.values()) {\n if (leaf.current) this.releaseRegion(leaf.current);\n if (leaf.outgoing) this.releaseRegion(leaf.outgoing);\n }\n this.leaves.clear();\n this.fades.clear();\n this.wanted.clear();\n this.chunks = [];\n this.activeChunks.clear();\n this.environment = undefined;\n this.manifest = undefined;\n this.lodLeaves.clear();\n this.view = undefined;\n this.selection = EMPTY_SELECTION;\n }\n}\n"],"names":["ptr","module","initWasm","_a","error","BundledWorker","index","waiter","THREE","SplatFileType","SplatEditSdfType","SplatEditRgbaBlendMode","encodeQuaternion","axisX","axisY","axisZ","state","loadSplatData","wasm.isInitialized","buffer","buffer2","TSL","NodeUpdateType","value","distance","splatDefines","splatVertex","splatFragment","FullScreenQuad","splatGenerate","NodeMaterial","QuadMesh","camera","size","shaders","Vector2","Matrix4","Vector3","DepthStencilFormat","DepthFormat","ColorManagement","NeverDepth","AlwaysDepth","makeTexture","StorageArrayTexture","WORKGROUP_SIZE","StorageBufferAttribute","IndirectStorageBufferAttribute","shrinkResources","WebGLRenderTarget","HalfFloatType","DepthTexture","FloatType","Pass","Color","ShaderMaterial","GLSL3","NoBlending","NoToneMapping","SRGBTransfer","Node","RenderTarget","RendererUtils","UnsignedInt248Type","WebGLCoordinateSystem","CubeRenderTarget","target","PMREMGenerator","Opcode","InputField","immediate","register","onTrue","onFalse","_SplatPostDecodeProgramImpl","postDecode","DefaultLoadingManager","Loader","bytes","signal","changed","pool","storage"],"mappings":"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"}