super-three 0.184.0 → 0.185.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 (366) hide show
  1. package/build/three.cjs +1260 -927
  2. package/build/three.core.js +1104 -829
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +156 -98
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +11 -4
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +7538 -3367
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +7538 -3366
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +3 -0
  13. package/examples/jsm/controls/ArcballControls.js +6 -2
  14. package/examples/jsm/controls/FirstPersonControls.js +79 -42
  15. package/examples/jsm/controls/TransformControls.js +68 -15
  16. package/examples/jsm/csm/CSMFrustum.js +31 -6
  17. package/examples/jsm/csm/CSMShadowNode.js +4 -1
  18. package/examples/jsm/effects/AsciiEffect.js +14 -1
  19. package/examples/jsm/exporters/DRACOExporter.js +27 -6
  20. package/examples/jsm/exporters/GLTFExporter.js +114 -12
  21. package/examples/jsm/exporters/PLYExporter.js +286 -73
  22. package/examples/jsm/exporters/USDZExporter.js +347 -112
  23. package/examples/jsm/generators/CityGenerator.js +346 -0
  24. package/examples/jsm/generators/ForestGenerator.js +347 -0
  25. package/examples/jsm/generators/TerrainGenerator.js +504 -0
  26. package/examples/jsm/generators/TreeGenerator.js +377 -0
  27. package/examples/jsm/generators/city/SidewalkGenerator.js +253 -0
  28. package/examples/jsm/generators/city/SkyscraperGenerator.js +1357 -0
  29. package/examples/jsm/geometries/LoftGeometry.js +355 -0
  30. package/examples/jsm/helpers/LightProbeGridHelper.js +1 -1
  31. package/examples/jsm/helpers/LightProbeHelper.js +5 -4
  32. package/examples/jsm/helpers/ViewHelper.js +16 -6
  33. package/examples/jsm/inspector/Inspector.js +53 -15
  34. package/examples/jsm/inspector/RendererInspector.js +152 -36
  35. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +1 -1
  36. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -1
  37. package/examples/jsm/inspector/tabs/Console.js +200 -18
  38. package/examples/jsm/inspector/tabs/Memory.js +8 -0
  39. package/examples/jsm/inspector/tabs/Parameters.js +64 -4
  40. package/examples/jsm/inspector/tabs/Performance.js +21 -6
  41. package/examples/jsm/inspector/tabs/Settings.js +51 -9
  42. package/examples/jsm/inspector/tabs/Timeline.js +178 -93
  43. package/examples/jsm/inspector/tabs/Viewer.js +628 -16
  44. package/examples/jsm/inspector/ui/Graph.js +162 -25
  45. package/examples/jsm/inspector/ui/Item.js +92 -13
  46. package/examples/jsm/inspector/ui/List.js +1 -1
  47. package/examples/jsm/inspector/ui/Profiler.js +90 -45
  48. package/examples/jsm/inspector/ui/Style.js +1788 -1401
  49. package/examples/jsm/inspector/ui/Tab.js +5 -3
  50. package/examples/jsm/inspector/ui/Values.js +71 -6
  51. package/examples/jsm/inspector/ui/utils.js +130 -10
  52. package/examples/jsm/libs/basis/README.md +0 -1
  53. package/examples/jsm/libs/demuxer_mp4.js +3 -3
  54. package/examples/jsm/libs/draco/README.md +0 -1
  55. package/examples/jsm/libs/meshopt_clusterizer.module.js +421 -0
  56. package/examples/jsm/libs/meshopt_simplifier.module.js +627 -0
  57. package/examples/jsm/libs/mikktspace.module.js +34 -9
  58. package/examples/jsm/lighting/ClusteredLighting.js +55 -0
  59. package/examples/jsm/lighting/LightProbeGrid.js +106 -76
  60. package/examples/jsm/lines/LineMaterial.js +38 -15
  61. package/examples/jsm/lines/LineSegments2.js +8 -0
  62. package/examples/jsm/lines/webgpu/LineSegments2.js +8 -0
  63. package/examples/jsm/loaders/3DMLoader.js +1 -1
  64. package/examples/jsm/loaders/DRACOLoader.js +46 -13
  65. package/examples/jsm/loaders/EXRLoader.js +27 -55
  66. package/examples/jsm/loaders/HDRLoader.js +6 -28
  67. package/examples/jsm/loaders/KTX2Loader.js +31 -12
  68. package/examples/jsm/loaders/LDrawLoader.js +8 -8
  69. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  70. package/examples/jsm/loaders/LUTCubeLoader.js +2 -2
  71. package/examples/jsm/loaders/LWOLoader.js +4 -0
  72. package/examples/jsm/loaders/LottieLoader.js +1 -1
  73. package/examples/jsm/loaders/MaterialXLoader.js +31 -9
  74. package/examples/jsm/loaders/NRRDLoader.js +3 -3
  75. package/examples/jsm/loaders/PCDLoader.js +7 -7
  76. package/examples/jsm/loaders/PLYLoader.js +218 -55
  77. package/examples/jsm/loaders/SVGLoader.js +547 -495
  78. package/examples/jsm/loaders/TTFLoader.js +1 -1
  79. package/examples/jsm/loaders/USDLoader.js +33 -9
  80. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  81. package/examples/jsm/loaders/usd/USDAParser.js +93 -20
  82. package/examples/jsm/loaders/usd/USDCParser.js +1 -1
  83. package/examples/jsm/loaders/usd/USDComposer.js +52 -19
  84. package/examples/jsm/misc/TileCreasedNormalsPlugin.js +270 -0
  85. package/examples/jsm/misc/Volume.js +2 -2
  86. package/examples/jsm/objects/GroundedSkybox.js +1 -1
  87. package/examples/jsm/objects/Reflector.js +2 -3
  88. package/examples/jsm/objects/Water2Mesh.js +1 -1
  89. package/examples/jsm/physics/AmmoPhysics.js +15 -8
  90. package/examples/jsm/physics/RapierPhysics.js +27 -2
  91. package/examples/jsm/shaders/VolumeShader.js +31 -44
  92. package/examples/jsm/transpiler/GLSLDecoder.js +6 -6
  93. package/examples/jsm/transpiler/Linker.js +1 -1
  94. package/examples/jsm/tsl/display/BloomNode.js +59 -19
  95. package/examples/jsm/tsl/display/DepthOfFieldNode.js +2 -2
  96. package/examples/jsm/tsl/display/FXAANode.js +11 -12
  97. package/examples/jsm/tsl/display/GTAONode.js +34 -13
  98. package/examples/jsm/tsl/display/GodraysNode.js +1 -1
  99. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +560 -0
  100. package/examples/jsm/tsl/display/PixelationPassNode.js +2 -2
  101. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +912 -0
  102. package/examples/jsm/tsl/display/SSAAPassNode.js +13 -25
  103. package/examples/jsm/tsl/display/SSGINode.js +89 -39
  104. package/examples/jsm/tsl/display/SSRNode.js +829 -132
  105. package/examples/jsm/tsl/display/SSSNode.js +2 -2
  106. package/examples/jsm/tsl/display/TemporalReprojectNode.js +1023 -0
  107. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +622 -0
  108. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +1 -1
  109. package/examples/jsm/tsl/math/curlNoise.js +107 -0
  110. package/examples/jsm/tsl/shadows/TileShadowNode.js +1 -1
  111. package/examples/jsm/tsl/shadows/TileShadowNodeHelper.js +3 -3
  112. package/examples/jsm/tsl/utils/GroundedSkybox.js +62 -0
  113. package/examples/jsm/tsl/utils/RNoise.js +51 -0
  114. package/examples/jsm/tsl/utils/SpecularHelpers.js +325 -0
  115. package/examples/jsm/utils/BufferGeometryUtils.js +126 -59
  116. package/examples/jsm/utils/GeometryCompressionUtils.js +1 -1
  117. package/examples/jsm/utils/SceneOptimizer.js +1 -1
  118. package/examples/jsm/webxr/ARButton.js +1 -1
  119. package/examples/jsm/webxr/WebGLXRFallback.js +89 -0
  120. package/examples/jsm/webxr/XRControllerModelFactory.js +2 -2
  121. package/package.json +7 -7
  122. package/src/Three.TSL.js +10 -3
  123. package/src/Three.WebGPU.js +4 -0
  124. package/src/animation/AnimationAction.js +15 -11
  125. package/src/animation/AnimationClip.js +0 -139
  126. package/src/animation/KeyframeTrack.js +2 -2
  127. package/src/animation/PropertyBinding.js +2 -2
  128. package/src/cameras/Camera.js +2 -2
  129. package/src/cameras/StereoCamera.js +5 -2
  130. package/src/constants.js +1 -1
  131. package/src/core/BufferGeometry.js +29 -7
  132. package/src/core/Object3D.js +17 -7
  133. package/src/core/Raycaster.js +1 -1
  134. package/src/core/RenderTarget.js +15 -2
  135. package/src/extras/PMREMGenerator.js +6 -4
  136. package/src/extras/TextureUtils.js +1 -1
  137. package/src/extras/core/ShapePath.js +149 -160
  138. package/src/geometries/SphereGeometry.js +8 -3
  139. package/src/helpers/DirectionalLightHelper.js +2 -0
  140. package/src/helpers/HemisphereLightHelper.js +2 -0
  141. package/src/helpers/PointLightHelper.js +2 -0
  142. package/src/helpers/SpotLightHelper.js +1 -1
  143. package/src/loaders/DataTextureLoader.js +69 -38
  144. package/src/loaders/LoadingManager.js +5 -0
  145. package/src/loaders/MaterialLoader.js +36 -266
  146. package/src/loaders/ObjectLoader.js +3 -1
  147. package/src/materials/LineBasicMaterial.js +4 -0
  148. package/src/materials/Material.js +196 -1
  149. package/src/materials/MeshBasicMaterial.js +24 -0
  150. package/src/materials/MeshDepthMaterial.js +10 -0
  151. package/src/materials/MeshDistanceMaterial.js +10 -0
  152. package/src/materials/MeshLambertMaterial.js +40 -1
  153. package/src/materials/MeshMatcapMaterial.js +25 -1
  154. package/src/materials/MeshNormalMaterial.js +9 -1
  155. package/src/materials/MeshPhongMaterial.js +40 -1
  156. package/src/materials/MeshPhysicalMaterial.js +38 -0
  157. package/src/materials/MeshStandardMaterial.js +42 -1
  158. package/src/materials/MeshToonMaterial.js +34 -1
  159. package/src/materials/PointsMaterial.js +7 -0
  160. package/src/materials/ShaderMaterial.js +86 -0
  161. package/src/materials/SpriteMaterial.js +7 -0
  162. package/src/materials/nodes/Line2NodeMaterial.js +378 -322
  163. package/src/materials/nodes/MeshBasicNodeMaterial.js +2 -2
  164. package/src/materials/nodes/MeshNormalNodeMaterial.js +2 -2
  165. package/src/materials/nodes/MeshPhongNodeMaterial.js +0 -9
  166. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +0 -30
  167. package/src/materials/nodes/MeshSSSNodeMaterial.js +0 -13
  168. package/src/materials/nodes/MeshStandardNodeMaterial.js +0 -11
  169. package/src/materials/nodes/NodeMaterial.js +115 -71
  170. package/src/materials/nodes/SpriteNodeMaterial.js +0 -10
  171. package/src/materials/nodes/manager/NodeMaterialObserver.js +49 -20
  172. package/src/math/Box3.js +5 -0
  173. package/src/math/FrustumArray.js +103 -133
  174. package/src/math/Interpolant.js +1 -1
  175. package/src/math/MathUtils.js +2 -2
  176. package/src/math/Matrix3.js +11 -0
  177. package/src/math/Matrix4.js +28 -3
  178. package/src/math/Vector2.js +2 -2
  179. package/src/math/Vector3.js +2 -2
  180. package/src/math/Vector4.js +2 -2
  181. package/src/math/interpolants/BezierInterpolant.js +4 -6
  182. package/src/nodes/Nodes.js +2 -5
  183. package/src/nodes/TSL.js +8 -6
  184. package/src/nodes/accessors/Arrays.js +4 -4
  185. package/src/nodes/accessors/Batch.js +108 -0
  186. package/src/nodes/accessors/Bitangent.js +2 -2
  187. package/src/nodes/accessors/BufferAttributeNode.js +13 -2
  188. package/src/nodes/accessors/Camera.js +7 -7
  189. package/src/nodes/accessors/ClippingNode.js +1 -1
  190. package/src/nodes/accessors/Instance.js +264 -0
  191. package/src/nodes/accessors/MaterialNode.js +18 -2
  192. package/src/nodes/accessors/MaterialProperties.js +4 -3
  193. package/src/nodes/accessors/{MorphNode.js → Morph.js} +99 -112
  194. package/src/nodes/accessors/Normal.js +13 -13
  195. package/src/nodes/accessors/Position.js +5 -1
  196. package/src/nodes/accessors/ReferenceNode.js +1 -0
  197. package/src/nodes/accessors/ReflectVector.js +3 -3
  198. package/src/nodes/accessors/SceneProperties.js +1 -1
  199. package/src/nodes/accessors/Skinning.js +263 -0
  200. package/src/nodes/accessors/StorageBufferNode.js +2 -2
  201. package/src/nodes/accessors/StorageTexture3DNode.js +100 -0
  202. package/src/nodes/accessors/StorageTextureNode.js +39 -7
  203. package/src/nodes/accessors/Tangent.js +4 -4
  204. package/src/nodes/accessors/TextureNode.js +60 -5
  205. package/src/nodes/code/FunctionNode.js +2 -16
  206. package/src/nodes/core/MRTNode.js +7 -2
  207. package/src/nodes/core/Node.js +39 -2
  208. package/src/nodes/core/NodeBuilder.js +201 -41
  209. package/src/nodes/core/NodeUtils.js +13 -13
  210. package/src/nodes/core/OutputStructNode.js +1 -1
  211. package/src/nodes/core/OverrideContextNode.js +153 -0
  212. package/src/nodes/core/PropertyNode.js +51 -5
  213. package/src/nodes/core/StackNode.js +56 -34
  214. package/src/nodes/core/StructNode.js +4 -6
  215. package/src/nodes/core/StructTypeNode.js +6 -6
  216. package/src/nodes/core/VarNode.js +8 -0
  217. package/src/nodes/core/VaryingNode.js +12 -2
  218. package/src/nodes/display/BlendModes.js +1 -41
  219. package/src/nodes/display/BumpMapNode.js +6 -1
  220. package/src/nodes/display/ColorAdjustment.js +10 -9
  221. package/src/nodes/display/FrontFacingNode.js +38 -9
  222. package/src/nodes/display/NormalMapNode.js +2 -2
  223. package/src/nodes/display/PassNode.js +35 -43
  224. package/src/nodes/display/PremultiplyAlphaFunctions.js +39 -0
  225. package/src/nodes/display/RenderOutputNode.js +12 -3
  226. package/src/nodes/functions/VolumetricLightingModel.js +40 -7
  227. package/src/nodes/gpgpu/WorkgroupInfoNode.js +1 -1
  228. package/src/nodes/lighting/EnvironmentNode.js +2 -2
  229. package/src/nodes/lighting/IESSpotLightNode.js +40 -2
  230. package/src/nodes/lighting/LightingContextNode.js +10 -2
  231. package/src/nodes/lighting/LightsNode.js +90 -37
  232. package/src/nodes/lighting/PointShadowNode.js +6 -1
  233. package/src/nodes/lighting/ShadowFilterNode.js +21 -52
  234. package/src/nodes/lighting/ShadowNode.js +34 -14
  235. package/src/nodes/materialx/lib/mx_noise.js +2 -2
  236. package/src/nodes/math/ConditionalNode.js +3 -3
  237. package/src/nodes/math/MathNode.js +39 -11
  238. package/src/nodes/math/OperatorNode.js +23 -23
  239. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  240. package/src/nodes/pmrem/PMREMNode.js +33 -2
  241. package/src/nodes/tsl/TSLCore.js +63 -18
  242. package/src/nodes/utils/EquirectUV.js +30 -5
  243. package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
  244. package/src/nodes/utils/Packing.js +35 -4
  245. package/src/nodes/utils/RTTNode.js +40 -24
  246. package/src/nodes/utils/ReflectorNode.js +1 -0
  247. package/src/nodes/utils/StorageArrayElementNode.js +1 -1
  248. package/src/objects/BatchedMesh.js +22 -14
  249. package/src/objects/InstancedMesh.js +0 -11
  250. package/src/objects/Skeleton.js +0 -9
  251. package/src/renderers/WebGLRenderer.js +19 -15
  252. package/src/renderers/common/Backend.js +49 -5
  253. package/src/renderers/common/Bindings.js +114 -45
  254. package/src/renderers/common/Buffer.js +9 -0
  255. package/src/renderers/common/ClippingContext.js +10 -2
  256. package/src/renderers/common/Info.js +63 -22
  257. package/src/renderers/common/Lighting.js +53 -5
  258. package/src/renderers/common/RenderList.js +41 -4
  259. package/src/renderers/common/RenderObject.js +73 -13
  260. package/src/renderers/common/Renderer.js +281 -108
  261. package/src/renderers/common/Sampler.js +16 -48
  262. package/src/renderers/common/Textures.js +32 -5
  263. package/src/renderers/common/TimestampQueryPool.js +1 -1
  264. package/src/renderers/common/UniformsGroup.js +31 -9
  265. package/src/renderers/common/XRManager.js +340 -22
  266. package/src/renderers/common/extras/PMREMGenerator.js +15 -38
  267. package/src/renderers/common/nodes/NodeBuilderState.js +9 -1
  268. package/src/renderers/common/nodes/NodeLibrary.js +4 -4
  269. package/src/renderers/common/nodes/NodeManager.js +63 -14
  270. package/src/renderers/common/nodes/NodeUniformBuffer.js +13 -0
  271. package/src/renderers/shaders/ShaderChunk/common.glsl.js +13 -4
  272. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +0 -6
  273. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  274. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  275. package/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js +1 -1
  276. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  277. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +1 -1
  278. package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -2
  279. package/src/renderers/shaders/ShaderChunk/normal_vertex.glsl.js +6 -0
  280. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +1 -1
  281. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  282. package/src/renderers/shaders/ShaderLib/distance.glsl.js +1 -1
  283. package/src/renderers/webgl/WebGLOutput.js +2 -1
  284. package/src/renderers/webgl/WebGLProgram.js +5 -4
  285. package/src/renderers/webgl/WebGLPrograms.js +12 -5
  286. package/src/renderers/webgl/WebGLRenderLists.js +9 -1
  287. package/src/renderers/webgl/WebGLShaderCache.js +5 -11
  288. package/src/renderers/webgl/WebGLTextures.js +20 -7
  289. package/src/renderers/webgl/WebGLUniformsGroups.js +66 -38
  290. package/src/renderers/webgl-fallback/WebGLBackend.js +84 -25
  291. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +138 -8
  292. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +1 -1
  293. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -22
  294. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +4 -2
  295. package/src/renderers/webgpu/WebGPUBackend.js +480 -169
  296. package/src/renderers/webgpu/descriptors/GPUBindGroupDescriptor.js +48 -0
  297. package/src/renderers/webgpu/descriptors/GPUBufferDescriptor.js +57 -0
  298. package/src/renderers/webgpu/descriptors/GPUCommandEncoderDescriptor.js +30 -0
  299. package/src/renderers/webgpu/descriptors/GPUComputePassDescriptor.js +38 -0
  300. package/src/renderers/webgpu/descriptors/GPUComputePipelineDescriptor.js +48 -0
  301. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageDestInfo.js +47 -0
  302. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageSourceInfo.js +50 -0
  303. package/src/renderers/webgpu/descriptors/GPUExtent3D.js +51 -0
  304. package/src/renderers/webgpu/descriptors/GPUPipelineLayoutDescriptor.js +39 -0
  305. package/src/renderers/webgpu/descriptors/GPUQuerySetDescriptor.js +47 -0
  306. package/src/renderers/webgpu/descriptors/GPURenderBundleEncoderDescriptor.js +74 -0
  307. package/src/renderers/webgpu/descriptors/GPURenderPassColorAttachment.js +72 -0
  308. package/src/renderers/webgpu/descriptors/GPURenderPassDepthStencilAttachment.js +99 -0
  309. package/src/renderers/webgpu/descriptors/GPURenderPassDescriptor.js +72 -0
  310. package/src/renderers/webgpu/descriptors/GPURenderPassTimestampWrites.js +49 -0
  311. package/src/renderers/webgpu/descriptors/GPURenderPipelineDescriptor.js +130 -0
  312. package/src/renderers/webgpu/descriptors/GPUSamplerDescriptor.js +119 -0
  313. package/src/renderers/webgpu/descriptors/GPUShaderModuleDescriptor.js +46 -0
  314. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferInfo.js +57 -0
  315. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferLayout.js +48 -0
  316. package/src/renderers/webgpu/descriptors/GPUTexelCopyTextureInfo.js +61 -0
  317. package/src/renderers/webgpu/descriptors/GPUTextureDescriptor.js +99 -0
  318. package/src/renderers/webgpu/descriptors/GPUTextureViewDescriptor.js +108 -0
  319. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -1
  320. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +164 -7
  321. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +1 -1
  322. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +98 -38
  323. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -68
  324. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +164 -69
  325. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +158 -95
  326. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +297 -141
  327. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +33 -18
  328. package/src/renderers/webgpu/utils/WebGPUUtils.js +38 -3
  329. package/src/textures/DepthTexture.js +1 -1
  330. package/src/textures/ExternalTexture.js +0 -3
  331. package/examples/fonts/LICENSE +0 -13
  332. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  333. package/examples/fonts/MPLUSRounded1c/OFL.txt +0 -91
  334. package/examples/fonts/README.md +0 -11
  335. package/examples/fonts/droid/NOTICE +0 -190
  336. package/examples/fonts/droid/README.txt +0 -18
  337. package/examples/fonts/droid/droid_sans_bold.typeface.json +0 -1
  338. package/examples/fonts/droid/droid_sans_mono_regular.typeface.json +0 -1
  339. package/examples/fonts/droid/droid_sans_regular.typeface.json +0 -1
  340. package/examples/fonts/droid/droid_serif_bold.typeface.json +0 -1
  341. package/examples/fonts/droid/droid_serif_regular.typeface.json +0 -1
  342. package/examples/fonts/gentilis_bold.typeface.json +0 -1
  343. package/examples/fonts/gentilis_regular.typeface.json +0 -1
  344. package/examples/fonts/helvetiker_bold.typeface.json +0 -1
  345. package/examples/fonts/helvetiker_regular.typeface.json +0 -1
  346. package/examples/fonts/optimer_bold.typeface.json +0 -1
  347. package/examples/fonts/optimer_regular.typeface.json +0 -1
  348. package/examples/fonts/ttf/README.md +0 -9
  349. package/examples/fonts/ttf/kenpixel.ttf +0 -0
  350. package/examples/jsm/inspector/extensions/extensions.json +0 -6
  351. package/examples/jsm/libs/ammo.wasm.js +0 -822
  352. package/examples/jsm/libs/ammo.wasm.wasm +0 -0
  353. package/examples/jsm/libs/draco/draco_encoder.js +0 -33
  354. package/examples/jsm/libs/draco/gltf/draco_encoder.js +0 -33
  355. package/examples/jsm/libs/lottie_canvas.module.js +0 -14849
  356. package/examples/jsm/libs/opentype.module.js +0 -14506
  357. package/examples/jsm/libs/rhino3dm/rhino3dm.js +0 -21
  358. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +0 -16
  359. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  360. package/examples/jsm/lighting/TiledLighting.js +0 -42
  361. package/examples/jsm/tsl/display/AnamorphicNode.js +0 -293
  362. package/examples/jsm/tsl/lighting/TiledLightsNode.js +0 -442
  363. package/src/nodes/accessors/BatchNode.js +0 -163
  364. package/src/nodes/accessors/InstanceNode.js +0 -349
  365. package/src/nodes/accessors/InstancedMeshNode.js +0 -50
  366. package/src/nodes/accessors/SkinningNode.js +0 -328
