@gnsx/three 0.185.16 → 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 (418) hide show
  1. package/build/three.cjs +10 -82600
  2. package/build/three.core.js +1309 -807
  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/src/utils.js +6 -79
  411. package/build/three.core.min.js +0 -6
  412. package/build/three.module.min.js +0 -6
  413. package/build/three.tsl.min.js +0 -6
  414. package/build/three.webgpu.min.js +0 -6
  415. package/build/three.webgpu.nodes.min.js +0 -6
  416. package/examples/jsm/libs/ecsy.module.js +0 -1792
  417. package/examples/jsm/loaders/LottieLoader.js +0 -130
  418. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +0 -52
@@ -1,4 +1,4 @@
1
- import { EPSILON, Fn, If, abs, convertToTexture, dFdx, dFdy, dot, exp, float, floor, fwidth, getViewPosition, ivec2, luminance, max, min, mix, nodeObject, normalize, passTexture, screenCoordinate, select, smoothstep, sqrt, struct, texture, textureLoad, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4, velocity } from '@gnsx/three/tsl';
1
+ import { EPSILON, Fn, If, abs, convertToTexture, dFdx, dFdy, dot, exp, float, floor, fwidth, getViewPosition, ivec2, luminance, max, min, mix, nodeObject, normalize, passTexture, screenCoordinate, select, smoothstep, sqrt, struct, texture, textureLoad, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4, velocity, context, OnBeforeRenderPipeline, OnAfterRenderPipeline } from '@gnsx/three/tsl';
2
2
  import { DepthTexture, HalfFloatType, Matrix4, NodeMaterial, NodeUpdateType, QuadMesh, RenderTarget, RendererUtils, TempNode, Vector2, Vector3 } from '@gnsx/three/webgpu';
3
3
  import { ENV_RAY_LENGTH, ENV_RAY_LENGTH_THRESHOLD } from '../utils/SpecularHelpers.js';
4
4
 
