@plastic-software/three 0.181.3 → 0.183.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (437) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -4
  3. package/build/three.cjs +11330 -10017
  4. package/build/three.core.js +10011 -9493
  5. package/build/three.core.min.js +2 -2
  6. package/build/three.module.js +1414 -631
  7. package/build/three.module.min.js +2 -2
  8. package/build/three.tsl.js +21 -13
  9. package/build/three.tsl.min.js +2 -2
  10. package/build/three.webgpu.js +8007 -5427
  11. package/build/three.webgpu.min.js +2 -2
  12. package/build/three.webgpu.nodes.js +8005 -5426
  13. package/build/three.webgpu.nodes.min.js +2 -2
  14. package/examples/jsm/Addons.js +0 -3
  15. package/examples/jsm/animation/CCDIKSolver.js +2 -2
  16. package/examples/jsm/controls/ArcballControls.js +3 -3
  17. package/examples/jsm/controls/MapControls.js +55 -1
  18. package/examples/jsm/controls/OrbitControls.js +109 -6
  19. package/examples/jsm/controls/TrackballControls.js +6 -6
  20. package/examples/jsm/csm/CSM.js +2 -1
  21. package/examples/jsm/effects/AnaglyphEffect.js +102 -7
  22. package/examples/jsm/environments/ColorEnvironment.js +59 -0
  23. package/examples/jsm/environments/RoomEnvironment.js +3 -0
  24. package/examples/jsm/exporters/EXRExporter.js +1 -1
  25. package/examples/jsm/exporters/GLTFExporter.js +131 -4
  26. package/examples/jsm/exporters/USDZExporter.js +22 -3
  27. package/examples/jsm/geometries/DecalGeometry.js +1 -1
  28. package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
  29. package/examples/jsm/helpers/LightProbeHelperGPU.js +1 -1
  30. package/examples/jsm/helpers/TextureHelperGPU.js +1 -1
  31. package/examples/jsm/helpers/ViewHelper.js +67 -8
  32. package/examples/jsm/inspector/Inspector.js +74 -14
  33. package/examples/jsm/inspector/RendererInspector.js +12 -2
  34. package/examples/jsm/inspector/tabs/Console.js +41 -7
  35. package/examples/jsm/inspector/tabs/Parameters.js +18 -2
  36. package/examples/jsm/inspector/tabs/Performance.js +2 -2
  37. package/examples/jsm/inspector/tabs/Viewer.js +4 -4
  38. package/examples/jsm/inspector/ui/Profiler.js +1836 -31
  39. package/examples/jsm/inspector/ui/Style.js +973 -14
  40. package/examples/jsm/inspector/ui/Tab.js +188 -1
  41. package/examples/jsm/inspector/ui/Values.js +17 -1
  42. package/examples/jsm/libs/meshopt_decoder.module.js +6 -5
  43. package/examples/jsm/lines/LineMaterial.js +6 -0
  44. package/examples/jsm/loaders/3DMLoader.js +5 -4
  45. package/examples/jsm/loaders/3MFLoader.js +2 -2
  46. package/examples/jsm/loaders/AMFLoader.js +2 -2
  47. package/examples/jsm/loaders/ColladaLoader.js +24 -4026
  48. package/examples/jsm/loaders/DRACOLoader.js +5 -5
  49. package/examples/jsm/loaders/EXRLoader.js +5 -5
  50. package/examples/jsm/loaders/FBXLoader.js +2 -4
  51. package/examples/jsm/loaders/GCodeLoader.js +34 -8
  52. package/examples/jsm/loaders/GLTFLoader.js +122 -171
  53. package/examples/jsm/loaders/HDRLoader.js +0 -1
  54. package/examples/jsm/loaders/KMZLoader.js +5 -5
  55. package/examples/jsm/loaders/KTX2Loader.js +19 -3
  56. package/examples/jsm/loaders/LDrawLoader.js +2 -3
  57. package/examples/jsm/loaders/LWOLoader.js +7 -39
  58. package/examples/jsm/loaders/NRRDLoader.js +2 -2
  59. package/examples/jsm/loaders/PCDLoader.js +4 -2
  60. package/examples/jsm/loaders/SVGLoader.js +1 -1
  61. package/examples/jsm/loaders/TDSLoader.js +0 -2
  62. package/examples/jsm/loaders/TGALoader.js +0 -2
  63. package/examples/jsm/loaders/USDLoader.js +100 -40
  64. package/examples/jsm/loaders/UltraHDRLoader.js +285 -160
  65. package/examples/jsm/loaders/VOXLoader.js +660 -117
  66. package/examples/jsm/loaders/VRMLLoader.js +79 -2
  67. package/examples/jsm/loaders/VTKLoader.js +37 -24
  68. package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
  69. package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
  70. package/examples/jsm/loaders/usd/USDAParser.js +447 -366
  71. package/examples/jsm/loaders/usd/USDCParser.js +1841 -6
  72. package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
  73. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +2 -2
  74. package/examples/jsm/materials/WoodNodeMaterial.js +11 -11
  75. package/examples/jsm/math/Octree.js +131 -1
  76. package/examples/jsm/misc/Volume.js +0 -1
  77. package/examples/jsm/misc/VolumeSlice.js +0 -1
  78. package/examples/jsm/objects/LensflareMesh.js +1 -1
  79. package/examples/jsm/objects/Sky.js +76 -4
  80. package/examples/jsm/objects/SkyMesh.js +127 -10
  81. package/examples/jsm/objects/Water.js +4 -3
  82. package/examples/jsm/objects/Water2.js +5 -3
  83. package/examples/jsm/objects/WaterMesh.js +5 -7
  84. package/examples/jsm/physics/AmmoPhysics.js +12 -7
  85. package/examples/jsm/physics/JoltPhysics.js +10 -6
  86. package/examples/jsm/physics/RapierPhysics.js +9 -5
  87. package/examples/jsm/postprocessing/EffectComposer.js +7 -5
  88. package/examples/jsm/postprocessing/OutputPass.js +9 -0
  89. package/examples/jsm/postprocessing/RenderPass.js +10 -0
  90. package/examples/jsm/postprocessing/RenderTransitionPass.js +1 -1
  91. package/examples/jsm/postprocessing/UnrealBloomPass.js +48 -18
  92. package/examples/jsm/renderers/CSS3DRenderer.js +1 -1
  93. package/examples/jsm/renderers/Projector.js +268 -30
  94. package/examples/jsm/renderers/SVGRenderer.js +193 -60
  95. package/examples/jsm/shaders/GTAOShader.js +19 -6
  96. package/examples/jsm/shaders/HalftoneShader.js +12 -1
  97. package/examples/jsm/shaders/PoissonDenoiseShader.js +6 -2
  98. package/examples/jsm/shaders/SAOShader.js +17 -4
  99. package/examples/jsm/shaders/SSAOShader.js +11 -1
  100. package/examples/jsm/shaders/SSRShader.js +6 -5
  101. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -4
  102. package/examples/jsm/shaders/VignetteShader.js +1 -1
  103. package/examples/jsm/transpiler/AST.js +44 -0
  104. package/examples/jsm/transpiler/GLSLDecoder.js +61 -4
  105. package/examples/jsm/transpiler/ShaderToyDecoder.js +2 -0
  106. package/examples/jsm/transpiler/TSLEncoder.js +46 -3
  107. package/examples/jsm/transpiler/TranspilerUtils.js +3 -3
  108. package/examples/jsm/transpiler/WGSLEncoder.js +27 -0
  109. package/examples/jsm/tsl/display/AfterImageNode.js +1 -1
  110. package/examples/jsm/tsl/display/AnaglyphPassNode.js +458 -16
  111. package/examples/jsm/tsl/display/AnamorphicNode.js +1 -1
  112. package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
  113. package/examples/jsm/tsl/display/BloomNode.js +16 -6
  114. package/examples/jsm/tsl/display/CRT.js +150 -0
  115. package/examples/jsm/tsl/display/DenoiseNode.js +1 -1
  116. package/examples/jsm/tsl/display/DepthOfFieldNode.js +1 -1
  117. package/examples/jsm/tsl/display/DotScreenNode.js +1 -1
  118. package/examples/jsm/tsl/display/FXAANode.js +2 -2
  119. package/examples/jsm/tsl/display/GTAONode.js +5 -4
  120. package/examples/jsm/tsl/display/GaussianBlurNode.js +11 -2
  121. package/examples/jsm/tsl/display/GodraysNode.js +624 -0
  122. package/examples/jsm/tsl/display/LensflareNode.js +1 -1
  123. package/examples/jsm/tsl/display/Lut3DNode.js +1 -1
  124. package/examples/jsm/tsl/display/OutlineNode.js +3 -3
  125. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -2
  126. package/examples/jsm/tsl/display/PixelationPassNode.js +7 -6
  127. package/examples/jsm/tsl/display/RGBShiftNode.js +2 -2
  128. package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
  129. package/examples/jsm/tsl/display/SMAANode.js +2 -2
  130. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  131. package/examples/jsm/tsl/display/SSGINode.js +8 -20
  132. package/examples/jsm/tsl/display/SSRNode.js +8 -8
  133. package/examples/jsm/tsl/display/SSSNode.js +6 -4
  134. package/examples/jsm/tsl/display/Shape.js +29 -0
  135. package/examples/jsm/tsl/display/SobelOperatorNode.js +2 -2
  136. package/examples/jsm/tsl/display/StereoCompositePassNode.js +8 -1
  137. package/examples/jsm/tsl/display/StereoPassNode.js +1 -2
  138. package/examples/jsm/tsl/display/TRAANode.js +273 -125
  139. package/examples/jsm/tsl/display/TransitionNode.js +1 -1
  140. package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
  141. package/examples/jsm/tsl/display/radialBlur.js +68 -0
  142. package/examples/jsm/tsl/math/Bayer.js +40 -1
  143. package/examples/jsm/utils/LDrawUtils.js +1 -1
  144. package/examples/jsm/utils/ShadowMapViewer.js +24 -10
  145. package/examples/jsm/utils/ShadowMapViewerGPU.js +1 -1
  146. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  147. package/package.json +20 -26
  148. package/src/Three.Core.js +2 -1
  149. package/src/Three.TSL.js +19 -11
  150. package/src/Three.WebGPU.Nodes.js +2 -0
  151. package/src/Three.WebGPU.js +3 -0
  152. package/src/Three.js +1 -0
  153. package/src/animation/AnimationAction.js +1 -1
  154. package/src/animation/AnimationClip.js +1 -1
  155. package/src/animation/AnimationMixer.js +6 -0
  156. package/src/animation/AnimationUtils.js +1 -12
  157. package/src/animation/KeyframeTrack.js +47 -8
  158. package/src/animation/PropertyMixer.js +4 -4
  159. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  160. package/src/animation/tracks/ColorKeyframeTrack.js +1 -1
  161. package/src/animation/tracks/NumberKeyframeTrack.js +1 -1
  162. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -1
  163. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  164. package/src/animation/tracks/VectorKeyframeTrack.js +1 -1
  165. package/src/audio/Audio.js +1 -1
  166. package/src/audio/AudioListener.js +5 -3
  167. package/src/cameras/Camera.js +32 -2
  168. package/src/cameras/CubeCamera.js +20 -0
  169. package/src/constants.js +90 -5
  170. package/src/core/BufferGeometry.js +14 -2
  171. package/src/core/Clock.js +7 -0
  172. package/src/core/Object3D.js +56 -4
  173. package/src/core/Raycaster.js +2 -2
  174. package/src/core/RenderTarget.js +3 -4
  175. package/src/extras/PMREMGenerator.js +7 -18
  176. package/src/extras/TextureUtils.js +5 -1
  177. package/src/geometries/ExtrudeGeometry.js +2 -2
  178. package/src/geometries/PolyhedronGeometry.js +1 -1
  179. package/src/geometries/TorusGeometry.js +8 -3
  180. package/src/helpers/CameraHelper.js +3 -0
  181. package/src/helpers/DirectionalLightHelper.js +4 -1
  182. package/src/helpers/HemisphereLightHelper.js +3 -0
  183. package/src/helpers/PointLightHelper.js +1 -25
  184. package/src/helpers/SpotLightHelper.js +3 -0
  185. package/src/lights/DirectionalLight.js +13 -0
  186. package/src/lights/HemisphereLight.js +10 -0
  187. package/src/lights/Light.js +1 -11
  188. package/src/lights/LightProbe.js +0 -15
  189. package/src/lights/LightShadow.js +15 -6
  190. package/src/lights/PointLight.js +15 -0
  191. package/src/lights/PointLightShadow.js +0 -86
  192. package/src/lights/SpotLight.js +22 -1
  193. package/src/lights/webgpu/IESSpotLight.js +2 -1
  194. package/src/loaders/Cache.js +28 -0
  195. package/src/loaders/FileLoader.js +1 -1
  196. package/src/loaders/ImageBitmapLoader.js +8 -3
  197. package/src/loaders/Loader.js +6 -0
  198. package/src/loaders/MaterialLoader.js +2 -1
  199. package/src/loaders/ObjectLoader.js +21 -2
  200. package/src/loaders/nodes/NodeLoader.js +2 -2
  201. package/src/materials/Material.js +2 -0
  202. package/src/materials/MeshLambertMaterial.js +9 -0
  203. package/src/materials/MeshPhongMaterial.js +9 -0
  204. package/src/materials/ShaderMaterial.js +20 -1
  205. package/src/materials/nodes/Line2NodeMaterial.js +7 -7
  206. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +5 -2
  207. package/src/materials/nodes/MeshStandardNodeMaterial.js +5 -4
  208. package/src/materials/nodes/NodeMaterial.js +72 -25
  209. package/src/materials/nodes/manager/NodeMaterialObserver.js +10 -4
  210. package/src/math/Line3.js +3 -5
  211. package/src/math/MathUtils.js +10 -10
  212. package/src/math/Matrix4.js +74 -65
  213. package/src/math/Quaternion.js +3 -29
  214. package/src/math/Sphere.js +1 -1
  215. package/src/math/Vector3.js +3 -5
  216. package/src/math/interpolants/BezierInterpolant.js +108 -0
  217. package/src/nodes/Nodes.js +87 -68
  218. package/src/nodes/TSL.js +6 -6
  219. package/src/nodes/accessors/Arrays.js +1 -1
  220. package/src/nodes/accessors/BatchNode.js +10 -10
  221. package/src/nodes/accessors/Bitangent.js +5 -5
  222. package/src/nodes/accessors/BufferAttributeNode.js +98 -12
  223. package/src/nodes/accessors/BufferNode.js +29 -2
  224. package/src/nodes/accessors/Camera.js +149 -28
  225. package/src/nodes/accessors/ClippingNode.js +4 -4
  226. package/src/nodes/accessors/CubeTextureNode.js +20 -1
  227. package/src/nodes/accessors/InstanceNode.js +148 -43
  228. package/src/nodes/accessors/MaterialNode.js +9 -1
  229. package/src/nodes/accessors/MaterialReferenceNode.js +1 -2
  230. package/src/nodes/accessors/ModelNode.js +1 -1
  231. package/src/nodes/accessors/Normal.js +11 -11
  232. package/src/nodes/accessors/Position.js +34 -2
  233. package/src/nodes/accessors/ReferenceBaseNode.js +4 -4
  234. package/src/nodes/accessors/ReferenceNode.js +4 -4
  235. package/src/nodes/accessors/RendererReferenceNode.js +1 -2
  236. package/src/nodes/accessors/SceneProperties.js +53 -0
  237. package/src/nodes/accessors/SkinningNode.js +27 -26
  238. package/src/nodes/accessors/StorageBufferNode.js +4 -21
  239. package/src/nodes/accessors/StorageTextureNode.js +37 -1
  240. package/src/nodes/accessors/Tangent.js +4 -14
  241. package/src/nodes/accessors/Texture3DNode.js +32 -35
  242. package/src/nodes/accessors/TextureNode.js +58 -22
  243. package/src/nodes/accessors/UniformArrayNode.js +4 -2
  244. package/src/nodes/accessors/UserDataNode.js +1 -2
  245. package/src/nodes/accessors/VertexColorNode.js +1 -2
  246. package/src/nodes/code/FunctionNode.js +1 -2
  247. package/src/nodes/core/ArrayNode.js +20 -1
  248. package/src/nodes/core/AssignNode.js +2 -2
  249. package/src/nodes/core/AttributeNode.js +2 -2
  250. package/src/nodes/core/ContextNode.js +103 -4
  251. package/src/nodes/core/MRTNode.js +48 -2
  252. package/src/nodes/core/Node.js +29 -3
  253. package/src/nodes/core/NodeBuilder.js +170 -53
  254. package/src/nodes/core/NodeError.js +28 -0
  255. package/src/nodes/core/NodeFrame.js +12 -4
  256. package/src/nodes/core/NodeUtils.js +10 -8
  257. package/src/nodes/core/OutputStructNode.js +12 -10
  258. package/src/nodes/core/ParameterNode.js +3 -3
  259. package/src/nodes/core/PropertyNode.js +19 -3
  260. package/src/nodes/core/StackNode.js +65 -16
  261. package/src/nodes/core/StackTrace.js +139 -0
  262. package/src/nodes/core/StructNode.js +16 -2
  263. package/src/nodes/core/StructTypeNode.js +11 -17
  264. package/src/nodes/core/SubBuildNode.js +1 -1
  265. package/src/nodes/core/UniformNode.js +21 -5
  266. package/src/nodes/core/VarNode.js +47 -22
  267. package/src/nodes/core/VaryingNode.js +1 -18
  268. package/src/nodes/display/BlendModes.js +0 -64
  269. package/src/nodes/display/ColorAdjustment.js +17 -0
  270. package/src/nodes/display/ColorSpaceNode.js +3 -3
  271. package/src/nodes/display/NormalMapNode.js +39 -4
  272. package/src/nodes/display/PassNode.js +98 -9
  273. package/src/nodes/display/RenderOutputNode.js +3 -3
  274. package/src/nodes/display/ScreenNode.js +3 -1
  275. package/src/nodes/display/ToneMappingNode.js +1 -1
  276. package/src/nodes/display/ToonOutlinePassNode.js +2 -2
  277. package/src/nodes/display/ViewportDepthNode.js +52 -4
  278. package/src/nodes/display/ViewportTextureNode.js +21 -4
  279. package/src/nodes/fog/Fog.js +18 -35
  280. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +3 -3
  281. package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
  282. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  283. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +1 -1
  284. package/src/nodes/functions/PhysicalLightingModel.js +126 -45
  285. package/src/nodes/geometry/RangeNode.js +4 -2
  286. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -2
  287. package/src/nodes/gpgpu/ComputeNode.js +5 -4
  288. package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
  289. package/src/nodes/gpgpu/WorkgroupInfoNode.js +4 -4
  290. package/src/nodes/lighting/AnalyticLightNode.js +53 -0
  291. package/src/nodes/lighting/EnvironmentNode.js +28 -3
  292. package/src/nodes/lighting/LightsNode.js +2 -2
  293. package/src/nodes/lighting/PointShadowNode.js +162 -149
  294. package/src/nodes/lighting/ShadowFilterNode.js +53 -65
  295. package/src/nodes/lighting/ShadowNode.js +97 -41
  296. package/src/nodes/math/BitcountNode.js +433 -0
  297. package/src/nodes/math/ConditionalNode.js +2 -2
  298. package/src/nodes/math/MathNode.js +3 -40
  299. package/src/nodes/math/OperatorNode.js +2 -1
  300. package/src/nodes/math/PackFloatNode.js +98 -0
  301. package/src/nodes/math/UnpackFloatNode.js +96 -0
  302. package/src/nodes/pmrem/PMREMNode.js +1 -1
  303. package/src/nodes/pmrem/PMREMUtils.js +9 -15
  304. package/src/nodes/tsl/TSLCore.js +17 -14
  305. package/src/nodes/utils/ArrayElementNode.js +13 -0
  306. package/src/nodes/utils/DebugNode.js +11 -11
  307. package/src/nodes/utils/EventNode.js +1 -2
  308. package/src/nodes/utils/JoinNode.js +2 -2
  309. package/src/nodes/utils/LoopNode.js +1 -1
  310. package/src/nodes/utils/MemberNode.js +1 -1
  311. package/src/nodes/utils/Packing.js +13 -1
  312. package/src/nodes/utils/PostProcessingUtils.js +33 -1
  313. package/src/nodes/utils/RTTNode.js +1 -1
  314. package/src/nodes/utils/ReflectorNode.js +3 -4
  315. package/src/nodes/utils/SampleNode.js +1 -1
  316. package/src/nodes/utils/SpriteSheetUV.js +35 -0
  317. package/src/nodes/utils/UVUtils.js +28 -0
  318. package/src/objects/BatchedMesh.js +27 -14
  319. package/src/objects/InstancedMesh.js +11 -0
  320. package/src/objects/Line.js +1 -1
  321. package/src/objects/Mesh.js +1 -1
  322. package/src/objects/Points.js +1 -1
  323. package/src/objects/Skeleton.js +9 -0
  324. package/src/renderers/WebGLRenderer.js +178 -92
  325. package/src/renderers/common/Backend.js +29 -0
  326. package/src/renderers/common/Background.js +24 -11
  327. package/src/renderers/common/BindGroup.js +1 -9
  328. package/src/renderers/common/Binding.js +11 -0
  329. package/src/renderers/common/Bindings.js +27 -12
  330. package/src/renderers/common/BlendMode.js +143 -0
  331. package/src/renderers/common/Buffer.js +40 -0
  332. package/src/renderers/common/BundleGroup.js +1 -1
  333. package/src/renderers/common/ChainMap.js +30 -6
  334. package/src/renderers/common/CubeRenderTarget.js +50 -6
  335. package/src/renderers/common/Geometries.js +29 -3
  336. package/src/renderers/common/Lighting.js +5 -21
  337. package/src/renderers/common/Pipelines.js +4 -4
  338. package/src/renderers/common/PostProcessing.js +8 -206
  339. package/src/renderers/common/RenderBundles.js +2 -1
  340. package/src/renderers/common/RenderContext.js +16 -0
  341. package/src/renderers/common/RenderContexts.js +33 -49
  342. package/src/renderers/common/RenderLists.js +2 -1
  343. package/src/renderers/common/RenderObject.js +15 -3
  344. package/src/renderers/common/RenderObjectPipeline.js +40 -0
  345. package/src/renderers/common/RenderObjects.js +18 -2
  346. package/src/renderers/common/RenderPipeline.js +203 -17
  347. package/src/renderers/common/Renderer.js +257 -72
  348. package/src/renderers/common/Sampler.js +4 -4
  349. package/src/renderers/common/StorageBuffer.js +13 -1
  350. package/src/renderers/common/Textures.js +17 -1
  351. package/src/renderers/common/TimestampQueryPool.js +5 -3
  352. package/src/renderers/common/Uniform.js +8 -0
  353. package/src/renderers/common/UniformsGroup.js +61 -0
  354. package/src/renderers/common/XRManager.js +3 -2
  355. package/src/renderers/common/extras/PMREMGenerator.js +2 -8
  356. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  357. package/src/renderers/common/nodes/{Nodes.js → NodeManager.js} +18 -6
  358. package/src/renderers/common/nodes/NodeStorageBuffer.js +13 -2
  359. package/src/renderers/common/nodes/NodeUniformBuffer.js +52 -0
  360. package/src/renderers/shaders/DFGLUTData.js +19 -34
  361. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
  362. package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
  363. package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
  364. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
  365. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
  366. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +5 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
  371. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +112 -51
  372. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +225 -186
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  375. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  376. package/src/renderers/shaders/ShaderChunk.js +3 -3
  377. package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -0
  378. package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +1 -2
  379. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
  380. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
  381. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
  382. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
  383. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
  384. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -1
  385. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
  386. package/src/renderers/shaders/ShaderLib.js +7 -5
  387. package/src/renderers/shaders/UniformsLib.js +0 -3
  388. package/src/renderers/webgl/WebGLBackground.js +2 -2
  389. package/src/renderers/webgl/WebGLBindingStates.js +99 -27
  390. package/src/renderers/webgl/WebGLCapabilities.js +3 -4
  391. package/src/renderers/webgl/WebGLEnvironments.js +228 -0
  392. package/src/renderers/webgl/WebGLGeometries.js +10 -7
  393. package/src/renderers/webgl/WebGLLights.js +18 -1
  394. package/src/renderers/webgl/WebGLMaterials.js +12 -0
  395. package/src/renderers/webgl/WebGLObjects.js +3 -1
  396. package/src/renderers/webgl/WebGLOutput.js +267 -0
  397. package/src/renderers/webgl/WebGLProgram.js +45 -109
  398. package/src/renderers/webgl/WebGLPrograms.js +45 -49
  399. package/src/renderers/webgl/WebGLRenderLists.js +15 -0
  400. package/src/renderers/webgl/WebGLShadowMap.js +188 -24
  401. package/src/renderers/webgl/WebGLState.js +32 -37
  402. package/src/renderers/webgl/WebGLTextures.js +89 -28
  403. package/src/renderers/webgl/WebGLUniforms.js +40 -3
  404. package/src/renderers/webgl/WebGLUtils.js +6 -2
  405. package/src/renderers/webgl-fallback/WebGLBackend.js +148 -18
  406. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +156 -35
  407. package/src/renderers/webgl-fallback/utils/WebGLState.js +181 -5
  408. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +5 -3
  409. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -9
  410. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +6 -2
  411. package/src/renderers/webgpu/WebGPUBackend.js +119 -13
  412. package/src/renderers/webgpu/WebGPURenderer.js +2 -1
  413. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +322 -68
  414. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -17
  415. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +357 -200
  416. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -0
  417. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +61 -23
  418. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +152 -200
  419. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +65 -42
  420. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +7 -7
  421. package/src/renderers/webgpu/utils/WebGPUUtils.js +17 -11
  422. package/src/renderers/webxr/WebXRManager.js +2 -2
  423. package/src/textures/CubeDepthTexture.js +76 -0
  424. package/src/textures/Source.js +1 -1
  425. package/src/textures/Texture.js +3 -3
  426. package/src/utils.js +258 -3
  427. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -434
  428. package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -167
  429. package/examples/jsm/shaders/GodRaysShader.js +0 -333
  430. package/src/nodes/accessors/SceneNode.js +0 -145
  431. package/src/nodes/code/ScriptableNode.js +0 -726
  432. package/src/nodes/code/ScriptableValueNode.js +0 -253
  433. package/src/nodes/display/PosterizeNode.js +0 -65
  434. package/src/nodes/functions/BSDF/DFGApprox.js +0 -71
  435. package/src/nodes/utils/SpriteSheetUVNode.js +0 -90
  436. package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
  437. package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -134
