@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,5 +1,5 @@
1
1
  import { HalfFloatType, Vector2, RenderTarget, RendererUtils, QuadMesh, NodeMaterial, TempNode, NodeUpdateType, Matrix4, DepthTexture } from 'three/webgpu';
2
- import { add, float, If, Loop, int, Fn, min, max, clamp, nodeObject, texture, uniform, uv, vec2, vec4, luminance, convertToTexture, passTexture, velocity, getViewPosition, length } from 'three/tsl';
2
+ import { add, float, If, Fn, max, texture, uniform, uv, vec2, vec4, luminance, convertToTexture, passTexture, velocity, getViewPosition, viewZToPerspectiveDepth, struct, ivec2, mix } from 'three/tsl';
3
3
 
4
4
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
5
  const _size = /*@__PURE__*/ new Vector2();
@@ -77,60 +77,62 @@ class TRAANode extends TempNode {
77
77
  this.velocityNode = velocityNode;
78
78
 
79
79
  /**
80
- * The camera the scene is rendered with.
80
+ * The camera the scene is rendered with.
81
81
  *
82
82
  * @type {Camera}
83
83
  */
84
84
  this.camera = camera;
85
85
 
86
86
  /**
87
- * The jitter index selects the current camera offset value.
87
+ * When the difference between the current and previous depth goes above this threshold,
88
+ * the history is considered invalid.
88
89
  *
89
- * @private
90
90
  * @type {number}
91
- * @default 0
91
+ * @default 0.0005
92
92
  */
93
- this._jitterIndex = 0;
93
+ this.depthThreshold = 0.0005;
94
94
 
95
95
  /**
96
- * A uniform node holding the inverse resolution value.
96
+ * The depth difference within the 3×3 neighborhood to consider a pixel as an edge.
97
97
  *
98
- * @private
99
- * @type {UniformNode<vec2>}
98
+ * @type {number}
99
+ * @default 0.001
100
100
  */
101
- this._invSize = uniform( new Vector2() );
101
+ this.edgeDepthDiff = 0.001;
102
102
 
103
103
  /**
104
- * A uniform node holding the camera world matrix.
104
+ * The history becomes invalid as the pixel length of the velocity approaches this value.
105
105
  *
106
- * @private
107
- * @type {UniformNode<mat4>}
106
+ * @type {number}
107
+ * @default 128
108
108
  */
109
- this._cameraWorldMatrix = uniform( new Matrix4() );
109
+ this.maxVelocityLength = 128;
110
110
 
111
111
  /**
112
- * A uniform node holding the camera projection matrix inverse.
112
+ * Whether to decrease the weight on the current frame when the velocity is more subpixel.
113
+ * This reduces blurriness under motion, but can introduce a square pattern artifact.
113
114
  *
114
- * @private
115
- * @type {UniformNode<mat4>}
115
+ * @type {boolean}
116
+ * @default true
116
117
  */
117
- this._cameraProjectionMatrixInverse = uniform( new Matrix4() );
118
+ this.useSubpixelCorrection = true;
118
119
 
119
120
  /**
120
- * A uniform node holding the previous frame's view matrix.
121
+ * The jitter index selects the current camera offset value.
121
122
  *
122
123
  * @private
123
- * @type {UniformNode<mat4>}
124
+ * @type {number}
125
+ * @default 0
124
126
  */
125
- this._previousCameraWorldMatrix = uniform( new Matrix4() );
127
+ this._jitterIndex = 0;
126
128
 
127
129
  /**
128
- * A uniform node holding the previous frame's projection matrix inverse.
130
+ * A uniform node holding the inverse resolution value.
129
131
  *
130
132
  * @private
131
- * @type {UniformNode<mat4>}
133
+ * @type {UniformNode<vec2>}
132
134
  */
133
- this._previousCameraProjectionMatrixInverse = uniform( new Matrix4() );
135
+ this._invSize = uniform( new Vector2() );
134
136
 
135
137
  /**
136
138
  * The render target that represents the history of frame data.
@@ -175,6 +177,54 @@ class TRAANode extends TempNode {
175
177
  */
176
178
  this._originalProjectionMatrix = new Matrix4();
177
179
 
180
+ /**
181
+ * A uniform node holding the camera's near and far.
182
+ *
183
+ * @private
184
+ * @type {UniformNode<vec2>}
185
+ */
186
+ this._cameraNearFar = uniform( new Vector2() );
187
+
188
+ /**
189
+ * A uniform node holding the camera world matrix.
190
+ *
191
+ * @private
192
+ * @type {UniformNode<mat4>}
193
+ */
194
+ this._cameraWorldMatrix = uniform( new Matrix4() );
195
+
196
+ /**
197
+ * A uniform node holding the camera world matrix inverse.
198
+ *
199
+ * @private
200
+ * @type {UniformNode<mat4>}
201
+ */
202
+ this._cameraWorldMatrixInverse = uniform( new Matrix4() );
203
+
204
+ /**
205
+ * A uniform node holding the camera projection matrix inverse.
206
+ *
207
+ * @private
208
+ * @type {UniformNode<mat4>}
209
+ */
210
+ this._cameraProjectionMatrixInverse = uniform( new Matrix4() );
211
+
212
+ /**
213
+ * A uniform node holding the previous frame's view matrix.
214
+ *
215
+ * @private
216
+ * @type {UniformNode<mat4>}
217
+ */
218
+ this._previousCameraWorldMatrix = uniform( new Matrix4() );
219
+
220
+ /**
221
+ * A uniform node holding the previous frame's projection matrix inverse.
222
+ *
223
+ * @private
224
+ * @type {UniformNode<mat4>}
225
+ */
226
+ this._previousCameraProjectionMatrixInverse = uniform( new Matrix4() );
227
+
178
228
  /**
179
229
  * A texture node for the previous depth buffer.
180
230
  *
@@ -247,13 +297,13 @@ class TRAANode extends TempNode {
247
297
 
248
298
  };
249
299
 
250
- const jitterOffset = _JitterVectors[ this._jitterIndex ];
300
+ const jitterOffset = _haltonOffsets[ this._jitterIndex ];
251
301
 
252
302
  this.camera.setViewOffset(
253
303
 
254
304
  viewOffset.fullWidth, viewOffset.fullHeight,
255
305
 
256
- viewOffset.offsetX + jitterOffset[ 0 ] * 0.0625, viewOffset.offsetY + jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16
306
+ viewOffset.offsetX + jitterOffset[ 0 ] - 0.5, viewOffset.offsetY + jitterOffset[ 1 ] - 0.5,
257
307
 
258
308
  viewOffset.width, viewOffset.height
259
309
 
@@ -273,7 +323,7 @@ class TRAANode extends TempNode {
273
323
  // update jitter index
274
324
 
275
325
  this._jitterIndex ++;
276
- this._jitterIndex = this._jitterIndex % ( _JitterVectors.length - 1 );
326
+ this._jitterIndex = this._jitterIndex % ( _haltonOffsets.length - 1 );
277
327
 
278
328
  }
279
329
 
@@ -293,7 +343,9 @@ class TRAANode extends TempNode {
293
343
 
294
344
  // update camera matrices uniforms
295
345
 
346
+ this._cameraNearFar.value.set( this.camera.near, this.camera.far );
296
347
  this._cameraWorldMatrix.value.copy( this.camera.matrixWorld );
348
+ this._cameraWorldMatrixInverse.value.copy( this.camera.matrixWorldInverse );
297
349
  this._cameraProjectionMatrixInverse.value.copy( this.camera.projectionMatrixInverse );
298
350
 
299
351
  // keep the TRAA in sync with the dimensions of the beauty node
@@ -324,13 +376,10 @@ class TRAANode extends TempNode {
324
376
 
325
377
  if ( needsRestart === true ) {
326
378
 
327
- // bind and clear render target to make sure they are initialized after the resize which triggers a dispose()
379
+ // make sure render targets are initialized after the resize which triggers a dispose()
328
380
 
329
- renderer.setRenderTarget( this._historyRenderTarget );
330
- renderer.clear();
331
-
332
- renderer.setRenderTarget( this._resolveRenderTarget );
333
- renderer.clear();
381
+ renderer.initRenderTarget( this._historyRenderTarget );
382
+ renderer.initRenderTarget( this._resolveRenderTarget );
334
383
 
335
384
  // make sure to reset the history with the contents of the beauty buffer otherwise subsequent frames after the
336
385
  // resize will fade from a darker color to the correct one because the history was cleared with black.
@@ -382,20 +431,20 @@ class TRAANode extends TempNode {
382
431
  */
383
432
  setup( builder ) {
384
433
 
385
- const postProcessing = builder.context.postProcessing;
434
+ const renderPipeline = builder.context.renderPipeline;
386
435
 
387
- if ( postProcessing ) {
436
+ if ( renderPipeline ) {
388
437
 
389
438
  this._needsPostProcessingSync = true;
390
439
 
391
- postProcessing.context.onBeforePostProcessing = () => {
440
+ renderPipeline.context.onBeforeRenderPipeline = () => {
392
441
 
393
442
  const size = builder.renderer.getDrawingBufferSize( _size );
394
443
  this.setViewOffset( size.width, size.height );
395
444
 
396
445
  };
397
446
 
398
- postProcessing.context.onAfterPostProcessing = () => {
447
+ renderPipeline.context.onAfterRenderPipeline = () => {
399
448
 
400
449
  this.clearViewOffset();
401
450
 
@@ -403,123 +452,217 @@ class TRAANode extends TempNode {
403
452
 
404
453
  }
405
454
 
406
- const historyTexture = texture( this._historyRenderTarget.texture );
407
- const sampleTexture = this.beautyNode;
408
- const depthTexture = this.depthNode;
409
- const velocityTexture = this.velocityNode;
455
+ const currentDepthStruct = struct( {
410
456
 
411
- const resolve = Fn( () => {
457
+ closestDepth: 'float',
458
+ closestPositionTexel: 'vec2',
459
+ farthestDepth: 'float',
412
460
 
413
- const uvNode = uv();
461
+ } );
414
462
 
415
- const minColor = vec4( 10000 ).toVar();
416
- const maxColor = vec4( - 10000 ).toVar();
417
- const closestDepth = float( 1 ).toVar();
418
- const farthestDepth = float( 0 ).toVar();
419
- const closestDepthPixelPosition = vec2( 0 ).toVar();
463
+ // Samples 3×3 neighborhood pixels and returns the closest and farthest depths.
464
+ const sampleCurrentDepth = Fn( ( [ positionTexel ] ) => {
420
465
 
421
- // sample a 3x3 neighborhood to create a box in color space
422
- // clamping the history color with the resulting min/max colors mitigates ghosting
466
+ const closestDepth = float( 2 ).toVar();
467
+ const closestPositionTexel = vec2( 0 ).toVar();
468
+ const farthestDepth = float( - 1 ).toVar();
423
469
 
424
- Loop( { start: int( - 1 ), end: int( 1 ), type: 'int', condition: '<=', name: 'x' }, ( { x } ) => {
470
+ for ( let x = - 1; x <= 1; ++ x ) {
425
471
 
426
- Loop( { start: int( - 1 ), end: int( 1 ), type: 'int', condition: '<=', name: 'y' }, ( { y } ) => {
472
+ for ( let y = - 1; y <= 1; ++ y ) {
427
473
 
428
- const uvNeighbor = uvNode.add( vec2( float( x ), float( y ) ).mul( this._invSize ) ).toVar();
429
- const colorNeighbor = max( vec4( 0 ), sampleTexture.sample( uvNeighbor ) ).toVar(); // use max() to avoid propagate garbage values
474
+ const neighbor = positionTexel.add( vec2( x, y ) ).toVar();
475
+ const depth = this.depthNode.load( neighbor ).r.toVar();
430
476
 
431
- minColor.assign( min( minColor, colorNeighbor ) );
432
- maxColor.assign( max( maxColor, colorNeighbor ) );
477
+ If( depth.lessThan( closestDepth ), () => {
433
478
 
434
- const currentDepth = depthTexture.sample( uvNeighbor ).r.toVar();
479
+ closestDepth.assign( depth );
480
+ closestPositionTexel.assign( neighbor );
435
481
 
436
- // find the sample position of the closest depth in the neighborhood (used for velocity)
482
+ } );
437
483
 
438
- If( currentDepth.lessThan( closestDepth ), () => {
484
+ If( depth.greaterThan( farthestDepth ), () => {
439
485
 
440
- closestDepth.assign( currentDepth );
441
- closestDepthPixelPosition.assign( uvNeighbor );
486
+ farthestDepth.assign( depth );
442
487
 
443
488
  } );
444
489
 
445
- // find the farthest depth in the neighborhood (used to preserve edge anti-aliasing)
490
+ }
446
491
 
447
- If( currentDepth.greaterThan( farthestDepth ), () => {
492
+ }
448
493
 
449
- farthestDepth.assign( currentDepth );
494
+ return currentDepthStruct( closestDepth, closestPositionTexel, farthestDepth );
450
495
 
451
- } );
496
+ } );
452
497
 
453
- } );
498
+ // Samples a previous depth and reproject it using the current camera matrices.
499
+ const samplePreviousDepth = ( uv ) => {
454
500
 
455
- } );
501
+ const depth = this._previousDepthNode.sample( uv ).r;
502
+ const positionView = getViewPosition( uv, depth, this._previousCameraProjectionMatrixInverse );
503
+ const positionWorld = this._previousCameraWorldMatrix.mul( vec4( positionView, 1 ) ).xyz;
504
+ const viewZ = this._cameraWorldMatrixInverse.mul( vec4( positionWorld, 1 ) ).z;
505
+ return viewZToPerspectiveDepth( viewZ, this._cameraNearFar.x, this._cameraNearFar.y );
456
506
 
457
- // sampling/reprojection
507
+ };
458
508
 
459
- const offset = velocityTexture.sample( closestDepthPixelPosition ).xy.mul( vec2( 0.5, - 0.5 ) ); // NDC to uv offset
509
+ // Optimized version of AABB clipping.
510
+ // Reference: https://github.com/playdeadgames/temporal
511
+ const clipAABB = Fn( ( [ currentColor, historyColor, minColor, maxColor ] ) => {
512
+
513
+ const pClip = maxColor.rgb.add( minColor.rgb ).mul( 0.5 );
514
+ const eClip = maxColor.rgb.sub( minColor.rgb ).mul( 0.5 ).add( 1e-7 );
515
+ const vClip = historyColor.sub( vec4( pClip, currentColor.a ) );
516
+ const vUnit = vClip.xyz.div( eClip );
517
+ const absUnit = vUnit.abs();
518
+ const maxUnit = max( absUnit.x, absUnit.y, absUnit.z );
519
+ return maxUnit.greaterThan( 1 ).select(
520
+ vec4( pClip, currentColor.a ).add( vClip.div( maxUnit ) ),
521
+ historyColor
522
+ );
523
+
524
+ } ).setLayout( {
525
+ name: 'clipAABB',
526
+ type: 'vec4',
527
+ inputs: [
528
+ { name: 'currentColor', type: 'vec4' },
529
+ { name: 'historyColor', type: 'vec4' },
530
+ { name: 'minColor', type: 'vec4' },
531
+ { name: 'maxColor', type: 'vec4' }
532
+ ]
533
+ } );
460
534
 
461
- const currentColor = sampleTexture.sample( uvNode );
462
- const historyColor = historyTexture.sample( uvNode.sub( offset ) );
535
+ // Performs variance clipping.
536
+ // See: https://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf
537
+ const varianceClipping = Fn( ( [ positionTexel, currentColor, historyColor, gamma ] ) => {
463
538
 
464
- // clamping
539
+ const offsets = [
540
+ [ - 1, - 1 ],
541
+ [ - 1, 1 ],
542
+ [ 1, - 1 ],
543
+ [ 1, 1 ],
544
+ [ 1, 0 ],
545
+ [ 0, - 1 ],
546
+ [ 0, 1 ],
547
+ [ - 1, 0 ]
548
+ ];
465
549
 
466
- const clampedHistoryColor = clamp( historyColor, minColor, maxColor );
550
+ const moment1 = currentColor.toVar();
551
+ const moment2 = currentColor.pow2().toVar();
467
552
 
468
- // calculate current frame world position
553
+ for ( const [ x, y ] of offsets ) {
469
554
 
470
- const currentDepth = depthTexture.sample( uvNode ).r;
471
- const currentViewPosition = getViewPosition( uvNode, currentDepth, this._cameraProjectionMatrixInverse );
472
- const currentWorldPosition = this._cameraWorldMatrix.mul( vec4( currentViewPosition, 1.0 ) ).xyz;
555
+ // Use max() to prevent NaN values from propagating.
556
+ const neighbor = this.beautyNode.offset( ivec2( x, y ) ).load( positionTexel ).max( 0 );
557
+ moment1.addAssign( neighbor );
558
+ moment2.addAssign( neighbor.pow2() );
473
559
 
474
- // calculate previous frame world position from history UV and previous depth
560
+ }
475
561
 
476
- const historyUV = uvNode.sub( offset );
477
- const previousDepth = this._previousDepthNode.sample( historyUV ).r;
478
- const previousViewPosition = getViewPosition( historyUV, previousDepth, this._previousCameraProjectionMatrixInverse );
479
- const previousWorldPosition = this._previousCameraWorldMatrix.mul( vec4( previousViewPosition, 1.0 ) ).xyz;
562
+ const N = float( offsets.length + 1 );
563
+ const mean = moment1.div( N );
564
+ const variance = moment2.div( N ).sub( mean.pow2() ).max( 0 ).sqrt().mul( gamma );
565
+ const minColor = mean.sub( variance );
566
+ const maxColor = mean.add( variance );
480
567
 
481
- // calculate difference in world positions
568
+ return clipAABB( mean.clamp( minColor, maxColor ), historyColor, minColor, maxColor );
482
569
 
483
- const worldPositionDifference = length( currentWorldPosition.sub( previousWorldPosition ) ).toVar();
484
- worldPositionDifference.assign( min( max( worldPositionDifference.sub( 1.0 ), 0.0 ), 1.0 ) );
570
+ } );
485
571
 
486
- // Adaptive blend weights based on velocity magnitude suggested by CLAUDE in #32133
487
- // Higher velocity or position difference = more weight on current frame to reduce ghosting
572
+ // Returns the amount of subpixel (expressed within [0, 1]) in the velocity.
573
+ const subpixelCorrection = Fn( ( [ velocityUV, textureSize ] ) => {
574
+
575
+ const velocityTexel = velocityUV.mul( textureSize );
576
+ const phase = velocityTexel.fract().abs();
577
+ const weight = max( phase, phase.oneMinus() );
578
+ return weight.x.mul( weight.y ).oneMinus().div( 0.75 );
579
+
580
+ } ).setLayout( {
581
+ name: 'subpixelCorrection',
582
+ type: 'float',
583
+ inputs: [
584
+ { name: 'velocityUV', type: 'vec2' },
585
+ { name: 'textureSize', type: 'ivec2' }
586
+ ]
587
+ } );
488
588
 
489
- const velocityMagnitude = length( offset ).toConst();
490
- const motionFactor = max( worldPositionDifference.mul( 0.5 ), velocityMagnitude.mul( 10.0 ) ).toVar();
491
- motionFactor.assign( min( motionFactor, 1.0 ) );
589
+ // Flicker reduction based on luminance weighing.
590
+ const flickerReduction = Fn( ( [ currentColor, historyColor, currentWeight ] ) => {
492
591
 
493
- const currentWeight = float( 0.05 ).add( motionFactor.mul( 0.25 ) ).toVar();
494
- const historyWeight = currentWeight.oneMinus().toVar();
592
+ const historyWeight = currentWeight.oneMinus();
593
+ const compressedCurrent = currentColor.mul( float( 1 ).div( ( max( currentColor.r, currentColor.g, currentColor.b ).add( 1 ) ) ) );
594
+ const compressedHistory = historyColor.mul( float( 1 ).div( ( max( historyColor.r, historyColor.g, historyColor.b ).add( 1 ) ) ) );
495
595
 
496
- // zero out history weight if world positions are different (indicating motion) except on edges.
497
- // note that the constants 0.00001 and 0.5 were suggested by CLAUDE in #32133
596
+ const luminanceCurrent = luminance( compressedCurrent.rgb );
597
+ const luminanceHistory = luminance( compressedHistory.rgb );
498
598
 
499
- const isEdge = farthestDepth.sub( closestDepth ).greaterThan( 0.00001 );
500
- const strongDisocclusion = worldPositionDifference.greaterThan( 0.5 ).and( isEdge.not() );
599
+ currentWeight.mulAssign( float( 1 ).div( luminanceCurrent.add( 1 ) ) );
600
+ historyWeight.mulAssign( float( 1 ).div( luminanceHistory.add( 1 ) ) );
501
601
 
502
- If( strongDisocclusion, () => {
602
+ return add( currentColor.mul( currentWeight ), historyColor.mul( historyWeight ) ).div( max( currentWeight.add( historyWeight ), 0.00001 ) ).toVar();
503
603
 
504
- currentWeight.assign( 1.0 );
505
- historyWeight.assign( 0.0 );
604
+ } );
506
605
 
507
- } );
606
+ const historyNode = texture( this._historyRenderTarget.texture );
508
607
 
509
- // flicker reduction based on luminance weighing
608
+ const resolve = Fn( () => {
510
609
 
511
- const compressedCurrent = currentColor.mul( float( 1 ).div( ( max( currentColor.r, currentColor.g, currentColor.b ).add( 1.0 ) ) ) );
512
- const compressedHistory = clampedHistoryColor.mul( float( 1 ).div( ( max( clampedHistoryColor.r, clampedHistoryColor.g, clampedHistoryColor.b ).add( 1.0 ) ) ) );
610
+ const uvNode = uv();
611
+ const textureSize = this.beautyNode.size(); // Assumes all the buffers share the same size.
612
+ const positionTexel = uvNode.mul( textureSize );
513
613
 
514
- const luminanceCurrent = luminance( compressedCurrent.rgb );
515
- const luminanceHistory = luminance( compressedHistory.rgb );
614
+ // sample the closest and farthest depths in the current buffer
615
+
616
+ const currentDepth = sampleCurrentDepth( positionTexel );
617
+ const closestDepth = currentDepth.get( 'closestDepth' );
618
+ const closestPositionTexel = currentDepth.get( 'closestPositionTexel' );
619
+ const farthestDepth = currentDepth.get( 'farthestDepth' );
620
+
621
+ // convert the NDC offset to UV offset
622
+
623
+ const offsetUV = this.velocityNode.load( closestPositionTexel ).xy.mul( vec2( 0.5, - 0.5 ) );
624
+
625
+ // sample the previous depth
626
+
627
+ const historyUV = uvNode.sub( offsetUV );
628
+ const previousDepth = samplePreviousDepth( historyUV );
629
+
630
+ // history is considered valid when the UV is in range and there's no disocclusion except on edges
631
+
632
+ const isValidUV = historyUV.greaterThanEqual( 0 ).all().and( historyUV.lessThanEqual( 1 ).all() );
633
+ const isEdge = farthestDepth.sub( closestDepth ).greaterThan( this.edgeDepthDiff );
634
+ const isDisocclusion = closestDepth.sub( previousDepth ).greaterThan( this.depthThreshold );
635
+ const hasValidHistory = isValidUV.and( isEdge.or( isDisocclusion.not() ) );
636
+
637
+ // sample the current and previous colors
638
+
639
+ const currentColor = this.beautyNode.sample( uvNode );
640
+ const historyColor = historyNode.sample( uvNode.sub( offsetUV ) );
641
+
642
+ // increase the weight towards the current frame under motion
643
+
644
+ const motionFactor = uvNode.sub( historyUV ).mul( textureSize ).length().div( this.maxVelocityLength ).saturate();
645
+ const currentWeight = float( 0.05 ).toVar(); // A minimum weight
516
646
 
517
- currentWeight.mulAssign( float( 1.0 ).div( luminanceCurrent.add( 1 ) ) );
518
- historyWeight.mulAssign( float( 1.0 ).div( luminanceHistory.add( 1 ) ) );
647
+ if ( this.useSubpixelCorrection ) {
519
648
 
520
- const smoothedOutput = add( currentColor.mul( currentWeight ), clampedHistoryColor.mul( historyWeight ) ).div( max( currentWeight.add( historyWeight ), 0.00001 ) ).toVar();
649
+ // Increase the minimum weight towards the current frame when the velocity is more subpixel.
650
+ currentWeight.addAssign( subpixelCorrection( offsetUV, textureSize ).mul( 0.25 ) );
521
651
 
522
- return smoothedOutput;
652
+ }
653
+
654
+ currentWeight.assign( hasValidHistory.select( currentWeight.add( motionFactor ).saturate(), 1 ) );
655
+
656
+ // Perform neighborhood clipping/clamping. We use variance clipping here.
657
+
658
+ const varianceGamma = mix( 0.5, 1, motionFactor.oneMinus().pow2() ); // Reasonable gamma range is [0.75, 2]
659
+ const clippedHistoryColor = varianceClipping( positionTexel, currentColor, historyColor, varianceGamma );
660
+
661
+ // flicker reduction based on luminance weighing
662
+
663
+ const output = flickerReduction( currentColor, clippedHistoryColor, currentWeight );
664
+
665
+ return output;
523
666
 
524
667
  } );
525
668
 
@@ -548,21 +691,26 @@ class TRAANode extends TempNode {
548
691
 
549
692
  export default TRAANode;
550
693
 
551
- // These jitter vectors are specified in integers because it is easier.
552
- // I am assuming a [-8,8) integer grid, but it needs to be mapped onto [-0.5,0.5)
553
- // before being used, thus these integers need to be scaled by 1/16.
554
- //
555
- // Sample patterns reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
556
- const _JitterVectors = [
557
- [ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ],
558
- [ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ],
559
- [ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ],
560
- [ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ],
561
- [ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ],
562
- [ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ],
563
- [ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ],
564
- [ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
565
- ];
694
+ function _halton( index, base ) {
695
+
696
+ let fraction = 1;
697
+ let result = 0;
698
+ while ( index > 0 ) {
699
+
700
+ fraction /= base;
701
+ result += fraction * ( index % base );
702
+ index = Math.floor( index / base );
703
+
704
+ }
705
+
706
+ return result;
707
+
708
+ }
709
+
710
+ const _haltonOffsets = /*@__PURE__*/ Array.from(
711
+ { length: 32 },
712
+ ( _, index ) => [ _halton( index + 1, 2 ), _halton( index + 1, 3 ) ]
713
+ );
566
714
 
567
715
  /**
568
716
  * TSL function for creating a TRAA node for Temporal Reprojection Anti-Aliasing.
@@ -575,4 +723,4 @@ const _JitterVectors = [
575
723
  * @param {Camera} camera - The camera the scene is rendered with.
576
724
  * @returns {TRAANode}
577
725
  */
578
- export const traa = ( beautyNode, depthNode, velocityNode, camera ) => nodeObject( new TRAANode( convertToTexture( beautyNode ), depthNode, velocityNode, camera ) );
726
+ export const traa = ( beautyNode, depthNode, velocityNode, camera ) => new TRAANode( convertToTexture( beautyNode ), depthNode, velocityNode, camera );
@@ -138,4 +138,4 @@ export default TransitionNode;
138
138
  * @param {Node<float> | number} useTexture - Whether `mixTextureNode` should influence the transition or not.
139
139
  * @returns {TransitionNode}
140
140
  */
141
- export const transition = ( nodeA, nodeB, mixTextureNode, mixRatio, threshold, useTexture ) => nodeObject( new TransitionNode( convertToTexture( nodeA ), convertToTexture( nodeB ), convertToTexture( mixTextureNode ), nodeObject( mixRatio ), nodeObject( threshold ), nodeObject( useTexture ) ) );
141
+ export const transition = ( nodeA, nodeB, mixTextureNode, mixRatio, threshold, useTexture ) => new TransitionNode( convertToTexture( nodeA ), convertToTexture( nodeB ), convertToTexture( mixTextureNode ), nodeObject( mixRatio ), nodeObject( threshold ), nodeObject( useTexture ) );
@@ -0,0 +1,80 @@
1
+ import { abs, color, float, Fn, Loop, mix, nodeObject, perspectiveDepthToViewZ, reference, textureSize, uv, vec2, vec4, viewZToOrthographicDepth, int, If, array, ivec2 } from 'three/tsl';
2
+
3
+ /**
4
+ * Performs a depth-aware blend between a base scene and a secondary effect (like godrays).
5
+ * This function uses a Poisson disk sampling pattern to detect depth discontinuities
6
+ * in the neighborhood of the current pixel. If an edge is detected, it shifts the
7
+ * sampling coordinate for the blend node away from the edge to prevent light leaking/haloing.
8
+ *
9
+ * @param {Node} baseNode - The main scene/beauty pass texture node.
10
+ * @param {Node} blendNode - The effect to be blended (e.g., Godrays, Bloom).
11
+ * @param {Node} depthNode - The scene depth texture node.
12
+ * @param {Camera} camera - The camera used for the scene.
13
+ * @param {Object} [options={}] - Configuration for the blend effect.
14
+ * @param {Node|Color} [options.blendColor=Color(0xff0000)] - The color applied to the blend node.
15
+ * @param {Node<int> | number} [options.edgeRadius=2] - The search radius (in pixels) for detecting depth edges.
16
+ * @param {Node<float> | number} [options.edgeStrength=2] - How far to "push" the UV away from detected edges.
17
+ * @returns {Node<vec4>} The resulting blended color node.
18
+ */
19
+ export const depthAwareBlend = /*#__PURE__*/ Fn( ( [ baseNode, blendNode, depthNode, camera, options = {} ] ) => {
20
+
21
+ const uvNode = baseNode.uvNode || uv();
22
+
23
+ const cameraNear = reference( 'near', 'float', camera );
24
+ const cameraFar = reference( 'far', 'float', camera );
25
+
26
+ const blendColor = nodeObject( options.blendColor ) || color( 0xffffff );
27
+ const edgeRadius = nodeObject( options.edgeRadius ) || int( 2 );
28
+ const edgeStrength = nodeObject( options.edgeStrength ) || float( 2 );
29
+
30
+ const viewZ = perspectiveDepthToViewZ( depthNode, cameraNear, cameraFar );
31
+ const correctDepth = viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
32
+
33
+ const pushDir = vec2( 0.0 ).toVar();
34
+ const count = float( 0 ).toVar();
35
+
36
+ const resolution = ivec2( textureSize( baseNode ) ).toConst();
37
+ const pixelStep = vec2( 1 ).div( resolution );
38
+
39
+ const poissonDisk = array( [
40
+ vec2( 0.493393, 0.394269 ),
41
+ vec2( 0.798547, 0.885922 ),
42
+ vec2( 0.259143, 0.650754 ),
43
+ vec2( 0.605322, 0.023588 ),
44
+ vec2( - 0.574681, 0.137452 ),
45
+ vec2( - 0.430397, - 0.638423 ),
46
+ vec2( - 0.849487, - 0.366258 ),
47
+ vec2( 0.170621, - 0.569941 )
48
+ ] );
49
+
50
+ Loop( 8, ( { i } ) => {
51
+
52
+ const offset = poissonDisk.element( i ).mul( edgeRadius );
53
+
54
+ const sampleUv = uvNode.add( offset.mul( pixelStep ) );
55
+ const sampleDepth = depthNode.sample( sampleUv );
56
+
57
+ const sampleViewZ = perspectiveDepthToViewZ( sampleDepth, cameraNear, cameraFar );
58
+ const sampleLinearDepth = viewZToOrthographicDepth( sampleViewZ, cameraNear, cameraFar );
59
+
60
+ If( abs( sampleLinearDepth.sub( correctDepth ) ).lessThan( float( 0.05 ).mul( correctDepth ) ), () => {
61
+
62
+ pushDir.addAssign( offset );
63
+ count.addAssign( 1 );
64
+
65
+ } );
66
+
67
+ } );
68
+
69
+ count.assign( count.equal( 0 ).select( 1, count ) );
70
+
71
+ pushDir.divAssign( count ).normalize();
72
+
73
+ const sampleUv = pushDir.length().greaterThan( 0 ).select( uvNode.add( edgeStrength.mul( pushDir.div( resolution ) ) ), uvNode );
74
+
75
+ const bestChoice = blendNode.sample( sampleUv ).r;
76
+ const baseColor = baseNode.sample( uvNode );
77
+
78
+ return vec4( mix( baseColor, vec4( blendColor, 1 ), bestChoice ) );
79
+
80
+ } );