@babylonjs/loaders 9.13.0 → 9.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/BVH/bvhFileLoader.d.ts +4 -67
  2. package/BVH/bvhFileLoader.js +6 -130
  3. package/BVH/bvhFileLoader.js.map +1 -1
  4. package/BVH/bvhFileLoader.pure.d.ts +75 -0
  5. package/BVH/bvhFileLoader.pure.js +154 -0
  6. package/BVH/bvhFileLoader.pure.js.map +1 -0
  7. package/BVH/bvhFileLoader.types.d.ts +11 -0
  8. package/BVH/bvhFileLoader.types.js +2 -0
  9. package/BVH/bvhFileLoader.types.js.map +1 -0
  10. package/BVH/pure.d.ts +3 -0
  11. package/BVH/pure.js +5 -0
  12. package/BVH/pure.js.map +1 -0
  13. package/FBX/fbxFileLoader.d.ts +4 -192
  14. package/FBX/fbxFileLoader.js +6 -2437
  15. package/FBX/fbxFileLoader.js.map +1 -1
  16. package/FBX/fbxFileLoader.pure.d.ts +190 -0
  17. package/FBX/fbxFileLoader.pure.js +2451 -0
  18. package/FBX/fbxFileLoader.pure.js.map +1 -0
  19. package/FBX/fbxFileLoader.types.d.ts +11 -0
  20. package/FBX/fbxFileLoader.types.js +2 -0
  21. package/FBX/fbxFileLoader.types.js.map +1 -0
  22. package/FBX/pure.d.ts +3 -0
  23. package/FBX/pure.js +4 -0
  24. package/FBX/pure.js.map +1 -0
  25. package/OBJ/objFileLoader.d.ts +4 -134
  26. package/OBJ/objFileLoader.js +6 -315
  27. package/OBJ/objFileLoader.js.map +1 -1
  28. package/OBJ/objFileLoader.pure.d.ts +132 -0
  29. package/OBJ/objFileLoader.pure.js +329 -0
  30. package/OBJ/objFileLoader.pure.js.map +1 -0
  31. package/OBJ/objFileLoader.types.d.ts +11 -0
  32. package/OBJ/objFileLoader.types.js +2 -0
  33. package/OBJ/objFileLoader.types.js.map +1 -0
  34. package/OBJ/pure.d.ts +5 -0
  35. package/OBJ/pure.js +6 -0
  36. package/OBJ/pure.js.map +1 -0
  37. package/OBJ/solidParser.js +4 -3
  38. package/OBJ/solidParser.js.map +1 -1
  39. package/SPLAT/gaussianSplattingBlockAllocator.d.ts +137 -0
  40. package/SPLAT/gaussianSplattingBlockAllocator.js +555 -0
  41. package/SPLAT/gaussianSplattingBlockAllocator.js.map +1 -0
  42. package/SPLAT/gaussianSplattingDownloadManager.d.ts +109 -0
  43. package/SPLAT/gaussianSplattingDownloadManager.js +241 -0
  44. package/SPLAT/gaussianSplattingDownloadManager.js.map +1 -0
  45. package/SPLAT/gaussianSplattingResidencyController.d.ts +133 -0
  46. package/SPLAT/gaussianSplattingResidencyController.js +222 -0
  47. package/SPLAT/gaussianSplattingResidencyController.js.map +1 -0
  48. package/SPLAT/gaussianSplattingStream.d.ts +122 -4
  49. package/SPLAT/gaussianSplattingStream.js +413 -42
  50. package/SPLAT/gaussianSplattingStream.js.map +1 -1
  51. package/SPLAT/gaussianSplattingWorkBuffer.d.ts +36 -0
  52. package/SPLAT/gaussianSplattingWorkBuffer.js +125 -13
  53. package/SPLAT/gaussianSplattingWorkBuffer.js.map +1 -1
  54. package/SPLAT/gaussianSplattingWorkBufferShaders.d.ts +15 -0
  55. package/SPLAT/gaussianSplattingWorkBufferShaders.js +82 -0
  56. package/SPLAT/gaussianSplattingWorkBufferShaders.js.map +1 -1
  57. package/SPLAT/pure.d.ts +5 -0
  58. package/SPLAT/pure.js +7 -0
  59. package/SPLAT/pure.js.map +1 -0
  60. package/SPLAT/sog.d.ts +1 -97
  61. package/SPLAT/sog.js +1 -501
  62. package/SPLAT/sog.js.map +1 -1
  63. package/SPLAT/sog.pure.d.ts +102 -0
  64. package/SPLAT/sog.pure.js +514 -0
  65. package/SPLAT/sog.pure.js.map +1 -0
  66. package/SPLAT/splatFileLoader.d.ts +5 -106
  67. package/SPLAT/splatFileLoader.js +9 -636
  68. package/SPLAT/splatFileLoader.js.map +1 -1
  69. package/SPLAT/splatFileLoader.pure.d.ts +104 -0
  70. package/SPLAT/splatFileLoader.pure.js +650 -0
  71. package/SPLAT/splatFileLoader.pure.js.map +1 -0
  72. package/SPLAT/splatFileLoader.types.d.ts +11 -0
  73. package/SPLAT/splatFileLoader.types.js +2 -0
  74. package/SPLAT/splatFileLoader.types.js.map +1 -0
  75. package/STL/pure.d.ts +2 -0
  76. package/STL/pure.js +3 -0
  77. package/STL/pure.js.map +1 -0
  78. package/STL/stlFileLoader.d.ts +5 -76
  79. package/STL/stlFileLoader.js +7 -236
  80. package/STL/stlFileLoader.js.map +1 -1
  81. package/STL/stlFileLoader.pure.d.ts +73 -0
  82. package/STL/stlFileLoader.pure.js +249 -0
  83. package/STL/stlFileLoader.pure.js.map +1 -0
  84. package/STL/stlFileLoader.types.d.ts +10 -0
  85. package/STL/stlFileLoader.types.js +2 -0
  86. package/STL/stlFileLoader.types.js.map +1 -0
  87. package/glTF/1.0/pure.d.ts +3 -0
  88. package/glTF/1.0/pure.js +4 -0
  89. package/glTF/1.0/pure.js.map +1 -0
  90. package/glTF/2.0/Extensions/EXT_lights_area.d.ts +4 -39
  91. package/glTF/2.0/Extensions/EXT_lights_area.js +6 -91
  92. package/glTF/2.0/Extensions/EXT_lights_area.js.map +1 -1
  93. package/glTF/2.0/Extensions/EXT_lights_area.pure.d.ts +38 -0
  94. package/glTF/2.0/Extensions/EXT_lights_area.pure.js +106 -0
  95. package/glTF/2.0/Extensions/EXT_lights_area.pure.js.map +1 -0
  96. package/glTF/2.0/Extensions/EXT_lights_area.types.d.ts +9 -0
  97. package/glTF/2.0/Extensions/EXT_lights_area.types.js +2 -0
  98. package/glTF/2.0/Extensions/EXT_lights_area.types.js.map +1 -0
  99. package/glTF/2.0/Extensions/EXT_lights_ies.d.ts +4 -39
  100. package/glTF/2.0/Extensions/EXT_lights_ies.js +6 -81
  101. package/glTF/2.0/Extensions/EXT_lights_ies.js.map +1 -1
  102. package/glTF/2.0/Extensions/EXT_lights_ies.pure.d.ts +38 -0
  103. package/glTF/2.0/Extensions/EXT_lights_ies.pure.js +96 -0
  104. package/glTF/2.0/Extensions/EXT_lights_ies.pure.js.map +1 -0
  105. package/glTF/2.0/Extensions/EXT_lights_ies.types.d.ts +9 -0
  106. package/glTF/2.0/Extensions/EXT_lights_ies.types.js +2 -0
  107. package/glTF/2.0/Extensions/EXT_lights_ies.types.js.map +1 -0
  108. package/glTF/2.0/Extensions/EXT_lights_image_based.d.ts +4 -46
  109. package/glTF/2.0/Extensions/EXT_lights_image_based.js +6 -113
  110. package/glTF/2.0/Extensions/EXT_lights_image_based.js.map +1 -1
  111. package/glTF/2.0/Extensions/EXT_lights_image_based.pure.d.ts +37 -0
  112. package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js +128 -0
  113. package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js.map +1 -0
  114. package/glTF/2.0/Extensions/EXT_lights_image_based.types.d.ts +17 -0
  115. package/glTF/2.0/Extensions/EXT_lights_image_based.types.js +2 -0
  116. package/glTF/2.0/Extensions/EXT_lights_image_based.types.js.map +1 -0
  117. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.d.ts +5 -37
  118. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +7 -92
  119. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
  120. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.d.ts +35 -0
  121. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js +106 -0
  122. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js.map +1 -0
  123. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.d.ts +9 -0
  124. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js +2 -0
  125. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js.map +1 -0
  126. package/glTF/2.0/Extensions/EXT_meshopt_compression.d.ts +4 -37
  127. package/glTF/2.0/Extensions/EXT_meshopt_compression.js +6 -48
  128. package/glTF/2.0/Extensions/EXT_meshopt_compression.js.map +1 -1
  129. package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.d.ts +36 -0
  130. package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js +63 -0
  131. package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js.map +1 -0
  132. package/glTF/2.0/Extensions/EXT_meshopt_compression.types.d.ts +9 -0
  133. package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js +2 -0
  134. package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js.map +1 -0
  135. package/glTF/2.0/Extensions/EXT_texture_avif.d.ts +4 -32
  136. package/glTF/2.0/Extensions/EXT_texture_avif.js +6 -36
  137. package/glTF/2.0/Extensions/EXT_texture_avif.js.map +1 -1
  138. package/glTF/2.0/Extensions/EXT_texture_avif.pure.d.ts +31 -0
  139. package/glTF/2.0/Extensions/EXT_texture_avif.pure.js +51 -0
  140. package/glTF/2.0/Extensions/EXT_texture_avif.pure.js.map +1 -0
  141. package/glTF/2.0/Extensions/EXT_texture_avif.types.d.ts +9 -0
  142. package/glTF/2.0/Extensions/EXT_texture_avif.types.js +2 -0
  143. package/glTF/2.0/Extensions/EXT_texture_avif.types.js.map +1 -0
  144. package/glTF/2.0/Extensions/EXT_texture_webp.d.ts +4 -31
  145. package/glTF/2.0/Extensions/EXT_texture_webp.js +6 -35
  146. package/glTF/2.0/Extensions/EXT_texture_webp.js.map +1 -1
  147. package/glTF/2.0/Extensions/EXT_texture_webp.pure.d.ts +30 -0
  148. package/glTF/2.0/Extensions/EXT_texture_webp.pure.js +50 -0
  149. package/glTF/2.0/Extensions/EXT_texture_webp.pure.js.map +1 -0
  150. package/glTF/2.0/Extensions/EXT_texture_webp.types.d.ts +9 -0
  151. package/glTF/2.0/Extensions/EXT_texture_webp.types.js +2 -0
  152. package/glTF/2.0/Extensions/EXT_texture_webp.types.js.map +1 -0
  153. package/glTF/2.0/Extensions/ExtrasAsMetadata.d.ts +4 -51
  154. package/glTF/2.0/Extensions/ExtrasAsMetadata.js +6 -71
  155. package/glTF/2.0/Extensions/ExtrasAsMetadata.js.map +1 -1
  156. package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.d.ts +50 -0
  157. package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js +85 -0
  158. package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js.map +1 -0
  159. package/glTF/2.0/Extensions/ExtrasAsMetadata.types.d.ts +9 -0
  160. package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js +2 -0
  161. package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js.map +1 -0
  162. package/glTF/2.0/Extensions/KHR_animation_pointer.d.ts +5 -45
  163. package/glTF/2.0/Extensions/KHR_animation_pointer.js +7 -75
  164. package/glTF/2.0/Extensions/KHR_animation_pointer.js.map +1 -1
  165. package/glTF/2.0/Extensions/KHR_animation_pointer.pure.d.ts +43 -0
  166. package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js +89 -0
  167. package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js.map +1 -0
  168. package/glTF/2.0/Extensions/KHR_animation_pointer.types.d.ts +9 -0
  169. package/glTF/2.0/Extensions/KHR_animation_pointer.types.js +2 -0
  170. package/glTF/2.0/Extensions/KHR_animation_pointer.types.js.map +1 -0
  171. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.d.ts +4 -45
  172. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js +6 -90
  173. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js.map +1 -1
  174. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.d.ts +44 -0
  175. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js +105 -0
  176. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js.map +1 -0
  177. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.d.ts +9 -0
  178. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js +2 -0
  179. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js.map +1 -0
  180. package/glTF/2.0/Extensions/KHR_interactivity/pure.d.ts +4 -0
  181. package/glTF/2.0/Extensions/KHR_interactivity/pure.js +5 -0
  182. package/glTF/2.0/Extensions/KHR_interactivity/pure.js.map +1 -0
  183. package/glTF/2.0/Extensions/KHR_interactivity.d.ts +4 -36
  184. package/glTF/2.0/Extensions/KHR_interactivity.js +6 -148
  185. package/glTF/2.0/Extensions/KHR_interactivity.js.map +1 -1
  186. package/glTF/2.0/Extensions/KHR_interactivity.pure.d.ts +35 -0
  187. package/glTF/2.0/Extensions/KHR_interactivity.pure.js +163 -0
  188. package/glTF/2.0/Extensions/KHR_interactivity.pure.js.map +1 -0
  189. package/glTF/2.0/Extensions/KHR_interactivity.types.d.ts +9 -0
  190. package/glTF/2.0/Extensions/KHR_interactivity.types.js +2 -0
  191. package/glTF/2.0/Extensions/KHR_interactivity.types.js.map +1 -0
  192. package/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +4 -39
  193. package/glTF/2.0/Extensions/KHR_lights_punctual.js +6 -89
  194. package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
  195. package/glTF/2.0/Extensions/KHR_lights_punctual.pure.d.ts +38 -0
  196. package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js +104 -0
  197. package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js.map +1 -0
  198. package/glTF/2.0/Extensions/KHR_lights_punctual.types.d.ts +9 -0
  199. package/glTF/2.0/Extensions/KHR_lights_punctual.types.js +2 -0
  200. package/glTF/2.0/Extensions/KHR_lights_punctual.types.js.map +1 -0
  201. package/glTF/2.0/Extensions/KHR_materials_anisotropy.d.ts +4 -40
  202. package/glTF/2.0/Extensions/KHR_materials_anisotropy.js +6 -63
  203. package/glTF/2.0/Extensions/KHR_materials_anisotropy.js.map +1 -1
  204. package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.d.ts +39 -0
  205. package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js +78 -0
  206. package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js.map +1 -0
  207. package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.d.ts +9 -0
  208. package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js +2 -0
  209. package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js.map +1 -0
  210. package/glTF/2.0/Extensions/KHR_materials_clearcoat.d.ts +4 -41
  211. package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +6 -77
  212. package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
  213. package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.d.ts +40 -0
  214. package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js +92 -0
  215. package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js.map +1 -0
  216. package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.d.ts +9 -0
  217. package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js +2 -0
  218. package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js.map +1 -0
  219. package/glTF/2.0/Extensions/KHR_materials_coat.d.ts +4 -47
  220. package/glTF/2.0/Extensions/KHR_materials_coat.js +6 -117
  221. package/glTF/2.0/Extensions/KHR_materials_coat.js.map +1 -1
  222. package/glTF/2.0/Extensions/KHR_materials_coat.pure.d.ts +46 -0
  223. package/glTF/2.0/Extensions/KHR_materials_coat.pure.js +132 -0
  224. package/glTF/2.0/Extensions/KHR_materials_coat.pure.js.map +1 -0
  225. package/glTF/2.0/Extensions/KHR_materials_coat.types.d.ts +9 -0
  226. package/glTF/2.0/Extensions/KHR_materials_coat.types.js +2 -0
  227. package/glTF/2.0/Extensions/KHR_materials_coat.types.js.map +1 -0
  228. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.d.ts +4 -41
  229. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js +6 -56
  230. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js.map +1 -1
  231. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.d.ts +40 -0
  232. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js +71 -0
  233. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js.map +1 -0
  234. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.d.ts +9 -0
  235. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js +2 -0
  236. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js.map +1 -0
  237. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.d.ts +4 -41
  238. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js +6 -71
  239. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js.map +1 -1
  240. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.d.ts +40 -0
  241. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js +86 -0
  242. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js.map +1 -0
  243. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.d.ts +9 -0
  244. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js +2 -0
  245. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js.map +1 -0
  246. package/glTF/2.0/Extensions/KHR_materials_dispersion.d.ts +4 -41
  247. package/glTF/2.0/Extensions/KHR_materials_dispersion.js +6 -54
  248. package/glTF/2.0/Extensions/KHR_materials_dispersion.js.map +1 -1
  249. package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.d.ts +40 -0
  250. package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js +69 -0
  251. package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js.map +1 -0
  252. package/glTF/2.0/Extensions/KHR_materials_dispersion.types.d.ts +9 -0
  253. package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js +2 -0
  254. package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js.map +1 -0
  255. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.d.ts +4 -40
  256. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js +6 -45
  257. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js.map +1 -1
  258. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.d.ts +39 -0
  259. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js +60 -0
  260. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js.map +1 -0
  261. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.d.ts +9 -0
  262. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js +2 -0
  263. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js.map +1 -0
  264. package/glTF/2.0/Extensions/KHR_materials_fuzz.d.ts +4 -41
  265. package/glTF/2.0/Extensions/KHR_materials_fuzz.js +6 -75
  266. package/glTF/2.0/Extensions/KHR_materials_fuzz.js.map +1 -1
  267. package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.d.ts +40 -0
  268. package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js +90 -0
  269. package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js.map +1 -0
  270. package/glTF/2.0/Extensions/KHR_materials_fuzz.types.d.ts +9 -0
  271. package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js +2 -0
  272. package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js.map +1 -0
  273. package/glTF/2.0/Extensions/KHR_materials_ior.d.ts +4 -44
  274. package/glTF/2.0/Extensions/KHR_materials_ior.js +6 -52
  275. package/glTF/2.0/Extensions/KHR_materials_ior.js.map +1 -1
  276. package/glTF/2.0/Extensions/KHR_materials_ior.pure.d.ts +43 -0
  277. package/glTF/2.0/Extensions/KHR_materials_ior.pure.js +67 -0
  278. package/glTF/2.0/Extensions/KHR_materials_ior.pure.js.map +1 -0
  279. package/glTF/2.0/Extensions/KHR_materials_ior.types.d.ts +9 -0
  280. package/glTF/2.0/Extensions/KHR_materials_ior.types.js +2 -0
  281. package/glTF/2.0/Extensions/KHR_materials_ior.types.js.map +1 -0
  282. package/glTF/2.0/Extensions/KHR_materials_iridescence.d.ts +4 -40
  283. package/glTF/2.0/Extensions/KHR_materials_iridescence.js +6 -66
  284. package/glTF/2.0/Extensions/KHR_materials_iridescence.js.map +1 -1
  285. package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.d.ts +39 -0
  286. package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js +81 -0
  287. package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js.map +1 -0
  288. package/glTF/2.0/Extensions/KHR_materials_iridescence.types.d.ts +9 -0
  289. package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js +2 -0
  290. package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js.map +1 -0
  291. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.d.ts +4 -40
  292. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js +6 -72
  293. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js.map +1 -1
  294. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.d.ts +39 -0
  295. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js +87 -0
  296. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js.map +1 -0
  297. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.d.ts +9 -0
  298. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js +2 -0
  299. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js.map +1 -0
  300. package/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +4 -41
  301. package/glTF/2.0/Extensions/KHR_materials_sheen.js +6 -71
  302. package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
  303. package/glTF/2.0/Extensions/KHR_materials_sheen.pure.d.ts +40 -0
  304. package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js +86 -0
  305. package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js.map +1 -0
  306. package/glTF/2.0/Extensions/KHR_materials_sheen.types.d.ts +9 -0
  307. package/glTF/2.0/Extensions/KHR_materials_sheen.types.js +2 -0
  308. package/glTF/2.0/Extensions/KHR_materials_sheen.types.js.map +1 -0
  309. package/glTF/2.0/Extensions/KHR_materials_specular.d.ts +4 -40
  310. package/glTF/2.0/Extensions/KHR_materials_specular.js +6 -74
  311. package/glTF/2.0/Extensions/KHR_materials_specular.js.map +1 -1
  312. package/glTF/2.0/Extensions/KHR_materials_specular.pure.d.ts +39 -0
  313. package/glTF/2.0/Extensions/KHR_materials_specular.pure.js +89 -0
  314. package/glTF/2.0/Extensions/KHR_materials_specular.pure.js.map +1 -0
  315. package/glTF/2.0/Extensions/KHR_materials_specular.types.d.ts +9 -0
  316. package/glTF/2.0/Extensions/KHR_materials_specular.types.js +2 -0
  317. package/glTF/2.0/Extensions/KHR_materials_specular.types.js.map +1 -0
  318. package/glTF/2.0/Extensions/KHR_materials_transmission.d.ts +4 -40
  319. package/glTF/2.0/Extensions/KHR_materials_transmission.js +6 -70
  320. package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
  321. package/glTF/2.0/Extensions/KHR_materials_transmission.pure.d.ts +39 -0
  322. package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js +85 -0
  323. package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js.map +1 -0
  324. package/glTF/2.0/Extensions/KHR_materials_transmission.types.d.ts +9 -0
  325. package/glTF/2.0/Extensions/KHR_materials_transmission.types.js +2 -0
  326. package/glTF/2.0/Extensions/KHR_materials_transmission.types.js.map +1 -0
  327. package/glTF/2.0/Extensions/KHR_materials_unlit.d.ts +4 -40
  328. package/glTF/2.0/Extensions/KHR_materials_unlit.js +6 -64
  329. package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
  330. package/glTF/2.0/Extensions/KHR_materials_unlit.pure.d.ts +39 -0
  331. package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js +79 -0
  332. package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js.map +1 -0
  333. package/glTF/2.0/Extensions/KHR_materials_unlit.types.d.ts +9 -0
  334. package/glTF/2.0/Extensions/KHR_materials_unlit.types.js +2 -0
  335. package/glTF/2.0/Extensions/KHR_materials_unlit.types.js.map +1 -0
  336. package/glTF/2.0/Extensions/KHR_materials_variants.d.ts +4 -110
  337. package/glTF/2.0/Extensions/KHR_materials_variants.js +6 -260
  338. package/glTF/2.0/Extensions/KHR_materials_variants.js.map +1 -1
  339. package/glTF/2.0/Extensions/KHR_materials_variants.pure.d.ts +97 -0
  340. package/glTF/2.0/Extensions/KHR_materials_variants.pure.js +275 -0
  341. package/glTF/2.0/Extensions/KHR_materials_variants.pure.js.map +1 -0
  342. package/glTF/2.0/Extensions/KHR_materials_variants.types.d.ts +29 -0
  343. package/glTF/2.0/Extensions/KHR_materials_variants.types.js +2 -0
  344. package/glTF/2.0/Extensions/KHR_materials_variants.types.js.map +1 -0
  345. package/glTF/2.0/Extensions/KHR_materials_volume.d.ts +4 -41
  346. package/glTF/2.0/Extensions/KHR_materials_volume.js +6 -77
  347. package/glTF/2.0/Extensions/KHR_materials_volume.js.map +1 -1
  348. package/glTF/2.0/Extensions/KHR_materials_volume.pure.d.ts +40 -0
  349. package/glTF/2.0/Extensions/KHR_materials_volume.pure.js +92 -0
  350. package/glTF/2.0/Extensions/KHR_materials_volume.pure.js.map +1 -0
  351. package/glTF/2.0/Extensions/KHR_materials_volume.types.d.ts +9 -0
  352. package/glTF/2.0/Extensions/KHR_materials_volume.types.js +2 -0
  353. package/glTF/2.0/Extensions/KHR_materials_volume.types.js.map +1 -0
  354. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.d.ts +4 -43
  355. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js +6 -113
  356. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js.map +1 -1
  357. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.d.ts +42 -0
  358. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js +128 -0
  359. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js.map +1 -0
  360. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.d.ts +9 -0
  361. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js +2 -0
  362. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js.map +1 -0
  363. package/glTF/2.0/Extensions/KHR_mesh_quantization.d.ts +4 -27
  364. package/glTF/2.0/Extensions/KHR_mesh_quantization.js +6 -20
  365. package/glTF/2.0/Extensions/KHR_mesh_quantization.js.map +1 -1
  366. package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.d.ts +26 -0
  367. package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js +35 -0
  368. package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js.map +1 -0
  369. package/glTF/2.0/Extensions/KHR_mesh_quantization.types.d.ts +9 -0
  370. package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js +2 -0
  371. package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js.map +1 -0
  372. package/glTF/2.0/Extensions/KHR_node_hoverability.d.ts +4 -29
  373. package/glTF/2.0/Extensions/KHR_node_hoverability.js +6 -187
  374. package/glTF/2.0/Extensions/KHR_node_hoverability.js.map +1 -1
  375. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.d.ts +28 -0
  376. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +202 -0
  377. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -0
  378. package/glTF/2.0/Extensions/KHR_node_hoverability.types.d.ts +9 -0
  379. package/glTF/2.0/Extensions/KHR_node_hoverability.types.js +2 -0
  380. package/glTF/2.0/Extensions/KHR_node_hoverability.types.js.map +1 -0
  381. package/glTF/2.0/Extensions/KHR_node_selectability.d.ts +4 -28
  382. package/glTF/2.0/Extensions/KHR_node_selectability.js +6 -121
  383. package/glTF/2.0/Extensions/KHR_node_selectability.js.map +1 -1
  384. package/glTF/2.0/Extensions/KHR_node_selectability.pure.d.ts +27 -0
  385. package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +136 -0
  386. package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -0
  387. package/glTF/2.0/Extensions/KHR_node_selectability.types.d.ts +9 -0
  388. package/glTF/2.0/Extensions/KHR_node_selectability.types.js +2 -0
  389. package/glTF/2.0/Extensions/KHR_node_selectability.types.js.map +1 -0
  390. package/glTF/2.0/Extensions/KHR_node_visibility.d.ts +4 -28
  391. package/glTF/2.0/Extensions/KHR_node_visibility.js +6 -64
  392. package/glTF/2.0/Extensions/KHR_node_visibility.js.map +1 -1
  393. package/glTF/2.0/Extensions/KHR_node_visibility.pure.d.ts +27 -0
  394. package/glTF/2.0/Extensions/KHR_node_visibility.pure.js +79 -0
  395. package/glTF/2.0/Extensions/KHR_node_visibility.pure.js.map +1 -0
  396. package/glTF/2.0/Extensions/KHR_node_visibility.types.d.ts +9 -0
  397. package/glTF/2.0/Extensions/KHR_node_visibility.types.js +2 -0
  398. package/glTF/2.0/Extensions/KHR_node_visibility.types.js.map +1 -0
  399. package/glTF/2.0/Extensions/KHR_texture_basisu.d.ts +4 -31
  400. package/glTF/2.0/Extensions/KHR_texture_basisu.js +6 -35
  401. package/glTF/2.0/Extensions/KHR_texture_basisu.js.map +1 -1
  402. package/glTF/2.0/Extensions/KHR_texture_basisu.pure.d.ts +30 -0
  403. package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js +50 -0
  404. package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js.map +1 -0
  405. package/glTF/2.0/Extensions/KHR_texture_basisu.types.d.ts +9 -0
  406. package/glTF/2.0/Extensions/KHR_texture_basisu.types.js +2 -0
  407. package/glTF/2.0/Extensions/KHR_texture_basisu.types.js.map +1 -0
  408. package/glTF/2.0/Extensions/KHR_texture_transform.d.ts +4 -35
  409. package/glTF/2.0/Extensions/KHR_texture_transform.js +6 -56
  410. package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
  411. package/glTF/2.0/Extensions/KHR_texture_transform.pure.d.ts +34 -0
  412. package/glTF/2.0/Extensions/KHR_texture_transform.pure.js +71 -0
  413. package/glTF/2.0/Extensions/KHR_texture_transform.pure.js.map +1 -0
  414. package/glTF/2.0/Extensions/KHR_texture_transform.types.d.ts +9 -0
  415. package/glTF/2.0/Extensions/KHR_texture_transform.types.js +2 -0
  416. package/glTF/2.0/Extensions/KHR_texture_transform.types.js.map +1 -0
  417. package/glTF/2.0/Extensions/KHR_xmp_json_ld.d.ts +4 -37
  418. package/glTF/2.0/Extensions/KHR_xmp_json_ld.js +6 -45
  419. package/glTF/2.0/Extensions/KHR_xmp_json_ld.js.map +1 -1
  420. package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.d.ts +36 -0
  421. package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js +60 -0
  422. package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js.map +1 -0
  423. package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.d.ts +9 -0
  424. package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js +2 -0
  425. package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js.map +1 -0
  426. package/glTF/2.0/Extensions/MSFT_audio_emitter.d.ts +5 -54
  427. package/glTF/2.0/Extensions/MSFT_audio_emitter.js +7 -226
  428. package/glTF/2.0/Extensions/MSFT_audio_emitter.js.map +1 -1
  429. package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.d.ts +52 -0
  430. package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js +240 -0
  431. package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js.map +1 -0
  432. package/glTF/2.0/Extensions/MSFT_audio_emitter.types.d.ts +9 -0
  433. package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js +2 -0
  434. package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js.map +1 -0
  435. package/glTF/2.0/Extensions/MSFT_lod.d.ts +4 -102
  436. package/glTF/2.0/Extensions/MSFT_lod.js +6 -335
  437. package/glTF/2.0/Extensions/MSFT_lod.js.map +1 -1
  438. package/glTF/2.0/Extensions/MSFT_lod.pure.d.ts +96 -0
  439. package/glTF/2.0/Extensions/MSFT_lod.pure.js +350 -0
  440. package/glTF/2.0/Extensions/MSFT_lod.pure.js.map +1 -0
  441. package/glTF/2.0/Extensions/MSFT_lod.types.d.ts +14 -0
  442. package/glTF/2.0/Extensions/MSFT_lod.types.js +2 -0
  443. package/glTF/2.0/Extensions/MSFT_lod.types.js.map +1 -0
  444. package/glTF/2.0/Extensions/MSFT_minecraftMesh.d.ts +6 -27
  445. package/glTF/2.0/Extensions/MSFT_minecraftMesh.js +8 -40
  446. package/glTF/2.0/Extensions/MSFT_minecraftMesh.js.map +1 -1
  447. package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.d.ts +24 -0
  448. package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js +53 -0
  449. package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js.map +1 -0
  450. package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.d.ts +9 -0
  451. package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js +2 -0
  452. package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js.map +1 -0
  453. package/glTF/2.0/Extensions/MSFT_sRGBFactors.d.ts +6 -27
  454. package/glTF/2.0/Extensions/MSFT_sRGBFactors.js +8 -38
  455. package/glTF/2.0/Extensions/MSFT_sRGBFactors.js.map +1 -1
  456. package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.d.ts +24 -0
  457. package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js +51 -0
  458. package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js.map +1 -0
  459. package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.d.ts +9 -0
  460. package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js +2 -0
  461. package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js.map +1 -0
  462. package/glTF/2.0/Extensions/objectModelMapping.d.ts +31 -2
  463. package/glTF/2.0/Extensions/objectModelMapping.js +3 -3
  464. package/glTF/2.0/Extensions/objectModelMapping.js.map +1 -1
  465. package/glTF/2.0/Extensions/pure.d.ts +45 -0
  466. package/glTF/2.0/Extensions/pure.js +47 -0
  467. package/glTF/2.0/Extensions/pure.js.map +1 -0
  468. package/glTF/2.0/glTFLoader.d.ts +1 -471
  469. package/glTF/2.0/glTFLoader.js +3 -2539
  470. package/glTF/2.0/glTFLoader.js.map +1 -1
  471. package/glTF/2.0/glTFLoader.pure.d.ts +476 -0
  472. package/glTF/2.0/glTFLoader.pure.js +2575 -0
  473. package/glTF/2.0/glTFLoader.pure.js.map +1 -0
  474. package/glTF/2.0/glTFLoaderAnimation.d.ts +2 -2
  475. package/glTF/2.0/glTFLoaderAnimation.js +2 -2
  476. package/glTF/2.0/glTFLoaderAnimation.js.map +1 -1
  477. package/glTF/2.0/pbrMaterialLoadingAdapter.d.ts +1 -1
  478. package/glTF/2.0/pbrMaterialLoadingAdapter.js +2 -2
  479. package/glTF/2.0/pbrMaterialLoadingAdapter.js.map +1 -1
  480. package/glTF/2.0/pure.d.ts +8 -0
  481. package/glTF/2.0/pure.js +10 -0
  482. package/glTF/2.0/pure.js.map +1 -0
  483. package/glTF/glTFFileLoader.d.ts +5 -551
  484. package/glTF/glTFFileLoader.js +6 -996
  485. package/glTF/glTFFileLoader.js.map +1 -1
  486. package/glTF/glTFFileLoader.pure.d.ts +562 -0
  487. package/glTF/glTFFileLoader.pure.js +1024 -0
  488. package/glTF/glTFFileLoader.pure.js.map +1 -0
  489. package/glTF/glTFFileLoader.types.d.ts +11 -0
  490. package/glTF/glTFFileLoader.types.js +2 -0
  491. package/glTF/glTFFileLoader.types.js.map +1 -0
  492. package/glTF/glTFValidation.js +1 -1
  493. package/glTF/glTFValidation.js.map +1 -1
  494. package/glTF/pure.d.ts +6 -0
  495. package/glTF/pure.js +8 -0
  496. package/glTF/pure.js.map +1 -0
  497. package/package.json +56 -4
  498. package/pure.d.ts +8 -0
  499. package/pure.js +10 -0
  500. 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
- this._mrt = new MultiRenderTarget("gsWorkBuffer", { width: this._textureSize, height: this._textureSize }, 4, scene, {
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
- }, ["gsWorkCenters", "gsWorkCovA", "gsWorkCovB", "gsWorkColors"]);
70
- this._mrt.clearColor = new Color4(0, 0, 0, 0);
71
- this._mrt.renderList = [];
72
- // Take over clearing (no-op) so each decode accumulates into the buffer instead of wiping
73
- // previously-decoded files. Undecoded regions are never sampled (only active intervals render).
74
- this._mrt.onClearObservable.add(() => { });
75
- // One persistent decode material + fullscreen-triangle quad, reused (with per-file uniforms)
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"]}
@@ -0,0 +1,5 @@
1
+ /** Pure barrel — re-exports only side-effect-free modules */
2
+ export * from "./splatLoadingOptions.js";
3
+ export * from "./splatFileLoader.pure.js";
4
+ export * from "./gaussianSplattingStream.js";
5
+ export * from "./sog.pure.js";
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"]}