@@ -1,151 +1,134 @@
1
1
  import ShadowNode from './ShadowNode.js';
2
2
  import { uniform } from '../core/UniformNode.js';
3
- import { float, vec2, If, Fn, nodeObject } from '../tsl/TSLBase.js';
3
+ import { float, vec3, If, Fn } from '../tsl/TSLBase.js';
4
4
  import { reference } from '../accessors/ReferenceNode.js';
5
- import { texture } from '../accessors/TextureNode.js';
6
- import { max, abs, sign } from '../math/MathNode.js';
7
- import { sub, div } from '../math/OperatorNode.js';
5
+ import { cubeTexture } from '../accessors/CubeTextureNode.js';
8
6
  import { renderGroup } from '../core/UniformGroupNode.js';
9
- import { Vector2 } from '../../math/Vector2.js';
10
- import { Vector4 } from '../../math/Vector4.js';
7
+ import { Matrix4 } from '../../math/Matrix4.js';
8
+ import { Vector3 } from '../../math/Vector3.js';
11
9
  import { Color } from '../../math/Color.js';
12
- import { BasicShadowMap } from '../../constants.js';
10
+ import { BasicShadowMap, GreaterEqualCompare, LessEqualCompare, WebGPUCoordinateSystem } from '../../constants.js';
11
+ import { CubeDepthTexture } from '../../textures/CubeDepthTexture.js';
12
+ import { screenCoordinate } from '../display/ScreenNode.js';
13
+ import { interleavedGradientNoise, vogelDiskSample } from '../utils/PostProcessingUtils.js';
14
+ import { abs, normalize, cross } from '../math/MathNode.js';
15
+ import { viewZToPerspectiveDepth, viewZToReversedPerspectiveDepth } from '../display/ViewportDepthNode.js';
13
16
 
