@gnsx/three 0.185.15 → 0.186.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 (417) hide show
  1. package/build/three.cjs +10 -82600
  2. package/build/three.core.js +1303 -728
  3. package/build/three.module.js +439 -338
  4. package/build/three.tsl.js +74 -44
  5. package/build/three.webgpu.js +6036 -2184
  6. package/build/three.webgpu.nodes.js +6020 -2184
  7. package/examples/jsm/Addons.js +6 -6
  8. package/examples/jsm/controls/ArcballControls.js +1 -1
  9. package/examples/jsm/controls/FirstPersonControls.js +44 -20
  10. package/examples/jsm/controls/OrbitControls.js +9 -0
  11. package/examples/jsm/controls/TrackballControls.js +109 -4
  12. package/examples/jsm/csm/CSMShadowNode.js +13 -0
  13. package/examples/jsm/exporters/GLTFExporter.js +23 -7
  14. package/examples/jsm/exporters/USDZExporter.js +2 -2
  15. package/examples/jsm/generators/CityGenerator.js +377 -45
  16. package/examples/jsm/generators/ForestGenerator.js +12 -12
  17. package/examples/jsm/generators/TerrainGenerator.js +49 -37
  18. package/examples/jsm/generators/TreeGenerator.js +70 -76
  19. package/examples/jsm/generators/city/BenchGenerator.js +127 -0
  20. package/examples/jsm/generators/city/CarGenerator.js +479 -0
  21. package/examples/jsm/generators/city/CityGeneratorUtils.js +31 -0
  22. package/examples/jsm/generators/city/HydrantGenerator.js +106 -0
  23. package/examples/jsm/generators/city/InstancedMeshGenerator.js +86 -0
  24. package/examples/jsm/generators/city/PersonGenerator.js +447 -0
  25. package/examples/jsm/generators/city/SidewalkGenerator.js +33 -38
  26. package/examples/jsm/generators/city/SkyscraperGenerator.js +448 -48
  27. package/examples/jsm/generators/city/StreetTreeGenerator.js +231 -0
  28. package/examples/jsm/generators/city/StreetlightGenerator.js +100 -0
  29. package/examples/jsm/generators/city/TrafficlightGenerator.js +106 -0
  30. package/examples/jsm/generators/city/TrashcanGenerator.js +100 -0
  31. package/examples/jsm/geometries/BoxLineGeometry.js +1 -1
  32. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  33. package/examples/jsm/geometries/RoundedBoxGeometry.js +1 -1
  34. package/examples/jsm/gpgpu/CountingSort.js +271 -0
  35. package/examples/jsm/helpers/LightProbeGridHelper.js +60 -239
  36. package/examples/jsm/helpers/LightProbeGridHelperWebGL.js +221 -0
  37. package/examples/jsm/inspector/Extension.js +94 -0
  38. package/examples/jsm/inspector/Inspector.js +145 -41
  39. package/examples/jsm/inspector/RendererInspector.js +100 -52
  40. package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +2609 -0
  41. package/examples/jsm/inspector/extensions/color-grading/ColorWheel.js +352 -0
  42. package/examples/jsm/inspector/extensions/color-grading/CurveEditor.js +599 -0
  43. package/examples/jsm/inspector/extensions/color-grading/LUT3DStyle.js +1201 -0
  44. package/examples/jsm/inspector/extensions/color-grading/LUTMath.js +788 -0
  45. package/examples/jsm/inspector/extensions/color-grading/modules/BrightnessModule.js +72 -0
  46. package/examples/jsm/inspector/extensions/color-grading/modules/ColorWheelModule.js +112 -0
  47. package/examples/jsm/inspector/extensions/color-grading/modules/ContrastModule.js +82 -0
  48. package/examples/jsm/inspector/extensions/color-grading/modules/CurvesModule.js +109 -0
  49. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureHueModule.js +110 -0
  50. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureModule.js +73 -0
  51. package/examples/jsm/inspector/extensions/color-grading/modules/HueModule.js +78 -0
  52. package/examples/jsm/inspector/extensions/color-grading/modules/ImportedCubeModule.js +89 -0
  53. package/examples/jsm/inspector/extensions/color-grading/modules/Module.js +285 -0
  54. package/examples/jsm/inspector/extensions/color-grading/modules/OutputModule.js +101 -0
  55. package/examples/jsm/inspector/extensions/color-grading/modules/RendererModule.js +225 -0
  56. package/examples/jsm/inspector/extensions/color-grading/modules/SatVibranceModule.js +102 -0
  57. package/examples/jsm/inspector/extensions/color-grading/modules/SaturationModule.js +76 -0
  58. package/examples/jsm/inspector/extensions/color-grading/modules/VibranceModule.js +76 -0
  59. package/examples/jsm/inspector/extensions/color-grading/modules/WhiteBalanceModule.js +86 -0
  60. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +26 -31
  61. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -0
  62. package/examples/jsm/inspector/tabs/Memory.js +0 -2
  63. package/examples/jsm/inspector/tabs/Settings.js +4 -0
  64. package/examples/jsm/inspector/tabs/Timeline.js +223 -171
  65. package/examples/jsm/inspector/tabs/Viewer.js +515 -21
  66. package/examples/jsm/inspector/ui/List.js +15 -9
  67. package/examples/jsm/inspector/ui/Profiler.js +170 -14
  68. package/examples/jsm/inspector/ui/Style.js +269 -23
  69. package/examples/jsm/inspector/ui/Tab.js +2 -0
  70. package/examples/jsm/inspector/ui/Values.js +14 -2
  71. package/examples/jsm/interactive/HTMLMesh.js +19 -3
  72. package/examples/jsm/lighting/LightProbeGrid.js +484 -889
  73. package/examples/jsm/lighting/LightProbeGridUtils.js +107 -0
  74. package/examples/jsm/lighting/LightProbeGridWebGL.js +841 -0
  75. package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +194 -0
  76. package/examples/jsm/lighting/vxgi/VXGINode.js +660 -0
  77. package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +478 -0
  78. package/examples/jsm/lighting/vxgi/VXGIVolume.js +1430 -0
  79. package/examples/jsm/lights/SunLight.js +95 -0
  80. package/examples/jsm/lights/SunLightNode.js +56 -0
  81. package/examples/jsm/lights/SunLightShadow.js +319 -0
  82. package/examples/jsm/lights/SunShadowNode.js +312 -0
  83. package/examples/jsm/loaders/3DMLoader.js +150 -49
  84. package/examples/jsm/loaders/3MFLoader.js +202 -1
  85. package/examples/jsm/loaders/FBXLoader.js +81 -5
  86. package/examples/jsm/loaders/GLTFGaussianSplatLoaderExtension.js +330 -0
  87. package/examples/jsm/loaders/GLTFLoader.js +79 -14
  88. package/examples/jsm/loaders/GaussianSplatPLYLoader.js +386 -0
  89. package/examples/jsm/loaders/KSPLATLoader.js +463 -0
  90. package/examples/jsm/loaders/MaterialXLoader.js +111 -1010
  91. package/examples/jsm/loaders/PCDLoader.js +1 -1
  92. package/examples/jsm/loaders/SPLATLoader.js +139 -0
  93. package/examples/jsm/loaders/SPZLoader.js +561 -0
  94. package/examples/jsm/loaders/materialx/MaterialXArchive.js +108 -0
  95. package/examples/jsm/loaders/materialx/MaterialXDocument.js +878 -0
  96. package/examples/jsm/loaders/materialx/MaterialXHextile.js +183 -0
  97. package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +376 -0
  98. package/examples/jsm/loaders/materialx/MaterialXLog.js +75 -0
  99. package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +4 -0
  100. package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +1021 -0
  101. package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +661 -0
  102. package/examples/jsm/loaders/materialx/MaterialXUtils.js +57 -0
  103. package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +997 -0
  104. package/examples/jsm/loaders/materialx/parse/MaterialXParser.js +28 -0
  105. package/examples/jsm/loaders/usd/USDAParser.js +15 -2
  106. package/examples/jsm/loaders/usd/USDCParser.js +1 -4
  107. package/examples/jsm/loaders/usd/USDComposer.js +80 -42
  108. package/examples/jsm/materials/WoodNodeMaterial.js +6 -108
  109. package/examples/jsm/misc/RollerCoaster.js +2 -2
  110. package/examples/jsm/misc/SculptGL.LICENSE.txt +21 -0
  111. package/examples/jsm/misc/Sculptor.js +1679 -0
  112. package/examples/jsm/misc/SculptorMesh.js +1504 -0
  113. package/examples/jsm/misc/SculptorTools.js +1180 -0
  114. package/examples/jsm/misc/SculptorUtils.js +345 -0
  115. package/examples/jsm/misc/TubePainter.js +28 -16
  116. package/examples/jsm/misc/VolumeSlice.js +24 -24
  117. package/examples/jsm/modifiers/SimplifyModifier.js +63 -556
  118. package/examples/jsm/objects/GaussianSplat.js +1039 -0
  119. package/examples/jsm/objects/Sky.js +66 -45
  120. package/examples/jsm/objects/SkyMesh.js +70 -51
  121. package/examples/jsm/physics/JoltPhysics.js +1 -1
  122. package/examples/jsm/postprocessing/AfterimagePass.js +4 -2
  123. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  124. package/examples/jsm/postprocessing/GTAOPass.js +1 -1
  125. package/examples/jsm/postprocessing/OutlinePass.js +5 -5
  126. package/examples/jsm/postprocessing/SAOPass.js +1 -1
  127. package/examples/jsm/postprocessing/SSAOPass.js +1 -1
  128. package/examples/jsm/postprocessing/SSRPass.js +4 -2
  129. package/examples/jsm/postprocessing/SavePass.js +1 -1
  130. package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
  131. package/examples/jsm/postprocessing/UnrealBloomPass.js +30 -13
  132. package/examples/jsm/renderers/CSS2DRenderer.js +29 -5
  133. package/examples/jsm/shaders/DepthLimitedBlurShader.js +4 -1
  134. package/examples/jsm/shaders/ExposureShader.js +1 -1
  135. package/examples/jsm/shaders/FilmShader.js +2 -1
  136. package/examples/jsm/transpiler/AST.js +21 -2
  137. package/examples/jsm/transpiler/GLSLDecoder.js +498 -8
  138. package/examples/jsm/transpiler/TSLEncoder.js +82 -10
  139. package/examples/jsm/transpiler/WGSLEncoder.js +33 -4
  140. package/examples/jsm/tsl/WebGLNodesHandler.js +29 -39
  141. package/examples/jsm/tsl/display/AfterImageNode.js +2 -0
  142. package/examples/jsm/tsl/display/AnaglyphPassNode.js +3 -2
  143. package/examples/jsm/tsl/display/BilateralBlurNode.js +5 -2
  144. package/examples/jsm/tsl/display/BloomNode.js +55 -30
  145. package/examples/jsm/tsl/display/DenoiseNode.js +21 -1
  146. package/examples/jsm/tsl/display/DepthOfFieldNode.js +24 -6
  147. package/examples/jsm/tsl/display/DotScreenNode.js +11 -11
  148. package/examples/jsm/tsl/display/FSR1Node.js +8 -4
  149. package/examples/jsm/tsl/display/GTAONode.js +199 -86
  150. package/examples/jsm/tsl/display/GaussianBlurNode.js +65 -52
  151. package/examples/jsm/tsl/display/GodraysNode.js +5 -2
  152. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +2 -2
  153. package/examples/jsm/tsl/display/LensflareNode.js +5 -2
  154. package/examples/jsm/tsl/display/OITPassNode.js +352 -0
  155. package/examples/jsm/tsl/display/OutlineNode.js +2 -0
  156. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +3 -2
  157. package/examples/jsm/tsl/display/RGBShiftNode.js +9 -9
  158. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +7 -4
  159. package/examples/jsm/tsl/display/RetroPassNode.js +1 -1
  160. package/examples/jsm/tsl/display/SMAANode.js +22 -61
  161. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -4
  162. package/examples/jsm/tsl/display/SSAONode.js +436 -0
  163. package/examples/jsm/tsl/display/SSGINode.js +5 -2
  164. package/examples/jsm/tsl/display/SSRNode.js +7 -2
  165. package/examples/jsm/tsl/display/SSSNode.js +5 -2
  166. package/examples/jsm/tsl/display/SharpenNode.js +5 -4
  167. package/examples/jsm/tsl/display/StereoCompositePassNode.js +1 -3
  168. package/examples/jsm/tsl/display/StereoPassNode.js +1 -3
  169. package/examples/jsm/tsl/display/TAAUNode.js +22 -125
  170. package/examples/jsm/tsl/display/TRAANode.js +16 -142
  171. package/examples/jsm/tsl/display/TemporalReprojectNode.js +21 -15
  172. package/examples/jsm/tsl/display/depthAwareBlur.js +63 -0
  173. package/examples/jsm/tsl/display/hashBlur.js +3 -2
  174. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +38 -27
  175. package/examples/jsm/tsl/lighting/LightProbeGridNode.js +136 -0
  176. package/examples/jsm/tsl/math/voronoiNoise.js +112 -0
  177. package/examples/jsm/tsl/shadows/TileShadowNode.js +4 -6
  178. package/examples/jsm/tsl/utils/Raymarching.js +5 -5
  179. package/examples/jsm/tsl/utils/SoftParticles.js +60 -0
  180. package/examples/jsm/tsl/utils/TAAUtils.js +195 -0
  181. package/examples/jsm/utils/BufferGeometryUtils.js +14 -14
  182. package/examples/jsm/utils/GaussianSplatUtils.js +229 -0
  183. package/examples/jsm/utils/WebGLTextureUtils.js +1 -1
  184. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  185. package/examples/jsm/webxr/WebGLXRFallback.js +2 -16
  186. package/examples/jsm/webxr/XRControllerModelFactory.js +16 -4
  187. package/package.json +9 -16
  188. package/src/Three.Core.js +2 -1
  189. package/src/Three.TSL.js +73 -43
  190. package/src/Three.WebGPU.Nodes.js +1 -0
  191. package/src/Three.WebGPU.js +1 -0
  192. package/src/animation/AnimationClip.js +15 -2
  193. package/src/animation/AnimationObjectGroup.js +18 -6
  194. package/src/animation/AnimationUtils.js +26 -0
  195. package/src/animation/KeyframeTrack.js +37 -0
  196. package/src/constants.js +23 -1
  197. package/src/core/BufferAttribute.js +3 -2
  198. package/src/core/BufferGeometry.js +1 -1
  199. package/src/core/InterleavedBuffer.js +5 -1
  200. package/src/core/Object3D.js +40 -12
  201. package/src/core/Raycaster.js +4 -0
  202. package/src/core/RenderTarget.js +99 -9
  203. package/src/core/RenderTarget3D.js +12 -8
  204. package/src/extras/Controls.js +0 -8
  205. package/src/extras/PMREMGenerator.js +99 -205
  206. package/src/geometries/TorusGeometry.js +1 -1
  207. package/src/helpers/ArrowHelper.js +2 -0
  208. package/src/helpers/AxesHelper.js +2 -0
  209. package/src/helpers/Box3Helper.js +2 -0
  210. package/src/helpers/BoxHelper.js +2 -0
  211. package/src/helpers/CameraHelper.js +2 -0
  212. package/src/helpers/DirectionalLightHelper.js +2 -0
  213. package/src/helpers/GridHelper.js +2 -0
  214. package/src/helpers/HemisphereLightHelper.js +2 -0
  215. package/src/helpers/PlaneHelper.js +2 -0
  216. package/src/helpers/PointLightHelper.js +2 -0
  217. package/src/helpers/PolarGridHelper.js +2 -0
  218. package/src/helpers/SkeletonHelper.js +2 -0
  219. package/src/helpers/SpotLightHelper.js +2 -0
  220. package/src/lights/Light.js +0 -10
  221. package/src/lights/LightShadow.js +43 -12
  222. package/src/lights/SpotLightShadow.js +18 -0
  223. package/src/loaders/BufferGeometryLoader.js +5 -0
  224. package/src/loaders/ImageBitmapLoader.js +3 -1
  225. package/src/loaders/ObjectLoader.js +8 -5
  226. package/src/materials/Material.js +80 -57
  227. package/src/materials/MeshPhysicalMaterial.js +32 -0
  228. package/src/materials/nodes/Line2NodeMaterial.js +17 -8
  229. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +42 -5
  230. package/src/materials/nodes/NodeMaterial.js +19 -13
  231. package/src/materials/nodes/PointsNodeMaterial.js +2 -1
  232. package/src/materials/nodes/manager/NodeMaterialObserver.js +282 -55
  233. package/src/math/Frustum.js +9 -0
  234. package/src/math/FrustumArray.js +1 -1
  235. package/src/math/MathUtils.js +5 -3
  236. package/src/math/Matrix4.js +2 -9
  237. package/src/math/Plane.js +30 -1
  238. package/src/math/Quaternion.js +0 -10
  239. package/src/math/Ray.js +95 -45
  240. package/src/math/Triangle.js +0 -2
  241. package/src/math/Vector3.js +2 -2
  242. package/src/math/Vector4.js +0 -4
  243. package/src/math/interpolants/BezierInterpolant.js +36 -23
  244. package/src/nodes/Nodes.js +2 -0
  245. package/src/nodes/TSL.js +11 -3
  246. package/src/nodes/accessors/Batch.js +85 -13
  247. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  248. package/src/nodes/accessors/BuiltinNode.js +1 -1
  249. package/src/nodes/accessors/Instance.js +19 -18
  250. package/src/nodes/accessors/MaterialNode.js +9 -0
  251. package/src/nodes/accessors/ModelNode.js +85 -9
  252. package/src/nodes/accessors/ReferenceBaseNode.js +1 -70
  253. package/src/nodes/accessors/ReferenceElementNode.js +72 -0
  254. package/src/nodes/accessors/ReferenceNode.js +1 -70
  255. package/src/nodes/accessors/Skinning.js +124 -12
  256. package/src/nodes/accessors/StorageTextureNode.js +7 -3
  257. package/src/nodes/accessors/Texture3DNode.js +1 -1
  258. package/src/nodes/accessors/TextureNode.js +51 -21
  259. package/src/nodes/accessors/TextureSizeNode.js +4 -2
  260. package/src/nodes/accessors/UniformArrayNode.js +30 -5
  261. package/src/nodes/code/CodeNode.js +1 -1
  262. package/src/nodes/code/FunctionNode.js +12 -2
  263. package/src/nodes/core/ArrayNode.js +2 -2
  264. package/src/nodes/core/ContextNode.js +57 -4
  265. package/src/nodes/core/IndexNode.js +69 -4
  266. package/src/nodes/core/InspectorNode.js +2 -2
  267. package/src/nodes/core/MRTNode.js +44 -2
  268. package/src/nodes/core/Node.js +6 -3
  269. package/src/nodes/core/NodeBuilder.js +65 -50
  270. package/src/nodes/core/NodeFrame.js +11 -3
  271. package/src/nodes/core/NodeUtils.js +88 -0
  272. package/src/nodes/core/PropertyNode.js +8 -0
  273. package/src/nodes/core/StackNode.js +0 -1
  274. package/src/nodes/core/StructNode.js +4 -3
  275. package/src/nodes/core/UniformGroupNode.js +3 -2
  276. package/src/nodes/core/UniformNode.js +26 -12
  277. package/src/nodes/core/VarNode.js +0 -1
  278. package/src/nodes/display/BumpMapNode.js +2 -2
  279. package/src/nodes/display/ColorAdjustment.js +1 -1
  280. package/src/nodes/display/PassNode.js +76 -15
  281. package/src/nodes/display/ScreenNode.js +22 -65
  282. package/src/nodes/fog/Fog.js +4 -4
  283. package/src/nodes/functions/BSDF/BRDF_GGX.js +6 -6
  284. package/src/nodes/functions/BSDF/BRDF_Sheen.js +1 -1
  285. package/src/nodes/functions/BSDF/DFGLUT.js +2 -1
  286. package/src/nodes/functions/BSDF/LTC.js +1 -1
  287. package/src/nodes/functions/PhongLightingModel.js +1 -1
  288. package/src/nodes/functions/PhysicalLightingModel.js +83 -25
  289. package/src/nodes/functions/ToonLightingModel.js +2 -2
  290. package/src/nodes/functions/material/getParallaxCorrectNormal.js +3 -3
  291. package/src/nodes/gpgpu/AtomicFunctionNode.js +64 -13
  292. package/src/nodes/gpgpu/BarrierNode.js +13 -4
  293. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
  294. package/src/nodes/gpgpu/ComputeNode.js +20 -17
  295. package/src/nodes/gpgpu/SubgroupFunctionNode.js +165 -37
  296. package/src/nodes/gpgpu/WorkgroupInfoNode.js +44 -6
  297. package/src/nodes/lighting/EnvironmentNode.js +40 -4
  298. package/src/nodes/lighting/LightsNode.js +20 -4
  299. package/src/nodes/lighting/ShadowBaseNode.js +158 -1
  300. package/src/nodes/lighting/ShadowFilterNode.js +2 -106
  301. package/src/nodes/lighting/ShadowNode.js +22 -91
  302. package/src/nodes/materialx/{lib/mx_hsv.js → MaterialXColor.js} +3 -6
  303. package/src/nodes/materialx/{lib/mx_transform_color.js → MaterialXColorTransform.js} +3 -6
  304. package/src/nodes/materialx/MaterialXCore.js +37 -0
  305. package/src/nodes/materialx/MaterialXNodes.js +64 -72
  306. package/src/nodes/materialx/{lib/mx_noise.js → MaterialXNoise.js} +426 -197
  307. package/src/nodes/math/BitcountNode.js +24 -4
  308. package/src/nodes/math/MathNode.js +4 -4
  309. package/src/nodes/math/MathUtils.js +15 -4
  310. package/src/nodes/math/OperatorNode.js +2 -2
  311. package/src/nodes/math/PackFloatNode.js +29 -1
  312. package/src/nodes/math/Packed4x8IntegerNode.js +433 -0
  313. package/src/nodes/math/UnpackFloatNode.js +30 -2
  314. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  315. package/src/nodes/pmrem/PMREMNode.js +1 -1
  316. package/src/nodes/pmrem/PMREMUtils.js +31 -74
  317. package/src/nodes/shapes/Shapes.js +1 -1
  318. package/src/nodes/tsl/TSLCore.js +1 -31
  319. package/src/nodes/utils/EventNode.js +75 -0
  320. package/src/nodes/utils/LoopNode.js +54 -13
  321. package/src/nodes/utils/PostProcessingUtils.js +23 -2
  322. package/src/nodes/utils/RTTNode.js +97 -32
  323. package/src/nodes/utils/ReflectorNode.js +8 -4
  324. package/src/nodes/utils/RotateNode.js +85 -8
  325. package/src/nodes/utils/SpriteUtils.js +58 -23
  326. package/src/objects/BatchedMesh.js +6 -0
  327. package/src/objects/InstancedMesh.js +1 -1
  328. package/src/objects/LOD.js +1 -1
  329. package/src/objects/Line.js +12 -0
  330. package/src/objects/Mesh.js +12 -0
  331. package/src/objects/Points.js +12 -0
  332. package/src/objects/Sprite.js +12 -0
  333. package/src/renderers/WebGLRenderer.js +93 -27
  334. package/src/renderers/common/Animation.js +12 -2
  335. package/src/renderers/common/Backend.js +38 -10
  336. package/src/renderers/common/BindGroup.js +0 -1
  337. package/src/renderers/common/Bindings.js +50 -4
  338. package/src/renderers/common/BundleGroup.js +4 -0
  339. package/src/renderers/common/ClippingContext.js +11 -1
  340. package/src/renderers/common/Color4.js +9 -0
  341. package/src/renderers/common/Constants.js +0 -5
  342. package/src/renderers/common/DirectRenderPipeline.js +233 -0
  343. package/src/renderers/common/Geometries.js +24 -3
  344. package/src/renderers/common/Info.js +3 -3
  345. package/src/renderers/common/InspectorBase.js +37 -8
  346. package/src/renderers/common/Lighting.js +11 -4
  347. package/src/renderers/common/Pipelines.js +6 -4
  348. package/src/renderers/common/QuadMesh.js +16 -2
  349. package/src/renderers/common/RenderContext.js +8 -0
  350. package/src/renderers/common/RenderList.js +53 -19
  351. package/src/renderers/common/RenderLists.js +58 -11
  352. package/src/renderers/common/RenderObject.js +14 -0
  353. package/src/renderers/common/RenderObjects.js +14 -9
  354. package/src/renderers/common/RenderPipeline.js +52 -44
  355. package/src/renderers/common/Renderer.js +226 -55
  356. package/src/renderers/common/Storage3DTexture.js +16 -0
  357. package/src/renderers/common/Textures.js +3 -3
  358. package/src/renderers/common/XRManager.js +79 -72
  359. package/src/renderers/common/extras/PMREMGenerator.js +76 -144
  360. package/src/renderers/common/nodes/NodeManager.js +144 -6
  361. package/src/renderers/common/nodes/NodeStorageBuffer.js +3 -1
  362. package/src/renderers/common/nodes/NodeUniformBuffer.js +3 -1
  363. package/src/renderers/shaders/DFGLUTData.js +2 -1
  364. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +4 -2
  365. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +48 -0
  366. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +53 -4
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +20 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +20 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +61 -57
  371. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +82 -0
  372. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +9 -0
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +8 -1
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +15 -0
  375. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  376. package/src/renderers/shaders/ShaderLib.js +1 -0
  377. package/src/renderers/shaders/UniformsLib.js +16 -0
  378. package/src/renderers/webgl/WebGLAnimation.js +2 -2
  379. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  380. package/src/renderers/webgl/WebGLLights.js +74 -4
  381. package/src/renderers/webgl/WebGLMaterials.js +6 -0
  382. package/src/renderers/webgl/WebGLOutput.js +36 -24
  383. package/src/renderers/webgl/WebGLProgram.js +3 -0
  384. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  385. package/src/renderers/webgl/WebGLRenderLists.js +6 -10
  386. package/src/renderers/webgl/WebGLShadowMap.js +47 -44
  387. package/src/renderers/webgl/WebGLTextures.js +7 -7
  388. package/src/renderers/webgl-fallback/WebGLBackend.js +153 -45
  389. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +83 -29
  390. package/src/renderers/webgl-fallback/utils/WebGLState.js +163 -17
  391. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +32 -5
  392. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +11 -4
  393. package/src/renderers/webgpu/WebGPUBackend.js +513 -145
  394. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -20
  395. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -1
  396. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +3 -12
  397. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +24 -14
  398. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +80 -14
  399. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -7
  400. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +9 -3
  401. package/src/renderers/webgpu/utils/WebGPUUtils.js +16 -4
  402. package/src/renderers/webxr/WebXRManager.js +25 -2
  403. package/src/scenes/Scene.js +3 -3
  404. package/src/textures/CompressedArrayTexture.js +16 -0
  405. package/src/textures/Data3DTexture.js +16 -0
  406. package/src/textures/DataArrayTexture.js +16 -0
  407. package/src/textures/DepthTexture.js +3 -3
  408. package/src/textures/Texture.js +3 -3
  409. package/src/textures/{Source.js → TextureSource.js} +39 -8
  410. package/build/three.core.min.js +0 -6
  411. package/build/three.module.min.js +0 -6
  412. package/build/three.tsl.min.js +0 -6
  413. package/build/three.webgpu.min.js +0 -6
  414. package/build/three.webgpu.nodes.min.js +0 -6
  415. package/examples/jsm/libs/ecsy.module.js +0 -1792
  416. package/examples/jsm/loaders/LottieLoader.js +0 -130
  417. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +0 -52