@@ -0,0 +1,622 @@
1
+ import { DataTexture, FloatType, RGBAFormat, Vector2, Vector3, LightsNode, NodeUpdateType } from 'three/webgpu';
2
+
3
+ import {
4
+ attributeArray, nodeProxy, int, float, vec3, vec4, ivec2, ivec4, uniform, Break, Loop, positionView,
5
+ Fn, If, Return, textureLoad, instanceIndex, screenCoordinate, directPointLight,
6
+ renderGroup,
7
+ min, max, pow, log, clamp, dot
8
+ } from 'three/tsl';
9
+
10
+ const _vector3 = /*@__PURE__*/ new Vector3();
11
+ const _size = /*@__PURE__*/ new Vector2();
12
+
13
+ /**
14
+ * A custom version of `LightsNode` implementing Forward+ clustered shading:
15
+ * the view frustum is subdivided into a 3D grid of clusters (X × Y screen tiles
16
+ * times an exponentially-spaced set of Z depth slices), and each cluster holds
17
+ * only the point lights whose spheres intersect it. At shading time each fragment
18
+ * looks up its cluster and loops over just that cluster's lights. Unlike 2D tiled
19
+ * lighting, clustered shading culls lights that share screen pixels but lie at
20
+ * different depths — suitable for 3D scenes with real depth complexity.
21
+ *
22
+ * @augments LightsNode
23
+ * @three_import import { clusteredLights } from 'three/addons/tsl/lighting/ClusteredLightsNode.js';
24
+ */
25
+ class ClusteredLightsNode extends LightsNode {
26
+
27
+ static get type() {
28
+
29
+ return 'ClusteredLightsNode';
30
+
31
+ }
32
+
33
+ /**
34
+ * Constructs a new clustered lights node.
35
+ *
36
+ * @param {number} [maxLights=1024] - Maximum number of point lights.
37
+ * @param {number} [tileSize=32] - Screen tile size in pixels (cluster XY size).
38
+ * @param {number} [zSlices=24] - Number of exponential depth slices.
39
+ * @param {number} [maxLightsPerCluster=64] - Per-cluster light-list capacity.
40
+ */
41
+ constructor( maxLights = 1024, tileSize = 32, zSlices = 24, maxLightsPerCluster = 64 ) {
42
+
43
+ super();
44
+
45
+ this.materialLights = [];
46
+ this.clusteredLights = [];
47
+ this._allLights = [];
48
+
49
+ this.maxLights = maxLights;
50
+ this.tileSize = tileSize;
51
+ this.zSlices = zSlices;
52
+ this.maxLightsPerCluster = maxLightsPerCluster;
53
+
54
+ this._chunksPerCluster = Math.ceil( maxLightsPerCluster / 4 );
55
+
56
+ this._bufferSize = null;
57
+ this._lightIndexes = null;
58
+ this._screenClusterIndex = null;
59
+ this._compute = null;
60
+ this._lightsTexture = null;
61
+ this._zSliceRangesTexture = null;
62
+ this._zSliceRangesData = null;
63
+ this._lightViewZ = new Float32Array( maxLights );
64
+ this._lightSortOrder = [];
65
+
66
+ this._lightsCount = uniform( 0, 'int' );
67
+
68
+ // Render-group uniforms: shared between compute and fragment passes,
69
+ // updated manually each frame in updateBefore (compute lacks a camera context).
70
+ this._cameraNear = uniform( 0 ).setName( 'clusteredCameraNear' ).setGroup( renderGroup );
71
+ this._cameraFar = uniform( 0 ).setName( 'clusteredCameraFar' ).setGroup( renderGroup );
72
+ this._cameraViewMatrix = uniform( 'mat4' ).setName( 'clusteredCameraViewMatrix' ).setGroup( renderGroup );
73
+ this._cameraProjectionMatrix = uniform( 'mat4' ).setName( 'clusteredCameraProjectionMatrix' ).setGroup( renderGroup );
74
+
75
+ this._gridDimensions = uniform( new Vector2() );
76
+
77
+ this.updateBeforeType = NodeUpdateType.RENDER;
78
+
79
+ }
80
+
81
+ customCacheKey() {
82
+
83
+ return ( this._compute ? this._compute.getCacheKey() : 0 ) + super.customCacheKey();
84
+
85
+ }
86
+
87
+ updateLightsTexture( camera ) {
88
+
89
+ const { _lightsTexture: lightsTexture, clusteredLights } = this;
90
+
91
+ const data = lightsTexture.image.data;
92
+ const lineSize = lightsTexture.image.width * 4;
93
+ const count = clusteredLights.length;
94
+
95
+ this._lightsCount.value = count;
96
+
97
+ // Sort lights by view-space depth for Z-culling
98
+
99
+ const viewZ = this._lightViewZ;
100
+ const order = this._lightSortOrder;
101
+
102
+ for ( let i = 0; i < count; i ++ ) {
103
+
104
+ _vector3.setFromMatrixPosition( clusteredLights[ i ].matrixWorld );
105
+ _vector3.applyMatrix4( camera.matrixWorldInverse );
106
+ viewZ[ i ] = _vector3.z;
107
+ order[ i ] = i;
108
+
109
+ }
110
+
111
+ order.length = count;
112
+ order.sort( ( a, b ) => viewZ[ a ] - viewZ[ b ] );
113
+
114
+ // Write sorted lights to texture
115
+
116
+ for ( let i = 0; i < count; i ++ ) {
117
+
118
+ const light = clusteredLights[ order[ i ] ];
119
+
120
+ _vector3.setFromMatrixPosition( light.matrixWorld );
121
+
122
+ const offset = i * 4;
123
+
124
+ data[ offset + 0 ] = _vector3.x;
125
+ data[ offset + 1 ] = _vector3.y;
126
+ data[ offset + 2 ] = _vector3.z;
127
+ data[ offset + 3 ] = light.distance;
128
+
129
+ data[ lineSize + offset + 0 ] = light.color.r * light.intensity;
130
+ data[ lineSize + offset + 1 ] = light.color.g * light.intensity;
131
+ data[ lineSize + offset + 2 ] = light.color.b * light.intensity;
132
+ data[ lineSize + offset + 3 ] = light.decay;
133
+
134
+ }
135
+
136
+ lightsTexture.needsUpdate = true;
137
+
138
+ // Compute per Z-slice light ranges
139
+
140
+ const zRanges = this._zSliceRangesData;
141
+
142
+ if ( zRanges === null ) return;
143
+
144
+ const near = camera.near;
145
+ const far = camera.far;
146
+ const NZ = this.zSlices;
147
+
148
+ for ( let z = 0; z < NZ; z ++ ) {
149
+
150
+ // Exponential Z-slice bounds (view-space, negative values)
151
+ const sliceNear = - ( near * Math.pow( far / near, z / NZ ) );
152
+ const sliceFar = - ( near * Math.pow( far / near, ( z + 1 ) / NZ ) );
153
+
154
+ let rangeStart = count;
155
+ let rangeEnd = 0;
156
+
157
+ for ( let i = 0; i < count; i ++ ) {
158
+
159
+ const vz = viewZ[ order[ i ] ];
160
+ const r = clusteredLights[ order[ i ] ].distance;
161
+ const radius = r > 0 ? r : far;
162
+
163
+ // Light sphere Z: [vz - radius, vz + radius]
164
+ // Slice Z: [sliceFar, sliceNear] (both negative, sliceFar < sliceNear)
165
+ if ( vz + radius >= sliceFar && vz - radius <= sliceNear ) {
166
+
167
+ if ( i < rangeStart ) rangeStart = i;
168
+ if ( i + 1 > rangeEnd ) rangeEnd = i + 1;
169
+
170
+ }
171
+
172
+ }
173
+
174
+ if ( rangeStart >= count ) {
175
+
176
+ rangeStart = 0;
177
+ rangeEnd = 0;
178
+
179
+ }
180
+
181
+ zRanges[ z * 4 ] = rangeStart;
182
+ zRanges[ z * 4 + 1 ] = rangeEnd;
183
+
184
+ }
185
+
186
+ this._zSliceRangesTexture.needsUpdate = true;
187
+
188
+ }
189
+
190
+ updateBefore( frame ) {
191
+
192
+ const { renderer, camera } = frame;
193
+
194
+ this.updateProgram( renderer );
195
+
196
+ this.updateLightsTexture( camera );
197
+
198
+ this._cameraNear.value = camera.near;
199
+ this._cameraFar.value = camera.far;
200
+ this._cameraViewMatrix.value = camera.matrixWorldInverse;
201
+ this._cameraProjectionMatrix.value = camera.projectionMatrix;
202
+
203
+ renderer.compute( this._compute );
204
+
205
+ }
206
+
207
+ setLights( lights ) {
208
+
209
+ this._allLights = lights;
210
+
211
+ const { clusteredLights, materialLights } = this;
212
+
213
+ let materialIndex = 0;
214
+ let clusteredIndex = 0;
215
+
216
+ for ( const light of lights ) {
217
+
218
+ if ( light.isPointLight === true && light.castShadow !== true ) {
219
+
220
+ clusteredLights[ clusteredIndex ++ ] = light;
221
+
222
+ } else {
223
+
224
+ materialLights[ materialIndex ++ ] = light;
225
+
226
+ }
227
+
228
+ }
229
+
230
+ materialLights.length = materialIndex;
231
+ clusteredLights.length = clusteredIndex;
232
+
233
+ return super.setLights( materialLights );
234
+
235
+ }
236
+
237
+ getLights() {
238
+
239
+ return this._allLights;
240
+
241
+ }
242
+
243
+ getBlock() {
244
+
245
+ return this._lightIndexes.element( this._screenClusterIndex.mul( int( this._chunksPerCluster ) ) );
246
+
247
+ }
248
+
249
+ getTile( element ) {
250
+
251
+ element = int( element );
252
+
253
+ const stride = int( 4 );
254
+ const chunkOffset = element.div( stride );
255
+ const idx = this._screenClusterIndex.mul( int( this._chunksPerCluster ) ).add( chunkOffset );
256
+
257
+ return this._lightIndexes.element( idx ).element( element.mod( stride ) );
258
+
259
+ }
260
+
261
+ getClusterLightCount( zSliceNode ) {
262
+
263
+ const getCount = Fn( ( [ zSliceNode ] ) => {
264
+
265
+ const count = int( 0 ).toVar();
266
+
267
+ const debugClusterIndex = this._screenClusterIndex.toVar();
268
+
269
+ If( zSliceNode.greaterThanEqual( int( 0 ) ), () => {
270
+
271
+ const tileSize = int( this.tileSize );
272
+ const screenTile = screenCoordinate.div( tileSize ).floor();
273
+ const NX = int( this._gridDimensions.x );
274
+ const NY = int( this._gridDimensions.y );
275
+
276
+ debugClusterIndex.assign(
277
+ int( screenTile.x )
278
+ .add( int( screenTile.y ).mul( NX ) )
279
+ .add( zSliceNode.mul( NX.mul( NY ) ) )
280
+ );
281
+
282
+ } );
283
+
284
+ Loop( this.maxLightsPerCluster, ( { i } ) => {
285
+
286
+ const element = int( i );
287
+ const stride = int( 4 );
288
+ const chunkOffset = element.div( stride );
289
+ const idx = debugClusterIndex.mul( int( this._chunksPerCluster ) ).add( chunkOffset );
290
+ const lightIndex = this._lightIndexes.element( idx ).element( element.mod( stride ) );
291
+
292
+ If( lightIndex.equal( int( 0 ) ), () => {
293
+
294
+ Break();
295
+
296
+ } );
297
+
298
+ count.addAssign( int( 1 ) );
299
+
300
+ } );
301
+
302
+ return count;
303
+
304
+ } );
305
+
306
+ return getCount( zSliceNode );
307
+
308
+ }
309
+
310
+ getLightData( index ) {
311
+
312
+ index = int( index );
313
+
314
+ const dataA = textureLoad( this._lightsTexture, ivec2( index, 0 ) );
315
+ const dataB = textureLoad( this._lightsTexture, ivec2( index, 1 ) );
316
+
317
+ const position = dataA.xyz;
318
+ const viewPosition = this._cameraViewMatrix.mul( vec4( position, 1.0 ) ).xyz;
319
+ const distance = dataA.w;
320
+ const color = dataB.rgb;
321
+ const decay = dataB.w;
322
+
323
+ return {
324
+ position,
325
+ viewPosition,
326
+ distance,
327
+ color,
328
+ decay
329
+ };
330
+
331
+ }
332
+
333
+ setupLights( builder, lightNodes ) {
334
+
335
+ this.updateProgram( builder.renderer );
336
+
337
+ //
338
+
339
+ const lightingModel = builder.context.reflectedLight;
340
+
341
+ lightingModel.directDiffuse.toStack();
342
+ lightingModel.directSpecular.toStack();
343
+
344
+ super.setupLights( builder, lightNodes );
345
+
346
+ Fn( () => {
347
+
348
+ Loop( this.maxLightsPerCluster, ( { i } ) => {
349
+
350
+ const lightIndex = this.getTile( i );
351
+
352
+ If( lightIndex.equal( int( 0 ) ), () => {
353
+
354
+ Break();
355
+
356
+ } );
357
+
358
+ const { color, decay, viewPosition, distance } = this.getLightData( lightIndex.sub( 1 ) );
359
+
360
+ const lightVector = viewPosition.sub( positionView );
361
+
362
+ // Early-out: skip full BRDF if fragment is beyond the light's cutoff
363
+ If( distance.equal( 0 ).or( dot( lightVector, lightVector ).lessThanEqual( distance.mul( distance ) ) ), () => {
364
+
365
+ builder.lightsNode.setupDirectLight( builder, this, directPointLight( {
366
+ color,
367
+ lightVector,
368
+ cutoffDistance: distance,
369
+ decayExponent: decay
370
+ } ) );
371
+
372
+ } );
373
+
374
+ } );
375
+
376
+ }, 'void' )();
377
+
378
+ }
379
+
380
+ getBufferFitSize( value ) {
381
+
382
+ const multiple = this.tileSize;
383
+
384
+ return Math.ceil( value / multiple ) * multiple;
385
+
386
+ }
387
+
388
+ setSize( width, height ) {
389
+
390
+ width = this.getBufferFitSize( width );
391
+ height = this.getBufferFitSize( height );
392
+
393
+ if ( ! this._bufferSize || this._bufferSize.width !== width || this._bufferSize.height !== height ) {
394
+
395
+ this.create( width, height );
396
+
397
+ }
398
+
399
+ return this;
400
+
401
+ }
402
+
403
+ updateProgram( renderer ) {
404
+
405
+ renderer.getDrawingBufferSize( _size );
406
+
407
+ const width = this.getBufferFitSize( _size.width );
408
+ const height = this.getBufferFitSize( _size.height );
409
+
410
+ if ( this._bufferSize === null ) {
411
+
412
+ this.create( width, height );
413
+
414
+ } else if ( this._bufferSize.width !== width || this._bufferSize.height !== height ) {
415
+
416
+ this.create( width, height );
417
+
418
+ }
419
+
420
+ }
421
+
422
+ create( width, height ) {
423
+
424
+ const { tileSize, maxLights, zSlices, maxLightsPerCluster, _chunksPerCluster: chunksPerCluster } = this;
425
+
426
+ const bufferSize = new Vector2( width, height );
427
+
428
+ const NX = Math.floor( bufferSize.width / tileSize );
429
+ const NY = Math.floor( bufferSize.height / tileSize );
430
+ const NZ = zSlices;
431
+ const clusterCount = NX * NY * NZ;
432
+
433
+ this._gridDimensions.value.set( NX, NY );
434
+
435
+ // Lights data texture (same layout as TiledLightsNode)
436
+
437
+ const lightsData = new Float32Array( maxLights * 4 * 2 );
438
+ const lightsTexture = new DataTexture( lightsData, lightsData.length / 8, 2, RGBAFormat, FloatType );
439
+
440
+ // Per Z-slice light range for Z-culling (CPU-sorted, uploaded each frame)
441
+
442
+ const zSliceRangesData = new Float32Array( NZ * 4 );
443
+ const zSliceRangesTexture = new DataTexture( zSliceRangesData, NZ, 1, RGBAFormat, FloatType );
444
+
445
+ // Per-cluster light-index storage (ivec4 chunks)
446
+
447
+ const lightIndexesArray = new Int32Array( clusterCount * chunksPerCluster * 4 );
448
+ const lightIndexes = attributeArray( lightIndexesArray, 'ivec4' ).setName( 'lightIndexes' );
449
+
450
+ // compute-side accessors (use instanceIndex)
451
+
452
+ const getClusterChunk = ( chunkIdx ) => {
453
+
454
+ const idx = instanceIndex.mul( int( chunksPerCluster ) ).add( int( chunkIdx ) );
455
+
456
+ return lightIndexes.element( idx );
457
+
458
+ };
459
+
460
+ const getClusterSlot = ( slotIdx ) => {
461
+
462
+ slotIdx = int( slotIdx );
463
+
464
+ const stride = int( 4 );
465
+ const chunkOffset = slotIdx.div( stride );
466
+ const idx = instanceIndex.mul( int( chunksPerCluster ) ).add( chunkOffset );
467
+
468
+ return lightIndexes.element( idx ).element( slotIdx.mod( stride ) );
469
+
470
+ };
471
+
472
+ // compute: one thread per cluster
473
+
474
+ const compute = Fn( () => {
475
+
476
+ // view-space scale factors derived from the projection matrix:
477
+ // view_x = ndc_x * (-view_z) / focal_x = ndc_x * (-view_z) * invFocalX
478
+ // view_y = ndc_y * (-view_z) / focal_y = ndc_y * (-view_z) * invFocalY
479
+ // where focal_x = projMatrix[0][0] and focal_y = projMatrix[1][1].
480
+ const invFocalX = float( 1 ).div( this._cameraProjectionMatrix.element( 0 ).element( 0 ) );
481
+ const invFocalY = float( 1 ).div( this._cameraProjectionMatrix.element( 1 ).element( 1 ) );
482
+
483
+ // 3D cluster coordinates from instanceIndex
484
+ const cx = instanceIndex.mod( NX );
485
+ const cy = instanceIndex.div( NX ).mod( NY );
486
+ const cz = instanceIndex.div( NX * NY );
487
+
488
+ // NDC X/Y bounds of the cluster.
489
+ // Y is flipped: cy=0 is the top screen row (fragment y=0), which is NDC y=+1.
490
+ const ndcXmin = float( cx ).mul( 2.0 / NX ).sub( 1.0 );
491
+ const ndcXmax = float( cx.add( int( 1 ) ) ).mul( 2.0 / NX ).sub( 1.0 );
492
+ const ndcYmax = float( 1 ).sub( float( cy ).mul( 2.0 / NY ) );
493
+ const ndcYmin = float( 1 ).sub( float( cy.add( int( 1 ) ) ).mul( 2.0 / NY ) );
494
+
495
+ // View-space Z bounds (negative, exponential slicing)
496
+ const farOverNear = this._cameraFar.div( this._cameraNear );
497
+ const zNearCluster = this._cameraNear.mul( pow( farOverNear, float( cz ).mul( 1.0 / NZ ) ) ).negate();
498
+ const zFarCluster = this._cameraNear.mul( pow( farOverNear, float( cz.add( int( 1 ) ) ).mul( 1.0 / NZ ) ) ).negate();
499
+
500
+ const scaleNearX = zNearCluster.negate().mul( invFocalX );
501
+ const scaleFarX = zFarCluster.negate().mul( invFocalX );
502
+ const scaleNearY = zNearCluster.negate().mul( invFocalY );
503
+ const scaleFarY = zFarCluster.negate().mul( invFocalY );
504
+
505
+ const xMinNear = ndcXmin.mul( scaleNearX );
506
+ const xMaxNear = ndcXmax.mul( scaleNearX );
507
+ const xMinFar = ndcXmin.mul( scaleFarX );
508
+ const xMaxFar = ndcXmax.mul( scaleFarX );
509
+
510
+ const yMinNear = ndcYmin.mul( scaleNearY );
511
+ const yMaxNear = ndcYmax.mul( scaleNearY );
512
+ const yMinFar = ndcYmin.mul( scaleFarY );
513
+ const yMaxFar = ndcYmax.mul( scaleFarY );
514
+
515
+ // AABB of the 8 view-space corners (tile boundaries can straddle the view axis)
516
+ const aabbMinX = min( xMinNear, xMinFar );
517
+ const aabbMaxX = max( xMaxNear, xMaxFar );
518
+ const aabbMinY = min( yMinNear, yMinFar );
519
+ const aabbMaxY = max( yMaxNear, yMaxFar );
520
+
521
+ const aabbMin = vec3( aabbMinX, aabbMinY, zFarCluster );
522
+ const aabbMax = vec3( aabbMaxX, aabbMaxY, zNearCluster );
523
+
524
+ // clear stale data from previous frame
525
+ Loop( chunksPerCluster, ( { i } ) => {
526
+
527
+ getClusterChunk( i ).assign( ivec4( 0 ) );
528
+
529
+ } );
530
+
531
+ const index = int( 0 ).toVar();
532
+
533
+ // Z-culling: only test lights that can reach this cluster's Z-slice
534
+ const zRange = textureLoad( zSliceRangesTexture, ivec2( cz, 0 ) );
535
+ const rangeStart = int( zRange.x );
536
+ const rangeEnd = int( zRange.y );
537
+
538
+ Loop( this.maxLights, ( { i } ) => {
539
+
540
+ const lightIdx = rangeStart.add( i );
541
+
542
+ If( index.greaterThanEqual( int( maxLightsPerCluster ) ).or( lightIdx.greaterThanEqual( rangeEnd ) ), () => {
543
+
544
+ Return();
545
+
546
+ } );
547
+
548
+ const { viewPosition, distance } = this.getLightData( lightIdx );
549
+
550
+ // sphere-AABB intersection in view space
551
+ const pos = viewPosition.xyz;
552
+ const closest = max( aabbMin, min( pos, aabbMax ) );
553
+ const diff = pos.sub( closest );
554
+ const distSq = dot( diff, diff );
555
+
556
+ If( distSq.lessThanEqual( distance.mul( distance ) ), () => {
557
+
558
+ getClusterSlot( index ).assign( lightIdx.add( int( 1 ) ) );
559
+ index.addAssign( int( 1 ) );
560
+
561
+ } );
562
+
563
+ } );
564
+
565
+ } )().compute( clusterCount ).setName( 'Update Clustered Lights' );
566
+
567
+ // shading-side: fragment → cluster index
568
+
569
+ const getScreenClusterIndex = Fn( () => {
570
+
571
+ const screenTile = screenCoordinate.div( tileSize ).floor();
572
+
573
+ // view-space depth from positionView (negative in front); take magnitude
574
+ const viewDepth = positionView.z.negate();
575
+
576
+ // exponential Z slice: tz = floor( log(depth/near) / log(far/near) * NZ )
577
+ const invLogFarOverNear = float( 1 ).div( log( this._cameraFar.div( this._cameraNear ) ) );
578
+ const sliceFloat = log( viewDepth.div( this._cameraNear ) ).mul( invLogFarOverNear ).mul( float( NZ ) );
579
+ const zSlice = clamp( sliceFloat.floor(), float( 0 ), float( NZ - 1 ) );
580
+
581
+ return int( screenTile.x )
582
+ .add( int( screenTile.y ).mul( int( NX ) ) )
583
+ .add( int( zSlice ).mul( int( NX * NY ) ) );
584
+
585
+ } );
586
+
587
+ const screenClusterIndex = getScreenClusterIndex().toVar();
588
+
589
+ // assigns
590
+
591
+ this._bufferSize = bufferSize;
592
+ this._lightIndexes = lightIndexes;
593
+ this._screenClusterIndex = screenClusterIndex;
594
+ this._compute = compute;
595
+ this._lightsTexture = lightsTexture;
596
+ this._zSliceRangesTexture = zSliceRangesTexture;
597
+ this._zSliceRangesData = zSliceRangesData;
598
+
599
+ }
600
+
601
+ get hasLights() {
602
+
603
+ return super.hasLights || this.clusteredLights.length > 0;
604
+
605
+ }
606
+
607
+ }
608
+
609
+ export default ClusteredLightsNode;
610
+
611
+ /**
612
+ * TSL function that creates a clustered lights node.
613
+ *
614
+ * @tsl
615
+ * @function
616
+ * @param {number} [maxLights=1024] - Maximum number of point lights.
617
+ * @param {number} [tileSize=32] - Screen tile size in pixels.
618
+ * @param {number} [zSlices=24] - Depth slice count.
619
+ * @param {number} [maxLightsPerCluster=64] - Per-cluster light-list capacity.
620
+ * @return {ClusteredLightsNode} The clustered lights node.
621
+ */
622
+ export const clusteredLights = /*@__PURE__*/ nodeProxy( ClusteredLightsNode );
@@ -230,7 +230,7 @@ class DynamicLightsNode extends LightsNode {
230
230
 
231
231
  }
232
232
 
233
- this._lightNodes = lightNodes;
233
+ return lightNodes;
234
234
 
235
235
  }
236
236