14
17
  const _clearColor = /*@__PURE__*/ new Color();
18
+ const _projScreenMatrix = /*@__PURE__*/ new Matrix4();
19
+ const _lightPositionWorld = /*@__PURE__*/ new Vector3();
20
+ const _lookTarget = /*@__PURE__*/ new Vector3();
21
+
22
+ // Cube map face directions and up vectors for point light shadows
23
+ // Face order: +X, -X, +Y, -Y, +Z, -Z
24
+ // WebGPU coordinate system - Y faces swapped to match texture sampling convention
25
+ const _cubeDirectionsWebGPU = [
26
+ /*@__PURE__*/ new Vector3( 1, 0, 0 ), /*@__PURE__*/ new Vector3( - 1, 0, 0 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 ),
27
+ /*@__PURE__*/ new Vector3( 0, 1, 0 ), /*@__PURE__*/ new Vector3( 0, 0, 1 ), /*@__PURE__*/ new Vector3( 0, 0, - 1 )
28
+ ];
29
+
30
+ const _cubeUpsWebGPU = [
31
+ /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, 0, - 1 ),
32
+ /*@__PURE__*/ new Vector3( 0, 0, 1 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 )
33
+ ];
34
+
35
+ // WebGL coordinate system - standard OpenGL convention
36
+ const _cubeDirectionsWebGL = [
37
+ /*@__PURE__*/ new Vector3( 1, 0, 0 ), /*@__PURE__*/ new Vector3( - 1, 0, 0 ), /*@__PURE__*/ new Vector3( 0, 1, 0 ),
38
+ /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, 0, 1 ), /*@__PURE__*/ new Vector3( 0, 0, - 1 )
39
+ ];
40
+
41
+ const _cubeUpsWebGL = [
42
+ /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, 0, 1 ),
43
+ /*@__PURE__*/ new Vector3( 0, 0, - 1 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 )
44
+ ];
45
+
46
+ export const BasicPointShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, bd3D, dp } ) => {
47
+
48
+ return cubeTexture( depthTexture, bd3D ).compare( dp );
15
49
 
16
- // cubeToUV() maps a 3D direction vector suitable for cube texture mapping to a 2D
17
- // vector suitable for 2D texture mapping. This code uses the following layout for the
18
- // 2D texture:
19
- //
20
- // xzXZ
21
- // y Y
22
- //
23
- // Y - Positive y direction
24
- // y - Negative y direction
25
- // X - Positive x direction
26
- // x - Negative x direction
27
- // Z - Positive z direction
28
- // z - Negative z direction
29
- //
30
- // Source and test bed:
31
- // https://gist.github.com/tschw/da10c43c467ce8afd0c4
32
-
33
- export const cubeToUV = /*@__PURE__*/ Fn( ( [ pos, texelSizeY ] ) => {
34
-
35
- const v = pos.toVar();
36
-
37
- // Number of texels to avoid at the edge of each square
38
-
39
- const absV = abs( v );
40
-
41
- // Intersect unit cube
42
-
43
- const scaleToCube = div( 1.0, max( absV.x, max( absV.y, absV.z ) ) );
44
- absV.mulAssign( scaleToCube );
45
-
46
- // Apply scale to avoid seams
47
-
48
- // two texels less per square (one texel will do for NEAREST)
49
- v.mulAssign( scaleToCube.mul( texelSizeY.mul( 2 ).oneMinus() ) );
50
-
51
- // Unwrap
52
-
53
- // space: -1 ... 1 range for each square
54
- //
55
- // #X## dim := ( 4 , 2 )
56
- // # # center := ( 1 , 1 )
57
-
58
- const planar = vec2( v.xy ).toVar();
59
-
60
- const almostATexel = texelSizeY.mul( 1.5 );
61
- const almostOne = almostATexel.oneMinus();
62
-
63
- If( absV.z.greaterThanEqual( almostOne ), () => {
64
-
65
- If( v.z.greaterThan( 0.0 ), () => {
66
-
67
- planar.x.assign( sub( 4.0, v.x ) );
68
-
69
- } );
50
+ } );
70
51
 
71
- } ).ElseIf( absV.x.greaterThanEqual( almostOne ), () => {
52
+ /**
53
+ * A shadow filtering function for point lights using Vogel disk sampling and IGN.
54
+ *
55
+ * Uses 5 samples distributed via Vogel disk pattern in tangent space around the
56
+ * sample direction, rotated per-pixel using Interleaved Gradient Noise (IGN).
57
+ *
58
+ * @method
59
+ * @param {Object} inputs - The input parameter object.
60
+ * @param {CubeDepthTexture} inputs.depthTexture - A reference to the shadow cube map.
61
+ * @param {Node<vec3>} inputs.bd3D - The normalized direction from light to fragment.
62
+ * @param {Node<float>} inputs.dp - The depth value to compare against.
63
+ * @param {LightShadow} inputs.shadow - The light shadow.
64
+ * @return {Node<float>} The filtering result.
65
+ */
66
+ export const PointShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, bd3D, dp, shadow } ) => {
72
67
 
73
- const signX = sign( v.x );
74
- planar.x.assign( v.z.mul( signX ).add( signX.mul( 2.0 ) ) );
68
+ const radius = reference( 'radius', 'float', shadow ).setGroup( renderGroup );
69
+ const mapSize = reference( 'mapSize', 'vec2', shadow ).setGroup( renderGroup );
75
70
 
76
- } ).ElseIf( absV.y.greaterThanEqual( almostOne ), () => {
71
+ const texelSize = radius.div( mapSize.x );
77
72
 
78
- const signY = sign( v.y );
79
- planar.x.assign( v.x.add( signY.mul( 2.0 ) ).add( 2.0 ) );
80
- planar.y.assign( v.z.mul( signY ).sub( 2.0 ) );
73
+ // Build a tangent-space coordinate system for applying offsets
74
+ const absDir = abs( bd3D );
75
+ const tangent = normalize( cross( bd3D, absDir.x.greaterThan( absDir.z ).select( vec3( 0, 1, 0 ), vec3( 1, 0, 0 ) ) ) );
76
+ const bitangent = cross( bd3D, tangent );
81
77
 
82
- } );
78
+ // Use IGN to rotate sampling pattern per pixel (phi = IGN * 2π)
79
+ const phi = interleavedGradientNoise( screenCoordinate.xy ).mul( 6.28318530718 );
83
80
 