@@ -86,6 +86,16 @@ class FBXLoader extends Loader {
86
86
 
87
87
  super( manager );
88
88
 
89
+ /**
90
+ * Whether to trim animation clips to the time range of their
91
+ * animation stacks and shift them to start at time zero. Useful
92
+ * for assets that define multiple clips on a single timeline.
93
+ *
94
+ * @type {boolean}
95
+ * @default false
96
+ */
97
+ this.trimAnimationClips = false;
98
+
89
99
  }
90
100
 
91
101
  /**
@@ -172,7 +182,7 @@ class FBXLoader extends Loader {
172
182
 
173
183
  const textureLoader = new TextureLoader( this.manager ).setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin );
174
184
 
175
- return new FBXTreeParser( textureLoader, this.manager ).parse( fbxTree );
185
+ return new FBXTreeParser( textureLoader, this.manager, this.trimAnimationClips ).parse( fbxTree );
176
186
 
177
187
  }
178
188
 
@@ -181,10 +191,11 @@ class FBXLoader extends Loader {
181
191
  // Parse the FBXTree object returned by the BinaryParser or TextParser and return a Group
182
192
  class FBXTreeParser {
183
193
 
184
- constructor( textureLoader, manager ) {
194
+ constructor( textureLoader, manager, trimAnimationClips ) {
185
195
 
186
196
  this.textureLoader = textureLoader;
187
197
  this.manager = manager;
198
+ this.trimAnimationClips = trimAnimationClips;
188
199
 
189
200
  }
190
201
 
@@ -367,7 +378,7 @@ class FBXTreeParser {
367
378
  } else { // Binary Format
368
379
 
369
380
  const array = new Uint8Array( content );
370
- return window.URL.createObjectURL( new Blob( [ array ], { type: type } ) );
381
+ return URL.createObjectURL( new Blob( [ array ], { type: type } ) );
371
382
 
372
383
  }
373
384
 
@@ -1000,12 +1011,13 @@ class FBXTreeParser {
1000
1011
  // without a BindPose section).
1001
1012
  this.bindSkeleton( deformers.skeletons, geometryMap, modelMap );
1002
1013
 
1003
- const animations = new AnimationParser().parse();
1014
+ const animations = new AnimationParser( this.trimAnimationClips ).parse();
1004
1015
 
1005
1016
  // if all the models where already combined in a single group, just return that
1006
1017
  if ( sceneGraph.children.length === 1 && sceneGraph.children[ 0 ].isGroup ) {
1007
1018
 
1008
1019
  sceneGraph.children[ 0 ].animations = animations;
1020
+ Object.assign( sceneGraph.children[ 0 ].userData, sceneGraph.userData );
1009
1021
  sceneGraph = sceneGraph.children[ 0 ];
1010
1022
 
1011
1023
  }
@@ -2614,6 +2626,12 @@ class GeometryParser {
2614
2626
  // parse animation data from FBXTree
2615
2627
  class AnimationParser {
2616
2628
 
2629
+ constructor( trimAnimationClips ) {
2630
+
2631
+ this.trimAnimationClips = trimAnimationClips;
2632
+
2633
+ }
2634
+
2617
2635
  // take raw animation clips and turn them into three.js animation clips
2618
2636
  parse() {
2619
2637
 
@@ -2912,11 +2930,14 @@ class AnimationParser {
2912
2930
  }
2913
2931
 
2914
2932
  const layer = layersMap.get( children[ 0 ].ID );
2933
+ const rawStack = rawStacks[ nodeID ];
2915
2934
 
2916
2935
  rawClips[ nodeID ] = {
2917
2936
 
2918
- name: rawStacks[ nodeID ].attrName,
2937
+ name: rawStack.attrName,
2919
2938
  layer: layer,
2939
+ localStart: rawStack.LocalStart !== undefined ? convertFBXTimeToSeconds( Number( rawStack.LocalStart.value ) ) : 0,
2940
+ localStop: rawStack.LocalStop !== undefined ? convertFBXTimeToSeconds( Number( rawStack.LocalStop.value ) ) : 0,
2920
2941
 
2921
2942
  };
2922
2943
 
@@ -2937,10 +2958,65 @@ class AnimationParser {
2937
2958
 
2938
2959
  } );
2939
2960
 
2961
+ if ( this.trimAnimationClips === true && rawClip.localStop > rawClip.localStart ) {
2962
+
2963
+ tracks = this.trimTracks( tracks, rawClip.localStart, rawClip.localStop );
2964
+
2965
+ }
2966
+
2940
2967
  return new AnimationClip( rawClip.name, - 1, tracks );
2941
2968
 
2942
2969
  }
2943
2970
 
2971
+ // trims the given tracks to the time range [ startTime, endTime ] and shifts
2972
+ // them so they start at time zero. tracks without keyframes in the range are discarded
2973
+ trimTracks( tracks, startTime, endTime ) {
2974
+
2975
+ // track times are stored as float32 so compare against float32 boundaries
2976
+ // to keep keyframes lying exactly on the range limits
2977
+
2978
+ const start = Math.fround( startTime );
2979
+ const end = Math.fround( endTime );
2980
+
2981
+ const trimmedTracks = [];
2982
+
2983
+ for ( let i = 0; i < tracks.length; i ++ ) {
2984
+
2985
+ const track = tracks[ i ];
2986
+ const stride = track.getValueSize();
2987
+
2988
+ const times = [];
2989
+ const values = [];
2990
+
2991
+ for ( let j = 0; j < track.times.length; j ++ ) {
2992
+
2993
+ const time = track.times[ j ];
2994
+
2995
+ if ( time < start || time > end ) continue;
2996
+
2997
+ times.push( time - start );
2998
+
2999
+ for ( let k = 0; k < stride; k ++ ) {
3000
+
3001
+ values.push( track.values[ j * stride + k ] );
3002
+
3003
+ }
3004
+
3005
+ }
3006
+
3007
+ if ( times.length === 0 ) continue;
3008
+
3009
+ track.times = new Float32Array( times );
3010
+ track.values = new Float32Array( values );
3011
+
3012
+ trimmedTracks.push( track );
3013
+
3014
+ }
3015
+
3016
+ return trimmedTracks;
3017
+
3018
+ }
3019
+
2944
3020
  generateTracks( rawTracks ) {
2945
3021
 
2946
3022
  const tracks = [];
@@ -0,0 +1,330 @@
1
+ import {
2
+ Group
3
+ } from '@gnsx/three';
4
+
5
+ import { GaussianSplat } from '../objects/GaussianSplat.js';
6
+ import { SH_BAND_WORDS, createGaussianSplatGeometry, createPackedSphericalHarmonicsBand, writeColorBytesFromSH0, writeCovariance } from '../utils/GaussianSplatUtils.js';
7
+
8
+ const EXTENSION_NAME = 'KHR_gaussian_splatting';
9
+ const POINTS = 0;
10
+ const ATTRIBUTES = {
11
+ POSITION: 'position'
12
+ };
13
+
14
+ /**
15
+ * A glTF loader plugin for `KHR_gaussian_splatting`.
16
+ *
17
+ * This plugin must be registered explicitly because {@link GaussianSplat}
18
+ * requires {@link WebGPURenderer}.
19
+ *
20
+ * ```js
21
+ * const loader = new GLTFLoader();
22
+ * loader.register( function ( parser ) {
23
+ *
24
+ * return new GLTFGaussianSplatLoaderExtension( parser );
25
+ *
26
+ * } );
27
+ * ```
28
+ *
29
+ * @three_import import { GLTFGaussianSplatLoaderExtension } from 'three/addons/loaders/GLTFGaussianSplatLoaderExtension.js';
30
+ */
31
+ class GLTFGaussianSplatLoaderExtension {
32
+
33
+ /**
34
+ * Constructs a new glTF gaussian splatting extension plugin.
35
+ *
36
+ * @param {GLTFParser} parser - The glTF parser.
37
+ */
38
+ constructor( parser ) {
39
+
40
+ this.name = EXTENSION_NAME;
41
+ this.parser = parser;
42
+
43
+ }
44
+
45
+ /**
46
+ * Loads a glTF mesh containing gaussian splat primitives.
47
+ *
48
+ * @param {number} meshIndex - The mesh index.
49
+ * @return {?Promise<Group|GaussianSplat>} The loaded mesh or `null` when the mesh does not use this extension.
50
+ */
51
+ loadMesh( meshIndex ) {
52
+
53
+ const parser = this.parser;
54
+ const meshDef = parser.json.meshes[ meshIndex ];
55
+ const primitives = meshDef.primitives;
56
+
57
+ if ( primitives.some( isGaussianSplatPrimitive ) === false ) return null;
58
+
59
+ if ( primitives.every( isGaussianSplatPrimitive ) === false ) {
60
+
61
+ throw new Error( 'THREE.GLTFGaussianSplatLoaderExtension: Mixed gaussian and non-gaussian mesh primitives are not supported.' );
62
+
63
+ }
64
+
65
+ return parser.loadGeometries( primitives ).then( function ( geometries ) {
66
+
67
+ const meshes = [];
68
+
69
+ for ( let i = 0, il = geometries.length; i < il; i ++ ) {
70
+
71
+ const geometry = geometries[ i ];
72
+ const primitive = primitives[ i ];
73
+
74
+ if ( primitive.mode !== POINTS ) {
75
+
76
+ throw new Error( 'THREE.GLTFGaussianSplatLoaderExtension: Gaussian splat primitives must use POINTS mode.' );
77
+
78
+ }
79
+
80
+ const mesh = createGaussianSplat( geometry, primitive );
81
+ mesh.name = parser.createUniqueName( meshDef.name || ( 'mesh_' + meshIndex ) );
82
+
83
+ assignExtrasToUserData( mesh, meshDef );
84
+ parser.associations.set( mesh, {
85
+ meshes: meshIndex,
86
+ primitives: i
87
+ } );
88
+
89
+ meshes.push( mesh );
90
+
91
+ }
92
+
93
+ if ( meshes.length === 1 ) return meshes[ 0 ];
94
+
95
+ const group = new Group();
96
+ assignExtrasToUserData( group, meshDef );
97
+ parser.associations.set( group, { meshes: meshIndex } );
98
+
99
+ for ( let i = 0, il = meshes.length; i < il; i ++ ) {
100
+
101
+ group.add( meshes[ i ] );
102
+
103
+ }
104
+
105
+ return group;
106
+
107
+ } );
108
+
109
+ }
110
+
111
+ }
112
+
113
+ function isGaussianSplatPrimitive( primitiveDef ) {
114
+
115
+ return primitiveDef.extensions !== undefined &&
116
+ primitiveDef.extensions[ EXTENSION_NAME ] !== undefined;
117
+
118
+ }
119
+
120
+ function createGaussianSplat( geometry, primitiveDef ) {
121
+
122
+ const extensionDef = primitiveDef.extensions[ EXTENSION_NAME ];
123
+
124
+ if ( extensionDef.kernel !== 'ellipse' ) {
125
+
126
+ throw new Error( 'THREE.GLTFGaussianSplatLoaderExtension: Unsupported KHR_gaussian_splatting kernel.' );
127
+
128
+ }
129
+
130
+ if ( extensionDef.colorSpace === undefined ) {
131
+
132
+ throw new Error( 'THREE.GLTFGaussianSplatLoaderExtension: KHR_gaussian_splatting colorSpace is required.' );
133
+
134
+ }
135
+
136
+ if ( extensionDef.projection !== undefined && extensionDef.projection !== 'perspective' ) {
137
+
138
+ console.warn( 'THREE.GLTFGaussianSplatLoaderExtension: Unsupported KHR_gaussian_splatting projection. Results may be incorrect.' );
139
+
140
+ }
141
+
142
+ if ( extensionDef.sortingMethod !== undefined && extensionDef.sortingMethod !== 'cameraDistance' ) {
143
+
144
+ console.warn( 'THREE.GLTFGaussianSplatLoaderExtension: Unsupported KHR_gaussian_splatting sortingMethod. Results may be incorrect.' );
145
+
146
+ }
147
+
148
+ const position = getGaussianSplatAttribute( geometry, primitiveDef, 'POSITION' );
149
+ const scale = getGaussianSplatAttribute( geometry, primitiveDef, 'KHR_gaussian_splatting:SCALE' );
150
+ const rotation = getGaussianSplatAttribute( geometry, primitiveDef, 'KHR_gaussian_splatting:ROTATION' );
151
+ const opacity = getGaussianSplatAttribute( geometry, primitiveDef, 'KHR_gaussian_splatting:OPACITY' );
152
+ const sh0 = getGaussianSplatAttribute( geometry, primitiveDef, 'KHR_gaussian_splatting:SH_DEGREE_0_COEF_0' );
153
+ const count = position.count;
154
+
155
+ if ( scale.count !== count || rotation.count !== count || opacity.count !== count || sh0.count !== count ) {
156
+
157
+ throw new Error( 'THREE.GLTFGaussianSplatLoaderExtension: KHR_gaussian_splatting attribute counts must match POSITION.' );
158
+
159
+ }
160
+
161
+ const centers = new Float32Array( count * 3 );
162
+ const covariances = new Float32Array( count * 6 );
163
+ const colors = new Uint8ClampedArray( count * 4 );
164
+ const sphericalHarmonics = createGLTFSphericalHarmonicsAttributes( geometry, primitiveDef, count );
165
+
166
+ for ( let i = 0; i < count; i ++ ) {
167
+
168
+ const i3 = i * 3;
169
+
170
+ centers[ i3 ] = position.getX( i );
171
+ centers[ i3 + 1 ] = position.getY( i );
172
+ centers[ i3 + 2 ] = position.getZ( i );
173
+
174
+ writeCovariance(
175
+ covariances,
176
+ i * 6,
177
+ scale.getX( i ),
178
+ scale.getY( i ),
179
+ scale.getZ( i ),
180
+ rotation.getX( i ),
181
+ rotation.getY( i ),
182
+ rotation.getZ( i ),
183
+ rotation.getW( i )
184
+ );
185
+
186
+ writeColorBytesFromSH0(
187
+ colors,
188
+ i * 4,
189
+ sh0.getX( i ),
190
+ sh0.getY( i ),
191
+ sh0.getZ( i ),
192
+ opacity.getX( i )
193
+ );
194
+
195
+ }
196
+
197
+ const mesh = new GaussianSplat( createGaussianSplatGeometry( centers, covariances, colors, sphericalHarmonics ) );
198
+
199
+ mesh.userData.gltfExtensions = mesh.userData.gltfExtensions || {};
200
+ mesh.userData.gltfExtensions[ EXTENSION_NAME ] = Object.assign( {}, extensionDef );
201
+
202
+ return mesh;
203
+
204
+ }
205
+
206
+ function createGLTFSphericalHarmonicsAttributes( geometry, primitiveDef, count ) {
207
+
208
+ const sphericalHarmonics = {};
209
+
210
+ for ( let degree = 1; degree <= 3; degree ++ ) {
211
+
212
+ const coefficientCount = degree * 2 + 1;
213
+ const attributes = [];
214
+
215
+ for ( let coefficient = 0; coefficient < coefficientCount; coefficient ++ ) {
216
+
217
+ const semantic = `KHR_gaussian_splatting:SH_DEGREE_${ degree }_COEF_${ coefficient }`;
218
+ const attribute = getOptionalGaussianSplatAttribute( geometry, primitiveDef, semantic );
219
+
220
+ if ( attribute !== undefined ) {
221
+
222
+ if ( attribute.count !== count || attribute.itemSize !== 3 ) {
223
+
224
+ throw new Error( `THREE.GLTFGaussianSplatLoaderExtension: Invalid ${ semantic } attribute.` );
225
+
226
+ }
227
+
228
+ }
229
+
230
+ attributes.push( attribute );
231
+
232
+ }
233
+
234
+ if ( attributes.every( attribute => attribute === undefined ) ) break;
235
+
236
+ if ( attributes.some( attribute => attribute === undefined ) ) {
237
+
238
+ throw new Error( `THREE.GLTFGaussianSplatLoaderExtension: Incomplete KHR_gaussian_splatting SH degree ${ degree } coefficients.` );
239
+
240
+ }
241
+
242
+ const band = createPackedSphericalHarmonicsBand( count, degree );
243
+ const target = band.bytes;
244
+ const byteStride = SH_BAND_WORDS[ degree ] * 4;
245
+
246
+ for ( let i = 0; i < count; i ++ ) {
247
+
248
+ for ( let coefficient = 0; coefficient < coefficientCount; coefficient ++ ) {
249
+
250
+ const attribute = attributes[ coefficient ];
251
+ const targetOffset = i * byteStride + coefficient * 3;
252
+
253
+ target[ targetOffset ] = attribute.getX( i ) * 128 + 128;
254
+ target[ targetOffset + 1 ] = attribute.getY( i ) * 128 + 128;
255
+ target[ targetOffset + 2 ] = attribute.getZ( i ) * 128 + 128;
256
+
257
+ }
258
+
259
+ }
260
+
261
+ sphericalHarmonics[ `sh${ degree }` ] = band.packed;
262
+
263
+ }
264
+
265
+ for ( const semantic in primitiveDef.attributes ) {
266
+
267
+ const match = semantic.match( /^KHR_gaussian_splatting:SH_DEGREE_([1-3])_COEF_/ );
268
+
269
+ if ( match !== null && sphericalHarmonics[ `sh${ match[ 1 ] }` ] === undefined ) {
270
+
271
+ throw new Error( 'THREE.GLTFGaussianSplatLoaderExtension: KHR_gaussian_splatting spherical harmonics attributes must be contiguous.' );
272
+
273
+ }
274
+
275
+ }
276
+
277
+ return sphericalHarmonics;
278
+
279
+ }
280
+
281
+ function getGaussianSplatAttribute( geometry, primitiveDef, semantic ) {
282
+
283
+ if ( primitiveDef.attributes[ semantic ] === undefined ) {
284
+
285
+ throw new Error( `THREE.GLTFGaussianSplatLoaderExtension: KHR_gaussian_splatting requires ${ semantic }.` );
286
+
287
+ }
288
+
289
+ const attributeName = ATTRIBUTES[ semantic ] || semantic.toLowerCase();
290
+ const attribute = geometry.getAttribute( attributeName );
291
+
292
+ if ( attribute === undefined ) {
293
+
294
+ throw new Error( `THREE.GLTFGaussianSplatLoaderExtension: KHR_gaussian_splatting attribute ${ semantic } was not loaded.` );
295
+
296
+ }
297
+
298
+ return attribute;
299
+
300
+ }
301
+
302
+ function getOptionalGaussianSplatAttribute( geometry, primitiveDef, semantic ) {
303
+
304
+ if ( primitiveDef.attributes[ semantic ] === undefined ) return undefined;
305
+
306
+ const attributeName = ATTRIBUTES[ semantic ] || semantic.toLowerCase();
307
+
308
+ return geometry.getAttribute( attributeName );
309
+
310
+ }
311
+
312
+ function assignExtrasToUserData( object, gltfDef ) {
313
+
314
+ if ( gltfDef.extras !== undefined ) {
315
+
316
+ if ( typeof gltfDef.extras === 'object' ) {
317
+
318
+ Object.assign( object.userData, gltfDef.extras );
319
+
320
+ } else {
321
+
322
+ console.warn( 'THREE.GLTFGaussianSplatLoaderExtension: Ignoring primitive type .extras, ' + gltfDef.extras );
323
+
324
+ }
325
+
326
+ }
327
+
328
+ }
329
+
330
+ export { GLTFGaussianSplatLoaderExtension };
@@ -104,7 +104,8 @@ import { clone } from '../utils/SkeletonUtils.js';
104
104
  * - EXT_texture_avif
