@unikia/upe-renderer 0.186.110 → 0.187.11

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 (506) hide show
  1. package/README.md +5 -7
  2. package/UPSTREAM.md +4 -4
  3. package/build/three.core.js +853 -277
  4. package/build/three.module.js +1098 -1280
  5. package/build/three.tsl.js +41938 -686
  6. package/build/three.webgpu.js +10604 -49055
  7. package/build/three.webgpu.nodes.js +9249 -5788
  8. package/examples/jsm/Addons.js +2 -0
  9. package/examples/jsm/animation/CCDIKSolver.js +17 -5
  10. package/examples/jsm/controls/FirstPersonControls.js +1 -1
  11. package/examples/jsm/controls/OrbitControls.js +27 -14
  12. package/examples/jsm/csm/CSMShader.js +74 -3
  13. package/examples/jsm/curves/CurveExtras.js +4 -4
  14. package/examples/jsm/curves/NURBSCurve.js +14 -0
  15. package/examples/jsm/exporters/EXRExporter.js +673 -16
  16. package/examples/jsm/exporters/GLTFExporter.js +4 -4
  17. package/examples/jsm/exporters/KTX2Exporter.js +1 -1
  18. package/examples/jsm/exporters/OBJExporter.js +48 -5
  19. package/examples/jsm/exporters/PLYExporter.js +22 -11
  20. package/examples/jsm/generators/CityGenerator.js +3 -2
  21. package/examples/jsm/generators/city/SkyscraperGenerator.js +63 -21
  22. package/examples/jsm/gpgpu/BitonicSort.js +30 -23
  23. package/examples/jsm/helpers/VertexTangentsHelper.js +1 -1
  24. package/examples/jsm/inspector/Extension.js +1 -1
  25. package/examples/jsm/inspector/Inspector.js +6 -46
  26. package/examples/jsm/inspector/RendererInspector.js +43 -8
  27. package/examples/jsm/inspector/Storage.js +49 -0
  28. package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +32 -27
  29. package/examples/jsm/inspector/tabs/Parameters.js +5 -1
  30. package/examples/jsm/inspector/tabs/Performance.js +22 -7
  31. package/examples/jsm/inspector/tabs/Settings.js +1 -1
  32. package/examples/jsm/inspector/tabs/Timeline.js +83 -7
  33. package/examples/jsm/inspector/tabs/Viewer.js +25 -10
  34. package/examples/jsm/inspector/ui/Profiler.js +1 -1
  35. package/examples/jsm/inspector/ui/Style.js +21 -53
  36. package/examples/jsm/inspector/ui/Values.js +28 -3
  37. package/examples/jsm/libs/fflate.module.js +83 -56
  38. package/examples/jsm/libs/mikktspace.README.md +27 -0
  39. package/examples/jsm/libs/mikktspace.module.js +721 -109
  40. package/examples/jsm/lighting/ClusteredLighting.js +100 -2
  41. package/examples/jsm/lighting/LightMapper.js +295 -0
  42. package/examples/jsm/lighting/LightProbeGrid.js +242 -139
  43. package/examples/jsm/lighting/LightProbeGridWebGL.js +30 -14
  44. package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +54 -5
  45. package/examples/jsm/lighting/vxgi/VXGIIrradiance.js +43 -0
  46. package/examples/jsm/lighting/vxgi/VXGINode.js +13 -56
  47. package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +316 -1
  48. package/examples/jsm/lighting/vxgi/VXGIVolume.js +69 -59
  49. package/examples/jsm/lights/SunLight.js +9 -4
  50. package/examples/jsm/lights/SunLightNode.js +3 -3
  51. package/examples/jsm/lines/LineMaterial.js +26 -10
  52. package/examples/jsm/loaders/3DMLoader.js +10 -1
  53. package/examples/jsm/loaders/3MFLoader.js +5 -1
  54. package/examples/jsm/loaders/AMFLoader.js +2 -0
  55. package/examples/jsm/loaders/BVHLoader.js +2 -0
  56. package/examples/jsm/loaders/ColladaLoader.js +8 -0
  57. package/examples/jsm/loaders/DDSLoader.js +1 -1
  58. package/examples/jsm/loaders/DRACOLoader.js +5 -1
  59. package/examples/jsm/loaders/EXRLoader.js +120 -104
  60. package/examples/jsm/loaders/FBXLoader.js +4 -0
  61. package/examples/jsm/loaders/FontLoader.js +2 -0
  62. package/examples/jsm/loaders/GCodeLoader.js +5 -9
  63. package/examples/jsm/loaders/GLTFLoader.js +112 -31
  64. package/examples/jsm/loaders/GaussianSplatPLYLoader.js +2 -0
  65. package/examples/jsm/loaders/HDRCubeTextureLoader.js +3 -0
  66. package/examples/jsm/loaders/IESLoader.js +46 -12
  67. package/examples/jsm/loaders/JXLLoader.js +159 -0
  68. package/examples/jsm/loaders/KMZLoader.js +6 -0
  69. package/examples/jsm/loaders/KSPLATLoader.js +2 -0
  70. package/examples/jsm/loaders/KTX2Loader.js +49 -4
  71. package/examples/jsm/loaders/KTXLoader.js +5 -3
  72. package/examples/jsm/loaders/LDrawLoader.js +15 -22
  73. package/examples/jsm/loaders/LUT3dlLoader.js +5 -1
  74. package/examples/jsm/loaders/LUTCubeLoader.js +6 -2
  75. package/examples/jsm/loaders/LUTImageLoader.js +2 -0
  76. package/examples/jsm/loaders/LWOLoader.js +6 -0
  77. package/examples/jsm/loaders/MD2Loader.js +2 -0
  78. package/examples/jsm/loaders/MDDLoader.js +4 -0
  79. package/examples/jsm/loaders/MTLLoader.js +8 -0
  80. package/examples/jsm/loaders/MaterialXLoader.js +57 -5
  81. package/examples/jsm/loaders/NRRDLoader.js +4 -2
  82. package/examples/jsm/loaders/OBJLoader.js +10 -4
  83. package/examples/jsm/loaders/PCDLoader.js +6 -2
  84. package/examples/jsm/loaders/PDBLoader.js +5 -3
  85. package/examples/jsm/loaders/PLYLoader.js +39 -15
  86. package/examples/jsm/loaders/PVRLoader.js +2 -2
  87. package/examples/jsm/loaders/SPLATLoader.js +2 -0
  88. package/examples/jsm/loaders/SPZLoader.js +2 -0
  89. package/examples/jsm/loaders/STLLoader.js +3 -1
  90. package/examples/jsm/loaders/SVGLoader.js +27 -49
  91. package/examples/jsm/loaders/TDSLoader.js +4 -0
  92. package/examples/jsm/loaders/TGALoader.js +6 -5
  93. package/examples/jsm/loaders/TTFLoader.js +2 -0
  94. package/examples/jsm/loaders/USDLoader.js +14 -0
  95. package/examples/jsm/loaders/UltraHDRLoader.js +2 -0
  96. package/examples/jsm/loaders/VOXLoader.js +3 -0
  97. package/examples/jsm/loaders/VRMLLoader.js +4 -0
  98. package/examples/jsm/loaders/VTKLoader.js +2 -0
  99. package/examples/jsm/loaders/XYZLoader.js +2 -0
  100. package/examples/jsm/loaders/collada/ColladaComposer.js +15 -8
  101. package/examples/jsm/loaders/materialx/MaterialXDocument.js +610 -138
  102. package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +12 -95
  103. package/examples/jsm/loaders/materialx/MaterialXLog.js +4 -0
  104. package/examples/jsm/loaders/materialx/MaterialXNodeDefs.js +99 -0
  105. package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +760 -1
  106. package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +222 -372
  107. package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +163 -259
  108. package/examples/jsm/loaders/materialx/MaterialXUtils.js +25 -0
  109. package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +161 -159
  110. package/examples/jsm/loaders/usd/USDAParser.js +56 -47
  111. package/examples/jsm/loaders/usd/USDComposer.js +25 -30
  112. package/examples/jsm/math/ColorConverter.js +7 -3
  113. package/examples/jsm/math/Lut.js +2 -2
  114. package/examples/jsm/math/OBB.js +3 -3
  115. package/examples/jsm/math/Octree.js +20 -17
  116. package/examples/jsm/objects/GaussianSplat.js +5 -4
  117. package/examples/jsm/objects/Reflector.js +5 -0
  118. package/examples/jsm/objects/SkyMesh.js +14 -7
  119. package/examples/jsm/objects/Water2Mesh.js +2 -2
  120. package/examples/jsm/physics/RapierPhysics.js +2 -2
  121. package/examples/jsm/pipelines/MeshletDrawingPipeline.js +5571 -0
  122. package/examples/jsm/pipelines/VisibilityBufferDrawingPipeline.js +954 -0
  123. package/examples/jsm/postprocessing/BokehPass.js +1 -1
  124. package/examples/jsm/postprocessing/GTAOPass.js +26 -18
  125. package/examples/jsm/renderers/SVGRenderer.js +3 -2
  126. package/examples/jsm/shaders/GTAOShader.js +7 -4
  127. package/examples/jsm/shaders/PoissonDenoiseShader.js +1 -10
  128. package/examples/jsm/tsl/WebGLNodesHandler.js +21 -9
  129. package/examples/jsm/tsl/display/AfterImageNode.js +3 -3
  130. package/examples/jsm/tsl/display/BilateralBlurNode.js +3 -3
  131. package/examples/jsm/tsl/display/BloomNode.js +3 -3
  132. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +8 -19
  133. package/examples/jsm/tsl/display/DenoiseNode.js +5 -5
  134. package/examples/jsm/tsl/display/DepthOfFieldNode.js +3 -3
  135. package/examples/jsm/tsl/display/DotScreenNode.js +3 -3
  136. package/examples/jsm/tsl/display/FSR1Node.js +3 -3
  137. package/examples/jsm/tsl/display/FXAANode.js +3 -10
  138. package/examples/jsm/tsl/display/FilmNode.js +3 -3
  139. package/examples/jsm/tsl/display/GTAONode.js +33 -25
  140. package/examples/jsm/tsl/display/GaussianBlurNode.js +3 -3
  141. package/examples/jsm/tsl/display/GodraysNode.js +5 -19
  142. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +8 -4
  143. package/examples/jsm/tsl/display/LensflareNode.js +3 -3
  144. package/examples/jsm/tsl/display/Lut3DNode.js +3 -3
  145. package/examples/jsm/tsl/display/OITPassNode.js +0 -11
  146. package/examples/jsm/tsl/display/OutlineNode.js +107 -5
  147. package/examples/jsm/tsl/display/PixelationPassNode.js +85 -193
  148. package/examples/jsm/tsl/display/RGBShiftNode.js +3 -3
  149. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +23 -126
  150. package/examples/jsm/tsl/display/SMAANode.js +3 -3
  151. package/examples/jsm/tsl/display/SSAONode.js +6 -20
  152. package/examples/jsm/tsl/display/SSGINode.js +36 -29
  153. package/examples/jsm/tsl/display/SSRNode.js +135 -63
  154. package/examples/jsm/tsl/display/SSSNode.js +6 -20
  155. package/examples/jsm/tsl/display/SharpenNode.js +3 -3
  156. package/examples/jsm/tsl/display/SobelOperatorNode.js +3 -3
  157. package/examples/jsm/tsl/display/TAAUNode.js +10 -42
  158. package/examples/jsm/tsl/display/TRAANode.js +11 -43
  159. package/examples/jsm/tsl/display/TemporalReprojectNode.js +42 -47
  160. package/examples/jsm/tsl/display/TransitionNode.js +3 -3
  161. package/examples/jsm/tsl/display/lensDirt.js +30 -0
  162. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +482 -121
  163. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +41 -140
  164. package/examples/jsm/tsl/lighting/LightProbeGridNode.js +72 -25
  165. package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +6 -0
  166. package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +6 -0
  167. package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +6 -0
  168. package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +6 -0
  169. package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +6 -0
  170. package/examples/jsm/tsl/shadows/TileShadowNode.js +102 -14
  171. package/examples/jsm/tsl/utils/Raymarching.js +1 -1
  172. package/examples/jsm/tsl/utils/SoftParticles.js +5 -12
  173. package/examples/jsm/tsl/utils/SpecularHelpers.js +47 -70
  174. package/examples/jsm/tsl/utils/TAAUtils.js +6 -17
  175. package/examples/jsm/utils/BufferGeometryUtils.js +110 -88
  176. package/examples/jsm/utils/MeshletGeometryUtils.js +417 -0
  177. package/examples/jsm/utils/SceneOptimizer.js +2 -1
  178. package/examples/jsm/utils/SceneUtils.js +1 -1
  179. package/examples/jsm/utils/unwrapUVs.js +865 -0
  180. package/examples/jsm/webxr/XREstimatedLight.js +11 -4
  181. package/package.json +3 -3
  182. package/src/Three.TSL.js +2 -683
  183. package/src/Three.WebGPU.Nodes.js +2 -1
  184. package/src/Three.WebGPU.js +2 -1
  185. package/src/animation/AnimationAction.js +1 -1
  186. package/src/animation/AnimationUtils.js +1 -3
  187. package/src/animation/KeyframeTrack.js +19 -0
  188. package/src/cameras/ArrayCamera.js +12 -0
  189. package/src/cameras/CubeCamera.js +3 -3
  190. package/src/constants.js +1 -9
  191. package/src/core/BufferAttribute.js +57 -21
  192. package/src/core/BufferGeometry.js +5 -13
  193. package/src/core/Clock.js +1 -1
  194. package/src/core/InterleavedBuffer.js +28 -18
  195. package/src/core/InterleavedBufferAttribute.js +54 -20
  196. package/src/core/Object3D.js +19 -9
  197. package/src/core/Raycaster.js +2 -0
  198. package/src/core/RenderTarget.js +11 -5
  199. package/src/core/UniformsGroup.js +7 -3
  200. package/src/extras/PMREMGenerator.js +392 -685
  201. package/src/extras/core/Curve.js +4 -0
  202. package/src/extras/core/CurvePath.js +13 -0
  203. package/src/extras/core/ShapePath.js +1 -1
  204. package/src/geometries/EdgesGeometry.js +12 -10
  205. package/src/geometries/LatheGeometry.js +2 -0
  206. package/src/helpers/PolarGridHelper.js +1 -1
  207. package/src/lights/Light.js +11 -0
  208. package/src/lights/LightProbe.js +2 -0
  209. package/src/lights/LightShadow.js +2 -0
  210. package/src/loaders/AnimationLoader.js +2 -0
  211. package/src/loaders/AudioLoader.js +2 -0
  212. package/src/loaders/BufferGeometryLoader.js +2 -0
  213. package/src/loaders/CompressedTextureLoader.js +2 -0
  214. package/src/loaders/CubeTextureLoader.js +2 -0
  215. package/src/loaders/DataTextureLoader.js +2 -0
  216. package/src/loaders/FileLoader.js +2 -0
  217. package/src/loaders/ImageBitmapLoader.js +3 -1
  218. package/src/loaders/ImageLoader.js +1 -0
  219. package/src/loaders/Loader.js +47 -0
  220. package/src/loaders/MaterialLoader.js +2 -0
  221. package/src/loaders/ObjectLoader.js +27 -8
  222. package/src/loaders/TextureLoader.js +5 -3
  223. package/src/loaders/nodes/NodeLoader.js +2 -0
  224. package/src/materials/Material.js +21 -2
  225. package/src/materials/MeshDepthMaterial.js +1 -1
  226. package/src/materials/MeshDistanceMaterial.js +1 -1
  227. package/src/materials/MeshLambertMaterial.js +1 -1
  228. package/src/materials/MeshMatcapMaterial.js +1 -1
  229. package/src/materials/MeshNormalMaterial.js +1 -1
  230. package/src/materials/MeshPhongMaterial.js +1 -1
  231. package/src/materials/MeshPhysicalMaterial.js +90 -11
  232. package/src/materials/MeshStandardMaterial.js +1 -1
  233. package/src/materials/MeshToonMaterial.js +1 -1
  234. package/src/materials/nodes/Line2NodeMaterial.js +32 -10
  235. package/src/materials/nodes/MeshLambertNodeMaterial.js +13 -0
  236. package/src/materials/nodes/MeshPhongNodeMaterial.js +13 -0
  237. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +40 -5
  238. package/src/materials/nodes/MeshToonNodeMaterial.js +13 -0
  239. package/src/materials/nodes/NodeMaterial.js +36 -16
  240. package/src/materials/nodes/NodeMaterialInstance.js +193 -0
  241. package/src/materials/nodes/NodeMaterials.js +1 -0
  242. package/src/materials/nodes/PointsNodeMaterial.js +1 -1
  243. package/src/materials/nodes/SpriteNodeMaterial.js +3 -3
  244. package/src/materials/nodes/manager/NodeMaterialObserver.js +191 -22
  245. package/src/math/Box3.js +2 -2
  246. package/src/math/Color.js +8 -8
  247. package/src/math/ColorManagement.js +2 -21
  248. package/src/math/FrustumArray.js +12 -0
  249. package/src/math/Interpolant.js +1 -1
  250. package/src/math/Line3.js +2 -4
  251. package/src/math/MathUtils.js +33 -46
  252. package/src/math/Matrix2.js +1 -1
  253. package/src/math/Matrix3.js +1 -1
  254. package/src/math/Matrix4.js +1 -1
  255. package/src/math/Triangle.js +2 -1
  256. package/src/math/Vector2.js +1 -1
  257. package/src/math/Vector3.js +1 -1
  258. package/src/math/Vector4.js +1 -1
  259. package/src/nodes/Nodes.js +1 -0
  260. package/src/nodes/TSL.js +2 -0
  261. package/src/nodes/accessors/Arrays.js +1 -1
  262. package/src/nodes/accessors/Batch.js +29 -23
  263. package/src/nodes/accessors/BufferAttributeNode.js +21 -1
  264. package/src/nodes/accessors/BuiltinNode.js +6 -0
  265. package/src/nodes/accessors/Camera.js +100 -93
  266. package/src/nodes/accessors/ClippingNode.js +17 -6
  267. package/src/nodes/accessors/CubeTextureNode.js +12 -24
  268. package/src/nodes/accessors/Instance.js +198 -160
  269. package/src/nodes/accessors/Lights.js +19 -6
  270. package/src/nodes/accessors/MaterialNode.js +33 -4
  271. package/src/nodes/accessors/Morph.js +81 -22
  272. package/src/nodes/accessors/Normal.js +0 -42
  273. package/src/nodes/accessors/Object3DNode.js +6 -0
  274. package/src/nodes/accessors/PointUVNode.js +6 -0
  275. package/src/nodes/accessors/ReferenceAttributeNode.js +279 -0
  276. package/src/nodes/accessors/ReferenceBaseNode.js +6 -0
  277. package/src/nodes/accessors/ReferenceNode.js +6 -0
  278. package/src/nodes/accessors/Skinning.js +57 -52
  279. package/src/nodes/accessors/StorageBufferNode.js +3 -12
  280. package/src/nodes/accessors/TextureBicubic.js +30 -27
  281. package/src/nodes/accessors/TextureNode.js +164 -78
  282. package/src/nodes/accessors/TextureSizeNode.js +6 -0
  283. package/src/nodes/accessors/UniformArrayNode.js +8 -15
  284. package/src/nodes/accessors/VelocityNode.js +13 -8
  285. package/src/nodes/code/CodeNode.js +6 -0
  286. package/src/nodes/code/ExpressionNode.js +6 -0
  287. package/src/nodes/code/FunctionCallNode.js +3 -3
  288. package/src/nodes/code/FunctionNode.js +15 -13
  289. package/src/nodes/core/ArrayNode.js +3 -3
  290. package/src/nodes/core/AssignNode.js +10 -9
  291. package/src/nodes/core/AttributeNode.js +39 -0
  292. package/src/nodes/core/BypassNode.js +6 -0
  293. package/src/nodes/core/ConstNode.js +31 -1
  294. package/src/nodes/core/ContextNode.js +11 -6
  295. package/src/nodes/core/IndexNode.js +6 -0
  296. package/src/nodes/core/InputNode.js +6 -0
  297. package/src/nodes/core/InspectorNode.js +17 -31
  298. package/src/nodes/core/IsolateNode.js +8 -0
  299. package/src/nodes/core/Node.js +367 -67
  300. package/src/nodes/core/NodeBuilder.js +664 -222
  301. package/src/nodes/core/NodeUtils.js +25 -0
  302. package/src/nodes/core/NodeVar.js +10 -1
  303. package/src/nodes/core/OutputStructNode.js +6 -0
  304. package/src/nodes/core/OverrideContextNode.js +38 -37
  305. package/src/nodes/core/PropertyNode.js +14 -0
  306. package/src/nodes/core/StackNode.js +33 -21
  307. package/src/nodes/core/StructNode.js +6 -0
  308. package/src/nodes/core/StructTypeNode.js +6 -0
  309. package/src/nodes/core/SubBuildNode.js +8 -0
  310. package/src/nodes/core/TempNode.js +10 -35
  311. package/src/nodes/core/UniformGroupNode.js +6 -0
  312. package/src/nodes/core/VarNode.js +43 -135
  313. package/src/nodes/core/VaryingNode.js +33 -2
  314. package/src/nodes/display/BlendModes.js +5 -40
  315. package/src/nodes/display/BumpMapNode.js +17 -7
  316. package/src/nodes/display/ColorAdjustment.js +22 -10
  317. package/src/nodes/display/ColorSpaceFunctions.js +2 -14
  318. package/src/nodes/display/ColorSpaceNode.js +3 -3
  319. package/src/nodes/display/FrontFacingNode.js +6 -0
  320. package/src/nodes/display/NormalMapNode.js +3 -3
  321. package/src/nodes/display/PassNode.js +75 -16
  322. package/src/nodes/display/RenderOutputNode.js +22 -5
  323. package/src/nodes/display/ScreenNode.js +6 -0
  324. package/src/nodes/display/ToneMappingFunctions.js +9 -51
  325. package/src/nodes/display/ToneMappingNode.js +3 -3
  326. package/src/nodes/display/ToonOutlinePassNode.js +66 -2
  327. package/src/nodes/display/ViewportDepthNode.js +34 -4
  328. package/src/nodes/functions/BSDF/BRDF_EON.js +65 -0
  329. package/src/nodes/functions/BSDF/BRDF_GGX.js +5 -3
  330. package/src/nodes/functions/BSDF/BRDF_Sheen.js +2 -16
  331. package/src/nodes/functions/BSDF/D_GGX.js +1 -8
  332. package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +7 -10
  333. package/src/nodes/functions/BSDF/LTC.js +20 -47
  334. package/src/nodes/functions/BSDF/Schlick_to_F0.js +1 -9
  335. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -9
  336. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +10 -13
  337. package/src/nodes/functions/PhysicalLightingModel.js +84 -51
  338. package/src/nodes/functions/VolumetricLightingModel.js +1 -1
  339. package/src/nodes/functions/material/getAlphaHashThreshold.js +3 -9
  340. package/src/nodes/functions/material/getParallaxCorrectNormal.js +10 -11
  341. package/src/nodes/functions/material/getRoughness.js +3 -1
  342. package/src/nodes/geometry/RangeNode.js +52 -69
  343. package/src/nodes/gpgpu/AtomicFunctionNode.js +11 -6
  344. package/src/nodes/gpgpu/BarrierNode.js +6 -0
  345. package/src/nodes/gpgpu/ComputeBuiltinNode.js +6 -0
  346. package/src/nodes/gpgpu/ComputeNode.js +6 -0
  347. package/src/nodes/gpgpu/SubgroupFunctionNode.js +38 -29
  348. package/src/nodes/gpgpu/WorkgroupInfoNode.js +6 -0
  349. package/src/nodes/lighting/AnalyticLightNode.js +7 -14
  350. package/src/nodes/lighting/BasicEnvironmentNode.js +5 -1
  351. package/src/nodes/lighting/EnvironmentNode.js +58 -8
  352. package/src/nodes/lighting/IESSpotLightNode.js +19 -4
  353. package/src/nodes/lighting/LightProbeNode.js +2 -1
  354. package/src/nodes/lighting/LightUtils.js +2 -2
  355. package/src/nodes/lighting/LightingNode.js +6 -0
  356. package/src/nodes/lighting/LightsNode.js +26 -32
  357. package/src/nodes/lighting/PointShadowNode.js +92 -48
  358. package/src/nodes/lighting/ProjectorLightNode.js +1 -1
  359. package/src/nodes/lighting/RectAreaLightNode.js +13 -14
  360. package/src/nodes/lighting/ShadowBaseNode.js +9 -17
  361. package/src/nodes/lighting/ShadowFilterNode.js +26 -3
  362. package/src/nodes/lighting/ShadowNode.js +13 -11
  363. package/src/nodes/materialx/MaterialXColor.js +2 -14
  364. package/src/nodes/materialx/MaterialXColorTransform.js +1 -7
  365. package/src/nodes/materialx/MaterialXNodes.js +8 -11
  366. package/src/nodes/materialx/MaterialXNoise.js +195 -454
  367. package/src/nodes/math/BitcastNode.js +5 -5
  368. package/src/nodes/math/BitcountNode.js +18 -46
  369. package/src/nodes/math/ConditionalNode.js +92 -22
  370. package/src/nodes/math/Hash.js +1 -1
  371. package/src/nodes/math/MathNode.js +86 -64
  372. package/src/nodes/math/MathUtils.js +2 -2
  373. package/src/nodes/math/OperatorNode.js +42 -59
  374. package/src/nodes/math/PackFloatNode.js +9 -9
  375. package/src/nodes/math/Packed4x8IntegerNode.js +20 -52
  376. package/src/nodes/math/TriNoise3D.js +3 -23
  377. package/src/nodes/math/UnpackFloatNode.js +9 -9
  378. package/src/nodes/pmrem/PMREMNode.js +38 -75
  379. package/src/nodes/pmrem/PMREMUtils.js +108 -272
  380. package/src/nodes/procedural/Checker.js +1 -1
  381. package/src/nodes/tsl/TSLCore.js +199 -74
  382. package/src/nodes/utils/ArrayElementNode.js +19 -1
  383. package/src/nodes/utils/CubeMapNode.js +3 -3
  384. package/src/nodes/utils/DebugNode.js +2 -2
  385. package/src/nodes/utils/EventNode.js +6 -0
  386. package/src/nodes/utils/FlipNode.js +3 -3
  387. package/src/nodes/utils/FunctionOverloadingNode.js +7 -1
  388. package/src/nodes/utils/JoinNode.js +3 -3
  389. package/src/nodes/utils/LoopNode.js +14 -9
  390. package/src/nodes/utils/MemberNode.js +18 -0
  391. package/src/nodes/utils/PostProcessingUtils.js +20 -25
  392. package/src/nodes/utils/RTTNode.js +2 -0
  393. package/src/nodes/utils/ReflectorNode.js +24 -0
  394. package/src/nodes/utils/RotateNode.js +3 -3
  395. package/src/nodes/utils/SampleNode.js +6 -0
  396. package/src/nodes/utils/SetNode.js +3 -3
  397. package/src/nodes/utils/SplitNode.js +6 -0
  398. package/src/nodes/utils/UVUtils.js +2 -2
  399. package/src/objects/BatchedMesh.js +146 -15
  400. package/src/objects/InstancedMesh.js +12 -4
  401. package/src/objects/Line.js +20 -0
  402. package/src/objects/Mesh.js +8 -0
  403. package/src/objects/Points.js +20 -0
  404. package/src/objects/Skeleton.js +26 -0
  405. package/src/objects/SkinnedMesh.js +3 -3
  406. package/src/objects/Sprite.js +10 -0
  407. package/src/renderers/WebGLRenderer.js +104 -70
  408. package/src/renderers/common/Animation.js +5 -1
  409. package/src/renderers/common/Attributes.js +67 -57
  410. package/src/renderers/common/Backend.js +78 -3
  411. package/src/renderers/common/BindGroup.js +11 -0
  412. package/src/renderers/common/Binding.js +0 -11
  413. package/src/renderers/common/Bindings.js +116 -10
  414. package/src/renderers/common/Buffer.js +1 -1
  415. package/src/renderers/common/ClippingContext.js +12 -1
  416. package/src/renderers/common/ComputePipeline.js +17 -1
  417. package/src/renderers/common/DirectRenderPipeline.js +7 -3
  418. package/src/renderers/common/Geometries.js +170 -132
  419. package/src/renderers/common/Info.js +1 -1
  420. package/src/renderers/common/InspectorBase.js +5 -5
  421. package/src/renderers/common/Lighting.js +59 -0
  422. package/src/renderers/common/Pipelines.js +26 -12
  423. package/src/renderers/common/ProgrammableStage.js +1 -17
  424. package/src/renderers/common/RenderContext.js +21 -0
  425. package/src/renderers/common/RenderContexts.js +13 -4
  426. package/src/renderers/common/RenderObject.js +111 -35
  427. package/src/renderers/common/RenderObjects.js +37 -19
  428. package/src/renderers/common/Renderer.js +537 -295
  429. package/src/renderers/common/RendererUtils.js +15 -0
  430. package/src/renderers/common/StandardDrawingPipeline.js +343 -0
  431. package/src/renderers/common/Storage3DTexture.js +11 -0
  432. package/src/renderers/common/StorageArrayTexture.js +10 -0
  433. package/src/renderers/common/StorageTexture.js +0 -9
  434. package/src/renderers/common/Textures.js +144 -37
  435. package/src/renderers/common/UniformsGroup.js +19 -0
  436. package/src/renderers/common/XRManager.js +10 -91
  437. package/src/renderers/common/extras/PMREMGenerator.js +298 -576
  438. package/src/renderers/common/nodes/NodeBuilderState.js +7 -5
  439. package/src/renderers/common/nodes/NodeLibrary.js +11 -35
  440. package/src/renderers/common/nodes/NodeManager.js +80 -31
  441. package/src/renderers/common/nodes/NodeSampledTexture.js +14 -0
  442. package/src/renderers/common/nodes/NodeSampler.js +14 -0
  443. package/src/renderers/common/nodes/NodeStorageBuffer.js +1 -1
  444. package/src/renderers/common/nodes/NodeUniformBuffer.js +1 -14
  445. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +13 -4
  446. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +8 -8
  447. package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +23 -11
  448. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +21 -2
  449. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +1 -1
  450. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +18 -2
  451. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +104 -7
  452. package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +11 -2
  453. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +36 -20
  454. package/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js +5 -0
  455. package/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js +6 -0
  456. package/src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js +5 -0
  457. package/src/renderers/shaders/ShaderChunk.js +0 -2
  458. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +4 -18
  459. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +0 -1
  460. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +0 -1
  461. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +8 -1
  462. package/src/renderers/shaders/ShaderLib.js +3 -0
  463. package/src/renderers/shaders/UniformsLib.js +4 -5
  464. package/src/renderers/webgl/WebGLBackground.js +3 -3
  465. package/src/renderers/webgl/WebGLBindingStates.js +4 -2
  466. package/src/renderers/webgl/WebGLCapabilities.js +7 -1
  467. package/src/renderers/webgl/WebGLEnvironments.js +2 -2
  468. package/src/renderers/webgl/WebGLGeometries.js +42 -14
  469. package/src/renderers/webgl/WebGLMaterials.js +15 -2
  470. package/src/renderers/webgl/WebGLOutput.js +37 -1
  471. package/src/renderers/webgl/WebGLProgram.js +13 -54
  472. package/src/renderers/webgl/WebGLPrograms.js +22 -8
  473. package/src/renderers/webgl/WebGLRenderStates.js +11 -8
  474. package/src/renderers/webgl/WebGLShadowMap.js +6 -4
  475. package/src/renderers/webgl/WebGLState.js +10 -6
  476. package/src/renderers/webgl/WebGLTextures.js +129 -77
  477. package/src/renderers/webgl/WebGLUniforms.js +44 -6
  478. package/src/renderers/webgl/WebGLUniformsGroups.js +75 -69
  479. package/src/renderers/webgl-fallback/WebGLBackend.js +206 -278
  480. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +154 -20
  481. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +45 -42
  482. package/src/renderers/webgl-fallback/utils/WebGLState.js +29 -4
  483. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +129 -49
  484. package/src/renderers/webgl-fallback/utils/WebGLVertexArrayUtils.js +346 -0
  485. package/src/renderers/webgpu/WebGPUBackend.js +140 -82
  486. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  487. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +10 -10
  488. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +10 -10
  489. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +135 -60
  490. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +128 -55
  491. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
  492. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +15 -12
  493. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +55 -19
  494. package/src/renderers/webgpu/utils/WebGPUUtils.js +20 -3
  495. package/src/renderers/webxr/WebXRController.js +3 -3
  496. package/src/renderers/webxr/WebXRManager.js +5 -90
  497. package/src/scenes/Scene.js +4 -4
  498. package/src/textures/CompressedTexture.js +2 -2
  499. package/src/textures/DepthTexture.js +2 -2
  500. package/src/textures/FramebufferTexture.js +11 -0
  501. package/src/textures/Texture.js +29 -1
  502. package/src/textures/TextureSource.js +1 -1
  503. package/src/upe.js +1 -1
  504. package/src/utils.js +4 -4
  505. package/examples/jsm/libs/surfaceNet.js +0 -201
  506. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +0 -186