84
- // Transform to UV space
81
+ // 5 samples using Vogel disk distribution in tangent space
82
+ const sample0 = vogelDiskSample( 0, 5, phi );
83
+ const sample1 = vogelDiskSample( 1, 5, phi );
84
+ const sample2 = vogelDiskSample( 2, 5, phi );
85
+ const sample3 = vogelDiskSample( 3, 5, phi );
86
+ const sample4 = vogelDiskSample( 4, 5, phi );
85
87
 
86
- // scale := 0.5 / dim
87
- // translate := ( center + 0.5 ) / dim
88
- return vec2( 0.125, 0.25 ).mul( planar ).add( vec2( 0.375, 0.75 ) ).flipY();
88
+ return cubeTexture( depthTexture, bd3D.add( tangent.mul( sample0.x ).add( bitangent.mul( sample0.y ) ).mul( texelSize ) ) ).compare( dp )
89
+ .add( cubeTexture( depthTexture, bd3D.add( tangent.mul( sample1.x ).add( bitangent.mul( sample1.y ) ).mul( texelSize ) ) ).compare( dp ) )
90
+ .add( cubeTexture( depthTexture, bd3D.add( tangent.mul( sample2.x ).add( bitangent.mul( sample2.y ) ).mul( texelSize ) ) ).compare( dp ) )
91
+ .add( cubeTexture( depthTexture, bd3D.add( tangent.mul( sample3.x ).add( bitangent.mul( sample3.y ) ).mul( texelSize ) ) ).compare( dp ) )
92
+ .add( cubeTexture( depthTexture, bd3D.add( tangent.mul( sample4.x ).add( bitangent.mul( sample4.y ) ).mul( texelSize ) ) ).compare( dp ) )
93
+ .mul( 1.0 / 5.0 );
89
94
 
