@babylonjs/loaders 9.13.0 → 9.14.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.
- package/BVH/bvhFileLoader.d.ts +4 -67
- package/BVH/bvhFileLoader.js +6 -130
- package/BVH/bvhFileLoader.js.map +1 -1
- package/BVH/bvhFileLoader.pure.d.ts +75 -0
- package/BVH/bvhFileLoader.pure.js +154 -0
- package/BVH/bvhFileLoader.pure.js.map +1 -0
- package/BVH/bvhFileLoader.types.d.ts +11 -0
- package/BVH/bvhFileLoader.types.js +2 -0
- package/BVH/bvhFileLoader.types.js.map +1 -0
- package/BVH/pure.d.ts +3 -0
- package/BVH/pure.js +5 -0
- package/BVH/pure.js.map +1 -0
- package/FBX/fbxFileLoader.d.ts +4 -192
- package/FBX/fbxFileLoader.js +6 -2437
- package/FBX/fbxFileLoader.js.map +1 -1
- package/FBX/fbxFileLoader.pure.d.ts +190 -0
- package/FBX/fbxFileLoader.pure.js +2451 -0
- package/FBX/fbxFileLoader.pure.js.map +1 -0
- package/FBX/fbxFileLoader.types.d.ts +11 -0
- package/FBX/fbxFileLoader.types.js +2 -0
- package/FBX/fbxFileLoader.types.js.map +1 -0
- package/FBX/pure.d.ts +3 -0
- package/FBX/pure.js +4 -0
- package/FBX/pure.js.map +1 -0
- package/OBJ/objFileLoader.d.ts +4 -134
- package/OBJ/objFileLoader.js +6 -315
- package/OBJ/objFileLoader.js.map +1 -1
- package/OBJ/objFileLoader.pure.d.ts +132 -0
- package/OBJ/objFileLoader.pure.js +329 -0
- package/OBJ/objFileLoader.pure.js.map +1 -0
- package/OBJ/objFileLoader.types.d.ts +11 -0
- package/OBJ/objFileLoader.types.js +2 -0
- package/OBJ/objFileLoader.types.js.map +1 -0
- package/OBJ/pure.d.ts +5 -0
- package/OBJ/pure.js +6 -0
- package/OBJ/pure.js.map +1 -0
- package/OBJ/solidParser.js +4 -3
- package/OBJ/solidParser.js.map +1 -1
- package/SPLAT/gaussianSplattingBlockAllocator.d.ts +137 -0
- package/SPLAT/gaussianSplattingBlockAllocator.js +555 -0
- package/SPLAT/gaussianSplattingBlockAllocator.js.map +1 -0
- package/SPLAT/gaussianSplattingDownloadManager.d.ts +109 -0
- package/SPLAT/gaussianSplattingDownloadManager.js +241 -0
- package/SPLAT/gaussianSplattingDownloadManager.js.map +1 -0
- package/SPLAT/gaussianSplattingResidencyController.d.ts +133 -0
- package/SPLAT/gaussianSplattingResidencyController.js +222 -0
- package/SPLAT/gaussianSplattingResidencyController.js.map +1 -0
- package/SPLAT/gaussianSplattingStream.d.ts +122 -4
- package/SPLAT/gaussianSplattingStream.js +413 -42
- package/SPLAT/gaussianSplattingStream.js.map +1 -1
- package/SPLAT/gaussianSplattingWorkBuffer.d.ts +36 -0
- package/SPLAT/gaussianSplattingWorkBuffer.js +125 -13
- package/SPLAT/gaussianSplattingWorkBuffer.js.map +1 -1
- package/SPLAT/gaussianSplattingWorkBufferShaders.d.ts +15 -0
- package/SPLAT/gaussianSplattingWorkBufferShaders.js +82 -0
- package/SPLAT/gaussianSplattingWorkBufferShaders.js.map +1 -1
- package/SPLAT/pure.d.ts +5 -0
- package/SPLAT/pure.js +7 -0
- package/SPLAT/pure.js.map +1 -0
- package/SPLAT/sog.d.ts +1 -97
- package/SPLAT/sog.js +1 -501
- package/SPLAT/sog.js.map +1 -1
- package/SPLAT/sog.pure.d.ts +102 -0
- package/SPLAT/sog.pure.js +514 -0
- package/SPLAT/sog.pure.js.map +1 -0
- package/SPLAT/splatFileLoader.d.ts +5 -106
- package/SPLAT/splatFileLoader.js +9 -636
- package/SPLAT/splatFileLoader.js.map +1 -1
- package/SPLAT/splatFileLoader.pure.d.ts +104 -0
- package/SPLAT/splatFileLoader.pure.js +650 -0
- package/SPLAT/splatFileLoader.pure.js.map +1 -0
- package/SPLAT/splatFileLoader.types.d.ts +11 -0
- package/SPLAT/splatFileLoader.types.js +2 -0
- package/SPLAT/splatFileLoader.types.js.map +1 -0
- package/STL/pure.d.ts +2 -0
- package/STL/pure.js +3 -0
- package/STL/pure.js.map +1 -0
- package/STL/stlFileLoader.d.ts +5 -76
- package/STL/stlFileLoader.js +7 -236
- package/STL/stlFileLoader.js.map +1 -1
- package/STL/stlFileLoader.pure.d.ts +73 -0
- package/STL/stlFileLoader.pure.js +249 -0
- package/STL/stlFileLoader.pure.js.map +1 -0
- package/STL/stlFileLoader.types.d.ts +10 -0
- package/STL/stlFileLoader.types.js +2 -0
- package/STL/stlFileLoader.types.js.map +1 -0
- package/glTF/1.0/pure.d.ts +3 -0
- package/glTF/1.0/pure.js +4 -0
- package/glTF/1.0/pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_area.d.ts +4 -39
- package/glTF/2.0/Extensions/EXT_lights_area.js +6 -91
- package/glTF/2.0/Extensions/EXT_lights_area.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_area.pure.d.ts +38 -0
- package/glTF/2.0/Extensions/EXT_lights_area.pure.js +106 -0
- package/glTF/2.0/Extensions/EXT_lights_area.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_area.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_lights_area.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_lights_area.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.d.ts +4 -39
- package/glTF/2.0/Extensions/EXT_lights_ies.js +6 -81
- package/glTF/2.0/Extensions/EXT_lights_ies.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.d.ts +38 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js +96 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.d.ts +4 -46
- package/glTF/2.0/Extensions/EXT_lights_image_based.js +6 -113
- package/glTF/2.0/Extensions/EXT_lights_image_based.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_image_based.pure.d.ts +37 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js +128 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.types.d.ts +17 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.d.ts +5 -37
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +7 -92
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.d.ts +35 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js +106 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.d.ts +4 -37
- package/glTF/2.0/Extensions/EXT_meshopt_compression.js +6 -48
- package/glTF/2.0/Extensions/EXT_meshopt_compression.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.d.ts +36 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js +63 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.d.ts +4 -32
- package/glTF/2.0/Extensions/EXT_texture_avif.js +6 -36
- package/glTF/2.0/Extensions/EXT_texture_avif.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_texture_avif.pure.d.ts +31 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.pure.js +51 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.d.ts +4 -31
- package/glTF/2.0/Extensions/EXT_texture_webp.js +6 -35
- package/glTF/2.0/Extensions/EXT_texture_webp.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_texture_webp.pure.d.ts +30 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.pure.js +50 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.types.js.map +1 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.d.ts +4 -51
- package/glTF/2.0/Extensions/ExtrasAsMetadata.js +6 -71
- package/glTF/2.0/Extensions/ExtrasAsMetadata.js.map +1 -1
- package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.d.ts +50 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js +85 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js.map +1 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.types.d.ts +9 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js +2 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.d.ts +5 -45
- package/glTF/2.0/Extensions/KHR_animation_pointer.js +7 -75
- package/glTF/2.0/Extensions/KHR_animation_pointer.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_animation_pointer.pure.d.ts +43 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js +89 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.d.ts +4 -45
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js +6 -90
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.d.ts +44 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js +105 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.d.ts +4 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity.d.ts +4 -36
- package/glTF/2.0/Extensions/KHR_interactivity.js +6 -148
- package/glTF/2.0/Extensions/KHR_interactivity.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity.pure.d.ts +35 -0
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js +163 -0
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_interactivity.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_interactivity.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +4 -39
- package/glTF/2.0/Extensions/KHR_lights_punctual.js +6 -89
- package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.d.ts +38 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js +104 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js +6 -63
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js +78 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +6 -77
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js +92 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.d.ts +4 -47
- package/glTF/2.0/Extensions/KHR_materials_coat.js +6 -117
- package/glTF/2.0/Extensions/KHR_materials_coat.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_coat.pure.d.ts +46 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.pure.js +132 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js +6 -56
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js +71 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js +6 -71
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js +86 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_dispersion.js +6 -54
- package/glTF/2.0/Extensions/KHR_materials_dispersion.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js +69 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js +6 -45
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js +60 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_fuzz.js +6 -75
- package/glTF/2.0/Extensions/KHR_materials_fuzz.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js +90 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.d.ts +4 -44
- package/glTF/2.0/Extensions/KHR_materials_ior.js +6 -52
- package/glTF/2.0/Extensions/KHR_materials_ior.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_ior.pure.d.ts +43 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.pure.js +67 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js +6 -66
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js +81 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js +6 -72
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js +87 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_sheen.js +6 -71
- package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_sheen.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js +86 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_specular.js +6 -74
- package/glTF/2.0/Extensions/KHR_materials_specular.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_specular.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.pure.js +89 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_transmission.js +6 -70
- package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_transmission.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js +85 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_unlit.js +6 -64
- package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_unlit.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js +79 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.d.ts +4 -110
- package/glTF/2.0/Extensions/KHR_materials_variants.js +6 -260
- package/glTF/2.0/Extensions/KHR_materials_variants.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_variants.pure.d.ts +97 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.pure.js +275 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.types.d.ts +29 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_volume.js +6 -77
- package/glTF/2.0/Extensions/KHR_materials_volume.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_volume.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.pure.js +92 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.d.ts +4 -43
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js +6 -113
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.d.ts +42 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js +128 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.d.ts +4 -27
- package/glTF/2.0/Extensions/KHR_mesh_quantization.js +6 -20
- package/glTF/2.0/Extensions/KHR_mesh_quantization.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.d.ts +26 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js +35 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.d.ts +4 -29
- package/glTF/2.0/Extensions/KHR_node_hoverability.js +6 -187
- package/glTF/2.0/Extensions/KHR_node_hoverability.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.d.ts +28 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +202 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.d.ts +4 -28
- package/glTF/2.0/Extensions/KHR_node_selectability.js +6 -121
- package/glTF/2.0/Extensions/KHR_node_selectability.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.d.ts +27 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +136 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.d.ts +4 -28
- package/glTF/2.0/Extensions/KHR_node_visibility.js +6 -64
- package/glTF/2.0/Extensions/KHR_node_visibility.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_visibility.pure.d.ts +27 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.pure.js +79 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.d.ts +4 -31
- package/glTF/2.0/Extensions/KHR_texture_basisu.js +6 -35
- package/glTF/2.0/Extensions/KHR_texture_basisu.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_texture_basisu.pure.d.ts +30 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js +50 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.d.ts +4 -35
- package/glTF/2.0/Extensions/KHR_texture_transform.js +6 -56
- package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_texture_transform.pure.d.ts +34 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.pure.js +71 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.d.ts +4 -37
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.js +6 -45
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.d.ts +36 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js +60 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.d.ts +5 -54
- package/glTF/2.0/Extensions/MSFT_audio_emitter.js +7 -226
- package/glTF/2.0/Extensions/MSFT_audio_emitter.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.d.ts +52 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js +240 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.types.d.ts +9 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_lod.d.ts +4 -102
- package/glTF/2.0/Extensions/MSFT_lod.js +6 -335
- package/glTF/2.0/Extensions/MSFT_lod.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_lod.pure.d.ts +96 -0
- package/glTF/2.0/Extensions/MSFT_lod.pure.js +350 -0
- package/glTF/2.0/Extensions/MSFT_lod.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_lod.types.d.ts +14 -0
- package/glTF/2.0/Extensions/MSFT_lod.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_lod.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.d.ts +6 -27
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js +8 -40
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.d.ts +24 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js +53 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.d.ts +9 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.d.ts +6 -27
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.js +8 -38
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.d.ts +24 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js +51 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.d.ts +9 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js.map +1 -0
- package/glTF/2.0/Extensions/pure.d.ts +45 -0
- package/glTF/2.0/Extensions/pure.js +47 -0
- package/glTF/2.0/Extensions/pure.js.map +1 -0
- package/glTF/2.0/glTFLoader.d.ts +1 -471
- package/glTF/2.0/glTFLoader.js +3 -2539
- package/glTF/2.0/glTFLoader.js.map +1 -1
- package/glTF/2.0/glTFLoader.pure.d.ts +476 -0
- package/glTF/2.0/glTFLoader.pure.js +2563 -0
- package/glTF/2.0/glTFLoader.pure.js.map +1 -0
- package/glTF/2.0/pure.d.ts +8 -0
- package/glTF/2.0/pure.js +10 -0
- package/glTF/2.0/pure.js.map +1 -0
- package/glTF/glTFFileLoader.d.ts +5 -551
- package/glTF/glTFFileLoader.js +6 -996
- package/glTF/glTFFileLoader.js.map +1 -1
- package/glTF/glTFFileLoader.pure.d.ts +562 -0
- package/glTF/glTFFileLoader.pure.js +1024 -0
- package/glTF/glTFFileLoader.pure.js.map +1 -0
- package/glTF/glTFFileLoader.types.d.ts +11 -0
- package/glTF/glTFFileLoader.types.js +2 -0
- package/glTF/glTFFileLoader.types.js.map +1 -0
- package/glTF/pure.d.ts +6 -0
- package/glTF/pure.js +8 -0
- package/glTF/pure.js.map +1 -0
- package/package.json +56 -4
- package/pure.d.ts +8 -0
- package/pure.js +10 -0
- package/pure.js.map +1 -0
|
@@ -19,6 +19,9 @@ export declare class GaussianSplattingWorkBuffer {
|
|
|
19
19
|
private readonly _shaderLanguage;
|
|
20
20
|
private readonly _material;
|
|
21
21
|
private readonly _quad;
|
|
22
|
+
private _copyMaterial;
|
|
23
|
+
private _relayoutMapData;
|
|
24
|
+
private _relayoutMapTexture;
|
|
22
25
|
private _disposed;
|
|
23
26
|
private _readFbo;
|
|
24
27
|
/**
|
|
@@ -41,6 +44,14 @@ export declare class GaussianSplattingWorkBuffer {
|
|
|
41
44
|
* @param capacity total number of splats the work buffer must address
|
|
42
45
|
*/
|
|
43
46
|
constructor(scene: Scene, capacity: number);
|
|
47
|
+
/**
|
|
48
|
+
* Creates a 4-attachment MRT (centers F32 / covA F32 / covB F32 / colors U8) sized to the work buffer.
|
|
49
|
+
* @param name MRT and attachment base name
|
|
50
|
+
* @param disableClear when true, clearing is suppressed so renders accumulate (the decode buffer); when
|
|
51
|
+
* false the MRT clears to zero on each render (the temporary relayout buffer, so gaps stay zeroed)
|
|
52
|
+
* @returns the created MRT
|
|
53
|
+
*/
|
|
54
|
+
private _createMrt;
|
|
44
55
|
/**
|
|
45
56
|
* Decodes one SOG file into the work buffer at the given splat offset (accumulating; previously
|
|
46
57
|
* decoded files are preserved). Resolves once the GPU decode has been issued. The caller may
|
|
@@ -49,6 +60,31 @@ export declare class GaussianSplattingWorkBuffer {
|
|
|
49
60
|
* @param offset first splat index (pixel offset) for this file in the work buffer
|
|
50
61
|
*/
|
|
51
62
|
decodeAsync(pack: ISogTexturePack, offset: number): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Whether the relayout copy shader is compiled and ready. Lazily creates the copy material on first call.
|
|
65
|
+
* Callers should poll this before {@link relayoutSync} (which must only run when ready).
|
|
66
|
+
* @returns true when {@link relayoutSync} can run this frame
|
|
67
|
+
*/
|
|
68
|
+
isRelayoutReady(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Relayouts the decoded work-buffer textures to a new (defragmented) splat layout, keeping the same
|
|
71
|
+
* texture instances so the consuming mesh does not need to re-bind. `srcIndexByDst[d]` is the source splat
|
|
72
|
+
* index whose decoded data should end up at destination index `d`, or a negative value for a gap (left
|
|
73
|
+
* zeroed). Uses a temporary MRT ping-pong (old -> temp via the map, then temp -> old identity) so
|
|
74
|
+
* overlapping moves stay correct. Must be called at a frame-safe point (inside `onBeforeRender`) and only
|
|
75
|
+
* when {@link isRelayoutReady} returns true.
|
|
76
|
+
* @param srcIndexByDst per-destination source splat index (negative = gap)
|
|
77
|
+
*/
|
|
78
|
+
relayoutSync(srcIndexByDst: Float32Array): void;
|
|
79
|
+
/**
|
|
80
|
+
* Renders one relayout copy pass into the target MRT, sampling the given source textures.
|
|
81
|
+
* @param target destination MRT
|
|
82
|
+
* @param sources the four source work-buffer textures
|
|
83
|
+
* @param mapTexture the R32F destination-to-source index map
|
|
84
|
+
* @param useMap 1 to read source indices from the map (gaps discarded), 0 for an identity copy
|
|
85
|
+
*/
|
|
86
|
+
private _renderRelayoutPass;
|
|
87
|
+
private _createCopyMaterial;
|
|
52
88
|
/**
|
|
53
89
|
* Asynchronously reads back the decoded splat centers (stride-4 xyzw, w=1) for a contiguous splat range
|
|
54
90
|
* from the work buffer's centers texture, using a non-blocking GPU readback (WebGL2 PBO + fence, or WebGPU
|
|
@@ -5,7 +5,8 @@ import { Mesh } from "@babylonjs/core/Meshes/mesh.js";
|
|
|
5
5
|
import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData.js";
|
|
6
6
|
import { Color4 } from "@babylonjs/core/Maths/math.color.js";
|
|
7
7
|
import { Vector3, Vector4 } from "@babylonjs/core/Maths/math.vector.js";
|
|
8
|
-
import { GaussianSplattingWorkBufferVertexShaderGLSL, GaussianSplattingWorkBufferFragmentShaderGLSL, GaussianSplattingWorkBufferVertexShaderWGSL, GaussianSplattingWorkBufferFragmentShaderWGSL, } from "./gaussianSplattingWorkBufferShaders.js";
|
|
8
|
+
import { GaussianSplattingWorkBufferVertexShaderGLSL, GaussianSplattingWorkBufferFragmentShaderGLSL, GaussianSplattingWorkBufferVertexShaderWGSL, GaussianSplattingWorkBufferFragmentShaderWGSL, GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL, GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL, GaussianSplattingWorkBufferRelayoutShaderName, } from "./gaussianSplattingWorkBufferShaders.js";
|
|
9
|
+
import { RawTexture } from "@babylonjs/core/Materials/Textures/rawTexture.js";
|
|
9
10
|
/**
|
|
10
11
|
* A unified, GPU-decoded Gaussian Splatting work buffer.
|
|
11
12
|
*
|
|
@@ -48,13 +49,34 @@ export class GaussianSplattingWorkBuffer {
|
|
|
48
49
|
* @param capacity total number of splats the work buffer must address
|
|
49
50
|
*/
|
|
50
51
|
constructor(scene, capacity) {
|
|
52
|
+
// Relayout (defrag) copy material, created lazily on first relayout.
|
|
53
|
+
this._copyMaterial = null;
|
|
54
|
+
// Reusable destination->source index map for the relayout pass (created lazily, sized to the work buffer).
|
|
55
|
+
this._relayoutMapData = null;
|
|
56
|
+
this._relayoutMapTexture = null;
|
|
51
57
|
this._disposed = false;
|
|
52
58
|
// Reused WebGL framebuffer for the async centers readback (created lazily, freed in dispose).
|
|
53
59
|
this._readFbo = null;
|
|
54
60
|
this._scene = scene;
|
|
55
61
|
this._shaderLanguage = scene.getEngine().isWebGPU ? 1 /* ShaderLanguage.WGSL */ : 0 /* ShaderLanguage.GLSL */;
|
|
56
62
|
this._textureSize = Math.max(1, Math.ceil(Math.sqrt(Math.max(1, capacity))));
|
|
57
|
-
|
|
63
|
+
// The decode buffer accumulates (clear disabled) so each decode preserves previously-decoded files.
|
|
64
|
+
this._mrt = this._createMrt("gsWorkBuffer", true);
|
|
65
|
+
// One persistent decode material + fullscreen-triangle quad, reused (with per-file uniforms)
|
|
66
|
+
// for every decode so the shader is compiled only once.
|
|
67
|
+
this._material = this._createMaterial();
|
|
68
|
+
this._quad = this._createQuad();
|
|
69
|
+
this._quad.material = this._material;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Creates a 4-attachment MRT (centers F32 / covA F32 / covB F32 / colors U8) sized to the work buffer.
|
|
73
|
+
* @param name MRT and attachment base name
|
|
74
|
+
* @param disableClear when true, clearing is suppressed so renders accumulate (the decode buffer); when
|
|
75
|
+
* false the MRT clears to zero on each render (the temporary relayout buffer, so gaps stay zeroed)
|
|
76
|
+
* @returns the created MRT
|
|
77
|
+
*/
|
|
78
|
+
_createMrt(name, disableClear) {
|
|
79
|
+
const mrt = new MultiRenderTarget(name, { width: this._textureSize, height: this._textureSize }, 4, this._scene, {
|
|
58
80
|
types: [Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_UNSIGNED_BYTE],
|
|
59
81
|
samplingModes: [
|
|
60
82
|
Constants.TEXTURE_NEAREST_SAMPLINGMODE,
|
|
@@ -66,17 +88,13 @@ export class GaussianSplattingWorkBuffer {
|
|
|
66
88
|
generateDepthBuffer: false,
|
|
67
89
|
generateDepthTexture: false,
|
|
68
90
|
generateMipMaps: false,
|
|
69
|
-
}, [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// for every decode so the shader is compiled only once.
|
|
77
|
-
this._material = this._createMaterial();
|
|
78
|
-
this._quad = this._createQuad();
|
|
79
|
-
this._quad.material = this._material;
|
|
91
|
+
}, [`${name}Centers`, `${name}CovA`, `${name}CovB`, `${name}Colors`]);
|
|
92
|
+
mrt.clearColor = new Color4(0, 0, 0, 0);
|
|
93
|
+
mrt.renderList = [];
|
|
94
|
+
if (disableClear) {
|
|
95
|
+
mrt.onClearObservable.add(() => { });
|
|
96
|
+
}
|
|
97
|
+
return mrt;
|
|
80
98
|
}
|
|
81
99
|
/**
|
|
82
100
|
* Decodes one SOG file into the work buffer at the given splat offset (accumulating; previously
|
|
@@ -109,6 +127,98 @@ export class GaussianSplattingWorkBuffer {
|
|
|
109
127
|
this._scene.onBeforeRenderObservable.addOnce(attempt);
|
|
110
128
|
});
|
|
111
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Whether the relayout copy shader is compiled and ready. Lazily creates the copy material on first call.
|
|
132
|
+
* Callers should poll this before {@link relayoutSync} (which must only run when ready).
|
|
133
|
+
* @returns true when {@link relayoutSync} can run this frame
|
|
134
|
+
*/
|
|
135
|
+
isRelayoutReady() {
|
|
136
|
+
if (this._disposed) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
if (!this._copyMaterial) {
|
|
140
|
+
this._copyMaterial = this._createCopyMaterial();
|
|
141
|
+
}
|
|
142
|
+
return this._copyMaterial.isReady(this._quad);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Relayouts the decoded work-buffer textures to a new (defragmented) splat layout, keeping the same
|
|
146
|
+
* texture instances so the consuming mesh does not need to re-bind. `srcIndexByDst[d]` is the source splat
|
|
147
|
+
* index whose decoded data should end up at destination index `d`, or a negative value for a gap (left
|
|
148
|
+
* zeroed). Uses a temporary MRT ping-pong (old -> temp via the map, then temp -> old identity) so
|
|
149
|
+
* overlapping moves stay correct. Must be called at a frame-safe point (inside `onBeforeRender`) and only
|
|
150
|
+
* when {@link isRelayoutReady} returns true.
|
|
151
|
+
* @param srcIndexByDst per-destination source splat index (negative = gap)
|
|
152
|
+
*/
|
|
153
|
+
relayoutSync(srcIndexByDst) {
|
|
154
|
+
if (this._disposed || !this._copyMaterial) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const size = this._textureSize;
|
|
158
|
+
// Reuse the map buffer and its GPU texture across relayouts (the work-buffer size is fixed).
|
|
159
|
+
if (!this._relayoutMapData) {
|
|
160
|
+
this._relayoutMapData = new Float32Array(size * size);
|
|
161
|
+
}
|
|
162
|
+
const mapData = this._relayoutMapData;
|
|
163
|
+
mapData.fill(-1);
|
|
164
|
+
mapData.set(srcIndexByDst.subarray(0, Math.min(srcIndexByDst.length, mapData.length)));
|
|
165
|
+
if (!this._relayoutMapTexture) {
|
|
166
|
+
this._relayoutMapTexture = new RawTexture(mapData, size, size, Constants.TEXTUREFORMAT_R, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_FLOAT);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
this._relayoutMapTexture.update(mapData);
|
|
170
|
+
}
|
|
171
|
+
const mapTexture = this._relayoutMapTexture;
|
|
172
|
+
// The temporary ping-pong MRT is (re)created per relayout rather than kept resident: it is the same size
|
|
173
|
+
// as the work buffer, so a persistent copy would double GPU memory and defeat the streaming memory budget.
|
|
174
|
+
const temp = this._createMrt("gsRelayoutTemp", false);
|
|
175
|
+
try {
|
|
176
|
+
// Pass 1: old -> temp using the map (temp gets the new layout; gaps stay zeroed by the clear).
|
|
177
|
+
this._renderRelayoutPass(temp, this._mrt.textures, mapTexture, 1);
|
|
178
|
+
// Pass 2: temp -> old, identity (old textures get the new layout, full overwrite).
|
|
179
|
+
this._renderRelayoutPass(this._mrt, temp.textures, mapTexture, 0);
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
temp.dispose();
|
|
183
|
+
this._quad.material = this._material;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Renders one relayout copy pass into the target MRT, sampling the given source textures.
|
|
188
|
+
* @param target destination MRT
|
|
189
|
+
* @param sources the four source work-buffer textures
|
|
190
|
+
* @param mapTexture the R32F destination-to-source index map
|
|
191
|
+
* @param useMap 1 to read source indices from the map (gaps discarded), 0 for an identity copy
|
|
192
|
+
*/
|
|
193
|
+
_renderRelayoutPass(target, sources, mapTexture, useMap) {
|
|
194
|
+
const material = this._copyMaterial;
|
|
195
|
+
material.setTexture("uMapTex", mapTexture);
|
|
196
|
+
material.setTexture("uSrc0", sources[0]);
|
|
197
|
+
material.setTexture("uSrc1", sources[1]);
|
|
198
|
+
material.setTexture("uSrc2", sources[2]);
|
|
199
|
+
material.setTexture("uSrc3", sources[3]);
|
|
200
|
+
material.setInt("uDstWidth", this._textureSize);
|
|
201
|
+
material.setInt("uSrcWidth", this._textureSize);
|
|
202
|
+
material.setInt("uUseMap", useMap);
|
|
203
|
+
this._quad.material = material;
|
|
204
|
+
target.renderList = [this._quad];
|
|
205
|
+
target.render();
|
|
206
|
+
}
|
|
207
|
+
_createCopyMaterial() {
|
|
208
|
+
const isWGSL = this._shaderLanguage === 1 /* ShaderLanguage.WGSL */;
|
|
209
|
+
const material = new ShaderMaterial(GaussianSplattingWorkBufferRelayoutShaderName, this._scene, {
|
|
210
|
+
vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,
|
|
211
|
+
fragmentSource: isWGSL ? GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL : GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL,
|
|
212
|
+
}, {
|
|
213
|
+
attributes: ["position"],
|
|
214
|
+
uniforms: ["uDstWidth", "uSrcWidth", "uUseMap"],
|
|
215
|
+
samplers: ["uMapTex", "uSrc0", "uSrc1", "uSrc2", "uSrc3"],
|
|
216
|
+
shaderLanguage: this._shaderLanguage,
|
|
217
|
+
});
|
|
218
|
+
material.backFaceCulling = false;
|
|
219
|
+
material.disableDepthWrite = true;
|
|
220
|
+
return material;
|
|
221
|
+
}
|
|
112
222
|
/**
|
|
113
223
|
* Asynchronously reads back the decoded splat centers (stride-4 xyzw, w=1) for a contiguous splat range
|
|
114
224
|
* from the work buffer's centers texture, using a non-blocking GPU readback (WebGL2 PBO + fence, or WebGPU
|
|
@@ -191,6 +301,8 @@ export class GaussianSplattingWorkBuffer {
|
|
|
191
301
|
}
|
|
192
302
|
this._quad.dispose();
|
|
193
303
|
this._material.dispose(true, false);
|
|
304
|
+
this._copyMaterial?.dispose(true, false);
|
|
305
|
+
this._relayoutMapTexture?.dispose();
|
|
194
306
|
this._mrt.dispose();
|
|
195
307
|
}
|
|
196
308
|
_createQuad() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplattingWorkBuffer.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingWorkBuffer.ts"],"names":[],"mappings":"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","sourcesContent":["import { MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget\";\r\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { type Texture } from \"core/Materials/Textures/texture\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type ISogTexturePack } from \"./splatDefs\";\r\nimport {\r\n GaussianSplattingWorkBufferVertexShaderGLSL,\r\n GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n GaussianSplattingWorkBufferVertexShaderWGSL,\r\n GaussianSplattingWorkBufferFragmentShaderWGSL,\r\n} from \"./gaussianSplattingWorkBufferShaders\";\r\n\r\n/**\r\n * A unified, GPU-decoded Gaussian Splatting work buffer.\r\n *\r\n * Holds a square MRT texture set (centers / covA / covB / colors) sized to a fixed splat capacity\r\n * (PlayCanvas-style: `ceil(sqrt(capacity))`). Each streamed SOG file is decoded directly on the GPU\r\n * (no CPU readback) into its allocated pixel range. The decoded textures are consumed unchanged by the\r\n * standard (non-SOG) Gaussian Splatting draw path.\r\n *\r\n * @experimental\r\n */\r\nexport class GaussianSplattingWorkBuffer {\r\n private readonly _scene: Scene;\r\n private readonly _mrt: MultiRenderTarget;\r\n private readonly _textureSize: number;\r\n private readonly _shaderLanguage: ShaderLanguage;\r\n private readonly _material: ShaderMaterial;\r\n private readonly _quad: Mesh;\r\n private _disposed = false;\r\n // Reused WebGL framebuffer for the async centers readback (created lazily, freed in dispose).\r\n private _readFbo: Nullable<WebGLFramebuffer> = null;\r\n\r\n /**\r\n * True when the engine supports the non-blocking GPU readback used by {@link readCentersRangeAsync}:\r\n * WebGL2 (PBO + fence) or WebGPU (copyTextureToBuffer + mapAsync). When false (e.g. WebGL1), callers must\r\n * decode positions on the CPU instead.\r\n */\r\n public get supportsAsyncCentersReadback(): boolean {\r\n const engine = this._scene.getEngine();\r\n if (engine.isWebGPU) {\r\n return true;\r\n }\r\n const glEngine = engine as unknown as { _gl?: WebGL2RenderingContext; _readPixelsAsync?: unknown; webGLVersion?: number };\r\n return !!glEngine._gl && typeof glEngine._readPixelsAsync === \"function\" && (glEngine.webGLVersion ?? 0) >= 2;\r\n }\r\n\r\n /**\r\n * Square edge length (in pixels) of the work-buffer textures.\r\n */\r\n public get textureSize(): number {\r\n return this._textureSize;\r\n }\r\n\r\n /**\r\n * The decoded work-buffer textures: [centers, covA, covB, colors].\r\n */\r\n public get textures(): Texture[] {\r\n return this._mrt.textures;\r\n }\r\n\r\n /**\r\n * Creates a work buffer sized to hold `capacity` splats.\r\n * @param scene hosting scene\r\n * @param capacity total number of splats the work buffer must address\r\n */\r\n constructor(scene: Scene, capacity: number) {\r\n this._scene = scene;\r\n this._shaderLanguage = scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n this._textureSize = Math.max(1, Math.ceil(Math.sqrt(Math.max(1, capacity))));\r\n\r\n this._mrt = new MultiRenderTarget(\r\n \"gsWorkBuffer\",\r\n { width: this._textureSize, height: this._textureSize },\r\n 4,\r\n scene,\r\n {\r\n types: [Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n samplingModes: [\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n ],\r\n formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA],\r\n generateDepthBuffer: false,\r\n generateDepthTexture: false,\r\n generateMipMaps: false,\r\n },\r\n [\"gsWorkCenters\", \"gsWorkCovA\", \"gsWorkCovB\", \"gsWorkColors\"]\r\n );\r\n this._mrt.clearColor = new Color4(0, 0, 0, 0);\r\n this._mrt.renderList = [];\r\n // Take over clearing (no-op) so each decode accumulates into the buffer instead of wiping\r\n // previously-decoded files. Undecoded regions are never sampled (only active intervals render).\r\n this._mrt.onClearObservable.add(() => {});\r\n\r\n // One persistent decode material + fullscreen-triangle quad, reused (with per-file uniforms)\r\n // for every decode so the shader is compiled only once.\r\n this._material = this._createMaterial();\r\n this._quad = this._createQuad();\r\n this._quad.material = this._material;\r\n }\r\n\r\n /**\r\n * Decodes one SOG file into the work buffer at the given splat offset (accumulating; previously\r\n * decoded files are preserved). Resolves once the GPU decode has been issued. The caller may\r\n * dispose the source pack textures after this resolves.\r\n * @param pack the SOG texture pack (GPU source textures + per-file decode parameters)\r\n * @param offset first splat index (pixel offset) for this file in the work buffer\r\n */\r\n public async decodeAsync(pack: ISogTexturePack, offset: number): Promise<void> {\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._applyPack(pack, offset);\r\n // Render the decode pass at the start of a frame (the safe point for custom render targets),\r\n // once the shader is compiled — never re-entrantly from a promise/observable continuation.\r\n await new Promise<void>((resolve) => {\r\n const attempt = () => {\r\n if (this._disposed) {\r\n resolve();\r\n return;\r\n }\r\n if (!this._material.isReady(this._quad)) {\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n return;\r\n }\r\n this._mrt.renderList = [this._quad];\r\n this._mrt.render();\r\n resolve();\r\n };\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n });\r\n }\r\n\r\n /**\r\n * Asynchronously reads back the decoded splat centers (stride-4 xyzw, w=1) for a contiguous splat range\r\n * from the work buffer's centers texture, using a non-blocking GPU readback (WebGL2 PBO + fence, or WebGPU\r\n * copyTextureToBuffer + mapAsync) so it never stalls the frame the way a CPU image decode does. The centers\r\n * texture already holds the GPU-decoded positions (identical to the CPU decode), so this replaces decoding\r\n * positions on the CPU from the means images. Returns null when async readback is unsupported (caller should\r\n * fall back to CPU decoding).\r\n * @param splatOffset first splat index of the range\r\n * @param splatCount number of splats in the range\r\n * @returns a stride-4 Float32Array of length `splatCount * 4`, or null when unsupported/failed\r\n */\r\n public async readCentersRangeAsync(splatOffset: number, splatCount: number): Promise<Nullable<Float32Array>> {\r\n if (this._disposed || splatCount <= 0 || !this.supportsAsyncCentersReadback) {\r\n return null;\r\n }\r\n\r\n const width = this._textureSize;\r\n // The range maps to whole texel rows [rowStart, rowEnd); read that rectangle and slice the exact range.\r\n // Splat i lives at texel (i % width, floor(i / width)) in both decode and draw, so the readback (which\r\n // indexes the same texture storage directly, with no UV/flip) yields splat i at buffer position\r\n // i - rowStart * width on every backend.\r\n const rowStart = Math.floor(splatOffset / width);\r\n const rowEnd = Math.ceil((splatOffset + splatCount) / width);\r\n const rowCount = rowEnd - rowStart;\r\n const startInBuffer = (splatOffset - rowStart * width) * 4;\r\n const sliceEnd = startInBuffer + splatCount * 4;\r\n const centers = this._mrt.textures[0];\r\n\r\n const engine = this._scene.getEngine();\r\n\r\n if (engine.isWebGPU) {\r\n // WebGPU: copyTextureToBuffer of the row span + mapAsync (genuinely non-blocking). noDataConversion\r\n // returns the raw RGBA32F floats tightly packed (the 256-byte row alignment is removed internally).\r\n const result = await centers.readPixels(0, 0, null, true, true, 0, rowStart, width, rowCount);\r\n if (this._disposed || !result) {\r\n return null;\r\n }\r\n const floats = result instanceof Float32Array ? result : new Float32Array(result.buffer, result.byteOffset, result.byteLength / 4);\r\n return floats.length >= sliceEnd ? (floats.subarray(startInBuffer, sliceEnd) as Float32Array) : null;\r\n }\r\n\r\n // WebGL2: read directly from the centers texture via a reused FBO + async PBO readback.\r\n const glEngine = engine as unknown as {\r\n _gl: WebGL2RenderingContext;\r\n _currentFramebuffer: Nullable<WebGLFramebuffer>;\r\n _readPixelsAsync(x: number, y: number, w: number, h: number, format: number, type: number, o: ArrayBufferView): Nullable<Promise<ArrayBufferView>>;\r\n };\r\n const gl = glEngine._gl;\r\n const hardware = centers.getInternalTexture()?._hardwareTexture?.underlyingResource as Nullable<WebGLTexture>;\r\n if (!hardware) {\r\n return null;\r\n }\r\n const buffer = new Float32Array(width * rowCount * 4);\r\n if (!this._readFbo) {\r\n this._readFbo = gl.createFramebuffer();\r\n }\r\n const previousFbo = glEngine._currentFramebuffer;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._readFbo);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, hardware, 0);\r\n gl.readBuffer(gl.COLOR_ATTACHMENT0);\r\n\r\n // _readPixelsAsync issues the readPixels into a PBO synchronously, then resolves once the GPU fence\r\n // signals — so the framebuffer can be restored immediately while the transfer completes off-thread.\r\n const promise = glEngine._readPixelsAsync(0, rowStart, width, rowCount, gl.RGBA, gl.FLOAT, buffer);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, previousFbo);\r\n // gl.readBuffer is global state: restore the default-framebuffer read source (BACK) so later\r\n // readPixels on the default framebuffer aren't left pointing at COLOR_ATTACHMENT0. When restoring to\r\n // another FBO, COLOR_ATTACHMENT0 is the correct default read buffer, so only reset for the default one.\r\n if (!previousFbo) {\r\n gl.readBuffer(gl.BACK);\r\n }\r\n if (!promise) {\r\n return null;\r\n }\r\n await promise;\r\n if (this._disposed || buffer.length < sliceEnd) {\r\n return null;\r\n }\r\n return buffer.subarray(startInBuffer, sliceEnd) as Float32Array;\r\n }\r\n\r\n /**\r\n * Disposes the work buffer and its decode resources.\r\n */\r\n public dispose(): void {\r\n this._disposed = true;\r\n if (this._readFbo) {\r\n (this._scene.getEngine() as unknown as { _gl?: WebGL2RenderingContext })._gl?.deleteFramebuffer(this._readFbo);\r\n this._readFbo = null;\r\n }\r\n this._quad.dispose();\r\n this._material.dispose(true, false);\r\n this._mrt.dispose();\r\n }\r\n\r\n private _createQuad(): Mesh {\r\n const quad = new Mesh(\"gsWorkBufferQuad\", this._scene);\r\n const vertexData = new VertexData();\r\n // Fullscreen triangle in clip space (the vertex shader passes positions straight through).\r\n vertexData.positions = [-1, -1, 0, 3, -1, 0, -1, 3, 0];\r\n vertexData.indices = [0, 1, 2];\r\n vertexData.applyToMesh(quad);\r\n // Render only inside the work-buffer MRT, never in the main scene pass.\r\n this._scene.removeMesh(quad);\r\n return quad;\r\n }\r\n\r\n private _createMaterial(): ShaderMaterial {\r\n const isWGSL = this._shaderLanguage === ShaderLanguage.WGSL;\r\n const material = new ShaderMaterial(\r\n \"gsSogDecode\",\r\n this._scene,\r\n {\r\n vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,\r\n fragmentSource: isWGSL ? GaussianSplattingWorkBufferFragmentShaderWGSL : GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n },\r\n {\r\n attributes: [\"position\"],\r\n uniforms: [\"sogMeansMin\", \"sogMeansMax\", \"sogScalesMin\", \"sogScalesMax\", \"sogSh0Min\", \"sogSh0Max\", \"uVersion\", \"uOffset\", \"uCount\", \"uDestWidth\", \"uSrcWidth\"],\r\n samplers: [\"sogMeansLTex\", \"sogMeansUTex\", \"sogScalesTex\", \"sogQuatsTex\", \"sogSh0Tex\", \"sogCodebookTex\"],\r\n shaderLanguage: this._shaderLanguage,\r\n }\r\n );\r\n material.backFaceCulling = false;\r\n material.disableDepthWrite = true;\r\n return material;\r\n }\r\n\r\n private _applyPack(pack: ISogTexturePack, offset: number): void {\r\n const material = this._material;\r\n const srcWidth = (pack.meansTextureL as Texture).getSize().width;\r\n\r\n material.setTexture(\"sogMeansLTex\", pack.meansTextureL);\r\n material.setTexture(\"sogMeansUTex\", pack.meansTextureU);\r\n material.setTexture(\"sogScalesTex\", pack.scalesTexture);\r\n material.setTexture(\"sogQuatsTex\", pack.quatsTexture);\r\n material.setTexture(\"sogSh0Tex\", pack.sh0Texture);\r\n // Codebook only used for v2; bind a harmless placeholder otherwise so the sampler is always set.\r\n material.setTexture(\"sogCodebookTex\", pack.codebookTexture ?? pack.sh0Texture);\r\n\r\n material.setVector3(\"sogMeansMin\", new Vector3(pack.meansMin[0], pack.meansMin[1], pack.meansMin[2]));\r\n material.setVector3(\"sogMeansMax\", new Vector3(pack.meansMax[0], pack.meansMax[1], pack.meansMax[2]));\r\n const sMin = pack.scalesMin ?? [0, 0, 0];\r\n const sMax = pack.scalesMax ?? [0, 0, 0];\r\n material.setVector3(\"sogScalesMin\", new Vector3(sMin[0], sMin[1], sMin[2]));\r\n material.setVector3(\"sogScalesMax\", new Vector3(sMax[0], sMax[1], sMax[2]));\r\n const c0Min = pack.sh0Min ?? [0, 0, 0, 0];\r\n const c0Max = pack.sh0Max ?? [0, 0, 0, 0];\r\n material.setVector4(\"sogSh0Min\", new Vector4(c0Min[0], c0Min[1], c0Min[2], c0Min[3]));\r\n material.setVector4(\"sogSh0Max\", new Vector4(c0Max[0], c0Max[1], c0Max[2], c0Max[3]));\r\n\r\n material.setInt(\"uVersion\", pack.version);\r\n material.setInt(\"uOffset\", offset);\r\n material.setInt(\"uCount\", pack.splatCount);\r\n material.setInt(\"uDestWidth\", this._textureSize);\r\n material.setInt(\"uSrcWidth\", srcWidth);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplattingWorkBuffer.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingWorkBuffer.ts"],"names":[],"mappings":"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","sourcesContent":["import { MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget\";\r\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { type Texture } from \"core/Materials/Textures/texture\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type ISogTexturePack } from \"./splatDefs\";\r\nimport {\r\n GaussianSplattingWorkBufferVertexShaderGLSL,\r\n GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n GaussianSplattingWorkBufferVertexShaderWGSL,\r\n GaussianSplattingWorkBufferFragmentShaderWGSL,\r\n GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL,\r\n GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL,\r\n GaussianSplattingWorkBufferRelayoutShaderName,\r\n} from \"./gaussianSplattingWorkBufferShaders\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\n\r\n/**\r\n * A unified, GPU-decoded Gaussian Splatting work buffer.\r\n *\r\n * Holds a square MRT texture set (centers / covA / covB / colors) sized to a fixed splat capacity\r\n * (PlayCanvas-style: `ceil(sqrt(capacity))`). Each streamed SOG file is decoded directly on the GPU\r\n * (no CPU readback) into its allocated pixel range. The decoded textures are consumed unchanged by the\r\n * standard (non-SOG) Gaussian Splatting draw path.\r\n *\r\n * @experimental\r\n */\r\nexport class GaussianSplattingWorkBuffer {\r\n private readonly _scene: Scene;\r\n private readonly _mrt: MultiRenderTarget;\r\n private readonly _textureSize: number;\r\n private readonly _shaderLanguage: ShaderLanguage;\r\n private readonly _material: ShaderMaterial;\r\n private readonly _quad: Mesh;\r\n // Relayout (defrag) copy material, created lazily on first relayout.\r\n private _copyMaterial: Nullable<ShaderMaterial> = null;\r\n // Reusable destination->source index map for the relayout pass (created lazily, sized to the work buffer).\r\n private _relayoutMapData: Nullable<Float32Array> = null;\r\n private _relayoutMapTexture: Nullable<RawTexture> = null;\r\n private _disposed = false;\r\n // Reused WebGL framebuffer for the async centers readback (created lazily, freed in dispose).\r\n private _readFbo: Nullable<WebGLFramebuffer> = null;\r\n\r\n /**\r\n * True when the engine supports the non-blocking GPU readback used by {@link readCentersRangeAsync}:\r\n * WebGL2 (PBO + fence) or WebGPU (copyTextureToBuffer + mapAsync). When false (e.g. WebGL1), callers must\r\n * decode positions on the CPU instead.\r\n */\r\n public get supportsAsyncCentersReadback(): boolean {\r\n const engine = this._scene.getEngine();\r\n if (engine.isWebGPU) {\r\n return true;\r\n }\r\n const glEngine = engine as unknown as { _gl?: WebGL2RenderingContext; _readPixelsAsync?: unknown; webGLVersion?: number };\r\n return !!glEngine._gl && typeof glEngine._readPixelsAsync === \"function\" && (glEngine.webGLVersion ?? 0) >= 2;\r\n }\r\n\r\n /**\r\n * Square edge length (in pixels) of the work-buffer textures.\r\n */\r\n public get textureSize(): number {\r\n return this._textureSize;\r\n }\r\n\r\n /**\r\n * The decoded work-buffer textures: [centers, covA, covB, colors].\r\n */\r\n public get textures(): Texture[] {\r\n return this._mrt.textures;\r\n }\r\n\r\n /**\r\n * Creates a work buffer sized to hold `capacity` splats.\r\n * @param scene hosting scene\r\n * @param capacity total number of splats the work buffer must address\r\n */\r\n constructor(scene: Scene, capacity: number) {\r\n this._scene = scene;\r\n this._shaderLanguage = scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n this._textureSize = Math.max(1, Math.ceil(Math.sqrt(Math.max(1, capacity))));\r\n\r\n // The decode buffer accumulates (clear disabled) so each decode preserves previously-decoded files.\r\n this._mrt = this._createMrt(\"gsWorkBuffer\", true);\r\n\r\n // One persistent decode material + fullscreen-triangle quad, reused (with per-file uniforms)\r\n // for every decode so the shader is compiled only once.\r\n this._material = this._createMaterial();\r\n this._quad = this._createQuad();\r\n this._quad.material = this._material;\r\n }\r\n\r\n /**\r\n * Creates a 4-attachment MRT (centers F32 / covA F32 / covB F32 / colors U8) sized to the work buffer.\r\n * @param name MRT and attachment base name\r\n * @param disableClear when true, clearing is suppressed so renders accumulate (the decode buffer); when\r\n * false the MRT clears to zero on each render (the temporary relayout buffer, so gaps stay zeroed)\r\n * @returns the created MRT\r\n */\r\n private _createMrt(name: string, disableClear: boolean): MultiRenderTarget {\r\n const mrt = new MultiRenderTarget(\r\n name,\r\n { width: this._textureSize, height: this._textureSize },\r\n 4,\r\n this._scene,\r\n {\r\n types: [Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_FLOAT, Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n samplingModes: [\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n ],\r\n formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA],\r\n generateDepthBuffer: false,\r\n generateDepthTexture: false,\r\n generateMipMaps: false,\r\n },\r\n [`${name}Centers`, `${name}CovA`, `${name}CovB`, `${name}Colors`]\r\n );\r\n mrt.clearColor = new Color4(0, 0, 0, 0);\r\n mrt.renderList = [];\r\n if (disableClear) {\r\n mrt.onClearObservable.add(() => {});\r\n }\r\n return mrt;\r\n }\r\n\r\n /**\r\n * Decodes one SOG file into the work buffer at the given splat offset (accumulating; previously\r\n * decoded files are preserved). Resolves once the GPU decode has been issued. The caller may\r\n * dispose the source pack textures after this resolves.\r\n * @param pack the SOG texture pack (GPU source textures + per-file decode parameters)\r\n * @param offset first splat index (pixel offset) for this file in the work buffer\r\n */\r\n public async decodeAsync(pack: ISogTexturePack, offset: number): Promise<void> {\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._applyPack(pack, offset);\r\n // Render the decode pass at the start of a frame (the safe point for custom render targets),\r\n // once the shader is compiled — never re-entrantly from a promise/observable continuation.\r\n await new Promise<void>((resolve) => {\r\n const attempt = () => {\r\n if (this._disposed) {\r\n resolve();\r\n return;\r\n }\r\n if (!this._material.isReady(this._quad)) {\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n return;\r\n }\r\n this._mrt.renderList = [this._quad];\r\n this._mrt.render();\r\n resolve();\r\n };\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n });\r\n }\r\n\r\n /**\r\n * Whether the relayout copy shader is compiled and ready. Lazily creates the copy material on first call.\r\n * Callers should poll this before {@link relayoutSync} (which must only run when ready).\r\n * @returns true when {@link relayoutSync} can run this frame\r\n */\r\n public isRelayoutReady(): boolean {\r\n if (this._disposed) {\r\n return false;\r\n }\r\n if (!this._copyMaterial) {\r\n this._copyMaterial = this._createCopyMaterial();\r\n }\r\n return this._copyMaterial.isReady(this._quad);\r\n }\r\n\r\n /**\r\n * Relayouts the decoded work-buffer textures to a new (defragmented) splat layout, keeping the same\r\n * texture instances so the consuming mesh does not need to re-bind. `srcIndexByDst[d]` is the source splat\r\n * index whose decoded data should end up at destination index `d`, or a negative value for a gap (left\r\n * zeroed). Uses a temporary MRT ping-pong (old -> temp via the map, then temp -> old identity) so\r\n * overlapping moves stay correct. Must be called at a frame-safe point (inside `onBeforeRender`) and only\r\n * when {@link isRelayoutReady} returns true.\r\n * @param srcIndexByDst per-destination source splat index (negative = gap)\r\n */\r\n public relayoutSync(srcIndexByDst: Float32Array): void {\r\n if (this._disposed || !this._copyMaterial) {\r\n return;\r\n }\r\n const size = this._textureSize;\r\n // Reuse the map buffer and its GPU texture across relayouts (the work-buffer size is fixed).\r\n if (!this._relayoutMapData) {\r\n this._relayoutMapData = new Float32Array(size * size);\r\n }\r\n const mapData = this._relayoutMapData;\r\n mapData.fill(-1);\r\n mapData.set(srcIndexByDst.subarray(0, Math.min(srcIndexByDst.length, mapData.length)));\r\n if (!this._relayoutMapTexture) {\r\n this._relayoutMapTexture = new RawTexture(\r\n mapData,\r\n size,\r\n size,\r\n Constants.TEXTUREFORMAT_R,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_FLOAT\r\n );\r\n } else {\r\n this._relayoutMapTexture.update(mapData);\r\n }\r\n const mapTexture = this._relayoutMapTexture;\r\n // The temporary ping-pong MRT is (re)created per relayout rather than kept resident: it is the same size\r\n // as the work buffer, so a persistent copy would double GPU memory and defeat the streaming memory budget.\r\n const temp = this._createMrt(\"gsRelayoutTemp\", false);\r\n try {\r\n // Pass 1: old -> temp using the map (temp gets the new layout; gaps stay zeroed by the clear).\r\n this._renderRelayoutPass(temp, this._mrt.textures, mapTexture, 1);\r\n // Pass 2: temp -> old, identity (old textures get the new layout, full overwrite).\r\n this._renderRelayoutPass(this._mrt, temp.textures, mapTexture, 0);\r\n } finally {\r\n temp.dispose();\r\n this._quad.material = this._material;\r\n }\r\n }\r\n\r\n /**\r\n * Renders one relayout copy pass into the target MRT, sampling the given source textures.\r\n * @param target destination MRT\r\n * @param sources the four source work-buffer textures\r\n * @param mapTexture the R32F destination-to-source index map\r\n * @param useMap 1 to read source indices from the map (gaps discarded), 0 for an identity copy\r\n */\r\n private _renderRelayoutPass(target: MultiRenderTarget, sources: Texture[], mapTexture: RawTexture, useMap: number): void {\r\n const material = this._copyMaterial!;\r\n material.setTexture(\"uMapTex\", mapTexture);\r\n material.setTexture(\"uSrc0\", sources[0]);\r\n material.setTexture(\"uSrc1\", sources[1]);\r\n material.setTexture(\"uSrc2\", sources[2]);\r\n material.setTexture(\"uSrc3\", sources[3]);\r\n material.setInt(\"uDstWidth\", this._textureSize);\r\n material.setInt(\"uSrcWidth\", this._textureSize);\r\n material.setInt(\"uUseMap\", useMap);\r\n this._quad.material = material;\r\n target.renderList = [this._quad];\r\n target.render();\r\n }\r\n\r\n private _createCopyMaterial(): ShaderMaterial {\r\n const isWGSL = this._shaderLanguage === ShaderLanguage.WGSL;\r\n const material = new ShaderMaterial(\r\n GaussianSplattingWorkBufferRelayoutShaderName,\r\n this._scene,\r\n {\r\n vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,\r\n fragmentSource: isWGSL ? GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL : GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL,\r\n },\r\n {\r\n attributes: [\"position\"],\r\n uniforms: [\"uDstWidth\", \"uSrcWidth\", \"uUseMap\"],\r\n samplers: [\"uMapTex\", \"uSrc0\", \"uSrc1\", \"uSrc2\", \"uSrc3\"],\r\n shaderLanguage: this._shaderLanguage,\r\n }\r\n );\r\n material.backFaceCulling = false;\r\n material.disableDepthWrite = true;\r\n return material;\r\n }\r\n\r\n /**\r\n * Asynchronously reads back the decoded splat centers (stride-4 xyzw, w=1) for a contiguous splat range\r\n * from the work buffer's centers texture, using a non-blocking GPU readback (WebGL2 PBO + fence, or WebGPU\r\n * copyTextureToBuffer + mapAsync) so it never stalls the frame the way a CPU image decode does. The centers\r\n * texture already holds the GPU-decoded positions (identical to the CPU decode), so this replaces decoding\r\n * positions on the CPU from the means images. Returns null when async readback is unsupported (caller should\r\n * fall back to CPU decoding).\r\n * @param splatOffset first splat index of the range\r\n * @param splatCount number of splats in the range\r\n * @returns a stride-4 Float32Array of length `splatCount * 4`, or null when unsupported/failed\r\n */\r\n public async readCentersRangeAsync(splatOffset: number, splatCount: number): Promise<Nullable<Float32Array>> {\r\n if (this._disposed || splatCount <= 0 || !this.supportsAsyncCentersReadback) {\r\n return null;\r\n }\r\n\r\n const width = this._textureSize;\r\n // The range maps to whole texel rows [rowStart, rowEnd); read that rectangle and slice the exact range.\r\n // Splat i lives at texel (i % width, floor(i / width)) in both decode and draw, so the readback (which\r\n // indexes the same texture storage directly, with no UV/flip) yields splat i at buffer position\r\n // i - rowStart * width on every backend.\r\n const rowStart = Math.floor(splatOffset / width);\r\n const rowEnd = Math.ceil((splatOffset + splatCount) / width);\r\n const rowCount = rowEnd - rowStart;\r\n const startInBuffer = (splatOffset - rowStart * width) * 4;\r\n const sliceEnd = startInBuffer + splatCount * 4;\r\n const centers = this._mrt.textures[0];\r\n\r\n const engine = this._scene.getEngine();\r\n\r\n if (engine.isWebGPU) {\r\n // WebGPU: copyTextureToBuffer of the row span + mapAsync (genuinely non-blocking). noDataConversion\r\n // returns the raw RGBA32F floats tightly packed (the 256-byte row alignment is removed internally).\r\n const result = await centers.readPixels(0, 0, null, true, true, 0, rowStart, width, rowCount);\r\n if (this._disposed || !result) {\r\n return null;\r\n }\r\n const floats = result instanceof Float32Array ? result : new Float32Array(result.buffer, result.byteOffset, result.byteLength / 4);\r\n return floats.length >= sliceEnd ? (floats.subarray(startInBuffer, sliceEnd) as Float32Array) : null;\r\n }\r\n\r\n // WebGL2: read directly from the centers texture via a reused FBO + async PBO readback.\r\n const glEngine = engine as unknown as {\r\n _gl: WebGL2RenderingContext;\r\n _currentFramebuffer: Nullable<WebGLFramebuffer>;\r\n _readPixelsAsync(x: number, y: number, w: number, h: number, format: number, type: number, o: ArrayBufferView): Nullable<Promise<ArrayBufferView>>;\r\n };\r\n const gl = glEngine._gl;\r\n const hardware = centers.getInternalTexture()?._hardwareTexture?.underlyingResource as Nullable<WebGLTexture>;\r\n if (!hardware) {\r\n return null;\r\n }\r\n const buffer = new Float32Array(width * rowCount * 4);\r\n if (!this._readFbo) {\r\n this._readFbo = gl.createFramebuffer();\r\n }\r\n const previousFbo = glEngine._currentFramebuffer;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._readFbo);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, hardware, 0);\r\n gl.readBuffer(gl.COLOR_ATTACHMENT0);\r\n\r\n // _readPixelsAsync issues the readPixels into a PBO synchronously, then resolves once the GPU fence\r\n // signals — so the framebuffer can be restored immediately while the transfer completes off-thread.\r\n const promise = glEngine._readPixelsAsync(0, rowStart, width, rowCount, gl.RGBA, gl.FLOAT, buffer);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, previousFbo);\r\n // gl.readBuffer is global state: restore the default-framebuffer read source (BACK) so later\r\n // readPixels on the default framebuffer aren't left pointing at COLOR_ATTACHMENT0. When restoring to\r\n // another FBO, COLOR_ATTACHMENT0 is the correct default read buffer, so only reset for the default one.\r\n if (!previousFbo) {\r\n gl.readBuffer(gl.BACK);\r\n }\r\n if (!promise) {\r\n return null;\r\n }\r\n await promise;\r\n if (this._disposed || buffer.length < sliceEnd) {\r\n return null;\r\n }\r\n return buffer.subarray(startInBuffer, sliceEnd) as Float32Array;\r\n }\r\n\r\n /**\r\n * Disposes the work buffer and its decode resources.\r\n */\r\n public dispose(): void {\r\n this._disposed = true;\r\n if (this._readFbo) {\r\n (this._scene.getEngine() as unknown as { _gl?: WebGL2RenderingContext })._gl?.deleteFramebuffer(this._readFbo);\r\n this._readFbo = null;\r\n }\r\n this._quad.dispose();\r\n this._material.dispose(true, false);\r\n this._copyMaterial?.dispose(true, false);\r\n this._relayoutMapTexture?.dispose();\r\n this._mrt.dispose();\r\n }\r\n\r\n private _createQuad(): Mesh {\r\n const quad = new Mesh(\"gsWorkBufferQuad\", this._scene);\r\n const vertexData = new VertexData();\r\n // Fullscreen triangle in clip space (the vertex shader passes positions straight through).\r\n vertexData.positions = [-1, -1, 0, 3, -1, 0, -1, 3, 0];\r\n vertexData.indices = [0, 1, 2];\r\n vertexData.applyToMesh(quad);\r\n // Render only inside the work-buffer MRT, never in the main scene pass.\r\n this._scene.removeMesh(quad);\r\n return quad;\r\n }\r\n\r\n private _createMaterial(): ShaderMaterial {\r\n const isWGSL = this._shaderLanguage === ShaderLanguage.WGSL;\r\n const material = new ShaderMaterial(\r\n \"gsSogDecode\",\r\n this._scene,\r\n {\r\n vertexSource: isWGSL ? GaussianSplattingWorkBufferVertexShaderWGSL : GaussianSplattingWorkBufferVertexShaderGLSL,\r\n fragmentSource: isWGSL ? GaussianSplattingWorkBufferFragmentShaderWGSL : GaussianSplattingWorkBufferFragmentShaderGLSL,\r\n },\r\n {\r\n attributes: [\"position\"],\r\n uniforms: [\"sogMeansMin\", \"sogMeansMax\", \"sogScalesMin\", \"sogScalesMax\", \"sogSh0Min\", \"sogSh0Max\", \"uVersion\", \"uOffset\", \"uCount\", \"uDestWidth\", \"uSrcWidth\"],\r\n samplers: [\"sogMeansLTex\", \"sogMeansUTex\", \"sogScalesTex\", \"sogQuatsTex\", \"sogSh0Tex\", \"sogCodebookTex\"],\r\n shaderLanguage: this._shaderLanguage,\r\n }\r\n );\r\n material.backFaceCulling = false;\r\n material.disableDepthWrite = true;\r\n return material;\r\n }\r\n\r\n private _applyPack(pack: ISogTexturePack, offset: number): void {\r\n const material = this._material;\r\n const srcWidth = (pack.meansTextureL as Texture).getSize().width;\r\n\r\n material.setTexture(\"sogMeansLTex\", pack.meansTextureL);\r\n material.setTexture(\"sogMeansUTex\", pack.meansTextureU);\r\n material.setTexture(\"sogScalesTex\", pack.scalesTexture);\r\n material.setTexture(\"sogQuatsTex\", pack.quatsTexture);\r\n material.setTexture(\"sogSh0Tex\", pack.sh0Texture);\r\n // Codebook only used for v2; bind a harmless placeholder otherwise so the sampler is always set.\r\n material.setTexture(\"sogCodebookTex\", pack.codebookTexture ?? pack.sh0Texture);\r\n\r\n material.setVector3(\"sogMeansMin\", new Vector3(pack.meansMin[0], pack.meansMin[1], pack.meansMin[2]));\r\n material.setVector3(\"sogMeansMax\", new Vector3(pack.meansMax[0], pack.meansMax[1], pack.meansMax[2]));\r\n const sMin = pack.scalesMin ?? [0, 0, 0];\r\n const sMax = pack.scalesMax ?? [0, 0, 0];\r\n material.setVector3(\"sogScalesMin\", new Vector3(sMin[0], sMin[1], sMin[2]));\r\n material.setVector3(\"sogScalesMax\", new Vector3(sMax[0], sMax[1], sMax[2]));\r\n const c0Min = pack.sh0Min ?? [0, 0, 0, 0];\r\n const c0Max = pack.sh0Max ?? [0, 0, 0, 0];\r\n material.setVector4(\"sogSh0Min\", new Vector4(c0Min[0], c0Min[1], c0Min[2], c0Min[3]));\r\n material.setVector4(\"sogSh0Max\", new Vector4(c0Max[0], c0Max[1], c0Max[2], c0Max[3]));\r\n\r\n material.setInt(\"uVersion\", pack.version);\r\n material.setInt(\"uOffset\", offset);\r\n material.setInt(\"uCount\", pack.splatCount);\r\n material.setInt(\"uDestWidth\", this._textureSize);\r\n material.setInt(\"uSrcWidth\", srcWidth);\r\n }\r\n}\r\n"]}
|
|
@@ -23,3 +23,18 @@ export declare const GaussianSplattingWorkBufferVertexShaderWGSL = "\nattribute
|
|
|
23
23
|
* Fragment shader (WGSL/WebGPU) — same decode as the GLSL variant, writing 4 MRT attachments.
|
|
24
24
|
*/
|
|
25
25
|
export declare const GaussianSplattingWorkBufferFragmentShaderWGSL = "\nvar sogMeansLTexSampler : sampler;\nvar sogMeansLTex : texture_2d<f32>;\nvar sogMeansUTexSampler : sampler;\nvar sogMeansUTex : texture_2d<f32>;\nvar sogScalesTexSampler : sampler;\nvar sogScalesTex : texture_2d<f32>;\nvar sogQuatsTexSampler : sampler;\nvar sogQuatsTex : texture_2d<f32>;\nvar sogSh0TexSampler : sampler;\nvar sogSh0Tex : texture_2d<f32>;\nvar sogCodebookTexSampler : sampler;\nvar sogCodebookTex : texture_2d<f32>;\n\nuniform sogMeansMin : vec3<f32>;\nuniform sogMeansMax : vec3<f32>;\nuniform sogScalesMin : vec3<f32>;\nuniform sogScalesMax : vec3<f32>;\nuniform sogSh0Min : vec4<f32>;\nuniform sogSh0Max : vec4<f32>;\nuniform uVersion : i32;\nuniform uOffset : i32;\nuniform uCount : i32;\nuniform uDestWidth : i32;\nuniform uSrcWidth : i32;\n\n@fragment\nfn main(input : FragmentInputs) -> FragmentOutputs {\n let p : vec2<i32> = vec2<i32>(i32(fragmentInputs.position.x), i32(fragmentInputs.position.y));\n let global : i32 = p.y * uniforms.uDestWidth + p.x;\n if (global < uniforms.uOffset || global >= uniforms.uOffset + uniforms.uCount) {\n discard;\n }\n let k : i32 = global - uniforms.uOffset;\n let src : vec2<i32> = vec2<i32>(k - (k / uniforms.uSrcWidth) * uniforms.uSrcWidth, k / uniforms.uSrcWidth);\n\n let mL : vec3<f32> = textureLoad(sogMeansLTex, src, 0).xyz;\n let mU : vec3<f32> = textureLoad(sogMeansUTex, src, 0).xyz;\n let sRaw : vec3<f32> = textureLoad(sogScalesTex, src, 0).xyz;\n let qRaw : vec4<f32> = textureLoad(sogQuatsTex, src, 0);\n let c0 : vec4<f32> = textureLoad(sogSh0Tex, src, 0);\n\n let q16 : vec3<f32> = (mU * 256.0 + mL) * (255.0 / 65535.0);\n let nPos : vec3<f32> = mix(uniforms.sogMeansMin, uniforms.sogMeansMax, q16);\n let center : vec3<f32> = sign(nPos) * (exp(abs(nPos)) - vec3<f32>(1.0));\n\n var splatScale : vec3<f32>;\n if (uniforms.uVersion == 2) {\n let sIdx : vec3<f32> = floor(sRaw * 255.0 + 0.5);\n splatScale.x = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.x), 0), 0).r);\n splatScale.y = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.y), 0), 0).r);\n splatScale.z = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.z), 0), 0).r);\n } else {\n splatScale = exp(mix(uniforms.sogScalesMin, uniforms.sogScalesMax, sRaw));\n }\n\n let invSqrt2 : f32 = 0.70710678118;\n let qabc : vec3<f32> = (qRaw.xyz - vec3<f32>(0.5)) * 2.0 * invSqrt2;\n let qMode : i32 = i32(qRaw.w * 255.0 + 0.5) - 252;\n let qd : f32 = sqrt(max(0.0, 1.0 - dot(qabc, qabc)));\n var quat : vec4<f32>;\n if (qMode == 0) {\n quat = vec4<f32>(qd, qabc.x, qabc.y, qabc.z);\n } else if (qMode == 1) {\n quat = vec4<f32>(qabc.x, qd, qabc.y, qabc.z);\n } else if (qMode == 2) {\n quat = vec4<f32>(qabc.x, qabc.y, qd, qabc.z);\n } else {\n quat = vec4<f32>(qabc.x, qabc.y, qabc.z, qd);\n }\n\n let qw : f32 = quat.x;\n let qx : f32 = quat.y;\n let qy : f32 = quat.z;\n let qz : f32 = quat.w;\n let R : mat3x3<f32> = mat3x3<f32>(\n 1.0 - 2.0 * (qy * qy + qz * qz), 2.0 * (qx * qy + qw * qz), 2.0 * (qx * qz - qw * qy),\n 2.0 * (qx * qy - qw * qz), 1.0 - 2.0 * (qx * qx + qz * qz), 2.0 * (qy * qz + qw * qx),\n 2.0 * (qx * qz + qw * qy), 2.0 * (qy * qz - qw * qx), 1.0 - 2.0 * (qx * qx + qy * qy)\n );\n let S2 : mat3x3<f32> = mat3x3<f32>(\n 4.0 * splatScale.x * splatScale.x, 0.0, 0.0,\n 0.0, 4.0 * splatScale.y * splatScale.y, 0.0,\n 0.0, 0.0, 4.0 * splatScale.z * splatScale.z\n );\n let Sigma : mat3x3<f32> = R * S2 * transpose(R);\n\n let SH_C0 : f32 = 0.28209479177387814;\n var colRgb : vec3<f32>;\n var colA : f32;\n if (uniforms.uVersion == 2) {\n var c3 : vec3<f32>;\n c3.x = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.x * 255.0 + 0.5), 0), 0).r;\n c3.y = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.y * 255.0 + 0.5), 0), 0).r;\n c3.z = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.z * 255.0 + 0.5), 0), 0).r;\n colRgb = vec3<f32>(0.5) + c3 * SH_C0;\n colA = c0.w;\n } else {\n let cLerp : vec4<f32> = mix(uniforms.sogSh0Min, uniforms.sogSh0Max, c0);\n colRgb = vec3<f32>(0.5) + cLerp.xyz * SH_C0;\n colA = 1.0 / (1.0 + exp(-cLerp.w));\n }\n\n fragmentOutputs.fragData0 = vec4<f32>(center, 1.0);\n fragmentOutputs.fragData1 = vec4<f32>(Sigma[0][0], Sigma[0][1], Sigma[0][2], Sigma[1][1]);\n fragmentOutputs.fragData2 = vec4<f32>(Sigma[1][2], Sigma[2][2], 0.0, 0.0);\n fragmentOutputs.fragData3 = vec4<f32>(colRgb, colA);\n}\n";
|
|
26
|
+
/**
|
|
27
|
+
* Shader name for the work-buffer relayout (defrag/compaction) copy pass.
|
|
28
|
+
*/
|
|
29
|
+
export declare const GaussianSplattingWorkBufferRelayoutShaderName = "gsWorkBufferRelayout";
|
|
30
|
+
/**
|
|
31
|
+
* Relayout copy fragment shader (GLSL/WebGL2). Copies the four decoded work-buffer textures from a source
|
|
32
|
+
* layout to a destination layout, one output texel per draw. In map mode (`uUseMap == 1`) each destination
|
|
33
|
+
* texel reads its source splat index from `uMapTex` (R32F; a negative value marks a gap and is discarded so
|
|
34
|
+
* the cleared destination stays zero). In identity mode the source texel equals the destination texel.
|
|
35
|
+
*/
|
|
36
|
+
export declare const GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL = "precision highp float;\nprecision highp int;\n\nuniform sampler2D uMapTex;\nuniform sampler2D uSrc0;\nuniform sampler2D uSrc1;\nuniform sampler2D uSrc2;\nuniform sampler2D uSrc3;\nuniform int uDstWidth;\nuniform int uSrcWidth;\nuniform int uUseMap;\n\nlayout(location = 0) out vec4 glFragData[4];\n\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n int srcIdx;\n if (uUseMap == 1) {\n float m = texelFetch(uMapTex, p, 0).r;\n if (m < 0.0) {\n discard;\n }\n srcIdx = int(m + 0.5);\n } else {\n srcIdx = p.y * uDstWidth + p.x;\n }\n ivec2 s = ivec2(srcIdx - (srcIdx / uSrcWidth) * uSrcWidth, srcIdx / uSrcWidth);\n glFragData[0] = texelFetch(uSrc0, s, 0);\n glFragData[1] = texelFetch(uSrc1, s, 0);\n glFragData[2] = texelFetch(uSrc2, s, 0);\n glFragData[3] = texelFetch(uSrc3, s, 0);\n}\n";
|
|
37
|
+
/**
|
|
38
|
+
* Relayout copy fragment shader (WGSL/WebGPU) — same copy as the GLSL variant.
|
|
39
|
+
*/
|
|
40
|
+
export declare const GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL = "\nvar uMapTexSampler : sampler;\nvar uMapTex : texture_2d<f32>;\nvar uSrc0Sampler : sampler;\nvar uSrc0 : texture_2d<f32>;\nvar uSrc1Sampler : sampler;\nvar uSrc1 : texture_2d<f32>;\nvar uSrc2Sampler : sampler;\nvar uSrc2 : texture_2d<f32>;\nvar uSrc3Sampler : sampler;\nvar uSrc3 : texture_2d<f32>;\n\nuniform uDstWidth : i32;\nuniform uSrcWidth : i32;\nuniform uUseMap : i32;\n\n@fragment\nfn main(input : FragmentInputs) -> FragmentOutputs {\n let p : vec2<i32> = vec2<i32>(i32(fragmentInputs.position.x), i32(fragmentInputs.position.y));\n var srcIdx : i32;\n if (uniforms.uUseMap == 1) {\n let m : f32 = textureLoad(uMapTex, p, 0).r;\n if (m < 0.0) {\n discard;\n }\n srcIdx = i32(m + 0.5);\n } else {\n srcIdx = p.y * uniforms.uDstWidth + p.x;\n }\n let s : vec2<i32> = vec2<i32>(srcIdx - (srcIdx / uniforms.uSrcWidth) * uniforms.uSrcWidth, srcIdx / uniforms.uSrcWidth);\n fragmentOutputs.fragData0 = textureLoad(uSrc0, s, 0);\n fragmentOutputs.fragData1 = textureLoad(uSrc1, s, 0);\n fragmentOutputs.fragData2 = textureLoad(uSrc2, s, 0);\n fragmentOutputs.fragData3 = textureLoad(uSrc3, s, 0);\n}\n";
|
|
@@ -252,4 +252,86 @@ fn main(input : FragmentInputs) -> FragmentOutputs {
|
|
|
252
252
|
fragmentOutputs.fragData3 = vec4<f32>(colRgb, colA);
|
|
253
253
|
}
|
|
254
254
|
`;
|
|
255
|
+
/**
|
|
256
|
+
* Shader name for the work-buffer relayout (defrag/compaction) copy pass.
|
|
257
|
+
*/
|
|
258
|
+
export const GaussianSplattingWorkBufferRelayoutShaderName = "gsWorkBufferRelayout";
|
|
259
|
+
/**
|
|
260
|
+
* Relayout copy fragment shader (GLSL/WebGL2). Copies the four decoded work-buffer textures from a source
|
|
261
|
+
* layout to a destination layout, one output texel per draw. In map mode (`uUseMap == 1`) each destination
|
|
262
|
+
* texel reads its source splat index from `uMapTex` (R32F; a negative value marks a gap and is discarded so
|
|
263
|
+
* the cleared destination stays zero). In identity mode the source texel equals the destination texel.
|
|
264
|
+
*/
|
|
265
|
+
export const GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL = `precision highp float;
|
|
266
|
+
precision highp int;
|
|
267
|
+
|
|
268
|
+
uniform sampler2D uMapTex;
|
|
269
|
+
uniform sampler2D uSrc0;
|
|
270
|
+
uniform sampler2D uSrc1;
|
|
271
|
+
uniform sampler2D uSrc2;
|
|
272
|
+
uniform sampler2D uSrc3;
|
|
273
|
+
uniform int uDstWidth;
|
|
274
|
+
uniform int uSrcWidth;
|
|
275
|
+
uniform int uUseMap;
|
|
276
|
+
|
|
277
|
+
layout(location = 0) out vec4 glFragData[4];
|
|
278
|
+
|
|
279
|
+
void main() {
|
|
280
|
+
ivec2 p = ivec2(gl_FragCoord.xy);
|
|
281
|
+
int srcIdx;
|
|
282
|
+
if (uUseMap == 1) {
|
|
283
|
+
float m = texelFetch(uMapTex, p, 0).r;
|
|
284
|
+
if (m < 0.0) {
|
|
285
|
+
discard;
|
|
286
|
+
}
|
|
287
|
+
srcIdx = int(m + 0.5);
|
|
288
|
+
} else {
|
|
289
|
+
srcIdx = p.y * uDstWidth + p.x;
|
|
290
|
+
}
|
|
291
|
+
ivec2 s = ivec2(srcIdx - (srcIdx / uSrcWidth) * uSrcWidth, srcIdx / uSrcWidth);
|
|
292
|
+
glFragData[0] = texelFetch(uSrc0, s, 0);
|
|
293
|
+
glFragData[1] = texelFetch(uSrc1, s, 0);
|
|
294
|
+
glFragData[2] = texelFetch(uSrc2, s, 0);
|
|
295
|
+
glFragData[3] = texelFetch(uSrc3, s, 0);
|
|
296
|
+
}
|
|
297
|
+
`;
|
|
298
|
+
/**
|
|
299
|
+
* Relayout copy fragment shader (WGSL/WebGPU) — same copy as the GLSL variant.
|
|
300
|
+
*/
|
|
301
|
+
export const GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL = `
|
|
302
|
+
var uMapTexSampler : sampler;
|
|
303
|
+
var uMapTex : texture_2d<f32>;
|
|
304
|
+
var uSrc0Sampler : sampler;
|
|
305
|
+
var uSrc0 : texture_2d<f32>;
|
|
306
|
+
var uSrc1Sampler : sampler;
|
|
307
|
+
var uSrc1 : texture_2d<f32>;
|
|
308
|
+
var uSrc2Sampler : sampler;
|
|
309
|
+
var uSrc2 : texture_2d<f32>;
|
|
310
|
+
var uSrc3Sampler : sampler;
|
|
311
|
+
var uSrc3 : texture_2d<f32>;
|
|
312
|
+
|
|
313
|
+
uniform uDstWidth : i32;
|
|
314
|
+
uniform uSrcWidth : i32;
|
|
315
|
+
uniform uUseMap : i32;
|
|
316
|
+
|
|
317
|
+
@fragment
|
|
318
|
+
fn main(input : FragmentInputs) -> FragmentOutputs {
|
|
319
|
+
let p : vec2<i32> = vec2<i32>(i32(fragmentInputs.position.x), i32(fragmentInputs.position.y));
|
|
320
|
+
var srcIdx : i32;
|
|
321
|
+
if (uniforms.uUseMap == 1) {
|
|
322
|
+
let m : f32 = textureLoad(uMapTex, p, 0).r;
|
|
323
|
+
if (m < 0.0) {
|
|
324
|
+
discard;
|
|
325
|
+
}
|
|
326
|
+
srcIdx = i32(m + 0.5);
|
|
327
|
+
} else {
|
|
328
|
+
srcIdx = p.y * uniforms.uDstWidth + p.x;
|
|
329
|
+
}
|
|
330
|
+
let s : vec2<i32> = vec2<i32>(srcIdx - (srcIdx / uniforms.uSrcWidth) * uniforms.uSrcWidth, srcIdx / uniforms.uSrcWidth);
|
|
331
|
+
fragmentOutputs.fragData0 = textureLoad(uSrc0, s, 0);
|
|
332
|
+
fragmentOutputs.fragData1 = textureLoad(uSrc1, s, 0);
|
|
333
|
+
fragmentOutputs.fragData2 = textureLoad(uSrc2, s, 0);
|
|
334
|
+
fragmentOutputs.fragData3 = textureLoad(uSrc3, s, 0);
|
|
335
|
+
}
|
|
336
|
+
`;
|
|
255
337
|
//# sourceMappingURL=gaussianSplattingWorkBufferShaders.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplattingWorkBufferShaders.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingWorkBufferShaders.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,yBAAyB,CAAC;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,2CAA2C,GAAG;;;;;CAK1D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,6CAA6C,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8G5D,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,2CAA2C,GAAG;;;;;;CAM1D,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,6CAA6C,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4G5D,CAAC","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Shared shader names for the SOG -> decoded work-buffer copy pass.\r\n */\r\nexport const GaussianSplattingWorkBufferShaderName = \"gsSogDecodeToWorkBuffer\";\r\n\r\n/**\r\n * Pass-through vertex shader (GLSL): the geometry is a fullscreen triangle already in NDC.\r\n */\r\nexport const GaussianSplattingWorkBufferVertexShaderGLSL = `precision highp float;\r\nattribute vec3 position;\r\nvoid main() {\r\n gl_Position = vec4(position.xy, 0.0, 1.0);\r\n}\r\n`;\r\n\r\n/**\r\n * Fragment shader (GLSL/WebGL2): decodes one SOG source file into the decoded GS work-buffer layout,\r\n * writing each splat into its allocated pixel. Mirrors the USE_SOG decode in ShadersInclude/gaussianSplatting.fx\r\n * but outputs the decoded MRT (center, covA, covB, color) consumed by the standard (non-SOG) draw path.\r\n *\r\n * MRT layout: 0 = center (x,y,z,1), 1 = covA (Sigma00,01,02,11), 2 = covB (Sigma12,22,0,0), 3 = color (rgba).\r\n */\r\nexport const GaussianSplattingWorkBufferFragmentShaderGLSL = `precision highp float;\r\nprecision highp int;\r\n\r\nuniform sampler2D sogMeansLTex;\r\nuniform sampler2D sogMeansUTex;\r\nuniform sampler2D sogScalesTex;\r\nuniform sampler2D sogQuatsTex;\r\nuniform sampler2D sogSh0Tex;\r\nuniform sampler2D sogCodebookTex;\r\n\r\nuniform vec3 sogMeansMin;\r\nuniform vec3 sogMeansMax;\r\nuniform vec3 sogScalesMin;\r\nuniform vec3 sogScalesMax;\r\nuniform vec4 sogSh0Min;\r\nuniform vec4 sogSh0Max;\r\nuniform int uVersion;\r\nuniform int uOffset;\r\nuniform int uCount;\r\nuniform int uDestWidth;\r\nuniform int uSrcWidth;\r\n\r\nlayout(location = 0) out vec4 glFragData[4];\r\n\r\nmat3 transposeM(mat3 m) {\r\n return mat3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);\r\n}\r\n\r\nvoid main() {\r\n ivec2 p = ivec2(gl_FragCoord.xy);\r\n int global = p.y * uDestWidth + p.x;\r\n if (global < uOffset || global >= uOffset + uCount) {\r\n discard;\r\n }\r\n int k = global - uOffset;\r\n ivec2 src = ivec2(k - (k / uSrcWidth) * uSrcWidth, k / uSrcWidth);\r\n\r\n vec3 mL = texelFetch(sogMeansLTex, src, 0).xyz;\r\n vec3 mU = texelFetch(sogMeansUTex, src, 0).xyz;\r\n vec3 sRaw = texelFetch(sogScalesTex, src, 0).xyz;\r\n vec4 qRaw = texelFetch(sogQuatsTex, src, 0);\r\n vec4 c0 = texelFetch(sogSh0Tex, src, 0);\r\n\r\n // Position: q16 = (u<<8)|l normalized; n = lerp(min,max,q16); pos = sign(n)*(exp(|n|)-1)\r\n vec3 q16 = (mU * 256.0 + mL) * (255.0 / 65535.0);\r\n vec3 nPos = mix(sogMeansMin, sogMeansMax, q16);\r\n vec3 center = sign(nPos) * (exp(abs(nPos)) - vec3(1.0));\r\n\r\n // Scale (v1: lerp+exp ; v2: codebook lookup)\r\n vec3 splatScale;\r\n if (uVersion == 2) {\r\n vec3 sIdx = floor(sRaw * 255.0 + 0.5);\r\n splatScale.x = exp(texelFetch(sogCodebookTex, ivec2(int(sIdx.x), 0), 0).r);\r\n splatScale.y = exp(texelFetch(sogCodebookTex, ivec2(int(sIdx.y), 0), 0).r);\r\n splatScale.z = exp(texelFetch(sogCodebookTex, ivec2(int(sIdx.z), 0), 0).r);\r\n } else {\r\n splatScale = exp(mix(sogScalesMin, sogScalesMax, sRaw));\r\n }\r\n\r\n // Quaternion (largest-omitted, mode in alpha as 252 + omitted-index)\r\n const float invSqrt2 = 0.70710678118;\r\n vec3 qabc = (qRaw.xyz - vec3(0.5)) * 2.0 * invSqrt2;\r\n int qMode = int(qRaw.w * 255.0 + 0.5) - 252;\r\n float qd = sqrt(max(0.0, 1.0 - dot(qabc, qabc)));\r\n vec4 quat;\r\n if (qMode == 0) {\r\n quat = vec4(qd, qabc.x, qabc.y, qabc.z);\r\n } else if (qMode == 1) {\r\n quat = vec4(qabc.x, qd, qabc.y, qabc.z);\r\n } else if (qMode == 2) {\r\n quat = vec4(qabc.x, qabc.y, qd, qabc.z);\r\n } else {\r\n quat = vec4(qabc.x, qabc.y, qabc.z, qd);\r\n }\r\n\r\n float qw = quat.x, qx = quat.y, qy = quat.z, qz = quat.w;\r\n mat3 R = mat3(\r\n 1.0 - 2.0 * (qy * qy + qz * qz), 2.0 * (qx * qy + qw * qz), 2.0 * (qx * qz - qw * qy),\r\n 2.0 * (qx * qy - qw * qz), 1.0 - 2.0 * (qx * qx + qz * qz), 2.0 * (qy * qz + qw * qx),\r\n 2.0 * (qx * qz + qw * qy), 2.0 * (qy * qz - qw * qx), 1.0 - 2.0 * (qx * qx + qy * qy)\r\n );\r\n mat3 S2 = mat3(\r\n 4.0 * splatScale.x * splatScale.x, 0.0, 0.0,\r\n 0.0, 4.0 * splatScale.y * splatScale.y, 0.0,\r\n 0.0, 0.0, 4.0 * splatScale.z * splatScale.z\r\n );\r\n mat3 Sigma = R * S2 * transposeM(R);\r\n\r\n // Color (sh0)\r\n const float SH_C0 = 0.28209479177387814;\r\n vec3 colRgb;\r\n float colA;\r\n if (uVersion == 2) {\r\n vec3 c3;\r\n c3.x = texelFetch(sogCodebookTex, ivec2(256 + int(c0.x * 255.0 + 0.5), 0), 0).r;\r\n c3.y = texelFetch(sogCodebookTex, ivec2(256 + int(c0.y * 255.0 + 0.5), 0), 0).r;\r\n c3.z = texelFetch(sogCodebookTex, ivec2(256 + int(c0.z * 255.0 + 0.5), 0), 0).r;\r\n colRgb = vec3(0.5) + c3 * SH_C0;\r\n colA = c0.w;\r\n } else {\r\n vec4 cLerp = mix(sogSh0Min, sogSh0Max, c0);\r\n colRgb = vec3(0.5) + cLerp.xyz * SH_C0;\r\n colA = 1.0 / (1.0 + exp(-cLerp.w));\r\n }\r\n\r\n glFragData[0] = vec4(center, 1.0);\r\n glFragData[1] = vec4(Sigma[0][0], Sigma[0][1], Sigma[0][2], Sigma[1][1]);\r\n glFragData[2] = vec4(Sigma[1][2], Sigma[2][2], 0.0, 0.0);\r\n glFragData[3] = vec4(colRgb, colA);\r\n}\r\n`;\r\n\r\n/**\r\n * Pass-through vertex shader (WGSL).\r\n */\r\nexport const GaussianSplattingWorkBufferVertexShaderWGSL = `\r\nattribute position : vec3<f32>;\r\n@vertex\r\nfn main(input : VertexInputs) -> FragmentInputs {\r\n vertexOutputs.position = vec4<f32>(input.position.xy, 0.0, 1.0);\r\n}\r\n`;\r\n\r\n/**\r\n * Fragment shader (WGSL/WebGPU) — same decode as the GLSL variant, writing 4 MRT attachments.\r\n */\r\nexport const GaussianSplattingWorkBufferFragmentShaderWGSL = `\r\nvar sogMeansLTexSampler : sampler;\r\nvar sogMeansLTex : texture_2d<f32>;\r\nvar sogMeansUTexSampler : sampler;\r\nvar sogMeansUTex : texture_2d<f32>;\r\nvar sogScalesTexSampler : sampler;\r\nvar sogScalesTex : texture_2d<f32>;\r\nvar sogQuatsTexSampler : sampler;\r\nvar sogQuatsTex : texture_2d<f32>;\r\nvar sogSh0TexSampler : sampler;\r\nvar sogSh0Tex : texture_2d<f32>;\r\nvar sogCodebookTexSampler : sampler;\r\nvar sogCodebookTex : texture_2d<f32>;\r\n\r\nuniform sogMeansMin : vec3<f32>;\r\nuniform sogMeansMax : vec3<f32>;\r\nuniform sogScalesMin : vec3<f32>;\r\nuniform sogScalesMax : vec3<f32>;\r\nuniform sogSh0Min : vec4<f32>;\r\nuniform sogSh0Max : vec4<f32>;\r\nuniform uVersion : i32;\r\nuniform uOffset : i32;\r\nuniform uCount : i32;\r\nuniform uDestWidth : i32;\r\nuniform uSrcWidth : i32;\r\n\r\n@fragment\r\nfn main(input : FragmentInputs) -> FragmentOutputs {\r\n let p : vec2<i32> = vec2<i32>(i32(fragmentInputs.position.x), i32(fragmentInputs.position.y));\r\n let global : i32 = p.y * uniforms.uDestWidth + p.x;\r\n if (global < uniforms.uOffset || global >= uniforms.uOffset + uniforms.uCount) {\r\n discard;\r\n }\r\n let k : i32 = global - uniforms.uOffset;\r\n let src : vec2<i32> = vec2<i32>(k - (k / uniforms.uSrcWidth) * uniforms.uSrcWidth, k / uniforms.uSrcWidth);\r\n\r\n let mL : vec3<f32> = textureLoad(sogMeansLTex, src, 0).xyz;\r\n let mU : vec3<f32> = textureLoad(sogMeansUTex, src, 0).xyz;\r\n let sRaw : vec3<f32> = textureLoad(sogScalesTex, src, 0).xyz;\r\n let qRaw : vec4<f32> = textureLoad(sogQuatsTex, src, 0);\r\n let c0 : vec4<f32> = textureLoad(sogSh0Tex, src, 0);\r\n\r\n let q16 : vec3<f32> = (mU * 256.0 + mL) * (255.0 / 65535.0);\r\n let nPos : vec3<f32> = mix(uniforms.sogMeansMin, uniforms.sogMeansMax, q16);\r\n let center : vec3<f32> = sign(nPos) * (exp(abs(nPos)) - vec3<f32>(1.0));\r\n\r\n var splatScale : vec3<f32>;\r\n if (uniforms.uVersion == 2) {\r\n let sIdx : vec3<f32> = floor(sRaw * 255.0 + 0.5);\r\n splatScale.x = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.x), 0), 0).r);\r\n splatScale.y = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.y), 0), 0).r);\r\n splatScale.z = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.z), 0), 0).r);\r\n } else {\r\n splatScale = exp(mix(uniforms.sogScalesMin, uniforms.sogScalesMax, sRaw));\r\n }\r\n\r\n let invSqrt2 : f32 = 0.70710678118;\r\n let qabc : vec3<f32> = (qRaw.xyz - vec3<f32>(0.5)) * 2.0 * invSqrt2;\r\n let qMode : i32 = i32(qRaw.w * 255.0 + 0.5) - 252;\r\n let qd : f32 = sqrt(max(0.0, 1.0 - dot(qabc, qabc)));\r\n var quat : vec4<f32>;\r\n if (qMode == 0) {\r\n quat = vec4<f32>(qd, qabc.x, qabc.y, qabc.z);\r\n } else if (qMode == 1) {\r\n quat = vec4<f32>(qabc.x, qd, qabc.y, qabc.z);\r\n } else if (qMode == 2) {\r\n quat = vec4<f32>(qabc.x, qabc.y, qd, qabc.z);\r\n } else {\r\n quat = vec4<f32>(qabc.x, qabc.y, qabc.z, qd);\r\n }\r\n\r\n let qw : f32 = quat.x;\r\n let qx : f32 = quat.y;\r\n let qy : f32 = quat.z;\r\n let qz : f32 = quat.w;\r\n let R : mat3x3<f32> = mat3x3<f32>(\r\n 1.0 - 2.0 * (qy * qy + qz * qz), 2.0 * (qx * qy + qw * qz), 2.0 * (qx * qz - qw * qy),\r\n 2.0 * (qx * qy - qw * qz), 1.0 - 2.0 * (qx * qx + qz * qz), 2.0 * (qy * qz + qw * qx),\r\n 2.0 * (qx * qz + qw * qy), 2.0 * (qy * qz - qw * qx), 1.0 - 2.0 * (qx * qx + qy * qy)\r\n );\r\n let S2 : mat3x3<f32> = mat3x3<f32>(\r\n 4.0 * splatScale.x * splatScale.x, 0.0, 0.0,\r\n 0.0, 4.0 * splatScale.y * splatScale.y, 0.0,\r\n 0.0, 0.0, 4.0 * splatScale.z * splatScale.z\r\n );\r\n let Sigma : mat3x3<f32> = R * S2 * transpose(R);\r\n\r\n let SH_C0 : f32 = 0.28209479177387814;\r\n var colRgb : vec3<f32>;\r\n var colA : f32;\r\n if (uniforms.uVersion == 2) {\r\n var c3 : vec3<f32>;\r\n c3.x = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.x * 255.0 + 0.5), 0), 0).r;\r\n c3.y = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.y * 255.0 + 0.5), 0), 0).r;\r\n c3.z = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.z * 255.0 + 0.5), 0), 0).r;\r\n colRgb = vec3<f32>(0.5) + c3 * SH_C0;\r\n colA = c0.w;\r\n } else {\r\n let cLerp : vec4<f32> = mix(uniforms.sogSh0Min, uniforms.sogSh0Max, c0);\r\n colRgb = vec3<f32>(0.5) + cLerp.xyz * SH_C0;\r\n colA = 1.0 / (1.0 + exp(-cLerp.w));\r\n }\r\n\r\n fragmentOutputs.fragData0 = vec4<f32>(center, 1.0);\r\n fragmentOutputs.fragData1 = vec4<f32>(Sigma[0][0], Sigma[0][1], Sigma[0][2], Sigma[1][1]);\r\n fragmentOutputs.fragData2 = vec4<f32>(Sigma[1][2], Sigma[2][2], 0.0, 0.0);\r\n fragmentOutputs.fragData3 = vec4<f32>(colRgb, colA);\r\n}\r\n`;\r\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplattingWorkBufferShaders.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingWorkBufferShaders.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,yBAAyB,CAAC;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,2CAA2C,GAAG;;;;;CAK1D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,6CAA6C,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8G5D,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,2CAA2C,GAAG;;;;;;CAM1D,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,6CAA6C,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4G5D,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,6CAA6C,GAAG,sBAAsB,CAAC;AAEpF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qDAAqD,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCpE,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,qDAAqD,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCpE,CAAC","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Shared shader names for the SOG -> decoded work-buffer copy pass.\r\n */\r\nexport const GaussianSplattingWorkBufferShaderName = \"gsSogDecodeToWorkBuffer\";\r\n\r\n/**\r\n * Pass-through vertex shader (GLSL): the geometry is a fullscreen triangle already in NDC.\r\n */\r\nexport const GaussianSplattingWorkBufferVertexShaderGLSL = `precision highp float;\r\nattribute vec3 position;\r\nvoid main() {\r\n gl_Position = vec4(position.xy, 0.0, 1.0);\r\n}\r\n`;\r\n\r\n/**\r\n * Fragment shader (GLSL/WebGL2): decodes one SOG source file into the decoded GS work-buffer layout,\r\n * writing each splat into its allocated pixel. Mirrors the USE_SOG decode in ShadersInclude/gaussianSplatting.fx\r\n * but outputs the decoded MRT (center, covA, covB, color) consumed by the standard (non-SOG) draw path.\r\n *\r\n * MRT layout: 0 = center (x,y,z,1), 1 = covA (Sigma00,01,02,11), 2 = covB (Sigma12,22,0,0), 3 = color (rgba).\r\n */\r\nexport const GaussianSplattingWorkBufferFragmentShaderGLSL = `precision highp float;\r\nprecision highp int;\r\n\r\nuniform sampler2D sogMeansLTex;\r\nuniform sampler2D sogMeansUTex;\r\nuniform sampler2D sogScalesTex;\r\nuniform sampler2D sogQuatsTex;\r\nuniform sampler2D sogSh0Tex;\r\nuniform sampler2D sogCodebookTex;\r\n\r\nuniform vec3 sogMeansMin;\r\nuniform vec3 sogMeansMax;\r\nuniform vec3 sogScalesMin;\r\nuniform vec3 sogScalesMax;\r\nuniform vec4 sogSh0Min;\r\nuniform vec4 sogSh0Max;\r\nuniform int uVersion;\r\nuniform int uOffset;\r\nuniform int uCount;\r\nuniform int uDestWidth;\r\nuniform int uSrcWidth;\r\n\r\nlayout(location = 0) out vec4 glFragData[4];\r\n\r\nmat3 transposeM(mat3 m) {\r\n return mat3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);\r\n}\r\n\r\nvoid main() {\r\n ivec2 p = ivec2(gl_FragCoord.xy);\r\n int global = p.y * uDestWidth + p.x;\r\n if (global < uOffset || global >= uOffset + uCount) {\r\n discard;\r\n }\r\n int k = global - uOffset;\r\n ivec2 src = ivec2(k - (k / uSrcWidth) * uSrcWidth, k / uSrcWidth);\r\n\r\n vec3 mL = texelFetch(sogMeansLTex, src, 0).xyz;\r\n vec3 mU = texelFetch(sogMeansUTex, src, 0).xyz;\r\n vec3 sRaw = texelFetch(sogScalesTex, src, 0).xyz;\r\n vec4 qRaw = texelFetch(sogQuatsTex, src, 0);\r\n vec4 c0 = texelFetch(sogSh0Tex, src, 0);\r\n\r\n // Position: q16 = (u<<8)|l normalized; n = lerp(min,max,q16); pos = sign(n)*(exp(|n|)-1)\r\n vec3 q16 = (mU * 256.0 + mL) * (255.0 / 65535.0);\r\n vec3 nPos = mix(sogMeansMin, sogMeansMax, q16);\r\n vec3 center = sign(nPos) * (exp(abs(nPos)) - vec3(1.0));\r\n\r\n // Scale (v1: lerp+exp ; v2: codebook lookup)\r\n vec3 splatScale;\r\n if (uVersion == 2) {\r\n vec3 sIdx = floor(sRaw * 255.0 + 0.5);\r\n splatScale.x = exp(texelFetch(sogCodebookTex, ivec2(int(sIdx.x), 0), 0).r);\r\n splatScale.y = exp(texelFetch(sogCodebookTex, ivec2(int(sIdx.y), 0), 0).r);\r\n splatScale.z = exp(texelFetch(sogCodebookTex, ivec2(int(sIdx.z), 0), 0).r);\r\n } else {\r\n splatScale = exp(mix(sogScalesMin, sogScalesMax, sRaw));\r\n }\r\n\r\n // Quaternion (largest-omitted, mode in alpha as 252 + omitted-index)\r\n const float invSqrt2 = 0.70710678118;\r\n vec3 qabc = (qRaw.xyz - vec3(0.5)) * 2.0 * invSqrt2;\r\n int qMode = int(qRaw.w * 255.0 + 0.5) - 252;\r\n float qd = sqrt(max(0.0, 1.0 - dot(qabc, qabc)));\r\n vec4 quat;\r\n if (qMode == 0) {\r\n quat = vec4(qd, qabc.x, qabc.y, qabc.z);\r\n } else if (qMode == 1) {\r\n quat = vec4(qabc.x, qd, qabc.y, qabc.z);\r\n } else if (qMode == 2) {\r\n quat = vec4(qabc.x, qabc.y, qd, qabc.z);\r\n } else {\r\n quat = vec4(qabc.x, qabc.y, qabc.z, qd);\r\n }\r\n\r\n float qw = quat.x, qx = quat.y, qy = quat.z, qz = quat.w;\r\n mat3 R = mat3(\r\n 1.0 - 2.0 * (qy * qy + qz * qz), 2.0 * (qx * qy + qw * qz), 2.0 * (qx * qz - qw * qy),\r\n 2.0 * (qx * qy - qw * qz), 1.0 - 2.0 * (qx * qx + qz * qz), 2.0 * (qy * qz + qw * qx),\r\n 2.0 * (qx * qz + qw * qy), 2.0 * (qy * qz - qw * qx), 1.0 - 2.0 * (qx * qx + qy * qy)\r\n );\r\n mat3 S2 = mat3(\r\n 4.0 * splatScale.x * splatScale.x, 0.0, 0.0,\r\n 0.0, 4.0 * splatScale.y * splatScale.y, 0.0,\r\n 0.0, 0.0, 4.0 * splatScale.z * splatScale.z\r\n );\r\n mat3 Sigma = R * S2 * transposeM(R);\r\n\r\n // Color (sh0)\r\n const float SH_C0 = 0.28209479177387814;\r\n vec3 colRgb;\r\n float colA;\r\n if (uVersion == 2) {\r\n vec3 c3;\r\n c3.x = texelFetch(sogCodebookTex, ivec2(256 + int(c0.x * 255.0 + 0.5), 0), 0).r;\r\n c3.y = texelFetch(sogCodebookTex, ivec2(256 + int(c0.y * 255.0 + 0.5), 0), 0).r;\r\n c3.z = texelFetch(sogCodebookTex, ivec2(256 + int(c0.z * 255.0 + 0.5), 0), 0).r;\r\n colRgb = vec3(0.5) + c3 * SH_C0;\r\n colA = c0.w;\r\n } else {\r\n vec4 cLerp = mix(sogSh0Min, sogSh0Max, c0);\r\n colRgb = vec3(0.5) + cLerp.xyz * SH_C0;\r\n colA = 1.0 / (1.0 + exp(-cLerp.w));\r\n }\r\n\r\n glFragData[0] = vec4(center, 1.0);\r\n glFragData[1] = vec4(Sigma[0][0], Sigma[0][1], Sigma[0][2], Sigma[1][1]);\r\n glFragData[2] = vec4(Sigma[1][2], Sigma[2][2], 0.0, 0.0);\r\n glFragData[3] = vec4(colRgb, colA);\r\n}\r\n`;\r\n\r\n/**\r\n * Pass-through vertex shader (WGSL).\r\n */\r\nexport const GaussianSplattingWorkBufferVertexShaderWGSL = `\r\nattribute position : vec3<f32>;\r\n@vertex\r\nfn main(input : VertexInputs) -> FragmentInputs {\r\n vertexOutputs.position = vec4<f32>(input.position.xy, 0.0, 1.0);\r\n}\r\n`;\r\n\r\n/**\r\n * Fragment shader (WGSL/WebGPU) — same decode as the GLSL variant, writing 4 MRT attachments.\r\n */\r\nexport const GaussianSplattingWorkBufferFragmentShaderWGSL = `\r\nvar sogMeansLTexSampler : sampler;\r\nvar sogMeansLTex : texture_2d<f32>;\r\nvar sogMeansUTexSampler : sampler;\r\nvar sogMeansUTex : texture_2d<f32>;\r\nvar sogScalesTexSampler : sampler;\r\nvar sogScalesTex : texture_2d<f32>;\r\nvar sogQuatsTexSampler : sampler;\r\nvar sogQuatsTex : texture_2d<f32>;\r\nvar sogSh0TexSampler : sampler;\r\nvar sogSh0Tex : texture_2d<f32>;\r\nvar sogCodebookTexSampler : sampler;\r\nvar sogCodebookTex : texture_2d<f32>;\r\n\r\nuniform sogMeansMin : vec3<f32>;\r\nuniform sogMeansMax : vec3<f32>;\r\nuniform sogScalesMin : vec3<f32>;\r\nuniform sogScalesMax : vec3<f32>;\r\nuniform sogSh0Min : vec4<f32>;\r\nuniform sogSh0Max : vec4<f32>;\r\nuniform uVersion : i32;\r\nuniform uOffset : i32;\r\nuniform uCount : i32;\r\nuniform uDestWidth : i32;\r\nuniform uSrcWidth : i32;\r\n\r\n@fragment\r\nfn main(input : FragmentInputs) -> FragmentOutputs {\r\n let p : vec2<i32> = vec2<i32>(i32(fragmentInputs.position.x), i32(fragmentInputs.position.y));\r\n let global : i32 = p.y * uniforms.uDestWidth + p.x;\r\n if (global < uniforms.uOffset || global >= uniforms.uOffset + uniforms.uCount) {\r\n discard;\r\n }\r\n let k : i32 = global - uniforms.uOffset;\r\n let src : vec2<i32> = vec2<i32>(k - (k / uniforms.uSrcWidth) * uniforms.uSrcWidth, k / uniforms.uSrcWidth);\r\n\r\n let mL : vec3<f32> = textureLoad(sogMeansLTex, src, 0).xyz;\r\n let mU : vec3<f32> = textureLoad(sogMeansUTex, src, 0).xyz;\r\n let sRaw : vec3<f32> = textureLoad(sogScalesTex, src, 0).xyz;\r\n let qRaw : vec4<f32> = textureLoad(sogQuatsTex, src, 0);\r\n let c0 : vec4<f32> = textureLoad(sogSh0Tex, src, 0);\r\n\r\n let q16 : vec3<f32> = (mU * 256.0 + mL) * (255.0 / 65535.0);\r\n let nPos : vec3<f32> = mix(uniforms.sogMeansMin, uniforms.sogMeansMax, q16);\r\n let center : vec3<f32> = sign(nPos) * (exp(abs(nPos)) - vec3<f32>(1.0));\r\n\r\n var splatScale : vec3<f32>;\r\n if (uniforms.uVersion == 2) {\r\n let sIdx : vec3<f32> = floor(sRaw * 255.0 + 0.5);\r\n splatScale.x = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.x), 0), 0).r);\r\n splatScale.y = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.y), 0), 0).r);\r\n splatScale.z = exp(textureLoad(sogCodebookTex, vec2<i32>(i32(sIdx.z), 0), 0).r);\r\n } else {\r\n splatScale = exp(mix(uniforms.sogScalesMin, uniforms.sogScalesMax, sRaw));\r\n }\r\n\r\n let invSqrt2 : f32 = 0.70710678118;\r\n let qabc : vec3<f32> = (qRaw.xyz - vec3<f32>(0.5)) * 2.0 * invSqrt2;\r\n let qMode : i32 = i32(qRaw.w * 255.0 + 0.5) - 252;\r\n let qd : f32 = sqrt(max(0.0, 1.0 - dot(qabc, qabc)));\r\n var quat : vec4<f32>;\r\n if (qMode == 0) {\r\n quat = vec4<f32>(qd, qabc.x, qabc.y, qabc.z);\r\n } else if (qMode == 1) {\r\n quat = vec4<f32>(qabc.x, qd, qabc.y, qabc.z);\r\n } else if (qMode == 2) {\r\n quat = vec4<f32>(qabc.x, qabc.y, qd, qabc.z);\r\n } else {\r\n quat = vec4<f32>(qabc.x, qabc.y, qabc.z, qd);\r\n }\r\n\r\n let qw : f32 = quat.x;\r\n let qx : f32 = quat.y;\r\n let qy : f32 = quat.z;\r\n let qz : f32 = quat.w;\r\n let R : mat3x3<f32> = mat3x3<f32>(\r\n 1.0 - 2.0 * (qy * qy + qz * qz), 2.0 * (qx * qy + qw * qz), 2.0 * (qx * qz - qw * qy),\r\n 2.0 * (qx * qy - qw * qz), 1.0 - 2.0 * (qx * qx + qz * qz), 2.0 * (qy * qz + qw * qx),\r\n 2.0 * (qx * qz + qw * qy), 2.0 * (qy * qz - qw * qx), 1.0 - 2.0 * (qx * qx + qy * qy)\r\n );\r\n let S2 : mat3x3<f32> = mat3x3<f32>(\r\n 4.0 * splatScale.x * splatScale.x, 0.0, 0.0,\r\n 0.0, 4.0 * splatScale.y * splatScale.y, 0.0,\r\n 0.0, 0.0, 4.0 * splatScale.z * splatScale.z\r\n );\r\n let Sigma : mat3x3<f32> = R * S2 * transpose(R);\r\n\r\n let SH_C0 : f32 = 0.28209479177387814;\r\n var colRgb : vec3<f32>;\r\n var colA : f32;\r\n if (uniforms.uVersion == 2) {\r\n var c3 : vec3<f32>;\r\n c3.x = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.x * 255.0 + 0.5), 0), 0).r;\r\n c3.y = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.y * 255.0 + 0.5), 0), 0).r;\r\n c3.z = textureLoad(sogCodebookTex, vec2<i32>(256 + i32(c0.z * 255.0 + 0.5), 0), 0).r;\r\n colRgb = vec3<f32>(0.5) + c3 * SH_C0;\r\n colA = c0.w;\r\n } else {\r\n let cLerp : vec4<f32> = mix(uniforms.sogSh0Min, uniforms.sogSh0Max, c0);\r\n colRgb = vec3<f32>(0.5) + cLerp.xyz * SH_C0;\r\n colA = 1.0 / (1.0 + exp(-cLerp.w));\r\n }\r\n\r\n fragmentOutputs.fragData0 = vec4<f32>(center, 1.0);\r\n fragmentOutputs.fragData1 = vec4<f32>(Sigma[0][0], Sigma[0][1], Sigma[0][2], Sigma[1][1]);\r\n fragmentOutputs.fragData2 = vec4<f32>(Sigma[1][2], Sigma[2][2], 0.0, 0.0);\r\n fragmentOutputs.fragData3 = vec4<f32>(colRgb, colA);\r\n}\r\n`;\r\n\r\n/**\r\n * Shader name for the work-buffer relayout (defrag/compaction) copy pass.\r\n */\r\nexport const GaussianSplattingWorkBufferRelayoutShaderName = \"gsWorkBufferRelayout\";\r\n\r\n/**\r\n * Relayout copy fragment shader (GLSL/WebGL2). Copies the four decoded work-buffer textures from a source\r\n * layout to a destination layout, one output texel per draw. In map mode (`uUseMap == 1`) each destination\r\n * texel reads its source splat index from `uMapTex` (R32F; a negative value marks a gap and is discarded so\r\n * the cleared destination stays zero). In identity mode the source texel equals the destination texel.\r\n */\r\nexport const GaussianSplattingWorkBufferRelayoutFragmentShaderGLSL = `precision highp float;\r\nprecision highp int;\r\n\r\nuniform sampler2D uMapTex;\r\nuniform sampler2D uSrc0;\r\nuniform sampler2D uSrc1;\r\nuniform sampler2D uSrc2;\r\nuniform sampler2D uSrc3;\r\nuniform int uDstWidth;\r\nuniform int uSrcWidth;\r\nuniform int uUseMap;\r\n\r\nlayout(location = 0) out vec4 glFragData[4];\r\n\r\nvoid main() {\r\n ivec2 p = ivec2(gl_FragCoord.xy);\r\n int srcIdx;\r\n if (uUseMap == 1) {\r\n float m = texelFetch(uMapTex, p, 0).r;\r\n if (m < 0.0) {\r\n discard;\r\n }\r\n srcIdx = int(m + 0.5);\r\n } else {\r\n srcIdx = p.y * uDstWidth + p.x;\r\n }\r\n ivec2 s = ivec2(srcIdx - (srcIdx / uSrcWidth) * uSrcWidth, srcIdx / uSrcWidth);\r\n glFragData[0] = texelFetch(uSrc0, s, 0);\r\n glFragData[1] = texelFetch(uSrc1, s, 0);\r\n glFragData[2] = texelFetch(uSrc2, s, 0);\r\n glFragData[3] = texelFetch(uSrc3, s, 0);\r\n}\r\n`;\r\n\r\n/**\r\n * Relayout copy fragment shader (WGSL/WebGPU) — same copy as the GLSL variant.\r\n */\r\nexport const GaussianSplattingWorkBufferRelayoutFragmentShaderWGSL = `\r\nvar uMapTexSampler : sampler;\r\nvar uMapTex : texture_2d<f32>;\r\nvar uSrc0Sampler : sampler;\r\nvar uSrc0 : texture_2d<f32>;\r\nvar uSrc1Sampler : sampler;\r\nvar uSrc1 : texture_2d<f32>;\r\nvar uSrc2Sampler : sampler;\r\nvar uSrc2 : texture_2d<f32>;\r\nvar uSrc3Sampler : sampler;\r\nvar uSrc3 : texture_2d<f32>;\r\n\r\nuniform uDstWidth : i32;\r\nuniform uSrcWidth : i32;\r\nuniform uUseMap : i32;\r\n\r\n@fragment\r\nfn main(input : FragmentInputs) -> FragmentOutputs {\r\n let p : vec2<i32> = vec2<i32>(i32(fragmentInputs.position.x), i32(fragmentInputs.position.y));\r\n var srcIdx : i32;\r\n if (uniforms.uUseMap == 1) {\r\n let m : f32 = textureLoad(uMapTex, p, 0).r;\r\n if (m < 0.0) {\r\n discard;\r\n }\r\n srcIdx = i32(m + 0.5);\r\n } else {\r\n srcIdx = p.y * uniforms.uDstWidth + p.x;\r\n }\r\n let s : vec2<i32> = vec2<i32>(srcIdx - (srcIdx / uniforms.uSrcWidth) * uniforms.uSrcWidth, srcIdx / uniforms.uSrcWidth);\r\n fragmentOutputs.fragData0 = textureLoad(uSrc0, s, 0);\r\n fragmentOutputs.fragData1 = textureLoad(uSrc1, s, 0);\r\n fragmentOutputs.fragData2 = textureLoad(uSrc2, s, 0);\r\n fragmentOutputs.fragData3 = textureLoad(uSrc3, s, 0);\r\n}\r\n`;\r\n"]}
|
package/SPLAT/pure.d.ts
ADDED
package/SPLAT/pure.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Pure barrel — re-exports only side-effect-free modules */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-restricted-imports */
|
|
3
|
+
export * from "./splatLoadingOptions.js";
|
|
4
|
+
export * from "./splatFileLoader.pure.js";
|
|
5
|
+
export * from "./gaussianSplattingStream.js";
|
|
6
|
+
export * from "./sog.pure.js";
|
|
7
|
+
//# sourceMappingURL=pure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pure.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,6DAA6D;AAC7D,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC","sourcesContent":["/** Pure barrel — re-exports only side-effect-free modules */\n/* eslint-disable @typescript-eslint/no-restricted-imports */\nexport * from \"./splatLoadingOptions\";\nexport * from \"./splatFileLoader.pure\";\nexport * from \"./gaussianSplattingStream\";\nexport * from \"./sog.pure\";\n"]}
|