gaussian-splat-lite 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/CONTRIBUTING.md +79 -0
  3. package/Gaussian-Splat-Lite.svg +104 -0
  4. package/LICENSE +202 -0
  5. package/NOTICE +10 -0
  6. package/README.md +272 -0
  7. package/THIRD_PARTY_LICENSES.md +53 -0
  8. package/dist/assets/worker-7HrXsEvI.js.map +1 -0
  9. package/dist/assets/worker-XHJGFfdJ.js.map +1 -0
  10. package/dist/gaussian-splat-lite.cjs +3039 -0
  11. package/dist/gaussian-splat-lite.cjs.map +1 -0
  12. package/dist/gaussian-splat-lite.min.cjs +886 -0
  13. package/dist/gaussian-splat-lite.min.cjs.map +1 -0
  14. package/dist/gaussian-splat-lite.module.js +3023 -0
  15. package/dist/gaussian-splat-lite.module.js.map +1 -0
  16. package/dist/gaussian-splat-lite.module.min.js +2840 -0
  17. package/dist/gaussian-splat-lite.module.min.js.map +1 -0
  18. package/dist/types/GaussianSplatRenderer.d.cts +385 -0
  19. package/dist/types/GaussianSplatRenderer.d.ts +385 -0
  20. package/dist/types/SplatAccumulator.d.cts +72 -0
  21. package/dist/types/SplatAccumulator.d.ts +72 -0
  22. package/dist/types/SplatEdit.d.cts +86 -0
  23. package/dist/types/SplatEdit.d.ts +86 -0
  24. package/dist/types/SplatGeometry.d.cts +4 -0
  25. package/dist/types/SplatGeometry.d.ts +4 -0
  26. package/dist/types/SplatLoader.d.cts +31 -0
  27. package/dist/types/SplatLoader.d.ts +31 -0
  28. package/dist/types/SplatMesh.d.cts +74 -0
  29. package/dist/types/SplatMesh.d.ts +74 -0
  30. package/dist/types/SplatSource.d.cts +23 -0
  31. package/dist/types/SplatSource.d.ts +23 -0
  32. package/dist/types/SplatWorker.d.cts +30 -0
  33. package/dist/types/SplatWorker.d.ts +30 -0
  34. package/dist/types/Splats.d.cts +54 -0
  35. package/dist/types/Splats.d.ts +54 -0
  36. package/dist/types/cameraRelative.d.cts +22 -0
  37. package/dist/types/cameraRelative.d.ts +22 -0
  38. package/dist/types/defines.d.cts +22 -0
  39. package/dist/types/defines.d.ts +22 -0
  40. package/dist/types/index.d.cts +12 -0
  41. package/dist/types/index.d.mts +1 -0
  42. package/dist/types/index.d.ts +12 -0
  43. package/dist/types/shaders.d.cts +1 -0
  44. package/dist/types/shaders.d.ts +1 -0
  45. package/dist/types/splatTransform.d.cts +10 -0
  46. package/dist/types/splatTransform.d.ts +10 -0
  47. package/dist/types/utils.d.cts +33 -0
  48. package/dist/types/utils.d.ts +33 -0
  49. package/dist/types/wasm.d.cts +2 -0
  50. package/dist/types/wasm.d.ts +2 -0
  51. package/dist/types/worker.d.cts +42 -0
  52. package/dist/types/worker.d.ts +42 -0
  53. package/docs/GaussianSplatRenderer.md +107 -0
  54. package/docs/SplatAccumulator.md +44 -0
  55. package/docs/SplatEdit.md +84 -0
  56. package/docs/SplatFileType.md +30 -0
  57. package/docs/SplatLoader.md +28 -0
  58. package/docs/SplatMesh.md +80 -0
  59. package/docs/SplatSource.md +26 -0
  60. package/docs/Splats.md +58 -0
  61. package/package.json +109 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gaussian-splat-lite.module.js","sources":["../src/cameraRelative.ts","../src/SplatEdit.ts","../rust/gaussian-splat-rs/pkg/gaussian_splat_rs.js","../src/defines.ts","../src/utils.ts","../virtual:decode-64","../src/wasm.ts","../src/SplatWorker.ts","../src/SplatLoader.ts","../src/Splats.ts","../src/SplatMesh.ts","../src/shaders/splatDefines.glsl","../src/shaders/splatFragment.glsl","../src/shaders/splatVertex.glsl","../src/shaders.ts","../src/shaders/splatGenerate.glsl","../src/splatTransform.ts","../src/SplatAccumulator.ts","../src/SplatGeometry.ts","../src/GaussianSplatRenderer.ts"],"sourcesContent":["import * as THREE from \"three\";\n\nimport type { SplatAccumulator } from \"./SplatAccumulator\";\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\n/**\n * Builds persistent sort centers relative to each mesh origin. Keeping the\n * Float64 world origin separate lets the worker form a fresh camera-to-mesh\n * offset for every sort without rebuilding the per-splat Float32 data.\n */\nexport function buildSortCenters(current: SplatAccumulator) {\n const centers = new Float32Array(current.numSplats * 3);\n const rangeBases = new Uint32Array(current.mapping.length);\n const rangeCounts = new Uint32Array(current.mapping.length);\n const rangeOrigins = new Float64Array(current.mapping.length * 3);\n // Mapping rows are texture-aligned. NaN keeps gaps and disabled splats out\n // of the active radix-sort range, matching the old infinity attachment.\n centers.fill(Number.NaN);\n\n const objectToWorld = new THREE.Matrix4();\n\n current.mapping.forEach(({ node, base, count }, rangeIndex) => {\n rangeBases[rangeIndex] = base;\n rangeCounts[rangeIndex] = count;\n\n const source = node.splats;\n if (!source) return;\n\n // Keep the complete affine basis, but store its Float64 translation once\n // per mesh instead of narrowing it into every Float32 splat center.\n objectToWorld.copy(node.matrixWorld);\n const elements = objectToWorld.elements;\n const originTarget = rangeIndex * 3;\n rangeOrigins[originTarget] = elements[12];\n rangeOrigins[originTarget + 1] = elements[13];\n rangeOrigins[originTarget + 2] = elements[14];\n\n source.forEachCenter((index, x, y, z) => {\n if (index >= count || Number.isNaN(x)) {\n return;\n }\n const target = (base + index) * 3;\n centers[target] = elements[0] * x + elements[4] * y + elements[8] * z;\n centers[target + 1] = elements[1] * x + elements[5] * y + elements[9] * z;\n centers[target + 2] =\n elements[2] * x + elements[6] * y + elements[10] * z;\n });\n });\n\n return { centers, rangeBases, rangeCounts, rangeOrigins };\n}\n","import * as THREE from \"three\";\n\nimport { rebaseAffineTransform } from \"./cameraRelative\";\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 = \"multiply\",\n ADD_RGBA = \"add_rgba\",\n}\n\nexport type SplatEditSdfOptions = {\n type?: SplatEditSdfType;\n invert?: boolean;\n opacity?: number;\n color?: THREE.Color;\n radius?: number;\n};\n\n/** A signed-distance shape carrying only color and opacity. */\nexport class SplatEditSdf extends THREE.Object3D {\n type: SplatEditSdfType;\n invert: boolean;\n opacity: number;\n color: THREE.Color;\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 ?? 1;\n this.color = options.color ?? new THREE.Color(1, 1, 1);\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;\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 = 5;\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 sdfFloatData: Float32Array;\n sdfTexture: THREE.DataTexture;\n\n maxEdits: number;\n numEdits = 0;\n editData: Uint32Array;\n editFloatData: Float32Array;\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.sdfFloatData = new Float32Array(this.sdfData.buffer);\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.editFloatData = new Float32Array(this.editData.buffer);\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 center = new THREE.Vector3();\n const quaternion = new THREE.Quaternion();\n const inverseScale = new THREE.Vector3();\n const sizes = new THREE.Vector4();\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 sizes.set(sdf.scale.x, sdf.scale.y, sdf.scale.z, sdf.radius);\n const originalScale = sdf.scale.clone();\n try {\n sdf.scale.setScalar(1);\n sdf.updateWorldMatrix(true, false);\n worldToSdf.copy(sdf.matrixWorld).invert();\n // Only the internal numeric frame changes. SDF Object3D transforms,\n // sizes, smoothing distances, and edit semantics remain world-space.\n if (coordinateOrigin) {\n rebaseAffineTransform(worldToSdf, coordinateOrigin);\n }\n worldToSdf.decompose(center, quaternion, inverseScale);\n } finally {\n sdf.scale.copy(originalScale);\n sdf.updateWorldMatrix(true, false);\n }\n\n sdfUpdated =\n this.encodeSdf(\n sdfIndex,\n sdf,\n center,\n quaternion,\n inverseScale,\n 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.sdfFloatData = new Float32Array(this.sdfData.buffer);\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.editFloatData = new Float32Array(this.editData.buffer);\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 =\n edit.rgbaBlendMode === SplatEditRgbaBlendMode.MULTIPLY ? 0 : 1;\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 center: THREE.Vector3,\n quaternion: THREE.Quaternion,\n scale: THREE.Vector3,\n sizes: THREE.Vector4,\n ) {\n const base = index * SDF_TEXELS * 4;\n const flags = sdfTypeToNumber(sdf.type) | (sdf.invert ? 1 << 8 : 0);\n let updated = this.setSdfFloat(base, center.x);\n updated = this.setSdfFloat(base + 1, center.y) || updated;\n updated = this.setSdfFloat(base + 2, center.z) || updated;\n updated = this.setSdfUint(base + 3, flags) || updated;\n\n updated = this.setSdfFloat(base + 4, quaternion.x) || updated;\n updated = this.setSdfFloat(base + 5, quaternion.y) || updated;\n updated = this.setSdfFloat(base + 6, quaternion.z) || updated;\n updated = this.setSdfFloat(base + 7, quaternion.w) || updated;\n\n updated = this.setSdfFloat(base + 8, scale.x) || updated;\n updated = this.setSdfFloat(base + 9, scale.y) || updated;\n updated = this.setSdfFloat(base + 10, scale.z) || updated;\n updated = this.setSdfUint(base + 11, 0) || 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, sdf.color.r) || updated;\n updated = this.setSdfFloat(base + 17, sdf.color.g) || updated;\n updated = this.setSdfFloat(base + 18, sdf.color.b) || updated;\n updated = this.setSdfFloat(base + 19, sdf.opacity) || 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 = makeUintTexture(new Uint32Array(4), 1, 1);\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.internalFormat = \"RGBA32UI\";\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\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}\nif (Symbol.dispose) ChunkDecoder.prototype[Symbol.dispose] = ChunkDecoder.prototype.free;\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 * @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 {Float32Array} centers\n * @param {Uint32Array} range_bases\n * @param {Uint32Array} range_counts\n * @param {Float64Array} range_origins\n */\nexport function set_sort_centers(centers, range_bases, range_counts, range_origins) {\n wasm.set_sort_centers(centers, range_bases, range_counts, range_origins);\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 {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, ordering) {\n const ret = wasm.sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, ordering);\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_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_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_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_with_length_41a22191b9bdfd66: function(arg0) {\n const ret = new Uint32Array(arg0 >>> 0);\n return ret;\n },\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_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_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_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));\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 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 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 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","// LN_SCALE_MIN..LN_SCALE_MAX define the internal scale range of for Gsplats,\n// covering approx 0.0001..8000 in range with discrete steps 7% apart.\n// The value \"0\" is reserved for truly flat scales, indicating a 2DGS.\n// If these values are changed, the corresponding values in splatDefines.glsl\n// must also be updated to match.\n\nexport const LN_SCALE_MIN = -12.0;\nexport const LN_SCALE_MAX = 9.0;\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\nexport enum SplatFileType {\n PLY = \"ply\",\n SPZ = \"spz\",\n}\n\nexport type SplatExtra = {\n sh1?: Uint32Array;\n sh2?: Uint32Array;\n sh3a?: Uint32Array;\n sh3b?: Uint32Array;\n};\n\nexport type SplatResult = {\n numSplats: number;\n splatArrays: [Uint32Array, Uint32Array];\n extra: SplatExtra;\n};\n","import * as THREE from \"three\";\n\n// Miscellaneous utility functions for Gaussian Splat Lite\n\nimport {\n SPLAT_TEX_HEIGHT,\n SPLAT_TEX_MIN_HEIGHT,\n SPLAT_TEX_WIDTH,\n} from \"./defines.js\";\n\nexport const threeRevision = Number.parseInt(THREE.REVISION);\nexport const threeMrtArray = threeRevision >= 179;\n\nconst f32buffer = new Float32Array(1);\nconst u32buffer = new Uint32Array(f32buffer.buffer);\nconst supportsFloat16Array = \"Float16Array\" in globalThis;\nconst f16buffer = supportsFloat16Array\n ? new globalThis[\"Float16Array\" as keyof typeof globalThis](1)\n : null;\nconst u16buffer = new Uint16Array(f16buffer?.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\nexport const toHalf = supportsFloat16Array ? toHalfNative : toHalfJS;\nexport const fromHalf = supportsFloat16Array ? fromHalfNative : fromHalfJS;\n\n// Encode a number as a float16, stored as a uint16 number.\nfunction toHalfNative(f: number): number {\n f16buffer[0] = f;\n return u16buffer[0];\n}\n\n// Encode a number as a float16, stored as a uint16 number.\nfunction toHalfJS(f: number): number {\n // Store the value into the shared Float32 array.\n f32buffer[0] = f;\n const bits = u32buffer[0];\n\n // Extract sign (1 bit), exponent (8 bits), and fraction (23 bits)\n const sign = (bits >> 31) & 0x1;\n const exp = (bits >> 23) & 0xff;\n const frac = bits & 0x7fffff;\n const halfSign = sign << 15;\n\n // Handle special cases: NaN and Infinity\n if (exp === 0xff) {\n // NaN: set all exponent bits to 1 and some nonzero fraction bits.\n if (frac !== 0) {\n return halfSign | 0x7fff;\n }\n // Infinity\n return halfSign | 0x7c00;\n }\n\n // Adjust the exponent from float32 bias (127) to float16 bias (15)\n const newExp = exp - 127 + 15;\n\n // Handle overflow: too large to represent in half precision.\n if (newExp >= 0x1f) {\n return halfSign | 0x7c00; // Infinity\n }\n if (newExp <= 0) {\n // Handle subnormals and underflow.\n if (newExp < -10) {\n // Too small: underflows to zero.\n return halfSign;\n }\n // Convert to subnormal: add the implicit leading 1 to the fraction,\n // then shift to align with the half-precision's 10 fraction bits.\n const subFrac = (frac | 0x800000) >> (1 - newExp + 13);\n return halfSign | subFrac;\n }\n\n // Normalized half-precision number: shift fraction to fit into 10 bits.\n const halfFrac = frac >> 13;\n return halfSign | (newExp << 10) | halfFrac;\n}\n\n// Convert a float16 stored as a uint16 number back to a float32.\nfunction fromHalfNative(u: number): number {\n u16buffer[0] = u;\n return f16buffer[0];\n}\n\n// Convert a float16 stored as a uint16 number back to a float32.\nfunction fromHalfJS(h: number): number {\n // Extract the sign (1 bit), exponent (5 bits), and fraction (10 bits)\n const sign = (h >> 15) & 0x1;\n const exp = (h >> 10) & 0x1f;\n const frac = h & 0x3ff;\n\n let f32bits: number;\n\n if (exp === 0) {\n if (frac === 0) {\n // Zero (positive or negative)\n f32bits = sign << 31;\n } else {\n // Subnormal half-precision number.\n // Normalize the subnormal number:\n let mant = frac;\n let e = -14; // For half, the exponent for subnormals is fixed at -14.\n // Shift left until the implicit leading 1 is in place.\n while ((mant & 0x400) === 0) {\n // 0x400 === 1 << 10\n mant <<= 1;\n e--;\n }\n // Remove the leading 1 (which is now implicit)\n mant &= 0x3ff;\n // Convert the half exponent (e) to the 32-bit float exponent:\n const newExp = e + 127; // 32-bit float bias is 127.\n const newFrac = mant << 13; // Align to 23-bit fraction (23 - 10 = 13)\n f32bits = (sign << 31) | (newExp << 23) | newFrac;\n }\n } else if (exp === 0x1f) {\n // Handle special cases for Infinity and NaN.\n if (frac === 0) {\n // Infinity\n f32bits = (sign << 31) | 0x7f800000;\n } else {\n // NaN (we choose a quiet NaN)\n f32bits = (sign << 31) | 0x7fc00000;\n }\n } else {\n // Normalized half-precision number.\n // Adjust exponent from half (bias 15) to float32 (bias 127)\n const newExp = exp - 15 + 127;\n const newFrac = frac << 13;\n f32bits = (sign << 31) | (newExp << 23) | newFrac;\n }\n\n // Write the 32-bit bit pattern to the shared buffer,\n // then read it as a float32 to return a JavaScript number.\n u32buffer[0] = f32bits;\n return f32buffer[0];\n}\n\n// Recursively finds all ArrayBuffers in an object and returns them as an array\n// to use as transferable objects to send between workers.\nexport function getTransferable(ctx: unknown): Transferable[] {\n const buffers: Transferable[] = [];\n const seen = new Set();\n\n function traverse(obj: unknown) {\n if (obj && typeof obj === \"object\" && !seen.has(obj)) {\n seen.add(obj);\n\n if (obj instanceof ArrayBuffer) {\n buffers.push(obj);\n } else if (ArrayBuffer.isView(obj)) {\n // Handles TypedArrays and DataView\n buffers.push(obj.buffer as ArrayBuffer);\n } else if (Array.isArray(obj)) {\n obj.forEach(traverse);\n } else {\n Object.values(obj).forEach(traverse);\n }\n }\n }\n\n traverse(ctx);\n return buffers;\n}\n\nexport function encodeSplat(\n splatArrays: [Uint32Array, Uint32Array],\n index: number,\n x: number,\n y: number,\n z: number,\n scaleX: number,\n scaleY: number,\n scaleZ: number,\n quatX: number,\n quatY: number,\n quatZ: number,\n quatW: number,\n opacity: number,\n r: number,\n g: number,\n b: number,\n) {\n const i4 = index * 4;\n const [splatA, splatB] = splatArrays;\n splatA[i4] = floatBitsToUint(x);\n splatA[i4 + 1] = floatBitsToUint(y);\n splatA[i4 + 2] = floatBitsToUint(z);\n splatA[i4 + 3] = toHalf(opacity);\n splatB[i4] = toHalf(r) | (toHalf(g) << 16);\n splatB[i4 + 1] = toHalf(b) | (toHalf(Math.log(scaleX)) << 16);\n splatB[i4 + 2] = toHalf(Math.log(scaleY)) | (toHalf(Math.log(scaleZ)) << 16);\n splatB[i4 + 3] = encodeQuatOctXy1010R12(quatX, quatY, quatZ, quatW);\n}\n\nexport function decodeSplat(\n splatArrays: [Uint32Array, Uint32Array],\n index: number,\n): {\n center: THREE.Vector3;\n scales: THREE.Vector3;\n quaternion: THREE.Quaternion;\n color: THREE.Color;\n opacity: number;\n} {\n // Returns a static object which is reused each time\n const result = splatFields;\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 = fromHalf(splatA[i4 + 3] & 0xffff);\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 splatCenter = new THREE.Vector3();\nconst splatScales = new THREE.Vector3();\nconst splatQuaternion = new THREE.Quaternion();\nconst splatColor = new THREE.Color();\nconst splatFields = {\n center: splatCenter,\n scales: splatScales,\n quaternion: splatQuaternion,\n color: splatColor,\n opacity: 0.0,\n};\n\n// Compute a texture array size that is large enough to fit numSplats. The most\n// common 2D texture size in WebGL2 is 4096x4096 which only allows for 16M splats,\n// so Gaussian Splat Lite stores Gsplat data in a 2D texture array, which most platforms support\n// up to 2048x2048x2048 = 8G splats. Allocations that fit within a single 2D texture\n// array layer will be rounded up to fill an entire texture row. Once a texture\n// array layer is filled, the allocation will be rounded up to fill an entire layer.\n// This is done so the entire set of splats can be covered by min/max coords across\n// each dimension.\nexport function getTextureSize(numSplats: number): {\n width: number;\n height: number;\n depth: number;\n maxSplats: number;\n} {\n // Compute a texture array size that is large enough to fit numSplats.\n // The width is always 2048, the height sized to fit the splats but no larger than 2048.\n // The depth is the number of layers needed to fit the splats.\n // maxSplats is computed as the new total available splats that can be stored.\n const width = SPLAT_TEX_WIDTH;\n const height = Math.max(\n SPLAT_TEX_MIN_HEIGHT,\n Math.min(SPLAT_TEX_HEIGHT, Math.ceil(numSplats / width)),\n );\n const depth = Math.ceil(numSplats / (width * height));\n const maxSplats = width * height * depth;\n return { width, height, depth, maxSplats };\n}\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\nexport function encodeQuatOctXy1010R12(\n qx: number,\n qy: number,\n qz: number,\n qw: number,\n): number {\n const qlen = Math.sqrt(qx * qx + qy * qy + qz * qz + qw * qw);\n // Force the minimal representation (q.w >= 0)\n const qnx = (qw < 0 ? -qx : qx) / qlen;\n const qny = (qw < 0 ? -qy : qy) / qlen;\n const qnz = (qw < 0 ? -qz : qz) / qlen;\n const qnw = (qw < 0 ? -qw : qw) / qlen;\n // Compute the rotation angle θ in [0, π]\n const theta = 2 * Math.acos(qnw);\n // Recover the rotation axis (default to (1,0,0) for near-zero rotation)\n const xyz_norm = Math.sqrt(qnx * qnx + qny * qny + qnz * qnz);\n const axisX = xyz_norm < 1e-6 ? 1 : qnx / xyz_norm;\n const axisY = xyz_norm < 1e-6 ? 0 : qny / xyz_norm;\n const axisZ = xyz_norm < 1e-6 ? 0 : qnz / xyz_norm;\n\n // --- Folded Octahedral Mapping (inline) ---\n // Compute p = (axis.x, axis.y) / (|axis.x|+|axis.y|+|axis.z|)\n const sum = Math.abs(axisX) + Math.abs(axisY) + Math.abs(axisZ);\n let p_x = axisX / sum;\n let p_y = axisY / sum;\n // Fold the lower hemisphere.\n if (axisZ < 0) {\n const tmp = p_x;\n p_x = (1 - Math.abs(p_y)) * (p_x >= 0 ? 1 : -1);\n p_y = (1 - Math.abs(tmp)) * (p_y >= 0 ? 1 : -1);\n }\n // Remap from [-1,1] to [0,1]\n const u_f = p_x * 0.5 + 0.5;\n const v_f = p_y * 0.5 + 0.5;\n // Quantize to 10 bits (0..1023)\n const quantU = Math.round(u_f * 1023);\n const quantV = Math.round(v_f * 1023);\n // --- Angle Quantization: Quantize θ ∈ [0,π] to 12 bits (0..4095) ---\n const angleInt = Math.round(theta * (4095 / Math.PI));\n\n // Pack into 32 bits: bits [0–9]: quantU, [10–19]: quantV, [20–31]: angleInt.\n return (angleInt << 20) | (quantV << 10) | quantU;\n}\n\nexport function decodeQuatOctXy1010R12(\n encoded: number,\n out: THREE.Quaternion,\n): THREE.Quaternion {\n // Extract 10‐bit quantU and quantV, and 12‐bit angleInt.\n const quantU = encoded & 0x3ff; // bits 0–9\n const quantV = (encoded >>> 10) & 0x3ff; // bits 10–19\n const angleInt = (encoded >>> 20) & 0xfff; // bits 20–31\n\n // Recover u and v in [0,1] then map to [-1,1]\n const u_f = quantU / 1023;\n const v_f = quantV / 1023;\n let f_x = (u_f - 0.5) * 2;\n let f_y = (v_f - 0.5) * 2;\n // Inverse folded mapping: recover z from the constraint |p_x|+|p_y|+z = 1.\n const f_z = 1 - (Math.abs(f_x) + Math.abs(f_y));\n const t = Math.max(-f_z, 0);\n f_x += f_x >= 0 ? -t : t;\n f_y += f_y >= 0 ? -t : t;\n const axisLen = Math.sqrt(f_x * f_x + f_y * f_y + f_z * f_z);\n const axisX = axisLen < 1e-6 ? 0 : f_x / axisLen;\n const axisY = axisLen < 1e-6 ? 0 : f_y / axisLen;\n const axisZ = axisLen < 1e-6 ? 0 : f_z / axisLen;\n\n // Decode the angle: θ ∈ [0,π]\n const theta = (angleInt / 4095) * Math.PI;\n const halfTheta = theta * 0.5;\n const s = Math.sin(halfTheta);\n const w = Math.cos(halfTheta);\n // Reconstruct the quaternion from axis-angle: (axis * sin(θ/2), cos(θ/2))\n out.set(axisX * s, axisY * s, axisZ * s, w);\n return out;\n}\n\nexport function uploadU32DataTextureRows(\n renderer: THREE.WebGLRenderer,\n texture: THREE.Texture,\n width: number,\n rows: number,\n data: Uint32Array,\n) {\n const gl = renderer.getContext() as WebGL2RenderingContext;\n const props = renderer.properties.get(texture) as {\n __webglTexture: WebGLTexture;\n };\n const glTexture = props?.__webglTexture;\n if (!glTexture) {\n throw new Error(\"texture not found\");\n }\n\n // renderer.state.pixelStorei is only available in newer Three.js releases,\n // so preserve these WebGL flags explicitly across the direct texture upload.\n const currentFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);\n const currentPremultiply = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL);\n renderer.state.activeTexture(gl.TEXTURE0);\n renderer.state.bindTexture(gl.TEXTURE_2D, glTexture);\n gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n gl.texSubImage2D(\n gl.TEXTURE_2D,\n 0,\n 0,\n 0,\n width,\n rows,\n gl.RGBA_INTEGER,\n gl.UNSIGNED_INT,\n data,\n );\n renderer.state.unbindTexture();\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, currentFlipY);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, currentPremultiply);\n}\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","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. */\ninitWasm({ module_or_path: WASM_MODULE }).then(() => {\n initialized = true;\n});\n\nexport function isInitialized() {\n return initialized;\n}\n","import { getTransferable } from \"./utils\";\nimport { WASM_MODULE } from \"./wasm\";\nimport type { RpcHandlers } from \"./worker\";\nimport BundledWorker from \"./worker?worker&inline\";\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\nexport class SplatWorker {\n worker: Worker;\n messages: Record<number, PromiseRecord> = {};\n static currentId = 0;\n\n constructor() {\n this.worker = new BundledWorker();\n this.worker.onmessage = (event) => this.onMessage(event);\n WASM_MODULE.then((module) => {\n this.worker.postMessage({ name: \"init-wasm\", module });\n });\n }\n\n onMessage(event: MessageEvent) {\n const { id, result, error, status } = event.data;\n const promise = this.messages[id];\n if (!promise) return;\n\n if (status !== undefined) {\n promise.statusQueue = promise.statusQueue.then(() => {\n if (this.messages[id] === promise) {\n return promise.onStatus?.(status);\n }\n });\n void promise.statusQueue.catch(() => {});\n return;\n }\n\n void promise.statusQueue\n .then(() => {\n if (error !== undefined) throw error;\n return result;\n })\n .finally(() => {\n delete this.messages[id];\n })\n .then(promise.resolve, promise.reject);\n }\n\n async call<Name extends keyof RpcHandlers>(\n name: Name,\n args: Parameters<RpcHandlers[Name]>[0],\n options: {\n onStatus?: (data: unknown) => void | Promise<void>;\n } = {},\n ): Promise<Awaited<ReturnType<RpcHandlers[Name]>>> {\n type Result = Awaited<ReturnType<RpcHandlers[Name]>>;\n const id = ++SplatWorker.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 this.worker.postMessage(\n { id, name, args },\n { transfer: getTransferable(args) },\n );\n return promise;\n }\n\n dispose() {\n this.worker.terminate();\n\n const messages = Object.values(this.messages);\n this.messages = {};\n for (const message of messages) {\n message.reject(new Error(\"Worker terminate\"));\n }\n }\n}\n\nclass SplatWorkerPool {\n maxWorkers;\n numWorkers = 0;\n freelist: SplatWorker[] = [];\n queue: ((worker: SplatWorker) => void)[] = [];\n\n constructor(maxWorkers = 4) {\n this.maxWorkers = maxWorkers;\n }\n\n async withWorker<T>(\n callback: (worker: SplatWorker) => Promise<T>,\n ): Promise<T> {\n const worker = await this.allocWorker();\n try {\n return await callback(worker);\n } finally {\n this.freeWorker(worker);\n }\n }\n\n async allocWorker(): Promise<SplatWorker> {\n const worker = this.freelist.pop();\n if (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 (this.numWorkers > this.maxWorkers) {\n // Worker no longer needed\n worker.dispose();\n this.numWorkers -= 1;\n return;\n }\n\n const waiter = this.queue.shift();\n if (waiter) {\n waiter(worker);\n return;\n }\n\n this.freelist.push(worker);\n }\n}\n\nexport const workerPool = new SplatWorkerPool();\n","import { Loader } from \"three\";\nimport { SplatMesh } from \"./SplatMesh\";\nimport { workerPool } from \"./SplatWorker\";\nimport { Splats, type SplatsOptions } from \"./Splats\";\nimport type { SplatFileType } from \"./defines\";\n\n// SplatLoader implements the THREE.Loader interface for PLY and SPZ files.\nexport class SplatLoader extends Loader {\n load(\n url: string,\n onLoad?: (decoded: Splats) => void,\n onProgress?: (event: ProgressEvent) => void,\n onError?: (error: unknown) => void,\n ) {\n return this.loadInternal({ url, onLoad, onProgress, onError });\n }\n\n async loadAsync(\n url: string,\n onProgress?: (event: ProgressEvent) => void,\n ): Promise<Splats> {\n return new Promise((resolve, reject) => {\n this.load(url, resolve, onProgress, reject);\n });\n }\n\n parse(splats: Splats): SplatMesh {\n return new SplatMesh({ splats });\n }\n\n loadInternal({\n splats,\n url,\n fileBytes,\n fileType,\n fileName,\n stream,\n streamLength,\n onLoad,\n onProgress,\n onError,\n }: {\n splats?: Splats;\n url?: string;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n stream?: ReadableStream;\n streamLength?: number;\n onLoad?: (decoded: Splats) => void;\n onProgress?: (event: ProgressEvent) => void;\n onError?: (error: unknown) => void;\n }) {\n const byteArray =\n fileBytes instanceof ArrayBuffer ? new Uint8Array(fileBytes) : fileBytes;\n const resolvedURL = byteArray\n ? undefined\n : this.manager.resolveURL((this.path ?? \"\") + (url ?? \"\"));\n let readStream = stream?.getReader();\n\n this.manager.itemStart(resolvedURL ?? \"\");\n\n workerPool\n .withWorker(async (worker) => {\n const onStatus = async (data: unknown) => {\n const { loaded, total } = data as {\n loaded?: number;\n total?: number;\n };\n if (loaded !== undefined && onProgress) {\n try {\n onProgress(\n new ProgressEvent(\"progress\", {\n lengthComputable: total !== 0,\n loaded,\n total: total ?? 0,\n }),\n );\n } catch (error) {\n console.error(\"Progress callback failed\", error);\n }\n }\n\n if ((data as { nextChunk?: boolean }).nextChunk) {\n let chunk: Uint8Array;\n if (!readStream) {\n chunk = new Uint8Array(0);\n } else {\n const { done, value } = await readStream\n .read()\n .catch(async (error) => {\n await worker.call(\"nextChunk\", { chunk: new Uint8Array(0) });\n throw error;\n });\n if (done) {\n readStream.releaseLock();\n readStream = undefined;\n chunk = new Uint8Array(0);\n } else {\n chunk = value;\n }\n }\n await worker.call(\"nextChunk\", { chunk });\n }\n };\n\n const basedUrl = resolvedURL\n ? new URL(resolvedURL, window.location.href).toString()\n : undefined;\n const decoded = await worker.call(\n \"loadSplats\",\n {\n url: basedUrl,\n requestHeader: this.requestHeader,\n withCredentials: this.withCredentials,\n fileBytes: byteArray?.slice(),\n fileType,\n pathName: resolvedURL || fileName,\n chunked: stream !== undefined,\n chunkedLength: streamLength,\n },\n { onStatus },\n );\n\n const result = splats ?? new Splats();\n result.initialize(decoded as SplatsOptions);\n onLoad?.(result);\n })\n .catch(async (error) => {\n if (readStream) {\n try {\n await readStream.cancel(error);\n } catch {\n // Preserve the worker decoding error if stream cancellation fails.\n }\n readStream.releaseLock();\n readStream = undefined;\n }\n this.manager.itemError(resolvedURL ?? \"\");\n onError?.(error);\n })\n .finally(() => {\n this.manager.itemEnd(resolvedURL ?? \"\");\n });\n }\n\n async loadInternalAsync({\n splats,\n url,\n fileBytes,\n fileType,\n fileName,\n stream,\n streamLength,\n onProgress,\n }: {\n splats?: Splats;\n url?: string;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n stream?: ReadableStream;\n streamLength?: number;\n onProgress?: (event: ProgressEvent) => void;\n }): Promise<Splats> {\n return new Promise((resolve, reject) => {\n this.loadInternal({\n splats,\n url,\n fileBytes,\n fileType,\n fileName,\n stream,\n streamLength,\n onLoad: resolve,\n onProgress,\n onError: reject,\n });\n });\n }\n}\n","import * as THREE from \"three\";\n\nimport { SplatLoader } from \"./SplatLoader\";\nimport type { SplatShTextures, SplatSource } from \"./SplatSource\";\nimport { SPLAT_TEX_WIDTH, type SplatFileType } from \"./defines\";\nimport { decodeSplat, encodeSplat, getTextureSize } from \"./utils\";\n\nexport type SplatsOptions = {\n url?: string;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n stream?: ReadableStream;\n streamLength?: number;\n maxSplats?: number;\n splatArrays?: [Uint32Array, Uint32Array];\n numSplats?: number;\n construct?: (splats: Splats) => Promise<void> | void;\n onProgress?: (event: ProgressEvent) => void;\n extra?: Record<string, unknown>;\n};\n\n/** A mutable splat source with two 16-byte texture records per splat. */\nexport class Splats implements SplatSource {\n maxSplats = 0;\n numSplats = 0;\n splatArrays: [Uint32Array, Uint32Array] = [\n new Uint32Array(0),\n new Uint32Array(0),\n ];\n extra: Record<string, unknown> = {};\n\n initialized: Promise<Splats>;\n isInitialized = false;\n needsUpdate = true;\n\n private textures: [THREE.DataArrayTexture, THREE.DataArrayTexture];\n private shTextures: SplatShTextures = {};\n\n constructor(options: SplatsOptions = {}) {\n this.textures = [Splats.emptyTexture, Splats.emptyTexture];\n this.initialized = Promise.resolve(this);\n this.reinitialize(options);\n }\n\n reinitialize(options: SplatsOptions) {\n this.isInitialized = false;\n this.disposeTextures();\n this.extra = {};\n this.maxSplats = options.maxSplats ?? 0;\n this.needsUpdate = true;\n\n if (\n options.url ||\n options.fileBytes ||\n options.stream ||\n options.construct\n ) {\n this.initialized = this.asyncInitialize(options).then(() => {\n this.isInitialized = true;\n return this;\n });\n } else {\n this.initialize(options);\n this.isInitialized = true;\n this.initialized = Promise.resolve(this);\n }\n }\n\n initialize(options: SplatsOptions) {\n this.disposeTextures();\n this.extra = options.extra ?? {};\n if (options.splatArrays) {\n this.splatArrays = options.splatArrays;\n this.maxSplats = Math.floor(\n Math.min(this.splatArrays[0].length, this.splatArrays[1].length) / 4,\n );\n this.maxSplats =\n Math.floor(this.maxSplats / SPLAT_TEX_WIDTH) * SPLAT_TEX_WIDTH;\n this.numSplats = Math.min(\n this.maxSplats,\n options.numSplats ?? this.maxSplats,\n );\n } else {\n this.maxSplats = options.maxSplats ?? 0;\n this.numSplats = 0;\n this.splatArrays = [new Uint32Array(0), new Uint32Array(0)];\n }\n this.needsUpdate = true;\n }\n\n private async asyncInitialize(options: SplatsOptions) {\n const loader = new SplatLoader();\n if (options.fileBytes || options.url || options.stream) {\n await loader.loadInternalAsync({\n splats: this,\n url: options.url,\n fileBytes: options.fileBytes,\n fileType: options.fileType,\n fileName: options.fileName,\n stream: options.stream,\n streamLength: options.streamLength,\n onProgress: options.onProgress,\n });\n }\n\n const maybePromise = options.construct?.(this);\n if (maybePromise instanceof Promise) {\n await maybePromise;\n }\n }\n\n dispose() {\n this.disposeTextures();\n this.splatArrays = [new Uint32Array(0), new Uint32Array(0)];\n this.extra = {};\n }\n\n private disposeTextures() {\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 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 getNumSh() {\n return !this.extra.sh1\n ? 0\n : !this.extra.sh2\n ? 1\n : !this.extra.sh3a || !this.extra.sh3b\n ? 2\n : 3;\n }\n\n ensureSplats(numSplats: number): [Uint32Array, Uint32Array] {\n const currentCapacity = this.splatArrays[0].length / 4;\n const targetSize =\n numSplats <= this.maxSplats\n ? this.maxSplats\n : Math.max(numSplats, 2 * this.maxSplats);\n if (targetSize > currentCapacity) {\n this.maxSplats = getTextureSize(Math.max(1, targetSize)).maxSplats;\n const first = new Uint32Array(this.maxSplats * 4);\n const second = new Uint32Array(this.maxSplats * 4);\n first.set(this.splatArrays[0]);\n second.set(this.splatArrays[1]);\n this.splatArrays = [first, second];\n this.needsUpdate = true;\n }\n return this.splatArrays;\n }\n\n getSplat(index: number) {\n if (index < 0 || index >= this.numSplats) {\n throw new Error(\"Invalid splat index\");\n }\n return decodeSplat(this.splatArrays, index);\n }\n\n setSplat(\n index: number,\n center: THREE.Vector3,\n scales: THREE.Vector3,\n quaternion: THREE.Quaternion,\n opacity: number,\n color: THREE.Color,\n ) {\n const arrays = this.ensureSplats(index + 1);\n encodeSplat(\n arrays,\n index,\n center.x,\n center.y,\n center.z,\n scales.x,\n scales.y,\n scales.z,\n quaternion.x,\n quaternion.y,\n quaternion.z,\n quaternion.w,\n opacity,\n color.r,\n color.g,\n color.b,\n );\n this.numSplats = Math.max(this.numSplats, index + 1);\n this.needsUpdate = true;\n }\n\n pushSplat(\n center: THREE.Vector3,\n scales: THREE.Vector3,\n quaternion: THREE.Quaternion,\n opacity: number,\n color: THREE.Color,\n ) {\n this.setSplat(this.numSplats, center, scales, quaternion, opacity, color);\n }\n\n forEachCenter(\n callback: (index: number, x: number, y: number, z: number) => void,\n ) {\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 i4 = index * 4;\n const scaleX = splatB[i4 + 1] >>> 16;\n const scaleY = splatB[i4 + 2] & 0xffff;\n const scaleZ = splatB[i4 + 2] >>> 16;\n if (scaleX === 0xfc00 && scaleY === 0xfc00 && scaleZ === 0xfc00) {\n callback(index, Number.NaN, Number.NaN, Number.NaN);\n continue;\n }\n callback(index, centerView[i4], centerView[i4 + 1], centerView[i4 + 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 for (let index = 0; index < this.numSplats; index += 1) {\n const splat = decodeSplat(this.splatArrays, index);\n callback(\n index,\n splat.center,\n splat.scales,\n splat.quaternion,\n splat.opacity,\n splat.color,\n );\n }\n }\n\n getSplatTextures() {\n if (this.maxSplats === 0 || this.splatArrays[0].length === 0) {\n return [Splats.emptyTexture, Splats.emptyTexture] as const;\n }\n\n const { width, height, depth } = getTextureSize(this.maxSplats);\n const textureData = this.textures[0].image.data;\n const incompatible =\n this.textures[0] === Splats.emptyTexture ||\n this.textures[0].image.width !== width ||\n this.textures[0].image.height !== height ||\n this.textures[0].image.depth !== depth ||\n textureData === null ||\n textureData.buffer !== this.splatArrays[0].buffer;\n if (incompatible) {\n this.disposeMainTextures();\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 getShTextures(): SplatShTextures {\n this.shTextures.sh1 = this.ensureShTexture(\"sh1\", this.shTextures.sh1);\n this.shTextures.sh2 = this.ensureShTexture(\"sh2\", this.shTextures.sh2);\n this.shTextures.sh3a = this.ensureShTexture(\"sh3a\", this.shTextures.sh3a);\n this.shTextures.sh3b = this.ensureShTexture(\"sh3b\", this.shTextures.sh3b);\n return this.shTextures;\n }\n\n private ensureShTexture(\n key: \"sh1\" | \"sh2\" | \"sh3a\" | \"sh3b\",\n current?: THREE.DataArrayTexture,\n ) {\n let texture = current;\n const data = this.extra[key] as Uint32Array | undefined;\n if (!data) {\n texture?.dispose();\n return undefined;\n }\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 const incompatible =\n texture &&\n (texture.image.width !== width ||\n texture.image.height !== height ||\n texture.image.depth !== depth ||\n texture.image.data === null ||\n texture.image.data.buffer !== padded.buffer);\n if (incompatible) {\n texture?.dispose();\n texture = undefined;\n }\n if (!texture) {\n texture = newUintArrayTexture(padded, width, height, depth);\n } else if (this.needsUpdate) {\n texture.needsUpdate = true;\n }\n return texture;\n }\n\n static emptyTexture = newUintArrayTexture(null, 1, 1, 1);\n}\n\nfunction newUintArrayTexture(\n data: Uint32Array | null,\n width: number,\n height: number,\n depth: number,\n) {\n const texture = new THREE.DataArrayTexture(\n data as Uint32Array<ArrayBuffer>,\n width,\n height,\n depth,\n );\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.internalFormat = \"RGBA32UI\";\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.generateMipmaps = false;\n texture.needsUpdate = true;\n return texture;\n}\n","import * as THREE from \"three\";\n\nimport {\n get_raycast_buffer,\n get_raycast_buffer2,\n raycast_splat_buffers,\n} from \"gaussian-splat-rs\";\nimport { SplatEdit, SplatEditSdf, SplatEdits } from \"./SplatEdit\";\nimport type { SplatSource } from \"./SplatSource\";\nimport { Splats } from \"./Splats\";\nimport type { SplatFileType } from \"./defines\";\nimport * as wasm from \"./wasm\";\n\nconst raycastWorldToMesh = new THREE.Matrix4();\nconst raycastDirectionMatrix = new THREE.Matrix3();\nconst raycastOrigin = new THREE.Vector3();\nconst raycastDirection = new THREE.Vector3();\n\nexport type { SplatSource } from \"./SplatSource\";\n\nexport type SplatMeshOptions = {\n url?: string;\n fileBytes?: Uint8Array | ArrayBuffer;\n fileType?: SplatFileType;\n fileName?: string;\n stream?: ReadableStream;\n streamLength?: number;\n splats?: SplatSource;\n maxSplats?: number;\n constructSplats?: (splats: Splats) => Promise<void> | void;\n onProgress?: (event: ProgressEvent) => 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 camera: THREE.Camera;\n globalEdits: SplatEdit[];\n};\n\n/** A scene object backed by a fixed encoded splat source and RGBA SDF edits. */\nexport class SplatMesh extends THREE.Object3D {\n initialized: Promise<SplatMesh>;\n isInitialized = false;\n\n splats?: SplatSource;\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 mappingVersion = 0;\n\n private lastSource?: SplatSource;\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 viewOrigin = new THREE.Vector3();\n private lastViewOrigin = new THREE.Vector3().setScalar(Number.NaN);\n private sdfCoordinateOrigin = new THREE.Vector3();\n\n constructor(options: SplatMeshOptions = {}) {\n super();\n\n this.splats =\n options.splats ?? new Splats({ maxSplats: options.maxSplats });\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.05;\n this.onFrame = options.onFrame;\n\n const mutableSplats =\n this.splats instanceof Splats ? this.splats : undefined;\n const needsAsyncInitialization = Boolean(\n mutableSplats &&\n (options.url ||\n options.fileBytes ||\n options.stream ||\n options.constructSplats ||\n !mutableSplats.isInitialized),\n );\n\n if (needsAsyncInitialization) {\n this.initialized = this.asyncInitialize(options).then(async () => {\n this.isInitialized = true;\n await options.onLoad?.(this);\n return this;\n });\n } else {\n this.isInitialized = true;\n const maybePromise = options.onLoad?.(this);\n this.initialized =\n maybePromise instanceof Promise\n ? maybePromise.then(() => this)\n : Promise.resolve(this);\n }\n }\n\n private async asyncInitialize(options: SplatMeshOptions) {\n const splats = this.splats;\n if (splats instanceof Splats) {\n if (\n options.url ||\n options.fileBytes ||\n options.stream ||\n options.constructSplats\n ) {\n splats.reinitialize({\n url: options.url,\n fileBytes: options.fileBytes,\n fileType: options.fileType,\n fileName: options.fileName,\n stream: options.stream,\n streamLength: options.streamLength,\n maxSplats: options.maxSplats,\n construct: options.constructSplats,\n onProgress: options.onProgress,\n });\n }\n await splats.initialized;\n }\n this.numSplats = this.splats?.getNumSplats() ?? 0;\n this.updateMappingVersion();\n }\n\n pushSplat(\n center: THREE.Vector3,\n scales: THREE.Vector3,\n quaternion: THREE.Quaternion,\n opacity: number,\n color: THREE.Color,\n ) {\n if (this.splats instanceof Splats) {\n this.splats.pushSplat(center, scales, quaternion, opacity, color);\n }\n this.numSplats = this.splats?.getNumSplats() ?? this.numSplats;\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 this.sdfEdits?.dispose();\n this.sdfEdits = null;\n this.splats?.dispose();\n this.splats = undefined;\n }\n\n getBoundingBox(centersOnly = true) {\n if (!this.isInitialized) {\n throw new Error(\n \"Cannot get bounding box before SplatMesh is initialized\",\n );\n }\n const minimum = new THREE.Vector3().setScalar(Number.POSITIVE_INFINITY);\n const maximum = new THREE.Vector3().setScalar(Number.NEGATIVE_INFINITY);\n const corner = new THREE.Vector3();\n\n if (centersOnly) {\n this.splats?.forEachCenter((_index, x, y, z) => {\n if (Number.isNaN(x)) return;\n corner.set(x, y, z);\n minimum.min(corner);\n maximum.max(corner);\n });\n return new THREE.Box3(minimum, maximum);\n }\n\n const signs = [-1, 1];\n this.splats?.forEachSplat((_index, center, scales, quaternion) => {\n for (const x of signs) {\n for (const y of signs) {\n for (const z of signs) {\n corner\n .set(x * scales.x, y * scales.y, z * scales.z)\n .applyQuaternion(quaternion)\n .add(center);\n minimum.min(corner);\n maximum.max(corner);\n }\n }\n }\n });\n return new THREE.Box3(minimum, maximum);\n }\n\n frameUpdate({ time, deltaTime, camera, globalEdits }: SplatMeshFrameContext) {\n this.onFrame?.({ mesh: this, time, deltaTime });\n\n const source = this.splats;\n if (!source) {\n return;\n }\n this.splats = source;\n\n let updated = false;\n let sortUpdated = false;\n const count = source.getNumSplats();\n if (source !== this.lastSource) {\n this.lastSource = source;\n updated = true;\n sortUpdated = true;\n }\n if (count !== this.lastNumSplats) {\n this.lastNumSplats = count;\n this.numSplats = count;\n this.mappingVersion += 1;\n updated = true;\n sortUpdated = true;\n }\n if (source.needsUpdate) {\n updated = true;\n sortUpdated = true;\n }\n if (this.maxSh !== this.lastMaxSh) {\n this.lastMaxSh = this.maxSh;\n updated = true;\n }\n if (this.maxSh > 0 && source.getNumSh() > 0) {\n camera.getWorldPosition(this.viewOrigin);\n if (!this.viewOrigin.equals(this.lastViewOrigin)) {\n this.lastViewOrigin.copy(this.viewOrigin);\n // Directional SH changes appearance but never changes splat depth.\n updated = true;\n }\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 sortUpdated = true;\n }\n\n const recolor = new THREE.Vector4(\n this.recolor.r,\n this.recolor.g,\n this.recolor.b,\n this.opacity,\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.updateVersion({ sort: sortUpdated });\n }\n }\n\n updateVersion({ sort = true }: { sort?: boolean } = {}) {\n this.version += 1;\n if (sort) this.sortVersion += 1;\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 (\n !wasm.isInitialized() ||\n !this.raycastable ||\n !(this.splats instanceof Splats)\n ) {\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\n const [first, second] = this.splats.splatArrays;\n for (let base = 0; base < this.numSplats; base += capacity) {\n const count = Math.min(capacity, this.numSplats - base);\n buffer.set(first.subarray(base * 4, (base + count) * 4));\n buffer2.set(second.subarray(base * 4, (base + count) * 4));\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\n for (let index = 0; index < distances.length; index += 1) {\n const distance = distances[index];\n intersects.push({\n distance,\n point: ray.at(distance, new THREE.Vector3()),\n object: this,\n });\n }\n }\n }\n}\n","const float LN_SCALE_MIN = -12.0;\nconst float LN_SCALE_MAX = 9.0;\n\nconst 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\nconst float INFINITY = 1.0 / 0.0;\n\nfloat sqr(float x) {\n return x * x;\n}\n\nvec3 srgbToLinear(vec3 rgb) {\n return pow(rgb, vec3(2.2));\n}\n\n// Encode a quaternion (vec4) into a 24‐bit uint with folded octahedral mapping.\nuint encodeQuatOctXy88R8(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(q.w);\n float halfTheta = theta * 0.5;\n float s = sin(halfTheta);\n // Recover the rotation axis; use a default if nearly zero rotation.\n vec3 axis = (abs(s) < 1e-6) ? vec3(1.0, 0.0, 0.0) : q.xyz / s;\n \n // --- Folded Octahedral Mapping (inline) ---\n // Compute p = (axis.x, axis.y) / (|axis.x|+|axis.y|+|axis.z|)\n float sum = abs(axis.x) + abs(axis.y) + abs(axis.z);\n vec2 p = vec2(axis.x, axis.y) / sum;\n // If axis.z < 0, fold the mapping.\n if (axis.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 8 bits (0 to 255)\n uint quantU = uint(clamp(round(u_f * 255.0), 0.0, 255.0));\n uint quantV = uint(clamp(round(v_f * 255.0), 0.0, 255.0));\n \n // --- Angle Quantization ---\n // Quantize θ ∈ [0,π] to 8 bits (0 to 255)\n uint angleInt = uint(clamp(round((theta / 3.14159265359) * 255.0), 0.0, 255.0));\n \n // Pack bits: bits [0–7]: quantU, [8–15]: quantV, [16–23]: angleInt.\n return (angleInt << 16u) | (quantV << 8u) | quantU;\n}\n\n// Decode a 24‐bit encoded uint into a quaternion (vec4) using the folded octahedral inverse.\nvec4 decodeQuatOctXy88R8(uint encoded) {\n // Extract the fields.\n uint quantU = encoded & uint(0xFFu); // bits 0–7\n uint quantV = (encoded >> 8u) & uint(0xFFu); // bits 8–15\n uint angleInt = encoded >> 16u; // bits 16–23\n\n // Recover u and v in [0,1], then map to [-1,1].\n float u_f = float(quantU) / 255.0;\n float v_f = float(quantV) / 255.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) / 255.0) * 3.14159265359;\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\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 halfTheta = acos(q.w);\n float theta = 2.0 * halfTheta;\n float s = sin(halfTheta);\n // Recover the rotation axis; use a default if nearly zero rotation.\n vec3 axis = (abs(s) < 1e-6) ? vec3(1.0, 0.0, 0.0) : q.xyz / s;\n \n // --- Folded Octahedral Mapping (inline) ---\n // Compute p = (axis.x, axis.y) / (|axis.x|+|axis.y|+|axis.z|)\n float sum = abs(axis.x) + abs(axis.y) + abs(axis.z);\n vec2 p = vec2(axis.x, axis.y) / sum;\n // If axis.z < 0, fold the mapping.\n if (axis.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\n// Encode a Splat into the compressed single-record representation.\nuvec4 encodePackedSplat(\n vec3 center, vec3 scales, vec4 quaternion, vec4 rgba, vec4 rgbMinMaxLnScaleMinMax\n) {\n float rgbMin = rgbMinMaxLnScaleMinMax.x;\n float rgbMax = rgbMinMaxLnScaleMinMax.y;\n vec3 encRgb = (rgba.rgb - vec3(rgbMin)) / (rgbMax - rgbMin);\n uvec4 uRgba = uvec4(round(clamp(vec4(encRgb, rgba.a) * 255.0, 0.0, 255.0)));\n\n uint uQuat = encodeQuatOctXy88R8(quaternion);\n uvec3 uQuat3 = uvec3(uQuat & 0xffu, (uQuat >> 8u) & 0xffu, (uQuat >> 16u) & 0xffu);\n\n // Encode scales in three uint8s, where 0=>0.0 and 1..=255 stores log scale\n float lnScaleMin = rgbMinMaxLnScaleMinMax.z;\n float lnScaleMax = rgbMinMaxLnScaleMinMax.w;\n float lnScaleScale = 254.0 / (lnScaleMax - lnScaleMin);\n uvec3 uScales = uvec3(\n (scales.x == 0.0) ? 0u : uint(round(clamp((log(scales.x) - lnScaleMin) * lnScaleScale, 0.0, 254.0))) + 1u,\n (scales.y == 0.0) ? 0u : uint(round(clamp((log(scales.y) - lnScaleMin) * lnScaleScale, 0.0, 254.0))) + 1u,\n (scales.z == 0.0) ? 0u : uint(round(clamp((log(scales.z) - lnScaleMin) * lnScaleScale, 0.0, 254.0))) + 1u\n );\n\n // Pack it all into 4 x uint32\n uint word0 = uRgba.r | (uRgba.g << 8u) | (uRgba.b << 16u) | (uRgba.a << 24u);\n uint word1 = packHalf2x16(center.xy);\n uint word2 = packHalf2x16(vec2(center.z, 0.0)) | (uQuat3.x << 16u) | (uQuat3.y << 24u);\n uint word3 = uScales.x | (uScales.y << 8u) | (uScales.z << 16u) | (uQuat3.z << 24u);\n return uvec4(word0, word1, word2, word3);\n}\n\nvoid decodePackedSplat(uvec4 packedData, out vec3 center, out vec3 scales, out vec4 quaternion, out vec4 rgba, vec4 rgbMinMaxLnScaleMinMax) {\n uint word0 = packedData.x, word1 = packedData.y, word2 = packedData.z, word3 = packedData.w;\n\n uvec4 uRgba = uvec4(word0 & 0xffu, (word0 >> 8u) & 0xffu, (word0 >> 16u) & 0xffu, (word0 >> 24u) & 0xffu);\n float rgbMin = rgbMinMaxLnScaleMinMax.x;\n float rgbMax = rgbMinMaxLnScaleMinMax.y;\n rgba = (vec4(uRgba) / 255.0);\n rgba.rgb = rgba.rgb * (rgbMax - rgbMin) + rgbMin;\n\n center = vec4(\n unpackHalf2x16(word1),\n unpackHalf2x16(word2 & 0xffffu)\n ).xyz;\n\n uvec3 uScales = uvec3(word3 & 0xffu, (word3 >> 8u) & 0xffu, (word3 >> 16u) & 0xffu);\n float lnScaleMin = rgbMinMaxLnScaleMinMax.z;\n float lnScaleMax = rgbMinMaxLnScaleMinMax.w;\n float lnScaleScale = (lnScaleMax - lnScaleMin) / 254.0;\n scales = vec3(\n (uScales.x == 0u) ? 0.0 : exp(lnScaleMin + float(uScales.x - 1u) * lnScaleScale),\n (uScales.y == 0u) ? 0.0 : exp(lnScaleMin + float(uScales.y - 1u) * lnScaleScale),\n (uScales.z == 0u) ? 0.0 : exp(lnScaleMin + float(uScales.z - 1u) * lnScaleScale)\n );\n\n\n uint uQuat = ((word2 >> 16u) & 0xFFFFu) | ((word3 >> 8u) & 0xFF0000u);\n quaternion = decodeQuatOctXy88R8(uQuat);\n}\n\n// Encode a normal Splat into the standard two-record representation.\nvoid encodeSplat(\n out uvec4 splatData, out uvec4 splatData2,\n vec3 center, vec3 scales, vec4 quaternion, vec4 rgba\n) {\n splatData.x = floatBitsToUint(center.x);\n splatData.y = floatBitsToUint(center.y);\n splatData.z = floatBitsToUint(center.z);\n splatData.w = packHalf2x16(vec2(rgba.a, 0.0));\n\n splatData2.x = packHalf2x16(rgba.rg);\n splatData2.y = packHalf2x16(vec2(rgba.b, log(scales.x)));\n splatData2.z = packHalf2x16(log(scales.yz));\n splatData2.w = encodeQuatOctXy1010R12(quaternion);\n}\n\nfloat decodeSplatAlpha(uvec4 splatData) {\n return unpackHalf2x16(splatData.w).x;\n}\n\nvoid decodeSplat(\n uvec4 splatData, uvec4 splatData2,\n out vec3 center, out vec3 scales, out vec4 quaternion, out vec4 rgba\n) {\n center.x = uintBitsToFloat(splatData.x);\n center.y = uintBitsToFloat(splatData.y);\n center.z = uintBitsToFloat(splatData.z);\n rgba.a = unpackHalf2x16(splatData.w).x;\n\n rgba.rg = unpackHalf2x16(splatData2.x);\n vec2 split = unpackHalf2x16(splatData2.y);\n rgba.b = split.x;\n scales.x = exp(split.y);\n scales.yz = exp(unpackHalf2x16(splatData2.z));\n quaternion = decodeQuatOctXy1010R12(splatData2.w);\n}\n\nvec3 decodeSplatShRgb(uint encoded) {\n uint biasedBase = (encoded >> 27u) & 0x1fu;\n float divisor = exp2(float(int(biasedBase) - 15)) / 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\n#include <splatDefines>\n\nuniform float near;\nuniform float far;\nuniform bool encodeLinear;\nuniform float time;\nuniform bool debugFlag;\nuniform float minAlpha;\n\nout vec4 fragColor;\n\nin vec4 vRgba;\nin vec2 vSplatUv;\nin vec3 vNdc;\nflat in uint vSplatIndex;\nflat in float adjustedStdDev;\nflat in float vSplatShape;\n\n#include <logdepthbuf_pars_fragment>\n\nvoid main() {\n vec4 rgba = vRgba;\n\n float z2 = dot(vSplatUv, vSplatUv);\n if (z2 > (adjustedStdDev * adjustedStdDev)) {\n discard;\n }\n\n float splatShape = vSplatShape;\n if (splatShape <= 1.0) {\n rgba.a *= exp(-0.5 * z2);\n } else {\n float a = exp((splatShape*splatShape - 1.0) / 2.718281828459045);\n float alpha = 1.0 - pow(1.0 - exp(-0.5 * z2), a);\n rgba.a *= alpha;\n }\n\n if (rgba.a < minAlpha) {\n discard;\n }\n if (encodeLinear) {\n rgba.rgb = srgbToLinear(rgba.rgb);\n }\n\n #ifdef 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 sampler2DArray;\nprecision highp usampler2DArray;\n\n#include <splatDefines>\n\nout vec4 vRgba;\nout vec2 vSplatUv;\nout vec3 vNdc;\nflat out uint vSplatIndex;\nflat out float adjustedStdDev;\nflat out float vSplatShape;\n\n// uniform uint numSplats;\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 bool enablePackedSplats;\nuniform float time;\nuniform float deltaTime;\nuniform bool debugFlag;\nuniform float minAlpha;\nuniform bool enable2DGS;\nuniform float blurAmount;\nuniform float preBlurAmount;\nuniform float focalDistance;\nuniform float apertureAngle;\nuniform float clipXY;\nuniform float focalAdjustment;\n\nuniform usampler2D ordering;\nuniform usampler2DArray splats;\nuniform usampler2DArray splats2;\nuniform sampler2DArray splatShape;\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\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 ivec2 orderingCoord = ivec2((gl_InstanceID >> 2) & 4095, gl_InstanceID >> 14);\n uint splatIndex = texelFetch(ordering, orderingCoord, 0)[gl_InstanceID & 3];\n if (splatIndex == 0xffffffffu) {\n // Special value reserved for \"no splat\"\n return;\n }\n\n ivec3 texCoord = splatTexCoord(int(splatIndex));\n vec3 center, scales;\n vec4 quaternion, rgba;\n float opacity;\n mat3 cov3D;\n bvec3 zeroScales = bvec3(false);\n\n if (enablePackedSplats) {\n uvec4 packedData = texelFetch(splats, texCoord, 0);\n decodePackedSplat(packedData, center, scales, quaternion, rgba, vec4(0.0, 1.0, LN_SCALE_MIN, LN_SCALE_MAX));\n zeroScales = equal(scales, vec3(0.0));\n if (all(zeroScales)) {\n return;\n }\n\n rgba.a *= 2.0;\n opacity = rgba.a;\n if ((opacity == 0.0) || (opacity < minAlpha)) {\n return;\n }\n } else {\n uvec4 splat1 = texelFetch(splats, texCoord, 0);\n opacity = decodeSplatAlpha(splat1);\n if ((opacity == 0.0) || (opacity < minAlpha)) {\n return;\n }\n uvec4 splat2 = texelFetch(splats2, texCoord, 0);\n\n decodeSplat(splat1, splat2, center, scales, quaternion, rgba);\n zeroScales = equal(scales, vec3(0.0));\n if (all(zeroScales)) {\n return;\n }\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 independently from mesh/SDF opacity, which remains in\n // the main splat's alpha.\n float shape = 1.0 + texelFetch(splatShape, texCoord, 0).r;\n if (shape > 1.0) {\n // Stretch the packed 1..2 range to the kernel's 1..5 shape range.\n shape = min(shape * 4.0 - 3.0, 5.0);\n }\n vSplatShape = shape;\n\n // Expand wider shape kernels until alpha is nearly zero before clipping.\n adjustedStdDev = maxStdDev + 0.7 * max(shape - 1.0, 0.0);\n\n scales *= renderToViewScale;\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 (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 vRgba = vec4(rgba.rgb, opacity);\n vSplatUv = position.xy * adjustedStdDev;\n\n // Record the splat index for entropy\n vSplatIndex = splatIndex;\n\n // Compute view space quaternion of splat\n vec4 viewQuaternion = quatQuat(renderToViewQuat, quaternion);\n\n if (enable2DGS && any(zeroScales)) {\n vec3 offset;\n if (zeroScales.z) {\n offset = vec3(vSplatUv.xy * scales.xy, 0.0);\n } else if (zeroScales.y) {\n offset = vec3(vSplatUv.x * scales.x, 0.0, vSplatUv.y * scales.z);\n } else {\n offset = vec3(0.0, vSplatUv.xy * scales.yz);\n }\n\n vec3 viewPos = viewCenter + quatVec(viewQuaternion, offset);\n gl_Position = projectionMatrix * vec4(viewPos, 1.0);\n vNdc = gl_Position.xyz / gl_Position.w;\n\n #include <logdepthbuf_vertex>\n return;\n }\n\n // Compute the 3D covariance matrix of the splat\n mat3 RS = scaleQuaternionToMatrix(scales, viewQuaternion);\n cov3D = RS * transpose(RS);\n\n // Compute the Jacobian of the splat's projection at its center\n vec2 scaledRenderSize = renderSize * focalAdjustment;\n vec2 focal = 0.5 * scaledRenderSize * vec2(projectionMatrix[0][0], projectionMatrix[1][1]);\n\n mat3 J;\n if (isOrthographic) {\n J = mat3(\n focal.x, 0.0, 0.0,\n 0.0, focal.y, 0.0,\n 0.0, 0.0, 0.0\n );\n } else {\n float invZ = 1.0 / viewCenter.z;\n vec2 J1 = focal * invZ;\n vec2 J2 = -(J1 * viewCenter.xy) * invZ;\n J = mat3(\n J1.x, 0.0, J2.x,\n 0.0, J1.y, J2.y,\n 0.0, 0.0, 0.0\n );\n }\n\n // Compute the 2D covariance by projecting the 3D covariance\n // and picking out the XY plane components.\n mat3 cov2D = transpose(J) * cov3D * J;\n float a = cov2D[0][0];\n float d = cov2D[1][1];\n float b = cov2D[0][1];\n\n // Optionally pre-blur the splat to match non-antialias optimized splats\n a += preBlurAmount;\n d += preBlurAmount;\n\n float fullBlurAmount = blurAmount;\n if ((focalDistance > 0.0) && (apertureAngle > 0.0)) {\n float focusRadius = maxPixelRadius;\n if (viewCenter.z < 0.0) {\n float focusBlur = abs((-viewCenter.z - focalDistance) / viewCenter.z);\n float apertureRadius = focal.x * tan(0.5 * apertureAngle);\n focusRadius = focusBlur * apertureRadius;\n }\n fullBlurAmount = clamp(sqr(focusRadius), blurAmount, sqr(maxPixelRadius));\n }\n\n // Do convolution with a 0.5-pixel Gaussian for anti-aliasing: sqrt(0.3) ~= 0.5\n float detOrig = a * d - b * b;\n a += fullBlurAmount;\n d += fullBlurAmount;\n float det = a * d - b * b;\n\n // Compute anti-aliasing intensity scaling factor\n float blurAdjust = sqrt(max(0.0, detOrig / det));\n opacity *= blurAdjust;\n if (opacity < minAlpha) {\n return;\n }\n vRgba.a = opacity;\n\n // Compute the eigenvalue and eigenvectors of the 2D covariance matrix\n float eigenAvg = 0.5 * (a + d);\n float eigenDelta = sqrt(max(0.0, eigenAvg * eigenAvg - det));\n float eigen1 = eigenAvg + eigenDelta;\n float eigen2 = eigenAvg - eigenDelta;\n\n vec2 eigenVec1 = (abs(b) > 0.001) ? 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 float scale1 = min(maxPixelRadius, adjustedStdDev * sqrt(eigen1));\n float scale2 = min(maxPixelRadius, adjustedStdDev * sqrt(eigen2));\n if (scale1 < minPixelRadius && scale2 < minPixelRadius) {\n return;\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 vNdc = ndc;\n gl_Position = vec4(ndc.xy * clipCenter.w, clipCenter.zw);\n\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;\n\nuniform usampler2DArray sourceSplats;\nuniform usampler2DArray sourceSplats2;\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 objectScale;\nuniform vec4 objectQuaternion;\nuniform vec4 recolor;\n\nuniform int numSdfs;\nuniform int numEdits;\nuniform usampler2D sdfTexture;\nuniform usampler2D editTexture;\n\n#ifdef OUTPUT_PACKED\nlayout(location = 0) out uvec4 target;\nlayout(location = 1) out vec4 targetShape;\n#else\nlayout(location = 0) out uvec4 target;\nlayout(location = 1) out uvec4 target2;\nlayout(location = 2) out vec4 targetShape;\n#endif\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 vec4 quaternion,\n out vec3 scale,\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 data = texelFetch(sdfTexture, ivec2(1, index), 0);\n quaternion = vec4(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z), uintBitsToFloat(data.w));\n data = texelFetch(sdfTexture, ivec2(2, index), 0);\n scale = vec3(uintBitsToFloat(data.x), uintBitsToFloat(data.y), uintBitsToFloat(data.z));\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 -INFINITY;\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 float k0 = length(position / sizes.xyz);\n float k1 = length(position / dot(sizes.xyz, sizes.xyz));\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 INFINITY;\n}\n\nfloat evaluateSdfs(\n int sdfFirst,\n int sdfCount,\n vec3 position,\n float smoothAmount,\n out vec4 resultRgba\n) {\n float distanceAccum = smoothAmount == 0.0 ? INFINITY : 0.0;\n float maxExponent = -INFINITY;\n resultRgba = 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 vec4 quaternion;\n vec3 scale;\n vec4 sizes;\n vec4 value;\n unpackSdf(index, flags, center, quaternion, scale, sizes, value);\n vec3 sdfPosition = quatVec(quaternion, position * scale) + center;\n float distance = sdfDistance(flags & 0xffu, sdfPosition, sizes);\n if ((flags & 0x100u) != 0u) distance = -distance;\n\n if (smoothAmount == 0.0) {\n if (distance < distanceAccum) {\n distanceAccum = distance;\n resultRgba = value;\n }\n } else {\n float exponent = -distance / smoothAmount;\n if (exponent > maxExponent) {\n float rescale = exp(maxExponent - exponent);\n distanceAccum *= rescale;\n resultRgba *= rescale;\n maxExponent = exponent;\n }\n float weight = exp(exponent - maxExponent);\n distanceAccum += weight;\n resultRgba += weight * value;\n }\n }\n\n if (smoothAmount == 0.0 || distanceAccum == 0.0) {\n return distanceAccum == 0.0 ? INFINITY : distanceAccum;\n }\n resultRgba /= distanceAccum;\n return (-log(distanceAccum) - maxExponent) * smoothAmount;\n}\n\nvoid applySdfEdits(vec3 position, inout vec4 rgba) {\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 float distance = evaluateSdfs(sdfFirst, sdfCount, position, smoothAmount, sdfRgba);\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 vec4 target = blendMode == 0u ? rgba * sdfRgba : rgba + sdfRgba;\n rgba = mix(rgba, target, amount);\n }\n}\n\nvoid produceSplat(int index) {\n ivec3 coord = splatTexCoord(index);\n vec3 center;\n vec3 scales;\n vec4 quaternion;\n vec4 rgba;\n decodeSplat(\n texelFetch(sourceSplats, coord, 0),\n texelFetch(sourceSplats2, coord, 0),\n center,\n scales,\n quaternion,\n rgba\n );\n if (all(equal(scales, vec3(0.0)))) return;\n\n float sourceAlpha = rgba.a;\n rgba.a = min(sourceAlpha, 1.0);\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 rgba.rgb += evaluateSH(coord, sourceViewDirection);\n }\n scales *= objectScale;\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 applySdfEdits(editPosition, rgba);\n vec3 relativeCenter = center;\n // Recolor and opacity are both mesh-wide overrides, so apply them together\n // after local SDF edits. This also ensures additive edits cannot bypass the\n // final mesh tint or fade.\n rgba *= vec4(recolor.rgb, clamp(recolor.a, 0.0, 1.0));\n\n#ifdef OUTPUT_PACKED\n vec4 packedRgba = vec4(rgba.rgb, rgba.a * 0.5);\n target = encodePackedSplat(relativeCenter, scales, quaternion, packedRgba, vec4(0.0, 1.0, LN_SCALE_MIN, LN_SCALE_MAX));\n#else\n encodeSplat(target, target2, relativeCenter, scales, quaternion, rgba);\n#endif\n\n targetShape = vec4(clamp(sourceAlpha - 1.0, 0.0, 1.0), 0.0, 0.0, 1.0);\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#ifndef OUTPUT_PACKED\n target2 = uvec4(0u);\n#endif\n targetShape = vec4(0.0, 0.0, 0.0, 1.0);\n if (index >= 0 && index < targetCount) {\n produceSplat(index);\n }\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 a model-level collapse can still produce a correctly oriented 2DGS.\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;\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;\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 if (matrix.determinant() < 0) axisX.negate();\n\n rotationMatrix.makeBasis(axisX, axisY, axisZ);\n rotation.setFromRotationMatrix(rotationMatrix).normalize();\n}\n","import * as THREE from \"three\";\nimport { FullScreenQuad } from \"three/addons/postprocessing/Pass.js\";\n\nimport { SplatEdit, SplatEdits } from \"./SplatEdit\";\nimport { SplatMesh } from \"./SplatMesh\";\nimport { SPLAT_TEX_HEIGHT, SPLAT_TEX_WIDTH } from \"./defines\";\nimport { getShaders } from \"./shaders\";\nimport splatGenerate from \"./shaders/splatGenerate.glsl\";\nimport { decomposeSplatTransform } from \"./splatTransform\";\nimport { IDENT_VERTEX_SHADER, getTextureSize, threeMrtArray } from \"./utils\";\n\nexport type SplatMapping = {\n node: SplatMesh;\n version: number;\n sortVersion: number;\n mappingVersion: number;\n base: number;\n count: number;\n};\n\ntype GenerateUniforms = Record<string, THREE.IUniform>;\n\nexport class SplatAccumulator {\n time = 0;\n deltaTime = 0;\n viewOrigin = 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 packedSplats: boolean;\n\n private transformScale = new THREE.Vector3();\n private transformQuaternion = new THREE.Quaternion();\n\n constructor({ packedSplats = false }: { packedSplats?: boolean } = {}) {\n if (!threeMrtArray) {\n throw new Error(\"Gaussian Splat Lite requires THREE.js r179 or above\");\n }\n this.packedSplats = packedSplats;\n }\n\n dispose() {\n this.target?.dispose();\n this.target = null;\n }\n\n getTextures(): THREE.DataArrayTexture[] {\n return this.target?.textures ?? SplatAccumulator.emptyTextures;\n }\n\n getSplatShapeTexture() {\n return (\n this.target?.textures[this.packedSplats ? 1 : 2] ??\n SplatAccumulator.emptySplatShape\n );\n }\n\n generateMapping(splatCounts: number[]) {\n let maxSplats = 0;\n const mapping = splatCounts.map((count) => {\n const base = maxSplats;\n maxSplats += Math.ceil(count / SPLAT_TEX_WIDTH) * SPLAT_TEX_WIDTH;\n return { base, count };\n });\n return { maxSplats, mapping };\n }\n\n ensureGenerate({ maxSplats }: { maxSplats: number }) {\n if (this.target && Math.max(1, maxSplats) <= this.maxSplats) {\n return false;\n }\n this.dispose();\n\n const textureSize = getTextureSize(Math.max(1, maxSplats));\n const { width, height, depth } = textureSize;\n this.maxSplats = textureSize.maxSplats;\n this.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 this.target.scissorTest = true;\n\n const shape = this.target.texture.clone();\n shape.format = THREE.RedFormat;\n shape.type = THREE.UnsignedByteType;\n shape.internalFormat = \"R8\";\n if (!this.packedSplats) {\n const second = this.target.texture.clone();\n this.target.textures = [this.target.texture, second, shape];\n } else {\n this.target.textures = [this.target.texture, shape];\n }\n return true;\n }\n\n private getMaterial() {\n const key = this.packedSplats;\n let material = SplatAccumulator.materials.get(key);\n if (!material) {\n getShaders();\n const defines: Record<string, string> = {};\n if (this.packedSplats) defines.OUTPUT_PACKED = \"1\";\n material = new THREE.RawShaderMaterial({\n glslVersion: THREE.GLSL3,\n vertexShader: IDENT_VERTEX_SHADER,\n fragmentShader: splatGenerate,\n uniforms: makeGenerateUniforms(),\n defines,\n depthTest: false,\n depthWrite: false,\n });\n SplatAccumulator.materials.set(key, material);\n }\n return material;\n }\n\n private prepareMaterial(mesh: SplatMesh) {\n const source = mesh.splats;\n if (!source) {\n throw new Error(\"SplatMesh has no source\");\n }\n const material = this.getMaterial();\n const uniforms = material.uniforms as GenerateUniforms;\n const [sourceSplats, sourceSplats2] = source.getSplatTextures();\n const sh = source.getShTextures();\n source.needsUpdate = false;\n\n uniforms.sourceSplats.value = sourceSplats;\n uniforms.sourceSplats2.value = sourceSplats2;\n uniforms.numSh.value = Math.min(mesh.maxSh, source.getNumSh());\n uniforms.sh1Texture.value = sh.sh1 ?? SplatAccumulator.emptyTexture;\n uniforms.sh2Texture.value = sh.sh2 ?? SplatAccumulator.emptyTexture;\n uniforms.sh3TextureA.value = sh.sh3a ?? SplatAccumulator.emptyTexture;\n uniforms.sh3TextureB.value = sh.sh3b ?? SplatAccumulator.emptyTexture;\n\n decomposeSplatTransform(\n mesh.matrixWorld,\n this.transformScale,\n this.transformQuaternion,\n );\n uniforms.objectBasis.value.setFromMatrix4(mesh.matrixWorld);\n uniforms.objectOffset.value.setFromMatrixPosition(mesh.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, but preserves ordinary scale/quaternion storage and 2DGS\n // zero axes.\n uniforms.objectScale.value.copy(this.transformScale);\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 mesh.opacity,\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 SplatAccumulator.fullScreenQuad.material = material;\n return material;\n }\n\n generate({\n mesh,\n base,\n count,\n renderer,\n }: {\n mesh: SplatMesh;\n base: number;\n count: number;\n renderer: THREE.WebGLRenderer;\n }) {\n if (!this.target) throw new Error(\"Accumulator target is not initialized\");\n if (base + count > this.maxSplats) {\n throw new Error(\"Splat generation range exceeds accumulator capacity\");\n }\n\n const material = this.prepareMaterial(mesh);\n const uniforms = material.uniforms as GenerateUniforms;\n const renderState = this.saveRenderState(renderer);\n const nextBase =\n Math.ceil((base + count) / SPLAT_TEX_WIDTH) * SPLAT_TEX_WIDTH;\n const layerSize = SPLAT_TEX_WIDTH * SPLAT_TEX_HEIGHT;\n uniforms.targetBase.value = base;\n uniforms.targetCount.value = count;\n\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 this.target.scissor.set(0, yStart, SPLAT_TEX_WIDTH, yEnd - yStart);\n renderer.setRenderTarget(this.target, layer);\n renderer.xr.enabled = false;\n renderer.autoClear = false;\n SplatAccumulator.fullScreenQuad.render(renderer);\n base += SPLAT_TEX_WIDTH * (yEnd - yStart);\n }\n this.resetRenderState(renderer, renderState);\n }\n\n prepareGenerate({\n renderer,\n scene,\n timer,\n camera,\n previous,\n }: {\n renderer: THREE.WebGLRenderer;\n scene: THREE.Scene;\n timer: THREE.Timer;\n camera: THREE.Camera;\n previous: SplatAccumulator;\n }) {\n camera.getWorldPosition(this.viewOrigin);\n camera.getWorldDirection(this.viewDirection);\n this.time = timer.getElapsed();\n this.deltaTime = timer.getDelta();\n\n const allMeshes: SplatMesh[] = [];\n scene.traverse((node) => {\n if (node instanceof SplatMesh && camera.layers.test(node.layers)) {\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 try {\n mesh.frameUpdate({\n time: this.time,\n deltaTime: this.deltaTime,\n camera,\n globalEdits: Array.from(globalEdits),\n });\n } catch (error) {\n console.error(\"SplatMesh frame update failed\", error);\n }\n }\n\n const visibleMeshes: SplatMesh[] = [];\n scene.traverseVisible((node) => {\n if (node instanceof SplatMesh && camera.layers.test(node.layers)) {\n visibleMeshes.push(node);\n }\n });\n const { maxSplats, mapping: ranges } = this.generateMapping(\n visibleMeshes.map((mesh) => mesh.numSplats),\n );\n\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 version: node.version,\n sortVersion: node.sortVersion,\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 } =\n previous.checkVersions(this.mapping);\n this.version = previous.version + (splatsUpdated ? 1 : 0);\n this.mappingVersion = previous.mappingVersion + (mappingUpdated ? 1 : 0);\n\n return {\n version: this.version,\n sortUpdated,\n generate: () => {\n this.ensureGenerate({ maxSplats });\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 if (this.mapping.length !== other.length) {\n return { splatsUpdated: true, mappingUpdated: true, sortUpdated: true };\n }\n const mappingUpdated = this.mapping.some((item, index) => {\n const previous = other[index];\n return (\n item.node !== previous.node ||\n item.base !== previous.base ||\n item.count !== previous.count ||\n item.mappingVersion !== previous.mappingVersion\n );\n });\n if (mappingUpdated) {\n return { splatsUpdated: true, mappingUpdated: true, sortUpdated: true };\n }\n return {\n splatsUpdated: this.mapping.some(\n (item, index) => item.version !== other[index].version,\n ),\n mappingUpdated: false,\n sortUpdated: this.mapping.some(\n (item, index) => item.sortVersion !== other[index].sortVersion,\n ),\n };\n }\n\n private saveRenderState(renderer: THREE.WebGLRenderer) {\n return {\n target: renderer.getRenderTarget(),\n activeCubeFace: renderer.getActiveCubeFace(),\n activeMipmapLevel: renderer.getActiveMipmapLevel(),\n xrEnabled: renderer.xr.enabled,\n autoClear: renderer.autoClear,\n };\n }\n\n private resetRenderState(\n renderer: THREE.WebGLRenderer,\n state: ReturnType<SplatAccumulator[\"saveRenderState\"]>,\n ) {\n renderer.setRenderTarget(\n state.target,\n state.activeCubeFace,\n state.activeMipmapLevel,\n );\n renderer.xr.enabled = state.xrEnabled;\n renderer.autoClear = state.autoClear;\n }\n\n static emptyTexture = (() => {\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.internalFormat = \"RGBA32UI\";\n texture.needsUpdate = true;\n return texture;\n })();\n\n static emptySplatShape = (() => {\n const { width, height, depth, maxSplats } = getTextureSize(1);\n const texture = new THREE.DataArrayTexture(\n new Uint8Array(maxSplats),\n width,\n height,\n depth,\n );\n texture.format = THREE.RedFormat;\n texture.type = THREE.UnsignedByteType;\n texture.internalFormat = \"R8\";\n texture.needsUpdate = true;\n return texture;\n })();\n\n static emptyTextures = [\n SplatAccumulator.emptyTexture,\n SplatAccumulator.emptyTexture,\n ];\n private static materials = new Map<boolean, THREE.RawShaderMaterial>();\n private static fullScreenQuad = new FullScreenQuad(\n new THREE.RawShaderMaterial({ visible: false }),\n );\n}\n\nfunction makeGenerateUniforms(): GenerateUniforms {\n return {\n targetLayer: { value: 0 },\n targetBase: { value: 0 },\n targetCount: { value: 0 },\n sourceSplats: { value: SplatAccumulator.emptyTexture },\n sourceSplats2: { value: SplatAccumulator.emptyTexture },\n numSh: { value: 0 },\n sh1Texture: { value: SplatAccumulator.emptyTexture },\n sh2Texture: { value: SplatAccumulator.emptyTexture },\n sh3TextureA: { value: SplatAccumulator.emptyTexture },\n sh3TextureB: { value: SplatAccumulator.emptyTexture },\n objectBasis: { value: new THREE.Matrix3() },\n objectOffset: { value: new THREE.Vector3() },\n objectScale: { value: new THREE.Vector3(1, 1, 1) },\n objectQuaternion: { value: new THREE.Quaternion() },\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","import * as THREE from \"three\";\n\n// SplatGeometry is an internal class used by GaussianSplatRenderer to render a collection\n// of Gsplats in a single draw call by extending THREE.InstancedBufferGeometry.\n// Each Gsplat is drawn as two triangles, with the order of the Gsplats determined\n// by a texture lookup via gl_InstanceID.\n\nexport class SplatGeometry extends THREE.InstancedBufferGeometry {\n constructor() {\n super();\n this.setAttribute(\"position\", new THREE.BufferAttribute(QUAD_VERTICES, 3));\n this.setIndex(new THREE.BufferAttribute(QUAD_INDICES, 1));\n }\n}\n\n// Each instance draws to triangles covering a quad over coords (-1,-1,0)..(1,1,0)\nconst QUAD_VERTICES = new Float32Array([\n -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0,\n]);\n\nconst QUAD_INDICES = new Uint16Array([0, 1, 2, 0, 2, 3]);\n","import * as THREE from \"three\";\nimport { SplatAccumulator } from \"./SplatAccumulator\";\nimport { SplatGeometry } from \"./SplatGeometry\";\nimport { SplatWorker } from \"./SplatWorker\";\nimport { buildSortCenters } from \"./cameraRelative\";\nimport { getShaders } from \"./shaders\";\nimport { resolveTimer, uploadU32DataTextureRows } from \"./utils\";\n\nconst renderToViewScaleTmp = new THREE.Vector3();\n\ntype UpdateRequest = {\n scene: THREE.Scene;\n camera: THREE.Camera;\n autoUpdate: boolean;\n};\n\n// Average (uniform) world scale of a camera.\nfunction getCameraWorldScale(camera: THREE.Camera): number {\n const scale = camera.getWorldScale(renderToViewScaleTmp);\n return (scale.x + scale.y + scale.z) / 3;\n}\n\nexport interface GaussianSplatRendererOptions {\n /**\n * Pass in your THREE.WebGLRenderer instance so Gaussian Splat Lite can perform work\n * outside the usual render loop. Should be created with antialias: false\n * (default setting) as WebGL anti-aliasing doesn't improve Gaussian Splatting\n * rendering and significantly reduces performance.\n */\n renderer: THREE.WebGLRenderer;\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 **\n * Minimum pixel radius for splat rendering.\n * @default 0.0\n */\n minPixelRadius?: number;\n /**\n * Maximum pixel radius for splat rendering.\n * @default 512.0\n */\n maxPixelRadius?: number;\n /**\n * Whether to use compressed Packed Splats for intermediary accumulator data.\n * Changing this at runtime regenerates the accumulator on the next update.\n * @default false\n */\n accumPackedSplats?: boolean;\n /**\n * Minimum alpha value for splat rendering.\n * @default 0.5 * (1.0 / 255.0)\n */\n minAlpha?: number;\n /**\n * Enable 2D Gaussian splatting rendering ability. When this mode is enabled,\n * any scale x/y/z component that is exactly 0 (minimum quantized value) results\n * in the other two non-0 axis being interpreted as an oriented 2D Gaussian Splat,\n * rather instead of the usual projected 3DGS Z-slice. When reading PLY files,\n * scale values less than e^-30 will be interpreted as 0.\n * @default false\n */\n enable2DGS?: boolean;\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.0\n */\n preBlurAmount?: number;\n /**\n * Scalar value to add to 2D splat covarianve diagonal, with opacity adjustment\n * to correctly account for \"blurring\" when anti-aliasing. Typically 0.3\n * (equivalent to approx 0.5 pixel radius) in scenes trained with anti-aliasing.\n */\n blurAmount?: number;\n /**\n * Depth-of-field distance to focal plane\n */\n focalDistance?: number;\n /**\n * Full-width angle of aperture opening (in radians), 0.0 to disable\n * @default 0.0\n */\n apertureAngle?: 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 * Minimum interval between sort calls in milliseconds.\n * @default 0\n */\n minSortIntervalMs?: number;\n /**\n * Configures an offline render target for the GaussianSplatRenderer (as opposed to\n * rendering to the canvas). This is useful for rendering environment maps,\n * additional viewpoints, or video frame rendering.\n * @default undefined\n */\n target?: {\n /**\n * Width of the render target in pixels.\n */\n width: number;\n /**\n * Height of the render target in pixels.\n */\n height: number;\n /**\n * If you want to be able to render a scene that depends on this target's\n * output (for example, a recursive viewport), set this to true to enable\n * double buffering.\n * @default false\n */\n doubleBuffer?: boolean;\n /**\n * Super-sampling factor for the render target. Values 1-4 are supported.\n * Note that re-sampling back down to .width x .height is done on the CPU\n * with simple averaging only when calling readTarget().\n * @default 1\n */\n superXY?: number;\n } & THREE.RenderTargetOptions;\n /**\n * Extra uniform values to pass to the shader.\n * @default undefined = no extra uniforms\n */\n extraUniforms?: Record<string, unknown>;\n /**\n * Replace the default `splatVertex.glsl` splat shader with a custom one.\n * @default undefined = use the default `splatVertex.glsl` shader\n */\n vertexShader?: string;\n /**\n * Replace the default `splatFragment.glsl` splat shader with a custom one.\n * @default undefined = use the default `splatFragment.glsl` shader\n */\n fragmentShader?: string;\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.\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 readonly renderer: THREE.WebGLRenderer;\n readonly material: THREE.ShaderMaterial;\n readonly uniforms: ReturnType<typeof GaussianSplatRenderer.makeUniforms>;\n\n autoUpdate: boolean;\n preUpdate: boolean;\n static gaussianSplatOverride?: GaussianSplatRenderer;\n\n renderSize = new THREE.Vector2();\n maxStdDev: number;\n minPixelRadius: number;\n maxPixelRadius: number;\n private accumPackedSplatsValue: boolean;\n minAlpha: number;\n enable2DGS: boolean;\n preBlurAmount: number;\n blurAmount: number;\n focalDistance: number;\n apertureAngle: number;\n clipXY: number;\n focalAdjustment: number;\n sortRadial: boolean;\n minSortIntervalMs: number;\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 orderingTexture: THREE.DataTexture | null = null;\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 sortCentersRevision = 0;\n private uploadedSortCentersRevision = -1;\n private updateRunning = false;\n private updatePromise: Promise<void> = Promise.resolve();\n private queuedUpdate: UpdateRequest | null = null;\n private disposed = false;\n\n target?: THREE.WebGLRenderTarget;\n backTarget?: THREE.WebGLRenderTarget;\n superPixels?: Uint8Array;\n targetPixels?: Uint8Array;\n superXY = 1;\n\n constructor(options: GaussianSplatRendererOptions) {\n if (!options) {\n throw new Error(\"GaussianSplatRenderer options are required\");\n }\n if (!options.renderer) {\n throw new Error(\"renderer is required in GaussianSplatRenderer options\");\n }\n\n const uniforms = GaussianSplatRenderer.makeUniforms();\n Object.assign(uniforms, options.extraUniforms ?? {});\n\n const shaders = getShaders();\n const premultipliedAlpha = options.premultipliedAlpha ?? true;\n const geometry = new SplatGeometry();\n const material = new THREE.ShaderMaterial({\n glslVersion: THREE.GLSL3,\n vertexShader: options.vertexShader ?? shaders.splatVertex,\n fragmentShader: options.fragmentShader ?? shaders.splatFragment,\n uniforms,\n premultipliedAlpha,\n transparent: options.transparent ?? true,\n depthTest: options.depthTest ?? true,\n depthWrite: options.depthWrite ?? false,\n side: THREE.DoubleSide,\n allowOverride: false,\n });\n\n super(geometry, material);\n this.material = material;\n this.uniforms = uniforms;\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.renderer = options.renderer;\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 ?? 512.0;\n this.accumPackedSplatsValue = options.accumPackedSplats ?? false;\n this.minAlpha = options.minAlpha ?? 0.5 * (1.0 / 255.0);\n this.enable2DGS = options.enable2DGS ?? false;\n this.preBlurAmount = options.preBlurAmount ?? 0.0;\n this.blurAmount = options.blurAmount ?? 0.3;\n this.focalDistance = options.focalDistance ?? 0.0;\n this.apertureAngle = options.apertureAngle ?? 0.0;\n this.clipXY = options.clipXY ?? 1.25;\n this.focalAdjustment = options.focalAdjustment ?? 2.0;\n this.sortRadial = options.sortRadial ?? false;\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 = this.createAccumulator();\n this.current = this.display;\n this.accumulators.push(this.createAccumulator());\n\n // Check if the provoking vertex convention should be changed.\n const provokingVertexExt = this.renderer\n .getContext()\n .getExtension(\"WEBGL_provoking_vertex\");\n if (provokingVertexExt) {\n provokingVertexExt.provokingVertexWEBGL(\n provokingVertexExt.FIRST_VERTEX_CONVENTION_WEBGL,\n );\n }\n\n if (options.target) {\n const {\n width,\n height,\n doubleBuffer,\n superXY: origSuperXY,\n ...origTargetOptions\n } = options.target;\n const superXY = Math.max(1, Math.min(4, origSuperXY ?? 1));\n if (width * superXY > 8192 || height * superXY > 8192) {\n throw new Error(\"Target size too large\");\n }\n this.superXY = superXY;\n\n const superWidth = width * superXY;\n const superHeight = height * superXY;\n const targetOptions: THREE.RenderTargetOptions = {\n format: THREE.RGBAFormat,\n type: THREE.UnsignedByteType,\n colorSpace: THREE.SRGBColorSpace,\n ...origTargetOptions,\n };\n\n this.target = new THREE.WebGLRenderTarget(\n superWidth,\n superHeight,\n targetOptions,\n );\n if (doubleBuffer) {\n this.backTarget = new THREE.WebGLRenderTarget(\n superWidth,\n superHeight,\n targetOptions,\n );\n }\n }\n }\n\n raycast(_raycaster: THREE.Raycaster, _intersects: THREE.Intersection[]) {}\n\n static makeUniforms() {\n const uniforms = {\n // // number of active splats to render\n // numSplats: { value: 0 },\n // Size of render viewport in pixels\n renderSize: { value: new THREE.Vector2() },\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: 512.0 },\n // Minimum alpha value for splat rendering\n minAlpha: { value: 0.5 * (1.0 / 255.0) },\n // Enable interpreting 0-thickness Gsplats as 2DGS\n enable2DGS: { value: false },\n // Add to projected 2D splat covariance diagonal (thickens and brightens)\n preBlurAmount: { value: 0.0 },\n // Add to 2D splat covariance diagonal and adjust opacity (anti-aliasing)\n blurAmount: { value: 0.3 },\n // Depth-of-field distance to focal plane\n focalDistance: { value: 0.0 },\n // Full-width angle of aperture opening (in radians)\n apertureAngle: { 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 encode Gsplat with linear RGB (for environment mapping)\n encodeLinear: { value: false },\n // Back-to-front sort ordering of splat indices\n ordering: { type: \"t\", value: GaussianSplatRenderer.emptyOrdering },\n enablePackedSplats: { value: false },\n // Gsplat collection to render\n splats: { type: \"t\", value: SplatAccumulator.emptyTexture },\n splats2: { type: \"t\", value: SplatAccumulator.emptyTexture },\n // Per-splat special shape amount, encoded in an R8 texture\n splatShape: { type: \"t\", value: SplatAccumulator.emptySplatShape },\n // Time in seconds for time-based effects\n time: { value: 0 },\n // Delta time in seconds since last frame\n deltaTime: { value: 0 },\n // Debug flag that alternates each frame\n debugFlag: { value: false },\n };\n return uniforms;\n }\n\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n this.queuedUpdate = null;\n\n if (this.target) {\n this.target.dispose();\n this.target = undefined;\n }\n if (this.backTarget) {\n this.backTarget.dispose();\n this.backTarget = undefined;\n }\n if (this.orderingTexture) {\n this.orderingTexture.dispose();\n this.orderingTexture = null;\n }\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\n if (this.sortWorker) {\n this.sortWorker.dispose();\n this.sortWorker = null;\n }\n\n this.geometry.dispose();\n this.material.dispose();\n }\n\n setDirty() {\n if (!this.dirty) {\n this.dirty = true;\n this.onDirty?.();\n }\n }\n\n private createAccumulator() {\n return new SplatAccumulator({\n packedSplats: this.accumPackedSplatsValue,\n });\n }\n\n private takeAccumulator() {\n let accumulator = this.accumulators.pop();\n while (\n accumulator &&\n accumulator.packedSplats !== this.accumPackedSplatsValue\n ) {\n accumulator.dispose();\n accumulator = this.accumulators.pop();\n }\n return accumulator ?? this.createAccumulator();\n }\n\n private releaseAccumulator(accumulator: SplatAccumulator) {\n if (accumulator.packedSplats === this.accumPackedSplatsValue) {\n this.accumulators.push(accumulator);\n } else {\n accumulator.dispose();\n }\n }\n\n onBeforeRender(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n camera: THREE.Camera,\n ) {\n const gaussianSplatRenderer =\n GaussianSplatRenderer.gaussianSplatOverride ?? this;\n\n const frame = renderer.info.render.frame;\n const isNewFrame = frame !== gaussianSplatRenderer.lastFrame;\n gaussianSplatRenderer.lastFrame = frame;\n\n const currentRenderTarget = renderer.getRenderTarget();\n const isXRRenderTarget = checkIsXRRenderTarget(currentRenderTarget);\n if (currentRenderTarget) {\n gaussianSplatRenderer.renderSize.set(\n currentRenderTarget.width,\n currentRenderTarget.height,\n );\n\n // WebXR mode on Apple Vision Pro returns 1x1 when presenting.\n // Use a different means to figure out the render size.\n if (\n isXRRenderTarget &&\n gaussianSplatRenderer.renderSize.x === 1 &&\n gaussianSplatRenderer.renderSize.y === 1\n ) {\n const baseLayer = renderer.xr.getSession()?.renderState.baseLayer;\n if (baseLayer) {\n gaussianSplatRenderer.renderSize.x = baseLayer.framebufferWidth;\n gaussianSplatRenderer.renderSize.y = baseLayer.framebufferHeight;\n }\n }\n } else {\n renderer.getDrawingBufferSize(gaussianSplatRenderer.renderSize);\n }\n this.uniforms.renderSize.value.copy(gaussianSplatRenderer.renderSize);\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 (gaussianSplatRenderer.autoUpdate && isNewFrame) {\n const preUpdate =\n gaussianSplatRenderer.preUpdate && !renderer.xr.isPresenting;\n let useCamera = camera;\n if (renderer.xr.isPresenting) {\n const xrCamera = renderer.xr.getCamera();\n // Keep the per-eye camera parented to the XR rig so its world transform\n // includes any scale applied to that rig.\n useCamera = xrCamera.cameras[0] ?? xrCamera;\n }\n if (preUpdate) {\n gaussianSplatRenderer.updateInternal({\n scene,\n camera: useCamera,\n autoUpdate: true,\n });\n } else if (gaussianSplatRenderer.updateTimeoutId === -1) {\n gaussianSplatRenderer.updateTimeoutId = setTimeout(() => {\n gaussianSplatRenderer.updateTimeoutId = -1;\n gaussianSplatRenderer.updateInternal({\n scene,\n camera: useCamera,\n autoUpdate: true,\n });\n }, 1);\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 geometry = this.geometry as SplatGeometry;\n geometry.instanceCount = gaussianSplatRenderer.activeSplats;\n\n const display = gaussianSplatRenderer.display;\n // Accumulator centers remain camera-relative regardless of packing.\n const accumToWorld = new THREE.Matrix4().makeTranslation(\n display.viewOrigin,\n );\n const cameraToWorld = camera.matrixWorld.clone();\n const worldToCamera = cameraToWorld.invert();\n const accumToCamera = worldToCamera.multiply(accumToWorld);\n accumToCamera.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 = gaussianSplatRenderer.maxStdDev;\n this.uniforms.minPixelRadius.value = gaussianSplatRenderer.minPixelRadius;\n this.uniforms.maxPixelRadius.value = gaussianSplatRenderer.maxPixelRadius;\n this.uniforms.minAlpha.value = gaussianSplatRenderer.minAlpha;\n this.uniforms.enable2DGS.value = gaussianSplatRenderer.enable2DGS;\n this.uniforms.preBlurAmount.value = gaussianSplatRenderer.preBlurAmount;\n this.uniforms.blurAmount.value = gaussianSplatRenderer.blurAmount;\n this.uniforms.focalDistance.value = gaussianSplatRenderer.focalDistance;\n this.uniforms.apertureAngle.value = gaussianSplatRenderer.apertureAngle;\n this.uniforms.clipXY.value = gaussianSplatRenderer.clipXY;\n this.uniforms.focalAdjustment.value = gaussianSplatRenderer.focalAdjustment;\n const outputColorSpace =\n currentRenderTarget === null\n ? renderer.outputColorSpace\n : isXRRenderTarget\n ? currentRenderTarget.texture.colorSpace\n : THREE.ColorManagement.workingColorSpace;\n this.uniforms.encodeLinear.value =\n outputColorSpace !== THREE.SRGBColorSpace;\n\n this.uniforms.ordering.value =\n gaussianSplatRenderer.orderingTexture ??\n GaussianSplatRenderer.emptyOrdering;\n this.uniforms.enablePackedSplats.value = display.packedSplats;\n const splatTextures = display.getTextures();\n this.uniforms.splats.value = splatTextures[0];\n if (display.packedSplats) {\n this.uniforms.splats2.value = splatTextures[0];\n } else {\n this.uniforms.splats2.value = splatTextures[1];\n }\n this.uniforms.splatShape.value = display.getSplatShapeTexture();\n\n this.uniforms.time.value = display.time;\n this.uniforms.deltaTime.value = display.deltaTime;\n // Alternating debug flag that can aid in visual debugging\n this.uniforms.debugFlag.value = (performance.now() / 1000.0) % 2.0 < 1.0;\n\n gaussianSplatRenderer.dirty = false;\n }\n\n clearSplats() {\n this.activeSplats = 0;\n this.display.numSplats = 0;\n this.setDirty();\n }\n\n async update({\n scene,\n camera,\n }: {\n scene: THREE.Scene;\n camera: THREE.Camera;\n }) {\n await this.updateInternal({ scene, camera, autoUpdate: false });\n }\n\n private updateInternal(request: UpdateRequest): Promise<void> {\n if (this.disposed) return Promise.resolve();\n\n const pending = this.queuedUpdate;\n this.queuedUpdate = {\n scene: request.scene,\n camera: request.camera,\n // A queued explicit update must not be weakened by a later automatic one.\n autoUpdate: request.autoUpdate && (pending?.autoUpdate ?? true),\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 } catch (error) {\n this.queuedUpdate = null;\n throw error;\n } finally {\n this.updateRunning = false;\n }\n }\n\n private async performUpdate({ scene, camera, autoUpdate }: UpdateRequest) {\n const renderer = this.renderer;\n if (this.ownsTimer) {\n this.timer.update();\n }\n\n const center = camera.getWorldPosition(new THREE.Vector3());\n const dir = camera.getWorldDirection(new THREE.Vector3());\n\n const viewChanged =\n center.distanceTo(this.sortedCenter) >\n 0.001 * getCameraWorldScale(camera) ||\n dir.dot(this.sortedDir) < 0.999 ||\n this.sortRadial !== this.sortedRadial;\n\n const next = this.takeAccumulator();\n if (next === this.current) {\n // Should never happen\n throw new Error(\n \"Next accumulator is the same as the current accumulator\",\n );\n }\n let preparation: ReturnType<SplatAccumulator[\"prepareGenerate\"]>;\n try {\n preparation = next.prepareGenerate({\n renderer,\n scene,\n timer: this.timer,\n camera,\n previous: this.current,\n });\n } catch (error) {\n this.releaseAccumulator(next);\n throw error;\n }\n const { version, sortUpdated, generate } = preparation;\n let doUpdate = true;\n const needsUpdate =\n viewChanged ||\n version !== this.current.version ||\n next.packedSplats !== this.current.packedSplats;\n const needsSort = viewChanged || sortUpdated;\n\n if (autoUpdate && !needsUpdate) {\n // Triggered by auto-update but no change\n doUpdate = false;\n }\n\n if (!doUpdate) {\n // Restore unused accumulator to the free list\n this.releaseAccumulator(next);\n } else {\n try {\n generate();\n } catch (error) {\n this.releaseAccumulator(next);\n throw error;\n }\n\n if (sortUpdated) {\n this.sortCentersRevision += 1;\n }\n\n if (this.display.mappingVersion === next.mappingVersion && !needsSort) {\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 await this.driveSort();\n }\n\n private async driveSort() {\n if (this.disposed || this.sorting || !this.sortDirty) {\n return;\n }\n\n const now = performance.now();\n const nextSortTime = this.lastSortTime\n ? this.lastSortTime + this.minSortIntervalMs\n : now;\n if (now < nextSortTime) {\n await new Promise((resolve) => setTimeout(resolve, nextSortTime - now));\n if (this.disposed) return;\n }\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 { numSplats, maxSplats } = current;\n const rows = Math.max(1, Math.ceil(maxSplats / 16384));\n const orderingMaxSplats = rows * 16384;\n this.maxSplats = Math.max(this.maxSplats, orderingMaxSplats);\n const ordering = new Uint32Array(this.maxSplats);\n\n if (!this.sortWorker) {\n this.sortWorker = new SplatWorker();\n }\n\n const centersRevision = this.sortCentersRevision;\n if (this.uploadedSortCentersRevision !== centersRevision) {\n const { centers, rangeBases, rangeCounts, rangeOrigins } =\n buildSortCenters(current);\n await this.sortWorker.call(\"setSortCenters\", {\n centers,\n rangeBases,\n rangeCounts,\n rangeOrigins,\n });\n this.uploadedSortCentersRevision = centersRevision;\n }\n\n const sortRadial = this.sortRadial;\n const result = await this.sortWorker.call(\"sortCenters32\", {\n numSplats,\n cameraPosition: [\n current.viewOrigin.x,\n current.viewOrigin.y,\n current.viewOrigin.z,\n ],\n direction: [\n current.viewDirection.x,\n current.viewDirection.y,\n current.viewDirection.z,\n ],\n radial: sortRadial,\n ordering,\n });\n\n this.activeSplats = result.activeSplats;\n const activeRows = Math.ceil(result.activeSplats / 16384);\n\n if (this.orderingTexture && rows > this.orderingTexture.image.height) {\n this.orderingTexture.dispose();\n this.orderingTexture = null;\n }\n\n if (!this.orderingTexture) {\n // console.log(`Allocating orderingTexture: ${4096}x${rows}`);\n const orderingTexture = new THREE.DataTexture(\n result.ordering,\n 4096,\n rows,\n THREE.RGBAIntegerFormat,\n THREE.UnsignedIntType,\n );\n orderingTexture.internalFormat = \"RGBA32UI\";\n orderingTexture.needsUpdate = true;\n this.orderingTexture = orderingTexture;\n } else {\n const renderer = this.renderer;\n if (!renderer.properties.has(this.orderingTexture)) {\n this.orderingTexture.image.data = result.ordering;\n this.orderingTexture.needsUpdate = true;\n } else if (activeRows > 0) {\n uploadU32DataTextureRows(\n renderer,\n this.orderingTexture,\n 4096,\n activeRows,\n result.ordering,\n );\n }\n }\n\n // console.log(`Sorted (${this.minSortIntervalMs}) ${numSplats} splats in ${(performance.now() - now).toFixed(0)} ms`);\n\n this.sortedCenter.copy(current.viewOrigin);\n this.sortedDir.copy(current.viewDirection);\n this.sortedRadial = sortRadial;\n if (this.current === current && 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\n this.sortDirty = true;\n if (\n this.current === current &&\n current !== this.display &&\n this.accumulators.length === 0\n ) {\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.uploadedSortCentersRevision = -1;\n }\n throw error;\n } finally {\n this.sorting = false;\n }\n }\n\n private static emptyOrdering = (() => {\n const numIndices = 4 * 4096 * 1;\n const emptyArray = new Uint32Array(numIndices);\n const texture = new THREE.DataTexture(emptyArray, 4096, 1);\n texture.format = THREE.RGBAIntegerFormat;\n texture.type = THREE.UnsignedIntType;\n texture.internalFormat = \"RGBA32UI\";\n texture.needsUpdate = true;\n return texture;\n })();\n\n render(scene: THREE.Scene, camera: THREE.Camera) {\n const previousOverride = GaussianSplatRenderer.gaussianSplatOverride;\n try {\n GaussianSplatRenderer.gaussianSplatOverride = this;\n this.renderer.render(scene, camera);\n } finally {\n GaussianSplatRenderer.gaussianSplatOverride = previousOverride;\n }\n }\n\n renderTarget({\n scene,\n camera,\n }: { scene: THREE.Scene; camera: THREE.Camera }): THREE.WebGLRenderTarget {\n const target = this.backTarget ?? this.target;\n if (!target) {\n throw new Error(\"No target\");\n }\n\n const previousTarget = this.renderer.getRenderTarget();\n const previousOverride = GaussianSplatRenderer.gaussianSplatOverride;\n try {\n this.renderer.setRenderTarget(target);\n GaussianSplatRenderer.gaussianSplatOverride = this;\n this.renderer.render(scene, camera);\n } finally {\n GaussianSplatRenderer.gaussianSplatOverride = previousOverride;\n this.renderer.setRenderTarget(previousTarget);\n }\n\n if (target !== this.target) {\n // Swap back buffer and target\n [this.target, this.backTarget] = [this.backTarget, this.target];\n }\n return target;\n }\n\n // Read back the previously rendered target image as a Uint8Array of packed\n // RGBA values (in that order). Subsequent calls to this.readTarget()\n // will reuse the same buffers to minimize memory allocations.\n async readTarget(): Promise<Uint8Array> {\n if (!this.target) {\n throw new Error(\"Must initialize with target\");\n }\n const { width, height } = this.target;\n const byteSize = width * height * 4;\n if (!this.superPixels || this.superPixels.length < byteSize) {\n this.superPixels = new Uint8Array(byteSize);\n // console.log(`Allocated superPixels: ${width}x${height} = ${pixelCount} bytes`);\n }\n const superPixels = this.superPixels;\n\n await this.renderer.readRenderTargetPixelsAsync(\n this.target,\n 0,\n 0,\n width,\n height,\n superPixels,\n );\n\n const { superXY } = this;\n if (superXY === 1) {\n return superPixels;\n }\n\n const subWidth = width / superXY;\n const subHeight = height / superXY;\n const subSize = subWidth * subHeight * 4;\n if (!this.targetPixels || this.targetPixels.length < subSize) {\n this.targetPixels = new Uint8Array(subSize);\n // console.log(`Allocated targetPixels: ${subWidth}x${subHeight} = ${subSize} bytes`);\n }\n const targetPixels = this.targetPixels;\n\n const super2 = superXY * superXY;\n for (let y = 0; y < subHeight; y++) {\n const row = y * subWidth;\n for (let x = 0; x < subWidth; x++) {\n const superCol = x * superXY;\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n for (let sy = 0; sy < superXY; sy++) {\n const superRow = (y * superXY + sy) * width;\n for (let sx = 0; sx < superXY; sx++) {\n const superIndex = (superRow + superCol + sx) * 4;\n r += superPixels[superIndex];\n g += superPixels[superIndex + 1];\n b += superPixels[superIndex + 2];\n a += superPixels[superIndex + 3];\n }\n }\n const pixelIndex = (row + x) * 4;\n targetPixels[pixelIndex] = r / super2;\n targetPixels[pixelIndex + 1] = g / super2;\n targetPixels[pixelIndex + 2] = b / super2;\n targetPixels[pixelIndex + 3] = a / super2;\n }\n }\n return targetPixels;\n }\n\n async renderReadTarget({\n scene,\n camera,\n }: {\n scene: THREE.Scene;\n camera: THREE.Camera;\n }): Promise<Uint8Array> {\n this.renderTarget({ scene, camera });\n return this.readTarget();\n }\n\n // Data and buffers used for environment map rendering\n private static cubeRender: {\n target: THREE.WebGLCubeRenderTarget;\n cubeCamera: THREE.CubeCamera;\n near: number;\n far: number;\n } | null = null;\n private static pmrem: THREE.PMREMGenerator | null = null;\n\n // Renders out the scene to a cube map that can be used for\n // Image-based lighting or similar applications. First optionally updates Gsplats,\n // sorts them with respect to the provided worldCenter, renders 6 cube faces.\n async renderCubeMap({\n scene,\n worldCenter,\n size = 256,\n near = 0.1,\n far = 1000,\n hideObjects = [],\n update = true,\n filter = false,\n }: {\n scene: THREE.Scene;\n worldCenter: THREE.Vector3;\n size?: number;\n near?: number;\n far?: number;\n hideObjects: THREE.Object3D[];\n update: boolean;\n filter: boolean;\n }): Promise<THREE.CubeTexture> {\n if (\n !GaussianSplatRenderer.cubeRender ||\n GaussianSplatRenderer.cubeRender.target.width !== size ||\n GaussianSplatRenderer.cubeRender.near !== near ||\n GaussianSplatRenderer.cubeRender.far !== far\n ) {\n if (GaussianSplatRenderer.cubeRender) {\n GaussianSplatRenderer.cubeRender.target.dispose();\n }\n const target = new THREE.WebGLCubeRenderTarget(size, {\n format: THREE.RGBAFormat,\n type: THREE.UnsignedByteType,\n generateMipmaps: filter,\n minFilter: filter ? THREE.LinearMipMapLinearFilter : THREE.LinearFilter,\n magFilter: THREE.LinearFilter,\n colorSpace: filter ? THREE.LinearSRGBColorSpace : THREE.SRGBColorSpace,\n });\n const cubeCamera = new THREE.CubeCamera(near, far, target);\n GaussianSplatRenderer.cubeRender = { target, cubeCamera, near, far };\n }\n\n const { target, cubeCamera } = GaussianSplatRenderer.cubeRender;\n cubeCamera.position.copy(worldCenter);\n\n // Save the visibility state of objects we want to hide before render\n const objectVisibility = new Map<THREE.Object3D, boolean>();\n for (const object of hideObjects) {\n if (!objectVisibility.has(object)) {\n objectVisibility.set(object, object.visible);\n }\n object.visible = false;\n }\n\n const previousOverride = GaussianSplatRenderer.gaussianSplatOverride;\n try {\n if (update) {\n const tempCamera = new THREE.Camera();\n tempCamera.position.copy(worldCenter);\n await this.update({ scene, camera: tempCamera });\n }\n\n GaussianSplatRenderer.gaussianSplatOverride = this;\n // Update the CubeCamera, which performs 6 cube face renders\n cubeCamera.update(this.renderer, scene);\n return target.texture;\n } finally {\n GaussianSplatRenderer.gaussianSplatOverride = previousOverride;\n for (const [object, visible] of objectVisibility.entries()) {\n object.visible = visible;\n }\n }\n }\n\n async readCubeTargets(): Promise<Uint8Array[]> {\n if (!GaussianSplatRenderer.cubeRender) {\n throw new Error(\"No cube render\");\n }\n\n const { target } = GaussianSplatRenderer.cubeRender;\n const { width, height } = target;\n const promises = [];\n const buffers = [];\n\n for (let i = 0; i < target.texture.images.length; ++i) {\n const byteSize = width * height * 4;\n const readback = new Uint8Array(byteSize);\n buffers.push(readback);\n const promise = this.renderer.readRenderTargetPixelsAsync(\n target,\n 0,\n 0,\n width,\n height,\n readback,\n i,\n );\n promises.push(promise);\n }\n\n await Promise.all(promises);\n return buffers;\n }\n\n // Renders out the scene to an environment map that can be used for\n // Image-based lighting or similar applications. First optionally updates Gsplats,\n // sorts them with respect to the provided worldCenter, renders 6 cube faces,\n // then pre-filters them using THREE.PMREMGenerator and returns a THREE.Texture\n // that can assigned directly to a THREE.MeshStandardMaterial.envMap property.\n async renderEnvMap({\n scene,\n worldCenter,\n size = 256,\n near = 0.1,\n far = 1000,\n hideObjects = [],\n update = true,\n }: {\n scene: THREE.Scene;\n worldCenter: THREE.Vector3;\n size?: number;\n near?: number;\n far?: number;\n hideObjects: THREE.Object3D[];\n update: boolean;\n }): Promise<THREE.Texture> {\n const cubeTexture = await this.renderCubeMap({\n scene,\n worldCenter,\n size,\n near,\n far,\n hideObjects,\n update,\n filter: true,\n });\n // Pre-filter the cube map using THREE.PMREMGenerator if requested\n if (!GaussianSplatRenderer.pmrem) {\n GaussianSplatRenderer.pmrem = new THREE.PMREMGenerator(this.renderer);\n }\n\n return GaussianSplatRenderer.pmrem?.fromCubemap(cubeTexture).texture;\n }\n\n // Utility function to recursively set the envMap property for any\n // THREE.MeshStandardMaterial within the subtree of root.\n recurseSetEnvMap(root: THREE.Object3D, envMap: THREE.Texture) {\n root.traverse((node) => {\n if (node instanceof THREE.Mesh) {\n if (Array.isArray(node.material)) {\n for (const material of node.material) {\n if (material instanceof THREE.MeshStandardMaterial) {\n material.envMap = envMap;\n }\n }\n } else {\n if (node.material instanceof THREE.MeshStandardMaterial) {\n node.material.envMap = envMap;\n }\n }\n }\n });\n }\n\n get premultipliedAlpha(): boolean {\n return this.material.premultipliedAlpha;\n }\n\n set premultipliedAlpha(value: boolean) {\n if (this.material.premultipliedAlpha !== value) {\n this.material.premultipliedAlpha = value;\n this.material.needsUpdate = true;\n }\n }\n\n /**\n * Whether intermediate accumulator data uses the compressed Packed Splat\n * encoding. Changing this preserves the current display until the replacement\n * accumulator is generated by the next automatic or explicit update.\n */\n get accumPackedSplats(): boolean {\n return this.accumPackedSplatsValue;\n }\n\n set accumPackedSplats(value: boolean) {\n if (this.accumPackedSplatsValue === value) return;\n\n this.accumPackedSplatsValue = value;\n if (this.disposed) return;\n\n for (const accumulator of this.accumulators) {\n accumulator.dispose();\n }\n this.accumulators = [this.createAccumulator()];\n this.setDirty();\n }\n}\n\nfunction checkIsXRRenderTarget(renderTarget: THREE.RenderTarget | null) {\n return (renderTarget as unknown as Record<string, boolean>)?.isXRRenderTarget;\n}\n"],"names":["SplatEditSdfType","SplatEditRgbaBlendMode","ptr","SplatFileType","axisX","axisY","axisZ","initWasm","BundledWorker","worker","_a","wasm.isInitialized","splatDefines","splatVertex","splatFragment","defines","splatGenerate","shaders","target","cubeCamera"],"mappings":"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"}