90
- } ).setLayout( {
91
- name: 'cubeToUV',
92
- type: 'vec2',
93
- inputs: [
94
- { name: 'pos', type: 'vec3' },
95
- { name: 'texelSizeY', type: 'float' }
96
- ]
97
95
  } );
98
96
 
99
- export const BasicPointShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, bd3D, dp, texelSize } ) => {
100
-
101
- return texture( depthTexture, cubeToUV( bd3D, texelSize.y ) ).compare( dp );
97
+ const pointShadowFilter = /*@__PURE__*/ Fn( ( { filterFn, depthTexture, shadowCoord, shadow }, builder ) => {
102
98
 
103
- } );
99
+ // for point lights, the uniform @vShadowCoord is re-purposed to hold
100
+ // the vector from the light to the world-space position of the fragment.
101
+ const shadowPosition = shadowCoord.xyz.toConst();
102
+ const shadowPositionAbs = shadowPosition.abs().toConst();
103
+ const viewZ = shadowPositionAbs.x.max( shadowPositionAbs.y ).max( shadowPositionAbs.z );
104
104
 
105
- export const PointShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, bd3D, dp, texelSize, shadow } ) => {
105
+ const shadowCameraNear = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.near );
106
+ const shadowCameraFar = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.far );
107
+ const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
106
108
 