@@ -1,7 +1,6 @@
1
1
  import {
2
+ ArrayCamera,
2
3
  Box3,
3
- CubeCamera,
4
- CubeRenderTarget,
5
4
  FloatType,
6
5
  HalfFloatType,
7
6
  Light,
@@ -9,16 +8,18 @@ import {
9
8
  MathUtils,
10
9
  NearestFilter,
11
10
  NodeMaterial,
11
+ PerspectiveCamera,
12
12
  QuadMesh,
13
13
  RenderTarget,
14
14
  RenderTarget3D,
15
15
  RGBAFormat,
16
- Vector3
16
+ Vector3,
17
+ Vector4
17
18
  } from 'three/webgpu';
18
19
 
19
20
  import {
20
21
  array,
21
- cubeTexture,
22
+ atan,
22
23
  float,
23
24
  Fn,
24
25
  int,
@@ -34,95 +35,125 @@ import {
34
35
  import { LightProbeGridNode, ATLAS_PADDING } from '../tsl/lighting/LightProbeGridNode.js';
35
36
  import { replaceSunLights, restoreSunLights } from './LightProbeGridUtils.js';
36
37
 
38
+ // Probes captured per render, six sub-cameras each.
39
+ const PROBES_PER_BATCH = 8;
40
+
41
+ // Row blocks per face, so each probe's projection spreads over more fragments.
42
+ const FACE_BLOCKS = 4;
43
+
44
+ // Per-face forward, right and up vectors of the capture cameras.
45
+ const FACE_FORWARD = [[ 1, 0, 0 ], [ - 1, 0, 0 ], [ 0, 1, 0 ], [ 0, - 1, 0 ], [ 0, 0, 1 ], [ 0, 0, - 1 ]];
46
+ const FACE_RIGHT = [[ 0, 0, 1 ], [ 0, 0, - 1 ], [ - 1, 0, 0 ], [ - 1, 0, 0 ], [ - 1, 0, 0 ], [ 1, 0, 0 ]];
47
+ const FACE_UP = [[ 0, 1, 0 ], [ 0, 1, 0 ], [ 0, 0, - 1 ], [ 0, 0, 1 ], [ 0, 1, 0 ], [ 0, 1, 0 ]];
48
+
37
49
  // Shared fullscreen-quad for the bake passes.
38
50
  const _quad = /*@__PURE__*/ new QuadMesh();
39
51
 
40
52
  // Reusable temp objects.
41
53
  const _position = /*@__PURE__*/ new Vector3();
54
+ const _target = /*@__PURE__*/ new Vector3();
42
55
  const _size = /*@__PURE__*/ new Vector3();
43
56
  const _copyRegion = /*@__PURE__*/ new Box3();
44
57
 
45
58
  // Bake materials, shared across grids so the shaders compile once, not per bake.
46
59
  let _shMaterial = null;
47
- let _shSampleCount = - 1;
48
- let _cubeNode = null;
60
+ let _shFaceSize = - 1;
61
+ let _faceNode = null;
49
62
  let _batchNode = null;
63
+ let _batchStartUniform = null;
50
64
  let _resolutionUniform = null;
51
65
  let _sliceZUniform = null;
52
66
  let _repackMaterials = null;
53
67
 
54
68
  // Bake render targets, pooled by size so rebakes don't churn allocations.
55
- let _cubeRenderTarget = null;
56
- let _cubeCamera = null;
57
- let _cubeKey = '';
69
+ let _faceTarget = null;
70
+ let _faceSize = - 1;
58
71
  let _batchTarget = null;
59
72
  let _batchProbes = - 1;
60
73
 
61
- // Golden-angle increment for the equal-area Fibonacci sphere.
62
- const GOLDEN_ANGLE = Math.PI * ( 3.0 - Math.sqrt( 5.0 ) );
74
+ // Renders all faces of a probe batch in one pass.
75
+ let _captureCamera = null;
63
76
 
64
77
  /**
65
78
  * Returns the output node for the spherical-harmonic projection pass. Each
66
- * fragment of the 9-wide batch row computes a single SH coefficient by
67
- * integrating the captured cubemap over an equal-area Fibonacci sphere,
68
- * selecting the basis function for its column. Sampling the cubemap by world
69
- * direction keeps the projection independent of the cube face layout.
79
+ * fragment of a batch row integrates one SH coefficient over one row block of a
80
+ * captured cube face, weighting every texel by its exact solid angle. Columns are ordered
81
+ * `( coefficient * 6 + face ) * FACE_BLOCKS + block`; the repack pass sums them.
70
82
  *
71
83
  * @private
72
- * @param {Node} cube - The captured environment cubemap texture node.
73
- * @param {number} sampleCount - Number of directions to integrate.
74
- * @return {Node<vec4>} The projected coefficient.
84
+ * @param {Node} faces - The face atlas texture node.
85
+ * @param {number} size - The face resolution.
86
+ * @param {Node<int>} batchStart - The probe index of the first batch row.
87
+ * @return {Node<vec4>} The projected coefficient for one face.
75
88
  */
76
- function projectSHNode( cube, sampleCount ) {
89
+ function projectSHNode( faces, size, batchStart ) {
77
90
 
78
91
  return Fn( () => {
79
92
 
80
- const coefIndex = int( screenCoordinate.x ).toVar();
93
+ const column = int( screenCoordinate.x );
94
+ const block = column.mod( FACE_BLOCKS );
95
+ const coefIndex = column.div( 6 * FACE_BLOCKS ).toVar();
96
+ const face = column.div( FACE_BLOCKS ).mod( 6 ).toVar();
97
+ const slot = int( screenCoordinate.y ).sub( batchStart );
98
+ const rows = size / FACE_BLOCKS;
99
+ const rowStart = block.mul( rows ).toVar();
100
+
101
+ const forward = array( FACE_FORWARD.map( ( v ) => vec3( ...v ) ) ).element( face ).toVar();
102
+ const right = array( FACE_RIGHT.map( ( v ) => vec3( ...v ) ) ).element( face ).toVar();
103
+ const up = array( FACE_UP.map( ( v ) => vec3( ...v ) ) ).element( face ).toVar();
104
+
105
+ const origin = ivec2( face.mul( size ), slot.mul( size ).add( rowStart ) ).toVar();
106
+ const texelSize = 2.0 / size;
81
107
  const accum = vec3( 0.0 ).toVar();
82
108
 
83
- Loop( sampleCount, ( { i } ) => {
109
+ // Signed area of the projected face region from its center to ( x, y ).
110
+ const area = ( x, y ) => atan( x.mul( y ).div( x.mul( x ).add( y.mul( y ) ).add( 1.0 ).sqrt() ) );
84
111
 
85
- const fi = float( i );
112
+ Loop( size, rows, ( { i, j } ) => {
86
113
 
87
- // Equal-area Fibonacci sphere direction.
88
- const z = float( 1.0 ).sub( fi.mul( 2.0 ).add( 1.0 ).div( sampleCount ) );
89
- const r = z.mul( z ).oneMinus().max( 0.0 ).sqrt();
90
- const phi = fi.mul( GOLDEN_ANGLE );
91
- const dir = vec3( r.mul( phi.cos() ), z, r.mul( phi.sin() ) ).toVar();
114
+ // Rows run top to bottom, so NDC y decreases with j.
115
+ const x0 = float( i ).mul( texelSize ).sub( 1.0 );
116
+ const x1 = x0.add( texelSize );
117
+ const y0 = float( 1.0 ).sub( float( j.add( rowStart ) ).mul( texelSize ) );
118
+ const y1 = y0.sub( texelSize );
92
119
 
93
- const radiance = cube.sample( dir ).level( 0 ).rgb;
120
+ const solidAngle = area( x0, y0 ).sub( area( x0, y1 ) ).sub( area( x1, y0 ) ).add( area( x1, y1 ) ).abs();
121
+
122
+ const x = x0.add( texelSize * 0.5 );
123
+ const y = y0.sub( texelSize * 0.5 );
124
+ const dir = forward.add( right.mul( x ) ).add( up.mul( y ) ).normalize().toVar();
125
+
126
+ const radiance = faces.load( origin.add( ivec2( i, j ) ) ).rgb;
94
127
 
95
128
  // The L2 SH basis function for this fragment's coefficient.
96
- const x = dir.x, y = dir.y, zc = dir.z;
129
+ const dx = dir.x, dy = dir.y, dz = dir.z;
97
130
  const basis = array( [
98
131
  float( 0.282095 ),
99
- y.mul( 0.488603 ),
100
- zc.mul( 0.488603 ),
101
- x.mul( 0.488603 ),
102
- x.mul( y ).mul( 1.092548 ),
103
- y.mul( zc ).mul( 1.092548 ),
104
- zc.mul( zc ).mul( 3.0 ).sub( 1.0 ).mul( 0.315392 ),
105
- x.mul( zc ).mul( 1.092548 ),
106
- x.mul( x ).sub( y.mul( y ) ).mul( 0.546274 )
132
+ dy.mul( 0.488603 ),
133
+ dz.mul( 0.488603 ),
134
+ dx.mul( 0.488603 ),
135
+ dx.mul( dy ).mul( 1.092548 ),
136
+ dy.mul( dz ).mul( 1.092548 ),
137
+ dz.mul( dz ).mul( 3.0 ).sub( 1.0 ).mul( 0.315392 ),
138
+ dx.mul( dz ).mul( 1.092548 ),
139
+ dx.mul( dx ).sub( dy.mul( dy ) ).mul( 0.546274 )
107
140
  ] ).element( coefIndex );
108
141
 
109
- accum.addAssign( radiance.mul( basis ) );
142
+ accum.addAssign( radiance.mul( basis.mul( solidAngle ) ) );
110
143
 
111
144
  } );
112
145
 
113
- // Equal-area quadrature: each direction covers 4*PI / sampleCount.
114
- const norm = float( 4.0 * Math.PI / sampleCount );
115
-
116
- return vec4( accum.mul( norm ), 1.0 );
146
+ return vec4( accum, 1.0 );
117
147
 
118
148
  } )();
119
149
 
120
150
  }
121
151
 
122
152
  /**
123
- * Returns the repack output node for one of the seven SH textures. It reads the
124
- * 9 projected coefficients from the batch texture for the probe at the current
125
- * texel and packs the four floats stored by this texture index.
153
+ * Returns the repack output node for one of the seven SH textures. It sums the
154
+ * per-face projections of the 9 coefficients from the batch texture for the
155
+ * probe at the current texel and packs the four floats stored by this texture
156
+ * index.
126
157
  *
127
158
  * @private
128
159
  * @param {Node} batch - The batch texture node holding projected coefficients.
@@ -138,19 +169,19 @@ function repackNode( batch, textureIndex, resolution, sliceZ ) {
138
169
  const ix = int( screenCoordinate.x );
139
170
  const iy = int( screenCoordinate.y );
140
171
 
172
+ // Batch rows follow the bake order (X, then Z, then Y).
141
173
  const nx = int( resolution.x );
142
- const ny = int( resolution.y );
143
- const probeIndex = ix.add( iy.mul( nx ) ).add( sliceZ.mul( nx ).mul( ny ) );
144
-
145
- const c0 = batch.load( ivec2( 0, probeIndex ) );
146
- const c1 = batch.load( ivec2( 1, probeIndex ) );
147
- const c2 = batch.load( ivec2( 2, probeIndex ) );
148
- const c3 = batch.load( ivec2( 3, probeIndex ) );
149
- const c4 = batch.load( ivec2( 4, probeIndex ) );
150
- const c5 = batch.load( ivec2( 5, probeIndex ) );
151
- const c6 = batch.load( ivec2( 6, probeIndex ) );
152
- const c7 = batch.load( ivec2( 7, probeIndex ) );
153
- const c8 = batch.load( ivec2( 8, probeIndex ) );
174
+ const nz = int( resolution.z );
175
+ const probeIndex = ix.add( sliceZ.mul( nx ) ).add( iy.mul( nx ).mul( nz ) ).toVar();
176
+
177
+ // Sum the face block projections of each coefficient.
178
+ const [ c0, c1, c2, c3, c4, c5, c6, c7, c8 ] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ].map( ( c ) => {
179
+
180
+ let sum = batch.load( ivec2( c * 6 * FACE_BLOCKS, probeIndex ) );
181
+ for ( let k = 1; k < 6 * FACE_BLOCKS; k ++ ) sum = sum.add( batch.load( ivec2( c * 6 * FACE_BLOCKS + k, probeIndex ) ) );
182
+ return sum;
183
+
184
+ } );
154
185
 
155
186
  let packed;
156
187
 
@@ -173,26 +204,76 @@ function repackNode( batch, textureIndex, resolution, sliceZ ) {
173
204
  }
174
205
 
175
206
  /**
176
- * Lazily pools the shared cube and batch render targets, recreating them only
177
- * when their dimensions change.
207
+ * Lazily creates the shared capture camera: six 90° sub-cameras per batch slot.
208
+ *
209
+ * @private
210
+ * @param {number} near - Capture near plane.
211
+ * @param {number} far - Capture far plane.
212
+ */
213
+ function ensureCaptureCamera( near, far ) {
214
+
215
+ if ( _captureCamera === null ) {
216
+
217
+ const cameras = [];
218
+
219
+ for ( let i = 0; i < PROBES_PER_BATCH * 6; i ++ ) {
220
+
221
+ const camera = new PerspectiveCamera( 90, 1, near, far );
222
+ camera.viewport = new Vector4();
223
+ camera.up.fromArray( FACE_UP[ i % 6 ] );
224
+ cameras.push( camera );
225
+
226
+ }
227
+
228
+ _captureCamera = new ArrayCamera( cameras );
229
+ _captureCamera.perCameraFrustumCulled = true;
230
+
231
+ }
232
+
233
+ for ( const camera of _captureCamera.cameras ) {
234
+
235
+ if ( camera.near !== near || camera.far !== far ) {
236
+
237
+ camera.near = near;
238
+ camera.far = far;
239
+ camera.updateProjectionMatrix();
240
+
241
+ }
242
+
243
+ }
244
+
245
+ }
246
+
247
+ /**
248
+ * Lazily pools the shared face atlas and batch render targets, recreating them
249
+ * only when their dimensions change. Each capture sub-camera renders into its
250
+ * own tile of the face atlas.
178
251
  *
179
252
  * @private
180
253
  * @param {number} cubemapSize - Resolution of each cubemap face.
181
- * @param {number} near - Cube camera near plane.
182
- * @param {number} far - Cube camera far plane.
183
254
  * @param {number} totalProbes - Number of probes (batch target height).
184
255
  */
185
- function ensureBakeTargets( cubemapSize, near, far, totalProbes ) {
256
+ function ensureBakeTargets( cubemapSize, totalProbes ) {
186
257
 
187
- const cubeKey = `${ cubemapSize },${ near },${ far }`;
258
+ if ( _faceTarget === null || _faceSize !== cubemapSize ) {
188
259
 
189
- if ( _cubeRenderTarget === null || _cubeKey !== cubeKey ) {
260
+ if ( _faceTarget !== null ) _faceTarget.dispose();
261
+
262
+ // One row of six face tiles per batch slot.
263
+ _faceTarget = new RenderTarget( 6 * cubemapSize, PROBES_PER_BATCH * cubemapSize, {
264
+ type: HalfFloatType,
265
+ minFilter: NearestFilter,
266
+ magFilter: NearestFilter,
267
+ generateMipmaps: false
268
+ } );
190
269
 
191
- if ( _cubeRenderTarget !== null ) _cubeRenderTarget.dispose();
270
+ _captureCamera.cameras.forEach( ( camera, i ) => {
192
271
 
193
- _cubeRenderTarget = new CubeRenderTarget( cubemapSize, { type: HalfFloatType, generateMipmaps: false } );
194
- _cubeCamera = new CubeCamera( near, far, _cubeRenderTarget );
195
- _cubeKey = cubeKey;
272
+ camera.viewport.set( ( i % 6 ) * cubemapSize, Math.floor( i / 6 ) * cubemapSize, cubemapSize, cubemapSize );
273
+
274
+ } );
275
+
276
+ _faceSize = cubemapSize;
196
277
 
197
278
  }
198
279
 
@@ -200,7 +281,8 @@ function ensureBakeTargets( cubemapSize, near, far, totalProbes ) {
200
281
 
201
282
  if ( _batchTarget !== null ) _batchTarget.dispose();
202
283
 
203
- _batchTarget = new RenderTarget( 9, totalProbes, {
284
+ // One row per probe: 9 coefficients x 6 faces x face blocks.
285
+ _batchTarget = new RenderTarget( 9 * 6 * FACE_BLOCKS, totalProbes, {
204
286
  type: FloatType,
205
287
  format: RGBAFormat,
206
288
  minFilter: NearestFilter,
@@ -216,20 +298,21 @@ function ensureBakeTargets( cubemapSize, near, far, totalProbes ) {
216
298
 
217
299
  /**
218
300
  * Lazily builds the shared bake materials and rebinds them to the current
219
- * cube/batch textures. The SH projection material is rebuilt only when the
220
- * sample count changes; the repack materials are static.
301
+ * face/batch textures. The SH projection material is rebuilt only when the
302
+ * face size changes; the repack materials are static.
221
303
  *
222
304
  * @private
223
- * @param {number} sampleCount - Number of directions integrated by the projection.
224
- * @param {CubeTexture} cubeMap - The current cube render target texture.
305
+ * @param {number} cubemapSize - Resolution of each cubemap face.
306
+ * @param {Texture} faceMap - The current face atlas texture.
225
307
  * @param {Texture} batchMap - The current batch render target texture.
226
308
  */
227
- function ensureBakeMaterials( sampleCount, cubeMap, batchMap ) {
309
+ function ensureBakeMaterials( cubemapSize, faceMap, batchMap ) {
228
310
 
229
311
  if ( _repackMaterials === null ) {
230
312
 
231
- _cubeNode = cubeTexture( cubeMap );
313
+ _faceNode = texture( faceMap );
232
314
  _batchNode = texture( batchMap );
315
+ _batchStartUniform = uniform( 0, 'int' );
233
316
  _resolutionUniform = uniform( new Vector3() );
234
317
  _sliceZUniform = uniform( 0, 'int' );
235
318
  _repackMaterials = [];
@@ -246,20 +329,20 @@ function ensureBakeMaterials( sampleCount, cubeMap, batchMap ) {
246
329
 
247
330
  } else {
248
331
 
249
- _cubeNode.value = cubeMap;
332
+ _faceNode.value = faceMap;
250
333
  _batchNode.value = batchMap;
251
334
 
252
335
  }
253
336
 
254
- if ( _shMaterial === null || _shSampleCount !== sampleCount ) {
337
+ if ( _shMaterial === null || _shFaceSize !== cubemapSize ) {
255
338
 
256
339
  if ( _shMaterial !== null ) _shMaterial.dispose();
257
340
 
258
341
  _shMaterial = new NodeMaterial();
259
- _shMaterial.outputNode = projectSHNode( _cubeNode, sampleCount );
342
+ _shMaterial.outputNode = projectSHNode( _faceNode, cubemapSize, _batchStartUniform );
260
343
  _shMaterial.depthTest = false;
261
344
  _shMaterial.depthWrite = false;
262
- _shSampleCount = sampleCount;
345
+ _shFaceSize = cubemapSize;
263
346
 
264
347
  }
265
348
 
@@ -287,14 +370,16 @@ class LightProbeGrid extends Light {
287
370
  /**
288
371
  * Constructs a new irradiance probe grid.
289
372
  *
290
- * The volume is centered at the object's position.
373
+ * The volume is centered at the object's position. It is split into one cell
374
+ * per probe, with each probe at the center of its cell, so the probes sit half
375
+ * a cell inside the volume.
291
376
  *
292
377
  * @param {number} [width=1] - Full width of the volume along X.
293
378
  * @param {number} [height=1] - Full height of the volume along Y.
294
379
  * @param {number} [depth=1] - Full depth of the volume along Z.
295
- * @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max( 2, Math.round( width ) + 1 )`.
296
- * @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max( 2, Math.round( height ) + 1 )`.
297
- * @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max( 2, Math.round( depth ) + 1 )`.
380
+ * @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max( 1, Math.round( width ) )`.
381
+ * @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max( 1, Math.round( height ) )`.
382
+ * @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max( 1, Math.round( depth ) )`.
298
383
  */
299
384
  constructor( width = 1, height = 1, depth = 1, widthProbes, heightProbes, depthProbes ) {
300
385
 
@@ -338,13 +423,14 @@ class LightProbeGrid extends Light {
338
423
  * @type {Vector3}
339
424
  */
340
425
  this.resolution = new Vector3(
341
- widthProbes !== undefined ? widthProbes : Math.max( 2, Math.round( width ) + 1 ),
342
- heightProbes !== undefined ? heightProbes : Math.max( 2, Math.round( height ) + 1 ),
343
- depthProbes !== undefined ? depthProbes : Math.max( 2, Math.round( depth ) + 1 )
426
+ widthProbes !== undefined ? widthProbes : Math.max( 1, Math.round( width ) ),
427
+ heightProbes !== undefined ? heightProbes : Math.max( 1, Math.round( height ) ),
428
+ depthProbes !== undefined ? depthProbes : Math.max( 1, Math.round( depth ) )
344
429
  );
345
430
 
346
431
  /**
347
- * The world-space bounding box for the grid. Updated automatically
432
+ * The world-space bounding box for the grid. This is the volume the grid
433
+ * lights, with the probes half a cell inside it. Updated automatically
348
434
  * by {@link LightProbeGrid#bake}.
349
435
  *
350
436
  * @type {Box3}
@@ -352,22 +438,19 @@ class LightProbeGrid extends Light {
352
438
  this.boundingBox = new Box3();
353
439
 
354
440
  /**
355
- * Distance in world units over which the grid contribution fades out
356
- * past the volume boundary. `0` applies the contribution everywhere
357
- * (clamped), which matches a single-volume setup. Use a small positive
358
- * value to blend multiple overlapping grids.
441
+ * Where grids overlap, the grid with the highest priority lights the
442
+ * fragment. On ties, the most recently created grid wins.
359
443
  *
360
444
  * @type {number}
361
445
  * @default 0
362
446
  */
363
- this.falloff = 0;
447
+ this.priority = 0;
364
448
 
365
449
  /**
366
450
  * The single RGBA atlas 3D texture storing all seven packed SH
367
451
  * sub-volumes stacked along Z.
368
452
  *
369
453
  * @type {?Data3DTexture}
370
- * @default null
371
454
  */
372
455
  this.texture = null;
373
456
 
@@ -385,6 +468,7 @@ class LightProbeGrid extends Light {
385
468
  this._bouncePass = - 1;
386
469
 
387
470
  this.updateBoundingBox();
471
+ this._ensureTextures();
388
472
 
389
473
  }
390
474
 
@@ -404,9 +488,9 @@ class LightProbeGrid extends Light {
404
488
  const w = this.width, h = this.height, d = this.depth;
405
489
 
406
490
  target.set(
407
- res.x > 1 ? pos.x - w / 2 + ix * w / ( res.x - 1 ) : pos.x,
408
- res.y > 1 ? pos.y - h / 2 + iy * h / ( res.y - 1 ) : pos.y,
409
- res.z > 1 ? pos.z - d / 2 + iz * d / ( res.z - 1 ) : pos.z
491
+ pos.x - w / 2 + ( ix + 0.5 ) * w / res.x,
492
+ pos.y - h / 2 + ( iy + 0.5 ) * h / res.y,
493
+ pos.z - d / 2 + ( iz + 0.5 ) * d / res.z
410
494
  );
411
495
 
412
496
  return target;
@@ -442,11 +526,10 @@ class LightProbeGrid extends Light {
442
526
  * @param {WebGPURenderer} renderer - The renderer.
443
527
  * @param {Scene} scene - The scene to render.
444
528
  * @param {Object} [options] - Bake options.
445
- * @param {number} [options.cubemapSize=8] - Resolution of each cubemap face.
529
+ * @param {number} [options.cubemapSize=8] - Resolution of each cubemap face. Must be a multiple of 4.
446
530
  * @param {number} [options.near=0.1] - Near plane for the cube camera.
447
531
  * @param {number} [options.far=100] - Far plane for the cube camera.
448
532
  * @param {number} [options.bounces=0] - Additional bounce passes. Only available when baking the whole grid.
449
- * @param {number} [options.sampleCount=512] - Directions integrated when projecting each cubemap to SH.
450
533
  * @param {number} [options.start=0] - Index of the first probe to bake.
451
534
  * @param {number} [options.count] - Number of probes to bake. Defaults to the remaining probes.
452
535
  * @param {number} [options.pass=0] - Starting pass. Zero captures direct light; later passes sample the previous pass. Ranged calls require `bounces: 0`.
@@ -467,13 +550,6 @@ class LightProbeGrid extends Light {
467
550
 
468
551
  }
469
552
 
470
- // Register the light node with this renderer (idempotent).
471
- if ( renderer.library.getLightNodeClass( LightProbeGrid ) === null ) {
472
-
473
- renderer.library.addLight( LightProbeGridNode, LightProbeGrid );
474
-
475
- }
476
-
477
553
  const res = this.resolution;
478
554
  const totalProbes = res.x * res.y * res.z;
479
555
  const {
@@ -481,7 +557,6 @@ class LightProbeGrid extends Light {
481
557
  near = 0.1,
482
558
  far = 100,
483
559
  bounces = 0,
484
- sampleCount = 512,
485
560
  start = 0,
486
561
  count = totalProbes - start,
487
562
  pass: firstPass = 0
@@ -519,8 +594,9 @@ class LightProbeGrid extends Light {
519
594
 
520
595
  // Bind the pooled bake resources to the current textures.
521
596
 
522
- ensureBakeTargets( cubemapSize, near, far, totalProbes );
523
- ensureBakeMaterials( sampleCount, _cubeRenderTarget.texture, _batchTarget.texture );
597
+ ensureCaptureCamera( near, far );
598
+ ensureBakeTargets( cubemapSize, totalProbes );
599
+ ensureBakeMaterials( cubemapSize, _faceTarget.texture, _batchTarget.texture );
524
600
  _resolutionUniform.value.copy( res );
525
601
 
526
602
  // Save renderer / scene state to restore after the bake.
@@ -541,6 +617,7 @@ class LightProbeGrid extends Light {
541
617
  try {
542
618
 
543
619
  renderer.inspector.enabled = false;
620
+ renderer.xr.enabled = false;
544
621
  this.visible = false;
545
622
 
546
623
  // Scene is static during the bake: update once, disable auto-update.
@@ -612,27 +689,20 @@ class LightProbeGrid extends Light {
612
689
  */
613
690
  _updateBounceGrid( renderer, scene, pass, start ) {
614
691
 
615
- if ( pass === 0 ) {
692
+ if ( this._bounceGrid === null ) {
616
693
 
617
- if ( start === 0 ) this._bouncePass = - 1;
618
- return;
694
+ const res = this.resolution;
695
+ this._bounceGrid = new LightProbeGrid( this.width, this.height, this.depth, res.x, res.y, res.z );
619
696
 
620
697
  }
621
698
 
622
- if ( start === 0 ) {
623
-
624
- const renderTarget = this._renderTarget;
625
-
626
- if ( this._bounceGrid === null ) {
699
+ if ( pass === 0 ) {
627
700
 
628
- const res = this.resolution;
629
- this._bounceGrid = new LightProbeGrid( this.width, this.height, this.depth, res.x, res.y, res.z );
630
- this._bounceGrid._ensureTextures();
701
+ if ( start === 0 ) this._bouncePass = - 1;
631
702
 
632
- }
703
+ } else if ( start === 0 ) {
633
704
 
634
- renderer.initRenderTarget( renderTarget );
635
- renderer.initRenderTarget( this._bounceGrid._renderTarget );
705
+ const renderTarget = this._renderTarget;
636
706
  _copyRegion.min.set( 0, 0, 0 );
637
707
  _copyRegion.max.set( renderTarget.width, renderTarget.height, renderTarget.depth );
638
708
  renderer.copyTextureToTexture( renderTarget.texture, this._bounceGrid.texture, _copyRegion );
@@ -642,14 +712,16 @@ class LightProbeGrid extends Light {
642
712
 
643
713
  const bounceGrid = this._bounceGrid;
644
714
  bounceGrid.boundingBox.copy( this.boundingBox );
645
- bounceGrid.intensity = this.intensity;
646
- bounceGrid.falloff = this.falloff;
715
+ // The direct pass adds the grid unlit, so all passes share the lights and their shaders.
716
+ bounceGrid.intensity = pass === 0 ? 0 : this.intensity;
717
+ bounceGrid.priority = this.priority;
647
718
  scene.add( bounceGrid );
648
719
 
649
720
  }
650
721
 
651
722
  /**
652
- * Captures cubemaps and projects their SH coefficients into the batch target.
723
+ * Captures the cube faces of probe batches in single passes and projects
724
+ * their SH coefficients into the batch target, one row per probe in bake order.
653
725
  *
654
726
  * @private
655
727
  * @param {WebGPURenderer} renderer - The renderer.
@@ -659,30 +731,59 @@ class LightProbeGrid extends Light {
659
731
  */
660
732
  _captureProbes( renderer, scene, start, end ) {
661
733
 
662
- const { x: nx, y: ny, z: nz } = this.resolution;
734
+ const { x: nx, z: nz } = this.resolution;
663
735
  const probesPerLayer = nx * nz;
736
+ const cameras = _captureCamera.cameras;
664
737
 
665
- _quad.material = _shMaterial;
738
+ for ( let batchStart = start; batchStart < end; batchStart += PROBES_PER_BATCH ) {
666
739
 
667
- for ( let probeIndex = start; probeIndex < end; probeIndex ++ ) {
740
+ const batchCount = Math.min( PROBES_PER_BATCH, end - batchStart );
668
741
 
669
- const ix = probeIndex % nx;
670
- const iy = Math.floor( probeIndex / probesPerLayer );
671
- const iz = Math.floor( probeIndex / nx ) % nz;
742
+ for ( let slot = 0; slot < PROBES_PER_BATCH; slot ++ ) {
672
743
 
673
- this.getProbePosition( ix, iy, iz, _position );
674
- _cubeCamera.position.copy( _position );
744
+ const probeIndex = batchStart + slot;
675
745
 
676
- // The cube faces must be cleared per face.
677
- renderer.autoClear = true;
678
- _cubeCamera.update( renderer, scene );
746
+ if ( slot < batchCount ) {
747
+
748
+ const ix = probeIndex % nx;
749
+ const iy = Math.floor( probeIndex / probesPerLayer );
750
+ const iz = Math.floor( probeIndex / nx ) % nz;
751
+
752
+ this.getProbePosition( ix, iy, iz, _position );
753
+
754
+ }
755
+
756
+ for ( let face = 0; face < 6; face ++ ) {
757
+
758
+ const camera = cameras[ slot * 6 + face ];
759
+
760
+ // unused slots draw nothing, keeping the camera count fixed
761
+ if ( slot < batchCount ) {
762
+
763
+ camera.layers.set( 0 );
764
+ camera.position.copy( _position );
765
+ camera.lookAt( _target.fromArray( FACE_FORWARD[ face ] ).add( _position ) );
766
+ camera.updateMatrixWorld();
767
+
768
+ } else {
679
769
 
680
- // Keep batch rows in texture order (X, Y, Z).
681
- const batchRow = ix + iy * nx + iz * nx * ny;
770
+ camera.layers.disableAll();
771
+
772
+ }
773
+
774
+ }
775
+
776
+ }
777
+
778
+ renderer.autoClear = true;
779
+ renderer.setRenderTarget( _faceTarget );
780
+ renderer.render( scene, _captureCamera );
682
781
 
683
782
  renderer.autoClear = false;
684
- _batchTarget.viewport.set( 0, batchRow, 9, 1 );
783
+ _batchStartUniform.value = batchStart;
784
+ _batchTarget.viewport.set( 0, batchStart, 9 * 6 * FACE_BLOCKS, batchCount );
685
785
  renderer.setRenderTarget( _batchTarget );
786
+ _quad.material = _shMaterial;
686
787
  _quad.render( renderer );
687
788
 
688
789
  }
@@ -817,4 +918,6 @@ class LightProbeGrid extends Light {
817
918
 
818
919
  }
819
920
 
921
+ LightProbeGrid.registerNode( LightProbeGridNode );
922
+
820
923
  export { LightProbeGrid };