@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
@@ -4,11 +4,11 @@ import {
4
4
  Data3DTexture,
5
5
  FloatType,
6
6
  HalfFloatType,
7
+ Light,
7
8
  LinearFilter,
8
9
  MathUtils,
9
10
  Mesh,
10
11
  NearestFilter,
11
- Object3D,
12
12
  OrthographicCamera,
13
13
  PlaneGeometry,
14
14
  RGBAFormat,
@@ -85,23 +85,25 @@ const ATLAS_PADDING = 1;
85
85
  *
86
86
  * @three_import import { LightProbeGridWebGL } from 'three/addons/lighting/LightProbeGridWebGL.js';
87
87
  */
88
- class LightProbeGridWebGL extends Object3D {
88
+ class LightProbeGridWebGL extends Light {
89
89
 
90
90
  /**
91
91
  * Constructs a new irradiance probe grid.
92
92
  *
93
- * The volume is centered at the object's position.
93
+ * The volume is centered at the object's position. It is split into one cell
94
+ * per probe, with each probe at the center of its cell, so the probes sit half
95
+ * a cell inside the volume.
94
96
  *
95
97
  * @param {number} [width=1] - Full width of the volume along X.
96
98
  * @param {number} [height=1] - Full height of the volume along Y.
97
99
  * @param {number} [depth=1] - Full depth of the volume along Z.
98
- * @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max( 2, Math.round( width ) + 1 )`.
99
- * @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max( 2, Math.round( height ) + 1 )`.
100
- * @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max( 2, Math.round( depth ) + 1 )`.
100
+ * @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max( 1, Math.round( width ) )`.
101
+ * @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max( 1, Math.round( height ) )`.
102
+ * @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max( 1, Math.round( depth ) )`.
101
103
  */
102
104
  constructor( width = 1, height = 1, depth = 1, widthProbes, heightProbes, depthProbes ) {
103
105
 
104
- super();
106
+ super( 0xffffff, 1 );
105
107
 
106
108
  /**
107
109
  * This flag can be used for type testing.
@@ -112,6 +114,8 @@ class LightProbeGridWebGL extends Object3D {
112
114
  */
113
115
  this.isLightProbeGrid = true;
114
116
 
117
+ this.type = 'LightProbeGridWebGL';
118
+
115
119
  /**
116
120
  * The full width of the volume along X.
117
121
  *
@@ -139,19 +143,29 @@ class LightProbeGridWebGL extends Object3D {
139
143
  * @type {Vector3}
140
144
  */
141
145
  this.resolution = new Vector3(
142
- widthProbes !== undefined ? widthProbes : Math.max( 2, Math.round( width ) + 1 ),
143
- heightProbes !== undefined ? heightProbes : Math.max( 2, Math.round( height ) + 1 ),
144
- depthProbes !== undefined ? depthProbes : Math.max( 2, Math.round( depth ) + 1 )
146
+ widthProbes !== undefined ? widthProbes : Math.max( 1, Math.round( width ) ),
147
+ heightProbes !== undefined ? heightProbes : Math.max( 1, Math.round( height ) ),
148
+ depthProbes !== undefined ? depthProbes : Math.max( 1, Math.round( depth ) )
145
149
  );
146
150
 
147
151
  /**
148
- * The world-space bounding box for the grid. Updated automatically
152
+ * The world-space bounding box for the grid. This is the volume the grid
153
+ * lights, with the probes half a cell inside it. Updated automatically
149
154
  * by {@link LightProbeGridWebGL#bake}.
150
155
  *
151
156
  * @type {Box3}
152
157
  */
153
158
  this.boundingBox = new Box3();
154
159
 
160
+ /**
161
+ * Where grids overlap, the grid with the highest priority lights the
162
+ * fragment. On ties, the most recently created grid wins.
163
+ *
164
+ * @type {number}
165
+ * @default 0
166
+ */
167
+ this.priority = 0;
168
+
155
169
  /**
156
170
  * The single RGBA atlas 3D texture storing all seven packed SH sub-volumes.
157
171
  *
@@ -193,9 +207,9 @@ class LightProbeGridWebGL extends Object3D {
193
207
  const w = this.width, h = this.height, d = this.depth;
194
208
 
195
209
  target.set(
196
- res.x > 1 ? pos.x - w / 2 + ix * w / ( res.x - 1 ) : pos.x,
197
- res.y > 1 ? pos.y - h / 2 + iy * h / ( res.y - 1 ) : pos.y,
198
- res.z > 1 ? pos.z - d / 2 + iz * d / ( res.z - 1 ) : pos.z
210
+ pos.x - w / 2 + ( ix + 0.5 ) * w / res.x,
211
+ pos.y - h / 2 + ( iy + 0.5 ) * h / res.y,
212
+ pos.z - d / 2 + ( iz + 0.5 ) * d / res.z
199
213
  );
200
214
 
201
215
  return target;
@@ -553,6 +567,8 @@ class LightProbeGridWebGL extends Object3D {
553
567
 
554
568
  }
555
569
 
570
+ super.dispose();
571
+
556
572
  }
557
573
 
558
574
  }
@@ -1,4 +1,4 @@
1
- import { float, vec3, vec4, If, Loop, Break, max, min, abs, dot, clamp, log2, exp2, select } from 'three/tsl';
1
+ import { float, vec3, vec4, If, Loop, Break, max, min, abs, dot, cross, normalize, clamp, log2, exp2, fract, sqrt, cos, sin, select, EPSILON, PI } from 'three/tsl';
2
2
 
3
3
  /**
4
4
  * Emits the intersection of a ray with the bounds of the given volume.
@@ -14,9 +14,9 @@ export function intersectVolume( volume, origin, direction ) {
14
14
  const boundsMax = boundsMin.add( volume.volumeSizeNode ).toConst();
15
15
 
16
16
  const safeDirection = vec3(
17
- select( abs( direction.x ).lessThan( 1e-6 ), 1e-6, direction.x ),
18
- select( abs( direction.y ).lessThan( 1e-6 ), 1e-6, direction.y ),
19
- select( abs( direction.z ).lessThan( 1e-6 ), 1e-6, direction.z )
17
+ select( abs( direction.x ).lessThan( EPSILON ), EPSILON, direction.x ),
18
+ select( abs( direction.y ).lessThan( EPSILON ), EPSILON, direction.y ),
19
+ select( abs( direction.z ).lessThan( EPSILON ), EPSILON, direction.z )
20
20
  ).toConst();
21
21
 
22
22
  const invDirection = float( 1 ).div( safeDirection ).toConst();
@@ -118,7 +118,7 @@ export function createConeTracer( volume, options = {} ) {
118
118
 
119
119
  // AO falloff 1 / ( 1 + r / aoDistance )
120
120
 
121
- const aoFalloff = aoDistance !== null ? select( aoDistance.greaterThan( 0 ), float( 1 ).div( max( aoDistance, 1e-6 ) ), float( 0 ) ).toConst() : null;
121
+ const aoFalloff = aoDistance !== null ? select( aoDistance.greaterThan( 0 ), float( 1 ).div( max( aoDistance, EPSILON ) ), float( 0 ) ).toConst() : null;
122
122
 
123
123
  If( tExit.greaterThan( t ), () => {
124
124
 
@@ -192,3 +192,52 @@ export function createConeTracer( volume, options = {} ) {
192
192
  };
193
193
 
194
194
  }
195
+
196
+ /**
197
+ * Emits a diffuse gather: Traces stratified cosine-weighted cones around the normal and averages them.
198
+ *
199
+ * @param {Function} trace - The cone tracing function, see {@link createConeTracer}.
200
+ * @param {Node<vec3>} origin - The origin of the cones.
201
+ * @param {Node<vec3>} normal - The normalized surface normal.
202
+ * @param {Node<uint>|number} coneCount - The number of cones.
203
+ * @param {Node<float>} tanHalfAngle - The tangent of half the cone angle.
204
+ * @param {Node<float>} maxDistance - The maximum trace distance.
205
+ * @param {Node<float>|number} rotation - Rotation of the cones around the normal in `[0, 1)`.
206
+ * @param {Node<float>|number} elevation - Offset of the cones within their elevation strata in `[0, 1)`.
207
+ * @param {?Node<float>} [aoDistance=null] - The AO falloff distance. AO is only computed if given.
208
+ * @return {{color: Node<vec3>, ao: Node<float>}} The mean radiance and the mean AO of the cones.
209
+ */
210
+ export function gather( trace, origin, normal, coneCount, tanHalfAngle, maxDistance, rotation, elevation, aoDistance = null ) {
211
+
212
+ // tangent frame
213
+
214
+ const up = select( abs( normal.y ).lessThan( 0.99 ), vec3( 0, 1, 0 ), vec3( 1, 0, 0 ) );
215
+ const tangent = normalize( cross( normal, up ) ).toConst();
216
+ const bitangent = cross( normal, tangent ).toConst();
217
+
218
+ const color = vec3( 0 ).toVar();
219
+ const ao = float( 0 ).toVar();
220
+
221
+ Loop( { start: 0, end: coneCount, type: 'uint', condition: '<', name: 'c' }, ( { c } ) => {
222
+
223
+ // stratified cosine-weighted directions
224
+
225
+ const u1 = float( c ).add( elevation ).div( float( coneCount ) ).toConst();
226
+ const u2 = fract( float( c ).mul( 0.618034 ).add( rotation ) ).toConst();
227
+ const sinTheta = sqrt( u1 ).toConst();
228
+ const cosTheta = sqrt( u1.oneMinus() ).toConst();
229
+ const phi = u2.mul( PI.mul( 2 ) ).toConst();
230
+
231
+ const direction = normalize( tangent.mul( cos( phi ).mul( sinTheta ) ).add( bitangent.mul( sin( phi ).mul( sinTheta ) ) ).add( normal.mul( cosTheta ) ) ).toConst();
232
+
233
+ const cone = trace( origin, direction, tanHalfAngle, maxDistance, aoDistance );
234
+
235
+ color.addAssign( cone.color );
236
+
237
+ if ( aoDistance !== null ) ao.addAssign( cone.ao );
238
+
239
+ } );
240
+
241
+ return { color: color.div( float( coneCount ) ), ao: ao.div( float( coneCount ) ) };
242
+
243
+ }
@@ -0,0 +1,43 @@
1
+ import { Fn, PI, float, interleavedGradientNoise, screenCoordinate, vec2 } from 'three/tsl';
2
+ import { createConeTracer, gather } from './VXGIConeTracer.js';
3
+
4
+ /**
5
+ * Creates a world-space diffuse irradiance sampler for a prepared {@link VXGIVolume}.
6
+ * Call `volume.update( renderer, scene )` before baking. The sampler traces cosine-weighted
7
+ * cones through the volume's radiance, including cached bounces.
8
+ * It can be passed directly to {@link LightMapper}, without a screen-space pass.
9
+ * The cones are rotated per pixel with interleaved gradient noise like `VXGINode`. When baking, the
10
+ * pixel is the light map texel. The optional sample index shifts the noise so that accumulated
11
+ * samples, or a temporal filter like TRAA, converge.
12
+ *
13
+ * @param {VXGIVolume} volume - The prepared voxel volume.
14
+ * @param {Object} [options] - Options.
15
+ * @param {number} [options.coneCount=8] - The number of cones per sample. Fewer cones are faster but coarser.
16
+ * @return {function(Node<vec3>, Node<vec3>, ?Node<float>): Node<vec3>} The irradiance sampler.
17
+ */
18
+ function vxgiIrradiance( volume, { coneCount = 8 } = {} ) {
19
+
20
+ const trace = createConeTracer( volume, {
21
+ radianceNode: volume.radianceNode,
22
+ directionalNode: volume.directionalRadiance ? volume.directionalNode : null
23
+ } );
24
+
25
+ return ( position, normal, sample = float( 0 ) ) => Fn( () => {
26
+
27
+ // interleaved gradient noise offsets of the stratified cone set, see VXGINode
28
+
29
+ const shift = screenCoordinate.add( sample.mul( 5.588238 ) ).toConst();
30
+ const elevation = interleavedGradientNoise( shift.add( vec2( 5.588238, 3.14159 ) ) ).toConst();
31
+ const rotation = interleavedGradientNoise( shift ).toConst();
32
+
33
+ const origin = position.add( normal.mul( volume.voxelSizeNode.mul( 1.5 ) ) ).toConst();
34
+
35
+ const { color } = gather( trace, origin, normal, coneCount, float( Math.tan( Math.PI / 9 ) ), volume.traceDistanceNode, rotation, elevation );
36
+
37
+ return color.mul( PI );
38
+
39
+ } )();
40
+
41
+ }
42
+
43
+ export { vxgiIrradiance };
@@ -1,8 +1,8 @@
1
- import { RenderTarget, Vector2, Vector3, TempNode, QuadMesh, NodeMaterial, RendererUtils, HalfFloatType, RGBAFormat, RedFormat, UnsignedByteType } from 'three/webgpu';
2
- import { Fn, NodeUpdateType, uniform, reference, vec2, vec3, vec4, float, uint, uv, mix, passTexture, getViewPosition, getNormalFromDepth, logarithmicDepthToViewZ, viewZToPerspectiveDepth, screenCoordinate, interleavedGradientNoise, normalize, cross, abs, select, sqrt, fract, floor, cos, sin, exp2, pow, PI, Loop, If, Break, property, outputStruct, context } from 'three/tsl';
1
+ import { RenderTarget, Vector2, Vector3, Node, QuadMesh, NodeMaterial, RendererUtils, HalfFloatType, RGBAFormat, RedFormat, UnsignedByteType } from 'three/webgpu';
2
+ import { Fn, NodeUpdateType, uniform, reference, vec2, vec4, float, uv, mix, passTexture, getViewPosition, getNormalFromDepth, screenCoordinate, interleavedGradientNoise, normalize, floor, exp2, pow, PI, Loop, If, Break, property, outputStruct, context, projectionDepth } from 'three/tsl';
3
3
 
4
4
  import { VXGIVolume } from './VXGIVolume.js';
5
- import { createConeTracer, intersectVolume, sampleDirectional } from './VXGIConeTracer.js';
5
+ import { createConeTracer, gather, intersectVolume, sampleDirectional } from './VXGIConeTracer.js';
6
6
 
7
7
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
8
8
  const _size = /*@__PURE__*/ new Vector2();
@@ -40,10 +40,10 @@ const _neutralContext = /*@__PURE__*/ context();
40
40
  *
41
41
  * Note: This node can only be used with `WebGPURenderer` and a WebGPU backend.
42
42
  *
43
- * @augments TempNode
43
+ * @augments Node
44
44
  * @three_import import { vxgi } from 'three/addons/lighting/vxgi/VXGINode.js';
45
45
  */
46
- class VXGINode extends TempNode {
46
+ class VXGINode extends Node {
47
47
 
48
48
  static get type() {
49
49
 
@@ -380,7 +380,7 @@ class VXGINode extends TempNode {
380
380
 
381
381
  if ( this._sharedContext !== null && this._directional !== this.volume.directionalRadiance ) {
382
382
 
383
- this._setupMaterial( renderer );
383
+ this._setupMaterial();
384
384
 
385
385
  }
386
386
 
@@ -425,7 +425,7 @@ class VXGINode extends TempNode {
425
425
  setup( builder ) {
426
426
 
427
427
  this._sharedContext = builder.getSharedContext();
428
- this._setupMaterial( builder.renderer );
428
+ this._setupMaterial();
429
429
 
430
430
  return this._aoNode;
431
431
 
@@ -435,29 +435,14 @@ class VXGINode extends TempNode {
435
435
  * Builds the TSL code of the effect into the internal pass material.
436
436
  *
437
437
  * @private
438
- * @param {Renderer} renderer - The renderer.
439
438
  */
440
- _setupMaterial( renderer ) {
439
+ _setupMaterial() {
441
440
 
442
441
  const volume = this.volume;
443
442
  const directional = this._directional = volume.directionalRadiance;
444
443
  const uvNode = uv();
445
444
 
446
- const sampleDepth = ( uv ) => {
447
-
448
- const depth = this.depthNode.sample( uv ).r;
449
-
450
- if ( renderer.logarithmicDepthBuffer === true ) {
451
-
452
- const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
453
-
454
- return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
455
-
456
- }
457
-
458
- return depth;
459
-
460
- };
445
+ const sampleDepth = ( uv ) => projectionDepth( this.depthNode.sample( uv ).r, this._cameraNear, this._cameraFar );
461
446
 
462
447
  const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.sample( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
463
448
 
@@ -491,47 +476,19 @@ class VXGINode extends TempNode {
491
476
  const rotationNoise = interleavedGradientNoise( screenCoordinate.add( temporalShift ) ).toConst();
492
477
  const elevationNoise = interleavedGradientNoise( screenCoordinate.add( temporalShift ).add( vec2( 5.588238, 3.14159 ) ) ).toConst();
493
478
 
494
- // tangent frame
495
-
496
- const up = select( abs( worldNormal.y ).lessThan( 0.99 ), vec3( 0, 1, 0 ), vec3( 1, 0, 0 ) );
497
- const tangent = normalize( cross( worldNormal, up ) ).toConst();
498
- const bitangent = cross( worldNormal, tangent ).toConst();
499
-
500
479
  const CONE_COUNT = this.coneCount.toConst();
501
480
  const tanHalfAngle = this.coneAngle.mul( 0.5 ).radians().tan().toConst();
502
481
  const traceDistance = volume.traceDistanceNode;
503
482
  const aoDistance = this.aoDistance;
504
- const originOffset = worldNormal.mul( voxelSize.mul( this.normalOffset ) ).toConst();
483
+ const origin = worldPosition.add( worldNormal.mul( voxelSize.mul( this.normalOffset ) ) ).toConst();
505
484
 
506
- const color = vec3( 0 ).toVar();
507
- const occlusion = float( 0 ).toVar();
508
-
509
- Loop( { start: uint( 0 ), end: CONE_COUNT, type: 'uint', condition: '<', name: 'c' }, ( { c } ) => {
510
-
511
- // stratified cosine-weighted directions
512
-
513
- const u1 = float( c ).add( elevationNoise ).div( float( CONE_COUNT ) ).toConst();
514
- const u2 = fract( float( c ).mul( 0.618034 ).add( rotationNoise ) ).toConst();
515
- const sinTheta = sqrt( u1 ).toConst();
516
- const cosTheta = sqrt( u1.oneMinus() ).toConst();
517
- const phi = u2.mul( PI.mul( 2 ) ).toConst();
518
-
519
- const direction = normalize( tangent.mul( cos( phi ).mul( sinTheta ) ).add( bitangent.mul( sin( phi ).mul( sinTheta ) ) ).add( worldNormal.mul( cosTheta ) ) ).toConst();
520
- const origin = worldPosition.add( originOffset ).toConst();
521
-
522
- const cone = trace( origin, direction, tanHalfAngle, traceDistance, aoDistance );
523
-
524
- color.addAssign( cone.color );
525
- occlusion.addAssign( cone.ao );
526
-
527
- } );
485
+ const { color: radiance, ao: occlusion } = gather( trace, origin, worldNormal, CONE_COUNT, tanHalfAngle, traceDistance, rotationNoise, elevationNoise, aoDistance );
528
486
 
529
487
  // the mean radiance over the cosine-weighted hemisphere times PI is the irradiance
530
488
 
531
- color.divAssign( float( CONE_COUNT ) );
532
- color.mulAssign( this.giIntensity.mul( PI ) );
489
+ const color = radiance.mul( this.giIntensity.mul( PI ) ).toVar();
533
490
 
534
- const ao = mix( this.aoMinVisibility, float( 1 ), pow( occlusion.div( float( CONE_COUNT ) ).oneMinus().clamp(), this.aoIntensity ) ).toVar();
491
+ const ao = mix( this.aoMinVisibility, float( 1 ), pow( occlusion.oneMinus().clamp(), this.aoIntensity ) ).toVar();
535
492
 
536
493
  // debug visualization: march the voxels from the camera
537
494
 
@@ -1,4 +1,4 @@
1
- import { Box3, Color, Matrix4, Vector2, Vector3, BackSide, DoubleSide, SRGBColorSpace } from 'three/webgpu';
1
+ import { Box3, Color, MathUtils, Matrix4, Vector2, Vector3, BackSide, DoubleSide, FrontSide, SRGBColorSpace } from 'three/webgpu';
2
2
 
3
3
  const _matrix = /*@__PURE__*/ new Matrix4();
4
4
  const _box = /*@__PURE__*/ new Box3();
@@ -12,8 +12,10 @@ const _uv = /*@__PURE__*/ new Vector2();
12
12
  const _color = /*@__PURE__*/ new Color();
13
13
  const _albedo = /*@__PURE__*/ new Color();
14
14
  const _emissive = /*@__PURE__*/ new Color();
15
+ const _columns = /*@__PURE__*/ new Map();
15
16
 
16
17
  const IMAGE_SAMPLE_SIZE = 64;
18
+ const POSITION_QUANTIZATION = 131072;
17
19
 
18
20
  /**
19
21
  * Number of floats per triangle record: three positions (vec4 each, w unused),
@@ -476,3 +478,316 @@ export function collectSceneTriangles( scene, options ) {
476
478
  return { data, count: data.length / TRIANGLE_STRIDE };
477
479
 
478
480
  }
481
+
482
+ /**
483
+ * Marks the sub-voxels inside closed meshes, so cones starting within an object are blocked. Only meshes
484
+ * with visible, opaque and single-sided materials whose geometry is closed and faces outwards are filled.
485
+ *
486
+ * @param {Scene} scene - The scene.
487
+ * @param {Object} options - Options.
488
+ * @param {Vector3} options.boundsMin - The minimum corner of the voxel grid.
489
+ * @param {number} options.voxelSize - The size of a voxel in world units.
490
+ * @param {Vector3} options.gridSize - The number of voxels per axis.
491
+ * @param {Layers} options.layers - Objects must pass this layer test.
492
+ * @param {Set<Object3D>} options.exclude - Objects to skip.
493
+ * @param {Uint8Array} target - One byte per voxel that receives the 2x2x2 sub-voxel bits of the interiors.
494
+ */
495
+ export function computeSolidVoxels( scene, options, target ) {
496
+
497
+ const { boundsMin, voxelSize, gridSize, layers, exclude } = options;
498
+
499
+ const closedGeometries = new Map();
500
+
501
+ scene.traverseVisible( ( object ) => {
502
+
503
+ if ( isVoxelizable( object, layers, exclude ) === false || hasSolidMaterials( object ) === false ) return;
504
+
505
+ const geometry = object.geometry;
506
+
507
+ if ( closedGeometries.has( geometry ) === false ) closedGeometries.set( geometry, isClosed( geometry ) && facesOutwards( geometry ) );
508
+
509
+ if ( closedGeometries.get( geometry ) === false ) return;
510
+
511
+ if ( object.isInstancedMesh === true ) {
512
+
513
+ for ( let i = 0; i < object.count; i ++ ) {
514
+
515
+ object.getMatrixAt( i, _matrix );
516
+ _matrix.premultiply( object.matrixWorld );
517
+ fillInterior( geometry, _matrix, boundsMin, voxelSize, gridSize, target );
518
+
519
+ }
520
+
521
+ } else {
522
+
523
+ fillInterior( geometry, object.matrixWorld, boundsMin, voxelSize, gridSize, target );
524
+
525
+ }
526
+
527
+ } );
528
+
529
+ }
530
+
531
+ /**
532
+ * Returns `true` if all materials of the mesh render an opaque, single-sided surface.
533
+ *
534
+ * @private
535
+ */
536
+ function hasSolidMaterials( mesh ) {
537
+
538
+ const materials = Array.isArray( mesh.material ) ? mesh.material : [ mesh.material ];
539
+
540
+ for ( const material of materials ) {
541
+
542
+ if ( material.visible === false || material.side !== FrontSide || material.transparent === true || material.alphaTest > 0 ) return false;
543
+
544
+ }
545
+
546
+ return true;
547
+
548
+ }
549
+
550
+ /**
551
+ * Returns `true` if every edge of the geometry is shared by an even number of triangles. Vertices with
552
+ * the same position (e.g. at uv seams) are treated as one vertex.
553
+ *
554
+ * @private
555
+ */
556
+ function isClosed( geometry ) {
557
+
558
+ const position = geometry.getAttribute( 'position' );
559
+
560
+ if ( position === undefined ) return false;
561
+
562
+ const index = geometry.index;
563
+ const indices = index !== null ? index.array : null;
564
+ const count = index !== null ? index.count : position.count;
565
+
566
+ _box.setFromBufferAttribute( position );
567
+
568
+ const min = _box.min;
569
+ const size = _box.getSize( _vb );
570
+ const scaleX = POSITION_QUANTIZATION / Math.max( size.x, 1e-9 );
571
+ const scaleY = POSITION_QUANTIZATION / Math.max( size.y, 1e-9 );
572
+ const scaleZ = POSITION_QUANTIZATION / Math.max( size.z, 1e-9 );
573
+
574
+ const vertexMask = MathUtils.ceilPowerOfTwo( Math.max( position.count, 1 ) * 2 ) - 1;
575
+ const vertexKeys = new Int32Array( ( vertexMask + 1 ) * 3 );
576
+ const vertexSlots = new Int32Array( vertexMask + 1 ).fill( - 1 );
577
+ const vertexIds = new Int32Array( position.count );
578
+ let vertexCount = 0;
579
+
580
+ for ( let i = 0; i < position.count; i ++ ) {
581
+
582
+ const x = Math.round( ( position.getX( i ) - min.x ) * scaleX );
583
+ const y = Math.round( ( position.getY( i ) - min.y ) * scaleY );
584
+ const z = Math.round( ( position.getZ( i ) - min.z ) * scaleZ );
585
+
586
+ let slot = ( Math.imul( x, 73856093 ) ^ Math.imul( y, 19349663 ) ^ Math.imul( z, 83492791 ) ) & vertexMask;
587
+
588
+ while ( vertexSlots[ slot ] !== - 1 && ( vertexKeys[ slot * 3 ] !== x || vertexKeys[ slot * 3 + 1 ] !== y || vertexKeys[ slot * 3 + 2 ] !== z ) ) slot = ( slot + 1 ) & vertexMask;
589
+
590
+ if ( vertexSlots[ slot ] === - 1 ) {
591
+
592
+ vertexSlots[ slot ] = vertexCount ++;
593
+ vertexKeys[ slot * 3 ] = x;
594
+ vertexKeys[ slot * 3 + 1 ] = y;
595
+ vertexKeys[ slot * 3 + 2 ] = z;
596
+
597
+ }
598
+
599
+ vertexIds[ i ] = vertexSlots[ slot ];
600
+
601
+ }
602
+
603
+ const edgeMask = MathUtils.ceilPowerOfTwo( Math.max( count, 1 ) * 2 ) - 1;
604
+ const edgeKeys = new Int32Array( ( edgeMask + 1 ) * 2 ).fill( - 1 );
605
+ const edgeParity = new Uint8Array( edgeMask + 1 );
606
+ let openEdges = 0;
607
+
608
+ const toggleEdge = ( a, b ) => {
609
+
610
+ if ( a > b ) {
611
+
612
+ const t = a; a = b; b = t;
613
+
614
+ }
615
+
616
+ let slot = ( Math.imul( a, 73856093 ) ^ Math.imul( b, 19349663 ) ) & edgeMask;
617
+
618
+ while ( edgeKeys[ slot * 2 ] !== - 1 && ( edgeKeys[ slot * 2 ] !== a || edgeKeys[ slot * 2 + 1 ] !== b ) ) slot = ( slot + 1 ) & edgeMask;
619
+
620
+ edgeKeys[ slot * 2 ] = a;
621
+ edgeKeys[ slot * 2 + 1 ] = b;
622
+ edgeParity[ slot ] ^= 1;
623
+ openEdges += edgeParity[ slot ] === 1 ? 1 : - 1;
624
+
625
+ };
626
+
627
+ for ( let i = 0; i + 2 < count; i += 3 ) {
628
+
629
+ const a = vertexIds[ indices !== null ? indices[ i ] : i ];
630
+ const b = vertexIds[ indices !== null ? indices[ i + 1 ] : i + 1 ];
631
+ const c = vertexIds[ indices !== null ? indices[ i + 2 ] : i + 2 ];
632
+
633
+ if ( a === b || b === c || c === a ) continue;
634
+
635
+ toggleEdge( a, b );
636
+ toggleEdge( b, c );
637
+ toggleEdge( c, a );
638
+
639
+ }
640
+
641
+ return openEdges === 0;
642
+
643
+ }
644
+
645
+ /**
646
+ * Returns `true` if the triangles of the given closed geometry face outwards (positive signed volume).
647
+ *
648
+ * @private
649
+ */
650
+ function facesOutwards( geometry ) {
651
+
652
+ const position = geometry.getAttribute( 'position' );
653
+ const index = geometry.index;
654
+ const indices = index !== null ? index.array : null;
655
+ const count = index !== null ? index.count : position.count;
656
+
657
+ _box.min.fromBufferAttribute( position, 0 );
658
+
659
+ let volume = 0;
660
+
661
+ for ( let i = 0; i + 2 < count; i += 3 ) {
662
+
663
+ _va.fromBufferAttribute( position, indices !== null ? indices[ i ] : i ).sub( _box.min );
664
+ _vb.fromBufferAttribute( position, indices !== null ? indices[ i + 1 ] : i + 1 ).sub( _box.min );
665
+ _vc.fromBufferAttribute( position, indices !== null ? indices[ i + 2 ] : i + 2 ).sub( _box.min );
666
+
667
+ volume += _va.dot( _vb.cross( _vc ) );
668
+
669
+ }
670
+
671
+ return volume > 0;
672
+
673
+ }
674
+
675
+ /**
676
+ * Marks the sub-voxels between pairs of surface crossings along each sub-voxel column in x.
677
+ *
678
+ * @private
679
+ */
680
+ function fillInterior( geometry, matrix, boundsMin, voxelSize, gridSize, target ) {
681
+
682
+ const position = geometry.getAttribute( 'position' );
683
+ const index = geometry.index;
684
+ const count = index !== null ? index.count : position.count;
685
+
686
+ const invSubVoxel = 2 / voxelSize;
687
+ const columnsY = gridSize.y * 2, columnsZ = gridSize.z * 2, length = gridSize.x * 2;
688
+
689
+ _columns.clear();
690
+
691
+ for ( let i = 0; i + 2 < count; i += 3 ) {
692
+
693
+ const a = _va.fromBufferAttribute( position, index !== null ? index.getX( i ) : i ).applyMatrix4( matrix ).sub( boundsMin ).multiplyScalar( invSubVoxel );
694
+ let b = _vb.fromBufferAttribute( position, index !== null ? index.getX( i + 1 ) : i + 1 ).applyMatrix4( matrix ).sub( boundsMin ).multiplyScalar( invSubVoxel );
695
+ let c = _vc.fromBufferAttribute( position, index !== null ? index.getX( i + 2 ) : i + 2 ).applyMatrix4( matrix ).sub( boundsMin ).multiplyScalar( invSubVoxel );
696
+
697
+ const area = edgeFunction( a, b, c.y, c.z );
698
+
699
+ if ( area === 0 ) continue;
700
+
701
+ if ( area < 0 ) {
702
+
703
+ const t = b; b = c; c = t;
704
+
705
+ }
706
+
707
+ const j0 = Math.max( Math.ceil( Math.min( a.y, b.y, c.y ) - 0.5 ), 0 );
708
+ const j1 = Math.min( Math.floor( Math.max( a.y, b.y, c.y ) - 0.5 ), columnsY - 1 );
709
+ const k0 = Math.max( Math.ceil( Math.min( a.z, b.z, c.z ) - 0.5 ), 0 );
710
+ const k1 = Math.min( Math.floor( Math.max( a.z, b.z, c.z ) - 0.5 ), columnsZ - 1 );
711
+
712
+ for ( let k = k0; k <= k1; k ++ ) {
713
+
714
+ for ( let j = j0; j <= j1; j ++ ) {
715
+
716
+ const y = j + 0.5, z = k + 0.5;
717
+
718
+ const wa = edgeFunction( b, c, y, z );
719
+ const wb = edgeFunction( c, a, y, z );
720
+ const wc = edgeFunction( a, b, y, z );
721
+
722
+ if ( isInside( wa, b, c ) && isInside( wb, c, a ) && isInside( wc, a, b ) ) {
723
+
724
+ const column = j + k * columnsY;
725
+ let crossings = _columns.get( column );
726
+
727
+ if ( crossings === undefined ) {
728
+
729
+ crossings = [];
730
+ _columns.set( column, crossings );
731
+
732
+ }
733
+
734
+ crossings.push( ( wa * a.x + wb * b.x + wc * c.x ) / ( wa + wb + wc ) );
735
+
736
+ }
737
+
738
+ }
739
+
740
+ }
741
+
742
+ }
743
+
744
+ for ( const [ column, crossings ] of _columns ) {
745
+
746
+ if ( crossings.length % 2 !== 0 ) continue;
747
+
748
+ crossings.sort( ( p, q ) => p - q );
749
+
750
+ const j = column % columnsY, k = ( column - j ) / columnsY;
751
+ const offset = gridSize.x * ( ( j >> 1 ) + gridSize.y * ( k >> 1 ) );
752
+ const bitsYZ = ( ( j & 1 ) << 1 ) | ( ( k & 1 ) << 2 );
753
+
754
+ for ( let n = 0; n < crossings.length; n += 2 ) {
755
+
756
+ const i0 = Math.max( Math.ceil( crossings[ n ] - 0.5 ), 0 );
757
+ const i1 = Math.min( Math.ceil( crossings[ n + 1 ] - 0.5 ), length );
758
+
759
+ for ( let i = i0; i < i1; i ++ ) target[ offset + ( i >> 1 ) ] |= 1 << ( ( i & 1 ) | bitsYZ );
760
+
761
+ }
762
+
763
+ }
764
+
765
+ }
766
+
767
+ /**
768
+ * Edge function of the edge from `a` to `b` at the given point in the yz plane. As in the watertight
769
+ * ray/triangle test, the vertices are taken relative to the point, so a shared edge evaluates exactly
770
+ * opposite for both of its triangles.
771
+ *
772
+ * @private
773
+ */
774
+ function edgeFunction( a, b, y, z ) {
775
+
776
+ return ( a.y - y ) * ( b.z - z ) - ( a.z - z ) * ( b.y - y );
777
+
778
+ }
779
+
780
+ /**
781
+ * Inside test for an edge function value. Points on an edge belong to one triangle only (top-left rule).
782
+ *
783
+ * @private
784
+ */
785
+ function isInside( w, a, b ) {
786
+
787
+ if ( w !== 0 ) return w > 0;
788
+
789
+ const dz = b.z - a.z;
790
+
791
+ return dz < 0 || ( dz === 0 && b.y > a.y );
792
+
793
+ }