107
- const radius = reference( 'radius', 'float', shadow ).setGroup( renderGroup );
108
- const offset = vec2( - 1.0, 1.0 ).mul( radius ).mul( texelSize.y );
109
-
110
- return texture( depthTexture, cubeToUV( bd3D.add( offset.xyy ), texelSize.y ) ).compare( dp )
111
- .add( texture( depthTexture, cubeToUV( bd3D.add( offset.yyy ), texelSize.y ) ).compare( dp ) )
112
- .add( texture( depthTexture, cubeToUV( bd3D.add( offset.xyx ), texelSize.y ) ).compare( dp ) )
113
- .add( texture( depthTexture, cubeToUV( bd3D.add( offset.yyx ), texelSize.y ) ).compare( dp ) )
114
- .add( texture( depthTexture, cubeToUV( bd3D, texelSize.y ) ).compare( dp ) )
115
- .add( texture( depthTexture, cubeToUV( bd3D.add( offset.xxy ), texelSize.y ) ).compare( dp ) )
116
- .add( texture( depthTexture, cubeToUV( bd3D.add( offset.yxy ), texelSize.y ) ).compare( dp ) )
117
- .add( texture( depthTexture, cubeToUV( bd3D.add( offset.xxx ), texelSize.y ) ).compare( dp ) )
118
- .add( texture( depthTexture, cubeToUV( bd3D.add( offset.yxx ), texelSize.y ) ).compare( dp ) )
119
- .mul( 1.0 / 9.0 );
109
+ const result = float( 1.0 ).toVar();
120
110
 