105
105
  * - EXT_texture_webp
106
106
  *
107
- * The following glTF 2.0 extension is supported by an external user plugin:
107
+ * The following glTF 2.0 extensions are supported by separately registered plugins:
108
+ * - KHR_gaussian_splatting
108
109
  * - [KHR_materials_variants](https://github.com/takahirox/three-gltf-extensions)
109
110
  * - [MSFT_texture_dds](https://github.com/takahirox/three-gltf-extensions)
110
111
  * - [KHR_animation_pointer](https://github.com/needle-tools/three-animation-pointer)
@@ -1786,6 +1787,9 @@ class GLTFMeshGpuInstancing {
1786
1787
  }
1787
1788
 
1788
1789
  // Add instance attributes to the geometry, excluding TRS.
1790
+
1791
+ let instanceGeometry = null;
1792
+
1789
1793
  for ( const attributeName in attributes ) {
1790
1794
 
1791
1795
  if ( attributeName === '_COLOR_0' ) {
@@ -1797,7 +1801,36 @@ class GLTFMeshGpuInstancing {
1797
1801
  attributeName !== 'ROTATION' &&
1798
1802
  attributeName !== 'SCALE' ) {
1799
1803
 
1800
- mesh.geometry.setAttribute( attributeName, attributes[ attributeName ] );
1804
+ if ( instanceGeometry === null ) {
1805
+
1806
+ // do a shallow clone of the goemetry so per-instance data are not shared
1807
+
1808
+ const source = instancedMesh.geometry;
1809
+ instanceGeometry = new BufferGeometry();
1810
+ instanceGeometry.name = source.name;
1811
+
1812
+ for ( const name in source.attributes ) instanceGeometry.setAttribute( name, source.attributes[ name ] );
1813
+ for ( const name in source.morphAttributes ) instanceGeometry.morphAttributes[ name ] = source.morphAttributes[ name ];
1814
+ if ( source.index !== null ) instanceGeometry.setIndex( source.index );
1815
+
1816
+ instanceGeometry.morphTargetsRelative = source.morphTargetsRelative;
1817
+
1818
+ for ( const group of source.groups ) instanceGeometry.addGroup( group.start, group.count, group.materialIndex );
1819
+
1820
+ if ( source.boundingBox !== null ) instanceGeometry.boundingBox = source.boundingBox.clone();
1821
+ if ( source.boundingSphere !== null ) instanceGeometry.boundingSphere = source.boundingSphere.clone();
1822
+
1823
+ instanceGeometry.drawRange.start = source.drawRange.start;
1824
+ instanceGeometry.drawRange.count = source.drawRange.count;
1825
+
1826
+ instanceGeometry.userData = Object.assign( {}, source.userData );
1827
+
1828
+ instancedMesh.geometry = instanceGeometry;
1829
+
1830
+ }
1831
+
1832
+ const attr = attributes[ attributeName ];
1833
+ instanceGeometry.setAttribute( attributeName, new InstancedBufferAttribute( attr.array, attr.itemSize, attr.normalized ) );
1801
1834
 
1802
1835
  }
1803
1836
 
@@ -2040,6 +2073,27 @@ class GLTFTextureTransformExtension {
2040
2073
 
2041
2074
  }
2042
2075
 
2076
+ if ( transform.rotation !== undefined ) {
2077
+
2078
+ // glTF's KHR_texture_transform order differs from three.js:
2079
+ // glTF defines the UV transform as T * R * S
2080
+ // three.js defines the UV transform as T * S * R
2081
+ //
2082
+ // To fix this, we need to override the matrix with the value computed per glTF spec
2083
+ // We still set the other fields so that you can inspect/export the resulting object.
2084
+
2085
+ const c = Math.cos( texture.rotation );
2086
+ const s = Math.sin( texture.rotation );
2087
+
2088
+ texture.matrix.set(
2089
+ texture.repeat.x * c, texture.repeat.y * s, texture.offset.x,
2090
+ - texture.repeat.x * s, texture.repeat.y * c, texture.offset.y,
2091
+ 0, 0, 1
2092
+ );
2093
+ texture.matrixAutoUpdate = false;
2094
+
2095
+ }
2096
+
2043
2097
  texture.needsUpdate = true;
2044
2098
 
2045
2099
  return texture;
@@ -3776,6 +3830,18 @@ class GLTFParser {
3776
3830
 
3777
3831
  }
3778
3832
 
3833
+ // Convert strip/fan primitives to triangles
3834
+
3835
+ if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {
3836
+
3837
+ geometryPromise = geometryPromise.then( geometry => toTrianglesDrawMode( geometry, TriangleStripDrawMode ) );
3838
+
3839
+ } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {
3840
+
3841
+ geometryPromise = geometryPromise.then( geometry => toTrianglesDrawMode( geometry, TriangleFanDrawMode ) );
3842
+
3843
+ }
3844
+
3779
3845
  // Cache this geometry
3780
3846
  cache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };
3781
3847
 
@@ -3819,7 +3885,7 @@ class GLTFParser {
3819
3885
 
3820
3886
  pending.push( parser.loadGeometries( primitives ) );
3821
3887
 
3822
- return Promise.all( pending ).then( function ( results ) {
3888
+ return Promise.all( pending ).then( async function ( results ) {
3823
3889
 
3824
3890
  const materials = results.slice( 0, results.length - 1 );
3825
3891
  const geometries = results[ results.length - 1 ];
@@ -3842,8 +3908,17 @@ class GLTFParser {
3842
3908
  primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||
3843
3909
  primitive.mode === undefined ) {
3844
3910
 
3911
+ const needsSkinning = meshDef.isSkinnedMesh === true;
3912
+ const hasSkinningAttributes = geometry.hasAttribute( 'skinIndex' ) && geometry.hasAttribute( 'skinWeight' );
3913
+
3914
+ if ( needsSkinning && hasSkinningAttributes === false ) {
3915
+
3916
+ console.warn( 'THREE.GLTFLoader: Missing skinIndex or skinWeight attributes. Skinning disabled.' );
3917
+
3918
+ }
3919
+
3845
3920
  // .isSkinnedMesh isn't in glTF spec. See ._markDefs()
3846
- mesh = meshDef.isSkinnedMesh === true
3921
+ mesh = ( needsSkinning && hasSkinningAttributes )
3847
3922
  ? new SkinnedMesh( geometry, material )
3848
3923
  : new Mesh( geometry, material );
3849
3924
 
@@ -3854,16 +3929,6 @@ class GLTFParser {
3854
3929
 
3855
3930
  }
3856
3931
 
3857
- if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {
3858
-
3859
- mesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleStripDrawMode );
3860
-
3861
- } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {
3862
-
3863
- mesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleFanDrawMode );
3864
-
3865
- }
3866
-
3867
3932
  } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
3868
3933
 
3869
3934
  mesh = new LineSegments( geometry, material );