@@ -256,7 +256,7 @@ const sampleBilinearTap = Fn( ( [
256
256
  const reprojDepth = textureLoad( previousDepthNode, tapCoord ).r;
257
257
  const reprojViewPos = getViewPosition( vec2( tapCoord ).add( 0.5 ).div( resolution ), reprojDepth, previousProjectionMatrixInverse );
258
258
  const reprojWorldPos = previousCameraWorldMatrix.mul( vec4( reprojViewPos, 1.0 ) ).xyz;
259
- const reprojWorldNorm = unpackRGBToNormal( textureLoad( previousNormalNode, tapCoord ).rgb ).transformDirection( previousCameraViewMatrix );
259
+ const reprojWorldNorm = unpackRGBToNormal( textureLoad( previousNormalNode, tapCoord ).rgb ).transformNormalByInverseViewMatrix( previousCameraViewMatrix );
260
260
 
261
261
  const planeDiff = abs( dot( reprojWorldPos.sub( worldPosition ), worldNormal ) ).toVar();
262
262
  planeDiff.divAssign( abs( reprojViewPos.z ) );
@@ -727,36 +727,39 @@ class TemporalReprojectNode extends TempNode {
727
727
 
728
728
  setup( builder ) {
729
729
 
730
- const renderPipeline = builder.context.renderPipeline;
730
+ const sharedContext = context( builder.getSharedContext() );
731
731
 
732
- if ( renderPipeline ) {
732
+ if ( builder.renderPipeline && ! builder.context.renderPipelineState.viewOffsetOwner ) {
733
+
734
+ builder.context.renderPipelineState.viewOffsetOwner = this;
733
735
 
734
736
  this._needsPostProcessingSync = true;
735
737
 
736
- renderPipeline.context.onBeforeRenderPipeline = () => {
738
+ OnBeforeRenderPipeline( () => {
737
739
 
738
740
  this.setViewOffset();
739
741
 
740
- };
742
+ } );
741
743
 
742
- renderPipeline.context.onAfterRenderPipeline = () => {
744
+ OnAfterRenderPipeline( () => {
743
745
 
744
746
  this.clearViewOffset();
745
747
 
746
- };
748
+ } );
747
749
 
748
750
  }
749
751
 
750
- this._resolveMaterial.fragmentNode = this._buildResolve( builder );
752
+ this._resolveMaterial.contextNode = sharedContext;
753
+ this._resolveMaterial.fragmentNode = this._buildResolve();
751
754
  this._resolveMaterial.needsUpdate = true;
752
755
 
753
- this._buildSeed( builder );
756
+ this._buildSeed( sharedContext );
754
757
 
755
758
  return this._textureNode;
756
759
 
757
760
  }
758
761
 
759
- _buildSeed( builder ) {
762
+ _buildSeed( sharedContext ) {
760
763
 
761
764
  const seed = Fn( () => {
762
765
 
@@ -768,12 +771,13 @@ class TemporalReprojectNode extends TempNode {
768
771
 
769
772
  } );
770
773
 
771
- this._seedMaterial.fragmentNode = seed().context( builder.getSharedContext() );
774
+ this._seedMaterial.contextNode = sharedContext;
775
+ this._seedMaterial.fragmentNode = seed();
772
776
  this._seedMaterial.needsUpdate = true;
773
777
 
774
778
  }
775
779
 
776
- _buildResolve( builder ) {
780
+ _buildResolve() {
777
781
 
778
782
  const isSpecular = this.mode === 'specular';
779
783
  const cameraUniforms = this._cameraUniforms;
@@ -794,7 +798,7 @@ class TemporalReprojectNode extends TempNode {
794
798
 
795
799
  // Shared 3×3 beauty fetch: feeds both the variance-clip box and the SSR ray-length stats.
796
800
  const neighborhood = collectNeighborhood( this.beautyNode, beautyTexel, inputColor, this.flickerSuppression );
797
- const worldNormal = viewNormal.transformDirection( cameraUniforms.viewMatrix ).toVar();
801
+ const worldNormal = viewNormal.transformNormalByInverseViewMatrix( cameraUniforms.viewMatrix ).toVar();
798
802
 
799
803
  const viewPosition = getViewPosition( uvNode, depth, cameraUniforms.projectionMatrixInverse ).toVar();
800
804
  const worldPosition = cameraUniforms.worldMatrix.mul( vec4( viewPosition, 1.0 ) ).xyz.toVar();
@@ -944,7 +948,7 @@ class TemporalReprojectNode extends TempNode {
944
948
 
945
949
  } );
946
950
 
947
- return resolve().context( builder.getSharedContext() );
951
+ return resolve();
948
952
 
949
953
  }
950
954
 
@@ -979,6 +983,8 @@ class TemporalReprojectNode extends TempNode {
979
983
 
980
984
  dispose() {
981
985
 
986
+ super.dispose();
987
+
982
988
  this._previousNormalTexture.dispose();
983
989
 
984
990
  if ( this._previousDepthNode.value !== this._historyRenderTarget.depthTexture ) {
@@ -0,0 +1,63 @@
1
+ import { abs, exp, float, Fn, int, logarithmicDepthToViewZ, Loop, max, perspectiveDepthToViewZ, reference, uv } from '@gnsx/three/tsl';
2
+
3
+ /**
4
+ * Applies one pass of a separable, depth-aware (bilateral) blur to a screen-space signal.
5
+ *
6
+ * The spatial term is a fixed 5-tap gaussian along `directionNode`; the edge-stopping term
7
+ * rejects neighbours whose view-space depth differs from the center, so the signal is smoothed
8
+ * across surfaces but not across silhouettes. Depth rejection is measured relative to `radius`,
9
+ * which keeps it scale invariant. Run it twice (horizontal then vertical) for a full separable
10
+ * blur. Handy for denoising a half-resolution effect such as ambient occlusion.
11
+ *
12
+ * @tsl
13
+ * @function
14
+ * @param {Node<vec4>} inputNode - The texture node to blur; its red channel is filtered.
15
+ * @param {Node<float>} depthNode - The scene depth texture node.
16
+ * @param {Node<vec2>} directionNode - One texel step along the blur axis, e.g. `vec2( 1 / width, 0 )`.
17
+ * @param {Camera} camera - The camera the scene is rendered with.
18
+ * @param {Node<float> | number} [sharpness=2] - How strongly a depth difference rejects a neighbour.
19
+ * @param {Node<float> | number} [radius=1] - The world-space scale the depth rejection is relative to.
20
+ * @returns {Node<float>} The blurred value.
21
+ */
22
+ export const depthAwareBlur = /*#__PURE__*/ Fn( ( [ inputNode, depthNode, directionNode, camera, sharpness = 2, radius = 1 ], builder ) => {
23
+
24
+ const cameraNear = reference( 'near', 'float', camera );
25
+ const cameraFar = reference( 'far', 'float', camera );
26
+
27
+ const viewZ = ( uvNode ) => {
28
+
29
+ const depth = depthNode.sample( uvNode ).r;
30
+
31
+ if ( builder.renderer.logarithmicDepthBuffer === true ) {
32
+
33
+ return logarithmicDepthToViewZ( depth, cameraNear, cameraFar );
34
+
35
+ }
36
+
37
+ return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
38
+
39
+ };
40
+
41
+ const uvNode = uv();
42
+ const centerViewZ = viewZ( uvNode ).toVar();
43
+
44
+ const sum = float( 0 ).toVar();
45
+ const weightSum = float( 0 ).toVar();
46
+
47
+ Loop( { start: int( - 2 ), end: int( 3 ), type: 'int', condition: '<' }, ( { i } ) => {
48
+
49
+ const fi = float( i );
50
+ const sampleUv = uvNode.add( directionNode.mul( fi ) );
51
+
52
+ const spatialWeight = exp( fi.mul( fi ).mul( - 0.5 ) );
53
+ const depthWeight = exp( abs( viewZ( sampleUv ).sub( centerViewZ ) ).div( radius ).mul( sharpness ).negate() );
54
+ const weight = spatialWeight.mul( depthWeight );
55
+
56
+ sum.addAssign( inputNode.sample( sampleUv ).r.mul( weight ) );
57
+ weightSum.addAssign( weight );
58
+
59
+ } );
60
+
61
+ return sum.div( max( weightSum, float( 0.0001 ) ) );
62
+
63
+ } );
@@ -1,4 +1,4 @@
1
- import { float, Fn, vec2, uv, sin, rand, degrees, cos, Loop, vec4, premultiplyAlpha, unpremultiplyAlpha, convertToTexture, nodeObject } from '@gnsx/three/tsl';
1
+ import { float, Fn, vec2, uv, sin, rand, TWO_PI, cos, Loop, vec4, premultiplyAlpha, unpremultiplyAlpha, convertToTexture, nodeObject } from '@gnsx/three/tsl';
2
2
 
3
3
  /**
4
4
  * Applies a hash blur effect to the given texture node.
@@ -41,7 +41,8 @@ export const hashBlur = /*#__PURE__*/ Fn( ( [ textureNode, bluramount = float( 0
41
41
 
42
42
  Loop( { start: 0., end: repeats, type: 'float' }, ( { i } ) => {
43
43
 
44
- const q = vec2( vec2( cos( degrees( i.div( repeats ).mul( 360. ) ) ), sin( degrees( i.div( repeats ).mul( 360. ) ) ) ).mul( rand( vec2( i, targetUV.x.add( targetUV.y ) ) ).add( bluramount ) ) );
44
+ const angle = i.div( repeats ).mul( TWO_PI ).toConst();
45
+ const q = vec2( cos( angle ), sin( angle ) ).mul( rand( vec2( i, targetUV.x.add( targetUV.y ) ) ).add( bluramount ) );
45
46
  const uv2 = vec2( targetUV.add( q.mul( bluramount ) ) );
46
47
  blurred_image.addAssign( tap( uv2 ) );
47
48
 
@@ -44,7 +44,6 @@ class ClusteredLightsNode extends LightsNode {
44
44
 
45
45
  this.materialLights = [];
46
46
  this.clusteredLights = [];
47
- this._allLights = [];
48
47
 
49
48
  this.maxLights = maxLights;
50
49
  this.tileSize = tileSize;
@@ -57,9 +56,15 @@ class ClusteredLightsNode extends LightsNode {
57
56
  this._lightIndexes = null;
58
57
  this._screenClusterIndex = null;
59
58
  this._compute = null;
60
- this._lightsTexture = null;
61
- this._zSliceRangesTexture = null;
62
- this._zSliceRangesData = null;
59
+
60
+ const lightsData = new Float32Array( maxLights * 4 * 2 );
61
+ this._lightsTexture = new DataTexture( lightsData, lightsData.length / 8, 2, RGBAFormat, FloatType );
62
+
63
+ // Per Z-slice light range for Z-culling (CPU-sorted, uploaded each frame)
64
+
65
+ this._zSliceRangesData = new Float32Array( zSlices * 4 );
66
+ this._zSliceRangesTexture = new DataTexture( this._zSliceRangesData, zSlices, 1, RGBAFormat, FloatType );
67
+
63
68
  this._lightViewZ = new Float32Array( maxLights );
64
69
  this._lightSortOrder = [];
65
70
 
@@ -139,8 +144,6 @@ class ClusteredLightsNode extends LightsNode {
139
144
 
140
145
  const zRanges = this._zSliceRangesData;
141
146
 
142
- if ( zRanges === null ) return;
143
-
144
147
  const near = camera.near;
145
148
  const far = camera.far;
146
149
  const NZ = this.zSlices;
@@ -206,8 +209,6 @@ class ClusteredLightsNode extends LightsNode {
206
209
 
207
210
  setLights( lights ) {
208
211
 
209
- this._allLights = lights;
210
-
211
212
  const { clusteredLights, materialLights } = this;
212
213
 
213
214
  let materialIndex = 0;
@@ -230,13 +231,13 @@ class ClusteredLightsNode extends LightsNode {
230
231
  materialLights.length = materialIndex;
231
232
  clusteredLights.length = clusteredIndex;
232
233
 
233
- return super.setLights( materialLights );
234
+ return super.setLights( lights );
234
235
 
235
236
  }
236
237
 
237
- getLights() {
238
+ getBuiltinLights() {
238
239
 
239
- return this._allLights;
240
+ return this.materialLights;
240
241
 
241
242
  }
242
243
 
@@ -421,7 +422,7 @@ class ClusteredLightsNode extends LightsNode {
421
422
 
422
423
  create( width, height ) {
423
424
 
424
- const { tileSize, maxLights, zSlices, maxLightsPerCluster, _chunksPerCluster: chunksPerCluster } = this;
425
+ const { tileSize, zSlices, maxLightsPerCluster, _chunksPerCluster: chunksPerCluster } = this;
425
426
 
426
427
  const bufferSize = new Vector2( width, height );
427
428
 
@@ -432,20 +433,25 @@ class ClusteredLightsNode extends LightsNode {
432
433
 
433
434
  this._gridDimensions.value.set( NX, NY );
434
435
 
435
- // Lights data texture (same layout as TiledLightsNode)
436
+ // release the compute pipeline and bindings built for the previous grid
436
437
 
437
- const lightsData = new Float32Array( maxLights * 4 * 2 );
438
- const lightsTexture = new DataTexture( lightsData, lightsData.length / 8, 2, RGBAFormat, FloatType );
438
+ if ( this._compute !== null ) this._compute.dispose();
439
439
 
440
- // Per Z-slice light range for Z-culling (CPU-sorted, uploaded each frame)
440
+ // Per-cluster light-index storage (ivec4 chunks).
441
+
442
+ const lightIndexesLength = clusterCount * chunksPerCluster * 4;
443
+
444
+ let lightIndexes = this._lightIndexes;
441
445
 
442
- const zSliceRangesData = new Float32Array( NZ * 4 );
443
- const zSliceRangesTexture = new DataTexture( zSliceRangesData, NZ, 1, RGBAFormat, FloatType );
446
+ if ( lightIndexes === null || lightIndexes.value.array.length < lightIndexesLength ) {
444
447
 
445
- // Per-cluster light-index storage (ivec4 chunks)
448
+ // TODO: Free the outgoing buffer once the renderer destroys the GPU resources of
449
+ // standalone storage attributes (`Bindings._destroyBindings()` skips storage buffers).
446
450
 
447
- const lightIndexesArray = new Int32Array( clusterCount * chunksPerCluster * 4 );
448
- const lightIndexes = attributeArray( lightIndexesArray, 'ivec4' ).setName( 'lightIndexes' );
451
+ const lightIndexesArray = new Int32Array( lightIndexesLength );
452
+ lightIndexes = attributeArray( lightIndexesArray, 'ivec4' ).setName( 'lightIndexes' );
453
+
454
+ }
449
455
 
450
456
  // compute-side accessors (use instanceIndex)
451
457
 
@@ -531,7 +537,7 @@ class ClusteredLightsNode extends LightsNode {
531
537
  const index = int( 0 ).toVar();
532
538
 
533
539
  // Z-culling: only test lights that can reach this cluster's Z-slice
534
- const zRange = textureLoad( zSliceRangesTexture, ivec2( cz, 0 ) );
540
+ const zRange = textureLoad( this._zSliceRangesTexture, ivec2( cz, 0 ) );
535
541
  const rangeStart = int( zRange.x );
536
542
  const rangeEnd = int( zRange.y );
537
543
 
@@ -592,15 +598,20 @@ class ClusteredLightsNode extends LightsNode {
592
598
  this._lightIndexes = lightIndexes;
593
599
  this._screenClusterIndex = screenClusterIndex;
594
600
  this._compute = compute;
595
- this._lightsTexture = lightsTexture;
596
- this._zSliceRangesTexture = zSliceRangesTexture;
597
- this._zSliceRangesData = zSliceRangesData;
598
601
 
599
602
  }
600
603
 
601
- get hasLights() {
604
+ /**
605
+ * Frees the GPU resources allocated by this node.
606
+ */
607
+ dispose() {
608
+
609
+ if ( this._compute !== null ) this._compute.dispose();
610
+
611
+ this._lightsTexture.dispose();
612
+ this._zSliceRangesTexture.dispose();
602
613
 
603
- return super.hasLights || this.clusteredLights.length > 0;
614
+ super.dispose();
604
615
 
605
616
  }
606
617
 
@@ -0,0 +1,136 @@
1
+ import { AnalyticLightNode, Vector3 } from '@gnsx/three/webgpu';
2
+ import { array, getShIrradianceAt, normalWorld, positionWorld, texture3D, uniform, vec3 } from '@gnsx/three/tsl';
3
+
4
+ // Padding texels at each boundary of every atlas sub-volume.
5
+ export const ATLAS_PADDING = 1;
6
+
7
+ /**
8
+ * Samples the packed SH atlas and evaluates L2 irradiance for the given normal.
9
+ *
10
+ * The atlas stores the seven RGBA sub-volumes stacked along Z, each occupying
11
+ * `( nz + 2 )` slices: one padding slice (a copy of the nearest edge slice) at
12
+ * each end to prevent color bleeding when the hardware trilinear filter reads
13
+ * across a sub-volume boundary.
14
+ *
15
+ * @private
16
+ * @param {Texture3DNode} atlas - The atlas texture node.
17
+ * @param {Node<vec3>} uvw - The probe-grid sample coordinate (texel centers).
18
+ * @param {Node<vec3>} res - The probe resolution.
19
+ * @param {Node<vec3>} normal - The world-space normal.
20
+ * @return {Node<vec3>} The non-negative irradiance.
21
+ */
22
+ function evaluateGridIrradiance( atlas, uvw, res, normal ) {
23
+
24
+ const nz = res.z;
25
+ const paddedSlices = nz.add( 2.0 * ATLAS_PADDING );
26
+ const atlasDepth = paddedSlices.mul( 7.0 );
27
+ const uvZBase = uvw.z.mul( nz ).add( ATLAS_PADDING );
28
+
29
+ const slice = ( t ) => atlas.sample( vec3( uvw.xy, uvZBase.add( paddedSlices.mul( t ) ).div( atlasDepth ) ) );
30
+
31
+ const s0 = slice( 0 ), s1 = slice( 1 ), s2 = slice( 2 ), s3 = slice( 3 );
32
+ const s4 = slice( 4 ), s5 = slice( 5 ), s6 = slice( 6 );
33
+
34
+ // Unpack 9 vec3 L2 SH coefficients and evaluate irradiance.
35
+
36
+ const sh = array( [
37
+ s0.xyz,
38
+ vec3( s0.w, s1.xy ),
39
+ vec3( s1.zw, s2.x ),
40
+ s2.yzw,
41
+ s3.xyz,
42
+ vec3( s3.w, s4.xy ),
43
+ vec3( s4.zw, s5.x ),
44
+ s5.yzw,
45
+ s6.xyz
46
+ ] );
47
+
48
+ return getShIrradianceAt( normal, sh ).max( vec3( 0.0 ) );
49
+
50
+ }
51
+
52
+ /**
53
+ * The light node that applies a {@link LightProbeGrid} to the scene. It samples
54
+ * the baked L2 spherical-harmonic atlas at the surface position and adds the
55
+ * resulting irradiance to the lighting context, so every standard node material
56
+ * picks up the grid automatically (same role as the WebGL `lights_fragment_begin`
57
+ * integration).
58
+ *
59
+ * @private
60
+ * @augments AnalyticLightNode
61
+ */
62
+ class LightProbeGridNode extends AnalyticLightNode {
63
+
64
+ static get type() {
65
+
66
+ return 'LightProbeGridNode';
67
+
68
+ }
69
+
70
+ constructor( light = null ) {
71
+
72
+ super( light );
73
+
74
+ this._min = uniform( new Vector3() );
75
+ this._max = uniform( new Vector3() );
76
+ this._resolution = uniform( new Vector3() );
77
+ this._intensity = uniform( 1 );
78
+ this._falloff = uniform( 0 );
79
+
80
+ }
81
+
82
+ update( /* frame */ ) {
83
+
84
+ const light = this.light;
85
+
86
+ this._min.value.copy( light.boundingBox.min );
87
+ this._max.value.copy( light.boundingBox.max );
88
+ this._resolution.value.copy( light.resolution );
89
+ this._intensity.value = light.intensity;
90
+ this._falloff.value = light.falloff;
91
+
92
+ }
93
+
94
+ setup( builder ) {
95
+
96
+ const light = this.light;
97
+
98
+ // No baked data yet: contribute nothing.
99
+
100
+ if ( light.texture === null ) return;
101
+
102
+ const min = this._min;
103
+ const max = this._max;
104
+ const res = this._resolution;
105
+
106
+ const range = max.sub( min );
107
+ const resMinusOne = res.sub( 1.0 );
108
+ const spacing = range.div( resMinusOne );
109
+
110
+ // Offset along the normal by half a probe spacing, then remap to texel centers.
111
+
112
+ const samplePos = positionWorld.add( normalWorld.mul( spacing ).mul( 0.5 ) );
113
+ const uvw = samplePos.sub( min ).div( range ).clamp( 0.0, 1.0 ).mul( resMinusOne ).div( res ).add( vec3( 0.5 ).div( res ) );
114
+
115
+ const result = evaluateGridIrradiance( texture3D( light.texture ), uvw, res, normalWorld );
116
+
117
+ let irradiance = result.mul( this._intensity );
118
+
119
+ // Optional smooth boundary for blending grids; falloff 0 applies everywhere.
120
+
121
+ if ( light.falloff > 0 ) {
122
+
123
+ const outside = min.sub( positionWorld ).max( 0.0 ).add( positionWorld.sub( max ).max( 0.0 ) );
124
+ const weight = outside.length().smoothstep( 0.0, this._falloff ).oneMinus();
125
+
126
+ irradiance = irradiance.mul( weight );
127
+
128
+ }
129
+
130
+ builder.context.irradiance.addAssign( irradiance );
131
+
132
+ }
133
+
134
+ }
135
+
136
+ export { LightProbeGridNode };
@@ -0,0 +1,112 @@
1
+ import { Fn, Loop, dot, float, fract, int, min, sin, vec2, vec3, TWO_PI } from '@gnsx/three/tsl';
2
+
3
+ /**
4
+ * @module VoronoiNoise
5
+ * @three_import import { voronoi2d, voronoi3d } from 'three/addons/tsl/math/voronoiNoise.js';
6
+ */
7
+
8
+ /**
9
+ * Generates a pseudo-random vec2 from the given coordinate.
10
+ *
11
+ * Reference: {@link https://www.shadertoy.com/view/MslGD8}.
12
+ *
13
+ * @tsl
14
+ * @function
15
+ * @param {Node<vec2>} p - The input coordinate.
16
+ * @return {Node<vec2>} A pseudo-random value in the range `[0, 1]`.
17
+ */
18
+ export const hash2d = /*@__PURE__*/ Fn( ( [ p ] ) => {
19
+
20
+ return fract( sin( vec2( dot( p, vec2( 127.1, 311.7 ) ), dot( p, vec2( 269.5, 183.3 ) ) ) ).mul( 18.5453 ) );
21
+
22
+ }, { p: 'vec2', return: 'vec2' } );
23
+
24
+ /**
25
+ * Animated 2D Voronoi noise. The feature points orbit inside their cells so the
26
+ * resulting pattern morphs over time.
27
+ *
28
+ * Reference: {@link https://www.shadertoy.com/view/MslGD8}.
29
+ *
30
+ * @tsl
31
+ * @function
32
+ * @param {Node<vec2>} p - The input coordinate.
33
+ * @param {Node<float>} time - The animation time.
34
+ * @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
35
+ */
36
+ export const voronoi2d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
37
+
38
+ const n = p.floor().toConst();
39
+ const f = p.fract().toConst();
40
+ const minDist = float( 8 ).toVar();
41
+
42
+ Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
43
+
44
+ Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
45
+
46
+ const g = vec2( float( x ), float( y ) ).toConst();
47
+ const o = hash2d( n.add( g ) ).toConst();
48
+ const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
49
+
50
+ minDist.assign( min( minDist, dot( r, r ) ) );
51
+
52
+ } );
53
+
54
+ } );
55
+
56
+ return minDist;
57
+
58
+ }, { p: 'vec2', time: 'float', return: 'float' } );
59
+
60
+ /**
61
+ * Generates a pseudo-random vec3 from the given coordinate.
62
+ *
63
+ * @tsl
64
+ * @function
65
+ * @param {Node<vec3>} p - The input coordinate.
66
+ * @return {Node<vec3>} A pseudo-random value in the range `[0, 1]`.
67
+ */
68
+ export const hash3d = /*@__PURE__*/ Fn( ( [ p ] ) => {
69
+
70
+ return fract( sin( vec3( dot( p, vec3( 127.1, 311.7, 74.7 ) ), dot( p, vec3( 269.5, 183.3, 246.1 ) ), dot( p, vec3( 113.5, 271.9, 124.6 ) ) ) ).mul( 18.5453 ) );
71
+
72
+ }, { p: 'vec3', return: 'vec3' } );
73
+
74
+ /**
75
+ * Animated 3D Voronoi noise. Like {@link voronoi2d} but with a volumetric input
76
+ * coordinate so the pattern can be applied to arbitrary surfaces without
77
+ * projection artifacts. Evaluates 27 cells instead of 9 and is therefore
78
+ * considerably more expensive than the 2D version.
79
+ *
80
+ * @tsl
81
+ * @function
82
+ * @param {Node<vec3>} p - The input coordinate.
83
+ * @param {Node<float>} time - The animation time.
84
+ * @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
85
+ */
86
+ export const voronoi3d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
87
+
88
+ const n = p.floor().toConst();
89
+ const f = p.fract().toConst();
90
+ const minDist = float( 8 ).toVar();
91
+
92
+ Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
93
+
94
+ Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
95
+
96
+ Loop( { start: int( - 1 ), end: int( 1 ), name: 'z', condition: '<=' }, ( { z } ) => {
97
+
98
+ const g = vec3( float( x ), float( y ), float( z ) ).toConst();
99
+ const o = hash3d( n.add( g ) ).toConst();
100
+ const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
101
+
102
+ minDist.assign( min( minDist, dot( r, r ) ) );
103
+
104
+ } );
105
+
106
+ } );
107
+
108
+ } );
109
+
110
+ return minDist;
111
+
112
+ }, { p: 'vec3', time: 'float', return: 'float' } );
@@ -14,7 +14,7 @@ import {
14
14
  Quaternion
15
15
  } from '@gnsx/three/webgpu';
16
16
 
17
- import { min, Fn, shadow, NodeUpdateType, getShadowMaterial, getShadowRenderObjectFunction } from '@gnsx/three/tsl';
17
+ import { min, Fn, shadow, NodeUpdateType } from '@gnsx/three/tsl';
18
18
 
19
19
  const { resetRendererAndSceneState, restoreRendererAndSceneState } = RendererUtils;
20
20
  let _rendererState;
@@ -273,14 +273,11 @@ class TileShadowNode extends ShadowBaseNode {
273
273
  const depthVersion = shadowMap.depthTexture.version;
274
274
  this._depthVersionCached = depthVersion;
275
275
  const currentRenderObjectFunction = renderer.getRenderObjectFunction();
276
- const currentMRT = renderer.getMRT();
277
- const useVelocity = currentMRT ? currentMRT.has( 'velocity' ) : false;
278
276
 
279
277
  _rendererState = resetRendererAndSceneState( renderer, scene, _rendererState );
280
- scene.overrideMaterial = getShadowMaterial( light );
278
+ scene.overrideMaterial = this.getShadowMaterial();
281
279
  renderer.setRenderTarget( this.shadowMap );
282
280
 
283
-
284
281
  for ( let index = 0; index < this.lights.length; index ++ ) {
285
282
 
286
283
  const light = this.lights[ index ];
@@ -297,7 +294,7 @@ class TileShadowNode extends ShadowBaseNode {
297
294
 
298
295
  shadow.updateMatrices( light );
299
296
 
300
- renderer.setRenderObjectFunction( getShadowRenderObjectFunction( renderer, shadow, shadowType, useVelocity ) );
297
+ renderer.setRenderObjectFunction( this.getShadowRenderObjectFunction( renderer, shadow ) );
301
298
  this.shadowMap.setSize( shadow.mapSize.width, shadow.mapSize.height, shadowMap.depth );
302
299
 
303
300
  }
@@ -447,6 +444,7 @@ class TileShadowNode extends ShadowBaseNode {
447
444
 
448
445
  // Dispose lights, nodes, and shadow map
449
446
  this.disposeLightsAndNodes();
447
+ this.disposeShadowMaterial();
450
448
  super.dispose();
451
449
 
452
450
  }
@@ -53,17 +53,17 @@ export const RaymarchingBox = ( steps, callback ) => {
53
53
  bounds.assign( vec2( max( bounds.x, 0.0 ), bounds.y ) );
54
54
 
55
55
  const inc = vec3( rayDir.abs().reciprocal() ).toVar();
56
- const delta = float( min( inc.x, min( inc.y, inc.z ) ) ).toVar();
56
+ const stepSize = float( min( inc.x, min( inc.y, inc.z ) ) ).toVar();
57
57
 
58
- delta.divAssign( float( steps ) );
58
+ stepSize.divAssign( float( steps ) );
59
59
 
60
60
  const positionRay = vec3( vOrigin.add( bounds.x.mul( rayDir ) ) ).toVar();
61
61
 
62
- Loop( { type: 'float', start: bounds.x, end: bounds.y, update: delta }, () => {
62
+ Loop( { type: 'float', start: bounds.x, end: bounds.y, update: stepSize }, () => {
63
63
 
64
- callback( { positionRay } );
64
+ callback( { positionRay, stepSize } );
65
65
 
66
- positionRay.addAssign( rayDir.mul( delta ) );
66
+ positionRay.addAssign( rayDir.mul( stepSize ) );
67
67
 
68
68
  } );
69
69