121
- } );
111
+ If( viewZ.sub( shadowCameraFar ).lessThanEqual( 0.0 ).and( viewZ.sub( shadowCameraNear ).greaterThanEqual( 0.0 ) ), () => {
122
112
 
123
- const pointShadowFilter = /*@__PURE__*/ Fn( ( { filterFn, depthTexture, shadowCoord, shadow } ) => {
113
+ let dp;
124
114
 
125
- // for point lights, the uniform @vShadowCoord is re-purposed to hold
126
- // the vector from the light to the world-space position of the fragment.
127
- const lightToPosition = shadowCoord.xyz.toVar();
128
- const lightToPositionLength = lightToPosition.length();
115
+ if ( builder.renderer.reversedDepthBuffer ) {
129
116
 
130
- const cameraNearLocal = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.near );
131
- const cameraFarLocal = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.far );
132
- const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
133
- const mapSize = uniform( shadow.mapSize ).setGroup( renderGroup );
117
+ dp = viewZToReversedPerspectiveDepth( viewZ.negate(), shadowCameraNear, shadowCameraFar );
118
+ dp.subAssign( bias );
134
119
 
135
- const result = float( 1.0 ).toVar();
120
+ } else {
136
121
 
137
- If( lightToPositionLength.sub( cameraFarLocal ).lessThanEqual( 0.0 ).and( lightToPositionLength.sub( cameraNearLocal ).greaterThanEqual( 0.0 ) ), () => {
122
+ dp = viewZToPerspectiveDepth( viewZ.negate(), shadowCameraNear, shadowCameraFar );
123
+ dp.addAssign( bias );
138
124
 
139
- // dp = normalized distance from light to fragment position
140
- const dp = lightToPositionLength.sub( cameraNearLocal ).div( cameraFarLocal.sub( cameraNearLocal ) ).toVar(); // need to clamp?
141
- dp.addAssign( bias );
125
+ }
142
126
 
143
- // bd3D = base direction 3D
144
- const bd3D = lightToPosition.normalize();
145
- const texelSize = vec2( 1.0 ).div( mapSize.mul( vec2( 4.0, 2.0 ) ) );
127
+ // bd3D = base direction 3D (direction from light to fragment)
128
+ const bd3D = shadowPosition.normalize();
146
129
 
147
- // percentage-closer filtering
148
- result.assign( filterFn( { depthTexture, bd3D, dp, texelSize, shadow } ) );
130
+ // percentage-closer filtering using cube texture sampling
131
+ result.assign( filterFn( { depthTexture, bd3D, dp, shadow } ) );
149
132
 
150
133
  } );
151
134
 
@@ -153,10 +136,6 @@ const pointShadowFilter = /*@__PURE__*/ Fn( ( { filterFn, depthTexture, shadowCo
153
136
 
154
137
  } );
155
138
 
156
- const _viewport = /*@__PURE__*/ new Vector4();
157
- const _viewportSize = /*@__PURE__*/ new Vector2();
158
- const _shadowMapSize = /*@__PURE__*/ new Vector2();
159
-
160
139
 
161
140
  /**
162
141
  * Represents the shadow implementation for point light nodes.
@@ -216,15 +195,35 @@ class PointShadowNode extends ShadowNode {
216
195
  * @param {NodeBuilder} builder - A reference to the current node builder.
217
196
  * @param {Object} inputs - A configuration object that defines the shadow filtering.
218
197
  * @param {Function} inputs.filterFn - This function defines the filtering type of the shadow map e.g. PCF.
219
- * @param {Texture} inputs.shadowTexture - A reference to the shadow map's texture.
220
- * @param {DepthTexture} inputs.depthTexture - A reference to the shadow map's texture data.
198
+ * @param {DepthTexture} inputs.depthTexture - A reference to the shadow map's depth texture.
221
199
  * @param {Node<vec3>} inputs.shadowCoord - Shadow coordinates which are used to sample from the shadow map.
222
200
  * @param {LightShadow} inputs.shadow - The light shadow.
223
201
  * @return {Node<float>} The result node of the shadow filtering.
224
202
  */
225
- setupShadowFilter( builder, { filterFn, shadowTexture, depthTexture, shadowCoord, shadow } ) {
203
+ setupShadowFilter( builder, { filterFn, depthTexture, shadowCoord, shadow } ) {
204
+
205
+ return pointShadowFilter( { filterFn, depthTexture, shadowCoord, shadow } );
206
+
207
+ }
208
+
209
+ /**
210
+ * Overwrites the default implementation to create a CubeRenderTarget with CubeDepthTexture.
211
+ *
212
+ * @param {LightShadow} shadow - The light shadow object.
213
+ * @param {NodeBuilder} builder - A reference to the current node builder.
214
+ * @return {Object} An object containing the shadow map and depth texture.
215
+ */
216
+ setupRenderTarget( shadow, builder ) {
217
+
218
+ const depthTexture = new CubeDepthTexture( shadow.mapSize.width );
219
+ depthTexture.name = 'PointShadowDepthTexture';
220
+ depthTexture.compareFunction = builder.renderer.reversedDepthBuffer ? GreaterEqualCompare : LessEqualCompare;
221
+
222
+ const shadowMap = builder.createCubeRenderTarget( shadow.mapSize.width );
223
+ shadowMap.texture.name = 'PointShadowMap';
224
+ shadowMap.depthTexture = depthTexture;
226
225
 
227
- return pointShadowFilter( { filterFn, shadowTexture, depthTexture, shadowCoord, shadow } );
226
+ return { shadowMap, depthTexture };
228
227
 
229
228
  }
230
229
 
@@ -239,14 +238,15 @@ class PointShadowNode extends ShadowNode {
239
238
  const { shadow, shadowMap, light } = this;
240
239
  const { renderer, scene } = frame;
241
240
 
242
- const shadowFrameExtents = shadow.getFrameExtents();
241
+ const camera = shadow.camera;
242
+ const shadowMatrix = shadow.matrix;
243
243
 
244
- _shadowMapSize.copy( shadow.mapSize );
245
- _shadowMapSize.multiply( shadowFrameExtents );
244
+ // Select cube directions/ups based on coordinate system
245
+ const isWebGPU = renderer.coordinateSystem === WebGPUCoordinateSystem;
246
+ const cubeDirections = isWebGPU ? _cubeDirectionsWebGPU : _cubeDirectionsWebGL;
247
+ const cubeUps = isWebGPU ? _cubeUpsWebGPU : _cubeUpsWebGL;
246
248
 
247
- shadowMap.setSize( _shadowMapSize.width, _shadowMapSize.height );
248
-
249
- _viewportSize.copy( shadow.mapSize );
249
+ shadowMap.setSize( shadow.mapSize.width, shadow.mapSize.width );
250
250
 
251
251
  //
252
252
 
@@ -257,33 +257,46 @@ class PointShadowNode extends ShadowNode {
257
257
 
258
258
  renderer.autoClear = false;
259
259
  renderer.setClearColor( shadow.clearColor, shadow.clearAlpha );
260
- renderer.clear();
261
260
 
262
- const viewportCount = shadow.getViewportCount();
261
+ // Render each cube face
262
+ for ( let face = 0; face < 6; face ++ ) {
263
+
264
+ // Set render target to the specific cube face
265
+ renderer.setRenderTarget( shadowMap, face );
266
+ renderer.clear();
267
+
268
+ // Update shadow camera matrices for this face
269
+
270
+ const far = light.distance || camera.far;
271
+
272
+ if ( far !== camera.far ) {
273
+
274
+ camera.far = far;
275
+ camera.updateProjectionMatrix();
263
276
 
264
- for ( let vp = 0; vp < viewportCount; vp ++ ) {
277
+ }
265
278
 
266
- const viewport = shadow.getViewport( vp );
279
+ _lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
280
+ camera.position.copy( _lightPositionWorld );
267
281
 
268
- const x = _viewportSize.x * viewport.x;
269
- const y = _shadowMapSize.y - _viewportSize.y - ( _viewportSize.y * viewport.y );
282
+ _lookTarget.copy( camera.position );
283
+ _lookTarget.add( cubeDirections[ face ] );
284
+ camera.up.copy( cubeUps[ face ] );
285
+ camera.lookAt( _lookTarget );
286
+ camera.updateMatrixWorld();
270
287
 
271
- _viewport.set(
272
- x,
273
- y,
274
- _viewportSize.x * viewport.z,
275
- _viewportSize.y * viewport.w
276
- );
288
+ shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );
277
289
 
278
- shadowMap.viewport.copy( _viewport );
290
+ _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
291
+ shadow._frustum.setFromProjectionMatrix( _projScreenMatrix, camera.coordinateSystem, camera.reversedDepth );
279
292
 
280
- shadow.updateMatrices( light, vp );
293
+ //
281
294
 
282
295
  const currentSceneName = scene.name;
283
296
 
284
- scene.name = `Point Light Shadow [ ${ light.name || 'ID: ' + light.id } ] - Face ${ vp + 1 }`;
297
+ scene.name = `Point Light Shadow [ ${ light.name || 'ID: ' + light.id } ] - Face ${ face + 1 }`;
285
298
 
286
- renderer.render( scene, shadow.camera );
299
+ renderer.render( scene, camera );
287
300
 
288
301
  scene.name = currentSceneName;
289
302
 
@@ -309,4 +322,4 @@ export default PointShadowNode;
309
322
  * @param {?PointLightShadow} [shadow=null] - An optional point light shadow.
310
323
  * @return {PointShadowNode} The created point shadow node.
311
324
  */
312
- export const pointShadow = ( light, shadow ) => nodeObject( new PointShadowNode( light, shadow ) );
325
+ export const pointShadow = ( light, shadow ) => new PointShadowNode( light, shadow );
@@ -5,8 +5,9 @@ import { mix, fract, step, max, clamp } from '../math/MathNode.js';
5
5
  import { add, sub } from '../math/OperatorNode.js';
6
6
  import { renderGroup } from '../core/UniformGroupNode.js';
7
7
  import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
8
- import { objectPosition } from '../accessors/Object3DNode.js';
9
- import { positionWorld } from '../accessors/Position.js';
8
+ import { screenCoordinate } from '../display/ScreenNode.js';
9
+ import { interleavedGradientNoise, vogelDiskSample } from '../utils/PostProcessingUtils.js';
10
+ import { NoBlending } from '../../constants.js';
10
11
 
11
12
  const shadowMaterialLib = /*@__PURE__*/ new WeakMap();
12
13
 
@@ -35,7 +36,11 @@ export const BasicShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord
35
36
  } );
36
37
 
37
38
  /**
38
- * A shadow filtering function performing PCF filtering.
39
+ * A shadow filtering function performing PCF filtering with Vogel disk sampling and IGN.
40
+ *
41
+ * Uses 5 samples distributed via Vogel disk pattern, rotated per-pixel using Interleaved
42
+ * Gradient Noise (IGN) to break up banding artifacts. Combined with hardware PCF (4-tap
43
+ * filtering per sample), this effectively provides 20 filtered taps with better distribution.
39
44
  *
40
45
  * @method
41
46
  * @param {Object} inputs - The input parameter object.
@@ -64,34 +69,19 @@ export const PCFShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord,
64
69
  const radius = reference( 'radius', 'float', shadow ).setGroup( renderGroup );
65
70
 
66
71
  const texelSize = vec2( 1 ).div( mapSize );
67
- const dx0 = texelSize.x.negate().mul( radius );
68
- const dy0 = texelSize.y.negate().mul( radius );
69
- const dx1 = texelSize.x.mul( radius );
70
- const dy1 = texelSize.y.mul( radius );
71
- const dx2 = dx0.div( 2 );
72
- const dy2 = dy0.div( 2 );
73
- const dx3 = dx1.div( 2 );
74
- const dy3 = dy1.div( 2 );
72
+ const radiusScaled = radius.mul( texelSize.x );
73
+
74
+ // Use IGN to rotate sampling pattern per pixel (phi = IGN * 2π)
75
+ const phi = interleavedGradientNoise( screenCoordinate.xy ).mul( 6.28318530718 );
75
76
 
77
+ // 5 samples using Vogel disk distribution
76
78
  return add(
77
- depthCompare( shadowCoord.xy.add( vec2( dx0, dy0 ) ), shadowCoord.z ),
78
- depthCompare( shadowCoord.xy.add( vec2( 0, dy0 ) ), shadowCoord.z ),
79
- depthCompare( shadowCoord.xy.add( vec2( dx1, dy0 ) ), shadowCoord.z ),
80
- depthCompare( shadowCoord.xy.add( vec2( dx2, dy2 ) ), shadowCoord.z ),
81
- depthCompare( shadowCoord.xy.add( vec2( 0, dy2 ) ), shadowCoord.z ),
82
- depthCompare( shadowCoord.xy.add( vec2( dx3, dy2 ) ), shadowCoord.z ),
83
- depthCompare( shadowCoord.xy.add( vec2( dx0, 0 ) ), shadowCoord.z ),
84
- depthCompare( shadowCoord.xy.add( vec2( dx2, 0 ) ), shadowCoord.z ),
85
- depthCompare( shadowCoord.xy, shadowCoord.z ),
86
- depthCompare( shadowCoord.xy.add( vec2( dx3, 0 ) ), shadowCoord.z ),
87
- depthCompare( shadowCoord.xy.add( vec2( dx1, 0 ) ), shadowCoord.z ),
88
- depthCompare( shadowCoord.xy.add( vec2( dx2, dy3 ) ), shadowCoord.z ),
89
- depthCompare( shadowCoord.xy.add( vec2( 0, dy3 ) ), shadowCoord.z ),
90
- depthCompare( shadowCoord.xy.add( vec2( dx3, dy3 ) ), shadowCoord.z ),
91
- depthCompare( shadowCoord.xy.add( vec2( dx0, dy1 ) ), shadowCoord.z ),
92
- depthCompare( shadowCoord.xy.add( vec2( 0, dy1 ) ), shadowCoord.z ),
93
- depthCompare( shadowCoord.xy.add( vec2( dx1, dy1 ) ), shadowCoord.z )
94
- ).mul( 1 / 17 );
79
+ depthCompare( shadowCoord.xy.add( vogelDiskSample( 0, 5, phi ).mul( radiusScaled ) ), shadowCoord.z ),
80
+ depthCompare( shadowCoord.xy.add( vogelDiskSample( 1, 5, phi ).mul( radiusScaled ) ), shadowCoord.z ),
81
+ depthCompare( shadowCoord.xy.add( vogelDiskSample( 2, 5, phi ).mul( radiusScaled ) ), shadowCoord.z ),
82
+ depthCompare( shadowCoord.xy.add( vogelDiskSample( 3, 5, phi ).mul( radiusScaled ) ), shadowCoord.z ),
83
+ depthCompare( shadowCoord.xy.add( vogelDiskSample( 4, 5, phi ).mul( radiusScaled ) ), shadowCoord.z )
84
+ ).mul( 1 / 5 );
95
85
 
96
86
  } );
97
87
 
@@ -183,9 +173,7 @@ export const PCFSoftShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoo
183
173
  * @param {Node<vec3>} inputs.shadowCoord - The shadow coordinates.
184
174
  * @return {Node<float>} The filtering result.
185
175
  */
186
- export const VSMShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, depthLayer } ) => {
187
-
188
- const occlusion = float( 1 ).toVar();
176
+ export const VSMShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, depthLayer }, builder ) => {
189
177
 
190
178
  let distribution = texture( depthTexture ).sample( shadowCoord.xy );
191
179
 
@@ -197,47 +185,31 @@ export const VSMShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord,
197
185
 
198
186
  distribution = distribution.rg;
199
187
 
200
- const hardShadow = step( shadowCoord.z, distribution.x );
188
+ const mean = distribution.x;
189
+ const variance = max( 0.0000001, distribution.y.mul( distribution.y ) );
201
190
 
202
- If( hardShadow.notEqual( float( 1.0 ) ), () => {
191
+ const hardShadow = ( builder.renderer.reversedDepthBuffer ) ? step( mean, shadowCoord.z ) : step( shadowCoord.z, mean );
203
192
 
204
- const distance = shadowCoord.z.sub( distribution.x );
205
- const variance = max( 0, distribution.y.mul( distribution.y ) );
206
- let softnessProbability = variance.div( variance.add( distance.mul( distance ) ) ); // Chebeyshevs inequality
207
- softnessProbability = clamp( sub( softnessProbability, 0.3 ).div( 0.95 - 0.3 ) );
208
- occlusion.assign( clamp( max( hardShadow, softnessProbability ) ) );
193
+ const output = float( 1 ).toVar(); // default, fully lit
209
194
 
210
- } );
195
+ If( hardShadow.notEqual( 1.0 ), () => {
211
196
 
212
- return occlusion;
197
+ // Distance from mean
198
+ const d = shadowCoord.z.sub( mean );
213
199
 
214
- } );
215
-
216
- //
200
+ // Chebyshev's inequality for upper bound on probability
201
+ let p_max = variance.div( variance.add( d.mul( d ) ) );
217
202
 
218
- const linearDistance = /*@__PURE__*/ Fn( ( [ position, cameraNear, cameraFar ] ) => {
203
+ // Reduce light bleeding by remapping [amount, 1] to [0, 1]
204
+ p_max = clamp( sub( p_max, 0.3 ).div( 0.65 ) );
219
205
 
220
- let dist = positionWorld.sub( position ).length();
221
- dist = dist.sub( cameraNear ).div( cameraFar.sub( cameraNear ) );
222
- dist = dist.saturate(); // clamp to [ 0, 1 ]
206
+ output.assign( max( hardShadow, p_max ) );
223
207
 
224
- return dist;
208
+ } );
209
+ return output;
225
210
 
226
211
  } );
227
212
 
228
- const linearShadowDistance = ( light ) => {
229
-
230
- const camera = light.shadow.camera;
231
-
232
- const nearDistance = reference( 'near', 'float', camera ).setGroup( renderGroup );
233
- const farDistance = reference( 'far', 'float', camera ).setGroup( renderGroup );
234
-
235
- const referencePosition = objectPosition( light );
236
-
237
- return linearDistance( referencePosition, nearDistance, farDistance );
238
-
239
- };
240
-
241
213
  /**
242
214
  * Retrieves or creates a shadow material for the given light source.
243
215
  *
@@ -258,13 +230,11 @@ export const getShadowMaterial = ( light ) => {
258
230
 
259
231
  if ( material === undefined ) {
260
232
 
261
- const depthNode = light.isPointLight ? linearShadowDistance( light ) : null;
262
-
263
233
  material = new NodeMaterial();
264
234
  material.colorNode = vec4( 0, 0, 0, 1 );
265
- material.depthNode = depthNode;
266
235
  material.isShadowPassMaterial = true; // Use to avoid other overrideMaterial override material.colorNode unintentionally when using material.shadowNode
267
236
  material.name = 'ShadowMaterial';
237
+ material.blending = NoBlending;
268
238
  material.fog = false;
269
239
 
270
240
  shadowMaterialLib.set( light, material );
@@ -274,3 +244,21 @@ export const getShadowMaterial = ( light ) => {
274
244
  return material;
275
245
 
276
246
  };
247
+
248
+ /**
249
+ * Disposes the shadow material for the given light source.
250
+ *
251
+ * @param {Light} light - The light source.
252
+ */
253
+ export const disposeShadowMaterial = ( light ) => {
254
+
255
+ const material = shadowMaterialLib.get( light );
256
+
257
+ if ( material !== undefined ) {
258
+
259
+ material.dispose();
260
+ shadowMaterialLib.delete( light );
261
+
262
+ }
263
+
264
+ };