@plastic-software/three 0.180.0 → 0.181.2

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 (357) hide show
  1. package/build/three.cjs +944 -487
  2. package/build/three.core.js +506 -327
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +436 -164
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +8 -2
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +3753 -1177
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +3752 -1176
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  13. package/examples/fonts/MPLUSRounded1c/OFL.txt +91 -0
  14. package/examples/jsm/animation/CCDIKSolver.js +1 -1
  15. package/examples/jsm/controls/ArcballControls.js +1 -1
  16. package/examples/jsm/controls/DragControls.js +1 -1
  17. package/examples/jsm/controls/FirstPersonControls.js +1 -1
  18. package/examples/jsm/controls/FlyControls.js +1 -1
  19. package/examples/jsm/controls/OrbitControls.js +2 -2
  20. package/examples/jsm/controls/PointerLockControls.js +2 -2
  21. package/examples/jsm/controls/TrackballControls.js +1 -1
  22. package/examples/jsm/controls/TransformControls.js +1 -1
  23. package/examples/jsm/effects/AsciiEffect.js +8 -8
  24. package/examples/jsm/exporters/DRACOExporter.js +2 -2
  25. package/examples/jsm/exporters/EXRExporter.js +1 -1
  26. package/examples/jsm/exporters/GLTFExporter.js +3 -3
  27. package/examples/jsm/exporters/USDZExporter.js +9 -2
  28. package/examples/jsm/geometries/DecalGeometry.js +2 -2
  29. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  30. package/examples/jsm/geometries/TeapotGeometry.js +2 -2
  31. package/examples/jsm/geometries/TextGeometry.js +3 -2
  32. package/examples/jsm/gpgpu/BitonicSort.js +715 -0
  33. package/examples/jsm/helpers/ViewHelper.js +43 -5
  34. package/examples/jsm/inspector/Inspector.js +427 -0
  35. package/examples/jsm/inspector/RendererInspector.js +415 -0
  36. package/examples/jsm/inspector/tabs/Console.js +204 -0
  37. package/examples/jsm/inspector/tabs/Parameters.js +332 -0
  38. package/examples/jsm/inspector/tabs/Performance.js +268 -0
  39. package/examples/jsm/inspector/tabs/Viewer.js +166 -0
  40. package/examples/jsm/inspector/ui/Graph.js +95 -0
  41. package/examples/jsm/inspector/ui/Item.js +170 -0
  42. package/examples/jsm/inspector/ui/List.js +75 -0
  43. package/examples/jsm/inspector/ui/Profiler.js +170 -0
  44. package/examples/jsm/inspector/ui/Style.js +654 -0
  45. package/examples/jsm/inspector/ui/Tab.js +46 -0
  46. package/examples/jsm/inspector/ui/Values.js +423 -0
  47. package/examples/jsm/inspector/ui/utils.js +56 -0
  48. package/examples/jsm/interactive/HTMLMesh.js +6 -10
  49. package/examples/jsm/interactive/InteractiveGroup.js +1 -1
  50. package/examples/jsm/interactive/SelectionBox.js +30 -0
  51. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  52. package/examples/jsm/loaders/3MFLoader.js +1 -1
  53. package/examples/jsm/loaders/ColladaLoader.js +2 -2
  54. package/examples/jsm/loaders/DDSLoader.js +1 -1
  55. package/examples/jsm/loaders/DRACOLoader.js +73 -22
  56. package/examples/jsm/loaders/FBXLoader.js +2 -2
  57. package/examples/jsm/loaders/FontLoader.js +23 -5
  58. package/examples/jsm/loaders/GLTFLoader.js +5 -3
  59. package/examples/jsm/loaders/KTX2Loader.js +28 -21
  60. package/examples/jsm/loaders/KTXLoader.js +2 -2
  61. package/examples/jsm/loaders/LDrawLoader.js +1 -1
  62. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  63. package/examples/jsm/loaders/LUTCubeLoader.js +1 -1
  64. package/examples/jsm/loaders/LWOLoader.js +2 -2
  65. package/examples/jsm/loaders/MaterialXLoader.js +22 -5
  66. package/examples/jsm/loaders/OBJLoader.js +1 -1
  67. package/examples/jsm/loaders/PDBLoader.js +1 -1
  68. package/examples/jsm/loaders/SVGLoader.js +2 -2
  69. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  70. package/examples/jsm/math/ConvexHull.js +1 -1
  71. package/examples/jsm/math/ImprovedNoise.js +1 -1
  72. package/examples/jsm/math/SimplexNoise.js +1 -1
  73. package/examples/jsm/misc/ProgressiveLightMap.js +9 -3
  74. package/examples/jsm/misc/ProgressiveLightMapGPU.js +7 -1
  75. package/examples/jsm/misc/TubePainter.js +383 -40
  76. package/examples/jsm/modifiers/SimplifyModifier.js +1 -1
  77. package/examples/jsm/objects/ReflectorForSSRPass.js +1 -0
  78. package/examples/jsm/objects/Sky.js +1 -1
  79. package/examples/jsm/objects/SkyMesh.js +1 -1
  80. package/examples/jsm/objects/Water.js +3 -3
  81. package/examples/jsm/objects/WaterMesh.js +6 -6
  82. package/examples/jsm/postprocessing/GlitchPass.js +2 -2
  83. package/examples/jsm/postprocessing/UnrealBloomPass.js +8 -6
  84. package/examples/jsm/renderers/CSS2DRenderer.js +16 -5
  85. package/examples/jsm/renderers/CSS3DRenderer.js +7 -6
  86. package/examples/jsm/renderers/SVGRenderer.js +1 -1
  87. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +1 -1
  88. package/examples/jsm/shaders/AfterimageShader.js +1 -1
  89. package/examples/jsm/shaders/BleachBypassShader.js +1 -1
  90. package/examples/jsm/shaders/BokehShader.js +1 -1
  91. package/examples/jsm/shaders/BokehShader2.js +1 -1
  92. package/examples/jsm/shaders/DotScreenShader.js +1 -1
  93. package/examples/jsm/shaders/FocusShader.js +1 -1
  94. package/examples/jsm/shaders/GTAOShader.js +2 -2
  95. package/examples/jsm/shaders/GodRaysShader.js +1 -1
  96. package/examples/jsm/shaders/KaleidoShader.js +1 -1
  97. package/examples/jsm/shaders/PoissonDenoiseShader.js +2 -2
  98. package/examples/jsm/shaders/SSRShader.js +1 -1
  99. package/examples/jsm/shaders/SepiaShader.js +1 -1
  100. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +1 -1
  101. package/examples/jsm/shaders/TriangleBlurShader.js +1 -1
  102. package/examples/jsm/shaders/VignetteShader.js +1 -1
  103. package/examples/jsm/transpiler/TSLEncoder.js +7 -0
  104. package/examples/jsm/tsl/display/AfterImageNode.js +26 -24
  105. package/examples/jsm/tsl/display/AnamorphicNode.js +2 -1
  106. package/examples/jsm/tsl/display/BloomNode.js +4 -0
  107. package/examples/jsm/tsl/display/DenoiseNode.js +2 -0
  108. package/examples/jsm/tsl/display/DepthOfFieldNode.js +7 -0
  109. package/examples/jsm/tsl/display/GTAONode.js +45 -5
  110. package/examples/jsm/tsl/display/GaussianBlurNode.js +5 -3
  111. package/examples/jsm/tsl/display/OutlineNode.js +11 -0
  112. package/examples/jsm/tsl/display/SSGINode.js +654 -0
  113. package/examples/jsm/tsl/display/SSRNode.js +2 -0
  114. package/examples/jsm/tsl/display/SSSNode.js +488 -0
  115. package/examples/jsm/tsl/display/TRAANode.js +123 -6
  116. package/examples/jsm/tsl/display/boxBlur.js +1 -0
  117. package/examples/jsm/tsl/display/hashBlur.js +1 -0
  118. package/examples/jsm/tsl/lighting/TiledLightsNode.js +21 -1
  119. package/examples/jsm/webxr/XRControllerModelFactory.js +1 -1
  120. package/examples/jsm/webxr/XRHandModelFactory.js +2 -6
  121. package/package.json +5 -10
  122. package/src/Three.Core.js +3 -2
  123. package/src/Three.TSL.js +7 -1
  124. package/src/Three.WebGPU.Nodes.js +2 -0
  125. package/src/Three.WebGPU.js +2 -0
  126. package/src/animation/AnimationClip.js +3 -2
  127. package/src/animation/AnimationMixer.js +3 -3
  128. package/src/animation/AnimationObjectGroup.js +2 -1
  129. package/src/animation/KeyframeTrack.js +7 -6
  130. package/src/animation/PropertyBinding.js +12 -11
  131. package/src/audio/Audio.js +10 -9
  132. package/src/audio/PositionalAudio.js +1 -1
  133. package/src/cameras/OrthographicCamera.js +1 -1
  134. package/src/cameras/PerspectiveCamera.js +1 -1
  135. package/src/cameras/StereoCamera.js +2 -2
  136. package/src/constants.js +1 -1
  137. package/src/core/BufferGeometry.js +8 -8
  138. package/src/core/EventDispatcher.js +1 -1
  139. package/src/core/InterleavedBuffer.js +1 -1
  140. package/src/core/InterleavedBufferAttribute.js +3 -2
  141. package/src/core/Object3D.js +3 -2
  142. package/src/core/Raycaster.js +2 -1
  143. package/src/core/RenderTarget.js +10 -1
  144. package/src/extras/Controls.js +5 -4
  145. package/src/extras/DataUtils.js +2 -1
  146. package/src/extras/Earcut.js +6 -0
  147. package/src/extras/ImageUtils.js +2 -2
  148. package/src/extras/PMREMGenerator.js +268 -55
  149. package/src/extras/core/Curve.js +2 -1
  150. package/src/extras/core/Interpolations.js +7 -1
  151. package/src/extras/core/ShapePath.js +4 -4
  152. package/src/extras/lib/earcut.js +7 -7
  153. package/src/geometries/BoxGeometry.js +1 -0
  154. package/src/geometries/CapsuleGeometry.js +1 -0
  155. package/src/geometries/CircleGeometry.js +1 -0
  156. package/src/geometries/ConeGeometry.js +1 -0
  157. package/src/geometries/CylinderGeometry.js +1 -0
  158. package/src/geometries/DodecahedronGeometry.js +1 -0
  159. package/src/geometries/ExtrudeGeometry.js +8 -6
  160. package/src/geometries/IcosahedronGeometry.js +1 -0
  161. package/src/geometries/LatheGeometry.js +1 -0
  162. package/src/geometries/OctahedronGeometry.js +1 -0
  163. package/src/geometries/PlaneGeometry.js +1 -0
  164. package/src/geometries/RingGeometry.js +1 -0
  165. package/src/geometries/ShapeGeometry.js +1 -0
  166. package/src/geometries/SphereGeometry.js +1 -0
  167. package/src/geometries/TetrahedronGeometry.js +1 -0
  168. package/src/geometries/TorusGeometry.js +1 -0
  169. package/src/geometries/TorusKnotGeometry.js +1 -0
  170. package/src/geometries/TubeGeometry.js +1 -0
  171. package/src/helpers/CameraHelper.js +1 -1
  172. package/src/loaders/AnimationLoader.js +2 -1
  173. package/src/loaders/AudioLoader.js +2 -1
  174. package/src/loaders/BufferGeometryLoader.js +2 -2
  175. package/src/loaders/Cache.js +2 -2
  176. package/src/loaders/DataTextureLoader.js +1 -1
  177. package/src/loaders/FileLoader.js +3 -2
  178. package/src/loaders/ImageBitmapLoader.js +5 -4
  179. package/src/loaders/ImageLoader.js +1 -1
  180. package/src/loaders/Loader.js +3 -3
  181. package/src/loaders/LoadingManager.js +25 -3
  182. package/src/loaders/MaterialLoader.js +3 -2
  183. package/src/loaders/ObjectLoader.js +13 -13
  184. package/src/loaders/TextureLoader.js +1 -1
  185. package/src/loaders/nodes/NodeLoader.js +3 -2
  186. package/src/materials/Material.js +4 -3
  187. package/src/materials/MeshBasicMaterial.js +1 -0
  188. package/src/materials/MeshDepthMaterial.js +1 -0
  189. package/src/materials/MeshLambertMaterial.js +2 -1
  190. package/src/materials/MeshMatcapMaterial.js +22 -0
  191. package/src/materials/MeshNormalMaterial.js +1 -0
  192. package/src/materials/MeshPhongMaterial.js +2 -1
  193. package/src/materials/MeshPhysicalMaterial.js +2 -1
  194. package/src/materials/MeshStandardMaterial.js +8 -7
  195. package/src/materials/MeshToonMaterial.js +1 -0
  196. package/src/materials/PointsMaterial.js +1 -1
  197. package/src/materials/ShaderMaterial.js +2 -2
  198. package/src/materials/nodes/Line2NodeMaterial.js +2 -2
  199. package/src/materials/nodes/MeshSSSNodeMaterial.js +1 -1
  200. package/src/materials/nodes/NodeMaterial.js +62 -22
  201. package/src/materials/nodes/manager/NodeMaterialObserver.js +2 -1
  202. package/src/math/Color.js +6 -5
  203. package/src/math/ColorManagement.js +2 -2
  204. package/src/math/Cylindrical.js +1 -1
  205. package/src/math/Euler.js +2 -1
  206. package/src/math/MathUtils.js +13 -11
  207. package/src/math/Matrix2.js +1 -1
  208. package/src/math/Matrix3.js +2 -2
  209. package/src/math/Matrix4.js +7 -7
  210. package/src/math/Plane.js +1 -1
  211. package/src/math/Quaternion.js +68 -66
  212. package/src/math/Spherical.js +1 -1
  213. package/src/nodes/Nodes.js +1 -1
  214. package/src/nodes/TSL.js +1 -1
  215. package/src/nodes/accessors/CubeTextureNode.js +3 -2
  216. package/src/nodes/accessors/InstanceNode.js +22 -4
  217. package/src/nodes/accessors/Lights.js +10 -0
  218. package/src/nodes/accessors/Normal.js +5 -4
  219. package/src/nodes/accessors/Position.js +18 -2
  220. package/src/nodes/accessors/ReferenceNode.js +2 -1
  221. package/src/nodes/accessors/SceneNode.js +2 -1
  222. package/src/nodes/accessors/StorageBufferNode.js +2 -1
  223. package/src/nodes/accessors/StorageTextureNode.js +22 -0
  224. package/src/nodes/accessors/Texture3DNode.js +1 -1
  225. package/src/nodes/accessors/TextureNode.js +61 -27
  226. package/src/nodes/code/FunctionCallNode.js +5 -4
  227. package/src/nodes/core/ArrayNode.js +1 -0
  228. package/src/nodes/core/AttributeNode.js +2 -1
  229. package/src/nodes/core/ContextNode.js +5 -10
  230. package/src/nodes/core/IndexNode.js +2 -2
  231. package/src/nodes/core/InputNode.js +2 -1
  232. package/src/nodes/core/InspectorNode.js +128 -0
  233. package/src/nodes/core/{CacheNode.js → IsolateNode.js} +40 -7
  234. package/src/nodes/core/Node.js +137 -12
  235. package/src/nodes/core/NodeBuilder.js +135 -21
  236. package/src/nodes/core/NodeFrame.js +20 -20
  237. package/src/nodes/core/NodeFunction.js +2 -1
  238. package/src/nodes/core/NodeParser.js +2 -1
  239. package/src/nodes/core/NodeUtils.js +17 -90
  240. package/src/nodes/core/ParameterNode.js +31 -0
  241. package/src/nodes/core/PropertyNode.js +7 -0
  242. package/src/nodes/core/StackNode.js +16 -14
  243. package/src/nodes/core/UniformNode.js +2 -1
  244. package/src/nodes/core/VarNode.js +70 -12
  245. package/src/nodes/core/VaryingNode.js +3 -2
  246. package/src/nodes/display/BlendModes.js +5 -4
  247. package/src/nodes/display/BumpMapNode.js +1 -1
  248. package/src/nodes/display/ColorAdjustment.js +1 -1
  249. package/src/nodes/display/NormalMapNode.js +2 -1
  250. package/src/nodes/display/PassNode.js +51 -10
  251. package/src/nodes/display/RenderOutputNode.js +28 -2
  252. package/src/nodes/display/ScreenNode.js +2 -1
  253. package/src/nodes/display/ToneMappingNode.js +31 -4
  254. package/src/nodes/display/ToonOutlinePassNode.js +8 -0
  255. package/src/nodes/fog/Fog.js +3 -2
  256. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
  257. package/src/nodes/functions/BSDF/DFGApprox.js +60 -19
  258. package/src/nodes/functions/BasicLightingModel.js +2 -1
  259. package/src/nodes/functions/PhysicalLightingModel.js +3 -2
  260. package/src/nodes/functions/VolumetricLightingModel.js +5 -5
  261. package/src/nodes/geometry/RangeNode.js +40 -4
  262. package/src/nodes/gpgpu/ComputeBuiltinNode.js +2 -1
  263. package/src/nodes/gpgpu/ComputeNode.js +17 -5
  264. package/src/nodes/gpgpu/SubgroupFunctionNode.js +25 -0
  265. package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
  266. package/src/nodes/lighting/EnvironmentNode.js +6 -6
  267. package/src/nodes/lighting/LightsNode.js +2 -3
  268. package/src/nodes/lighting/PointShadowNode.js +6 -0
  269. package/src/nodes/lighting/ShadowFilterNode.js +2 -0
  270. package/src/nodes/lighting/ShadowNode.js +75 -8
  271. package/src/nodes/math/ConditionalNode.js +6 -5
  272. package/src/nodes/math/MathNode.js +22 -4
  273. package/src/nodes/math/OperatorNode.js +3 -2
  274. package/src/nodes/pmrem/PMREMUtils.js +117 -2
  275. package/src/nodes/shapes/Shapes.js +1 -1
  276. package/src/nodes/tsl/TSLBase.js +5 -2
  277. package/src/nodes/tsl/TSLCore.js +36 -15
  278. package/src/nodes/utils/DebugNode.js +2 -1
  279. package/src/nodes/utils/EventNode.js +36 -0
  280. package/src/nodes/utils/FunctionOverloadingNode.js +37 -19
  281. package/src/nodes/utils/JoinNode.js +3 -2
  282. package/src/nodes/utils/LoopNode.js +20 -24
  283. package/src/nodes/utils/MemberNode.js +2 -1
  284. package/src/nodes/utils/PostProcessingUtils.js +28 -1
  285. package/src/nodes/utils/RTTNode.js +12 -2
  286. package/src/nodes/utils/ReflectorNode.js +10 -3
  287. package/src/objects/Line.js +2 -1
  288. package/src/objects/LineSegments.js +2 -1
  289. package/src/objects/Skeleton.js +3 -2
  290. package/src/objects/SkinnedMesh.js +3 -1
  291. package/src/objects/Sprite.js +2 -1
  292. package/src/renderers/WebGLRenderer.js +49 -33
  293. package/src/renderers/common/Animation.js +13 -1
  294. package/src/renderers/common/Backend.js +93 -30
  295. package/src/renderers/common/Background.js +2 -1
  296. package/src/renderers/common/Bindings.js +56 -2
  297. package/src/renderers/common/CanvasTarget.js +341 -0
  298. package/src/renderers/common/Geometries.js +26 -0
  299. package/src/renderers/common/Info.js +4 -2
  300. package/src/renderers/common/InspectorBase.js +146 -0
  301. package/src/renderers/common/PostProcessing.js +6 -25
  302. package/src/renderers/common/QuadMesh.js +7 -1
  303. package/src/renderers/common/RenderList.js +7 -3
  304. package/src/renderers/common/RenderObject.js +3 -1
  305. package/src/renderers/common/RenderObjects.js +1 -1
  306. package/src/renderers/common/Renderer.js +436 -228
  307. package/src/renderers/common/RendererUtils.js +9 -0
  308. package/src/renderers/common/SampledTexture.js +8 -0
  309. package/src/renderers/common/Sampler.js +37 -11
  310. package/src/renderers/common/StorageTexture.js +9 -1
  311. package/src/renderers/common/Textures.js +89 -35
  312. package/src/renderers/common/TimestampQueryPool.js +63 -1
  313. package/src/renderers/common/UniformsGroup.js +2 -1
  314. package/src/renderers/common/XRManager.js +7 -3
  315. package/src/renderers/common/extras/PMREMGenerator.js +160 -65
  316. package/src/renderers/common/nodes/NodeLibrary.js +4 -2
  317. package/src/renderers/common/nodes/NodeSampler.js +13 -1
  318. package/src/renderers/common/nodes/Nodes.js +38 -16
  319. package/src/renderers/shaders/DFGLUTData.js +64 -0
  320. package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
  321. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
  322. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
  323. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +52 -18
  324. package/src/renderers/shaders/UniformsLib.js +1 -0
  325. package/src/renderers/shaders/UniformsUtils.js +25 -4
  326. package/src/renderers/webgl/WebGLCapabilities.js +2 -1
  327. package/src/renderers/webgl/WebGLExtensions.js +2 -25
  328. package/src/renderers/webgl/WebGLInfo.js +3 -1
  329. package/src/renderers/webgl/WebGLProgram.js +11 -10
  330. package/src/renderers/webgl/WebGLPrograms.js +2 -1
  331. package/src/renderers/webgl/WebGLShadowMap.js +2 -1
  332. package/src/renderers/webgl/WebGLState.js +15 -14
  333. package/src/renderers/webgl/WebGLTextures.js +18 -14
  334. package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
  335. package/src/renderers/webgl-fallback/WebGLBackend.js +22 -41
  336. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +74 -11
  337. package/src/renderers/webgl-fallback/utils/WebGLConstants.js +2 -3
  338. package/src/renderers/webgl-fallback/utils/WebGLState.js +6 -5
  339. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +117 -16
  340. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +42 -12
  341. package/src/renderers/webgpu/WebGPUBackend.js +134 -108
  342. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +2 -1
  343. package/src/renderers/webgpu/WebGPURenderer.js +3 -2
  344. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +21 -19
  345. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +2 -1
  346. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +5 -3
  347. package/src/renderers/webgpu/utils/WebGPUConstants.js +5 -0
  348. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +44 -16
  349. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +6 -8
  350. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +146 -74
  351. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +29 -6
  352. package/src/renderers/webgpu/utils/WebGPUUtils.js +22 -2
  353. package/src/renderers/webxr/WebXRManager.js +3 -2
  354. package/src/textures/Source.js +2 -1
  355. package/src/textures/Texture.js +3 -2
  356. package/src/textures/VideoTexture.js +2 -0
  357. package/src/utils.js +67 -3
@@ -0,0 +1,654 @@
1
+ import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, MathUtils } from 'three/webgpu';
2
+ import { clamp, normalize, reference, nodeObject, Fn, NodeUpdateType, uniform, vec4, passTexture, uv, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, screenCoordinate, float, sub, fract, dot, vec2, rand, vec3, Loop, mul, PI, cos, sin, uint, cross, acos, sign, pow, luminance, If, max, abs, Break, sqrt, HALF_PI, div, ceil, shiftRight, convertToTexture, bool, getNormalFromDepth, interleavedGradientNoise } from 'three/tsl';
3
+
4
+ const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
+ const _size = /*@__PURE__*/ new Vector2();
6
+
7
+ // From Activision GTAO paper: https://www.activision.com/cdn/research/s2016_pbs_activision_occlusion.pptx
8
+ const _temporalRotations = [ 60, 300, 180, 240, 120, 0 ];
9
+ const _spatialOffsets = [ 0, 0.5, 0.25, 0.75 ];
10
+
11
+ let _rendererState;
12
+
13
+ /**
14
+ * Post processing node for applying Screen Space Global Illumination (SSGI) to a scene.
15
+ *
16
+ * References:
17
+ * - {@link https://github.com/cdrinmatane/SSRT3}.
18
+ * - {@link https://cdrinmatane.github.io/posts/ssaovb-code/}.
19
+ * - {@link https://cdrinmatane.github.io/cgspotlight-slides/ssilvb_slides.pdf}.
20
+ *
21
+ * The quality and performance of the effect mainly depend on `sliceCount` and `stepCount`.
22
+ * The total number of samples taken per pixel is `sliceCount` * `stepCount` * `2`. Here are some
23
+ * recommended presets depending on whether temporal filtering is used or not.
24
+ *
25
+ * With temporal filtering (recommended):
26
+ *
27
+ * - Low: `sliceCount` of `1`, `stepCount` of `12`.
28
+ * - Medium: `sliceCount` of `2`, `stepCount` of `8`.
29
+ * - High: `sliceCount` of `3`, `stepCount` of `16`.
30
+ *
31
+ * Use for a higher slice count if you notice temporal instabilities like flickering. Reduce the sample
32
+ * count then to mitigate the performance lost.
33
+ *
34
+ * Without temporal filtering:
35
+ *
36
+ * - Low: `sliceCount` of `2`, `stepCount` of `6`.
37
+ * - Medium: `sliceCount` of `3`, `stepCount` of `8`.
38
+ * - High: `sliceCount` of `4`, `stepCount` of `12`.
39
+ *
40
+ * @augments TempNode
41
+ * @three_import import { ssgi } from 'three/addons/tsl/display/SSGINode.js';
42
+ */
43
+ class SSGINode extends TempNode {
44
+
45
+ static get type() {
46
+
47
+ return 'SSGINode';
48
+
49
+ }
50
+
51
+ /**
52
+ * Constructs a new SSGI node.
53
+ *
54
+ * @param {TextureNode} beautyNode - A texture node that represents the beauty or scene pass.
55
+ * @param {TextureNode} depthNode - A texture node that represents the scene's depth.
56
+ * @param {TextureNode} normalNode - A texture node that represents the scene's normals.
57
+ * @param {PerspectiveCamera} camera - The camera the scene is rendered with.
58
+ */
59
+ constructor( beautyNode, depthNode, normalNode, camera ) {
60
+
61
+ super( 'vec4' );
62
+
63
+ /**
64
+ * A texture node that represents the beauty or scene pass.
65
+ *
66
+ * @type {TextureNode}
67
+ */
68
+ this.beautyNode = beautyNode;
69
+
70
+ /**
71
+ * A node that represents the scene's depth.
72
+ *
73
+ * @type {TextureNode}
74
+ */
75
+ this.depthNode = depthNode;
76
+
77
+ /**
78
+ * A node that represents the scene's normals. If no normals are passed to the
79
+ * constructor (because MRT is not available), normals can be automatically
80
+ * reconstructed from depth values in the shader.
81
+ *
82
+ * @type {TextureNode}
83
+ */
84
+ this.normalNode = normalNode;
85
+
86
+ /**
87
+ * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
88
+ * its effect once per frame in `updateBefore()`.
89
+ *
90
+ * @type {string}
91
+ * @default 'frame'
92
+ */
93
+ this.updateBeforeType = NodeUpdateType.FRAME;
94
+
95
+ /**
96
+ * Number of per-pixel hemisphere slices. This has a big performance cost and should be kept as low as possible.
97
+ * Should be in the range `[1, 4]`.
98
+ *
99
+ * @type {UniformNode<uint>}
100
+ * @default 1
101
+ */
102
+ this.sliceCount = uniform( 1, 'uint' );
103
+
104
+ /**
105
+ * Number of samples taken along one side of a given hemisphere slice. This has a big performance cost and should
106
+ * be kept as low as possible. Should be in the range `[1, 32]`.
107
+ *
108
+ * @type {UniformNode<uint>}
109
+ * @default 12
110
+ */
111
+ this.stepCount = uniform( 12, 'uint' );
112
+
113
+ /**
114
+ * Power function applied to AO to make it appear darker/lighter. Should be in the range `[0, 4]`.
115
+ *
116
+ * @type {UniformNode<float>}
117
+ * @default 1
118
+ */
119
+ this.aoIntensity = uniform( 1, 'float' );
120
+
121
+ /**
122
+ * Intensity of the indirect diffuse light. Should be in the range `[0, 100]`.
123
+ *
124
+ * @type {UniformNode<float>}
125
+ * @default 10
126
+ */
127
+ this.giIntensity = uniform( 10, 'float' );
128
+
129
+ /**
130
+ * Effective sampling radius in world space. AO and GI can only have influence within that radius.
131
+ * Should be in the range `[1, 25]`.
132
+ *
133
+ * @type {UniformNode<float>}
134
+ * @default 12
135
+ */
136
+ this.radius = uniform( 12, 'float' );
137
+
138
+ /**
139
+ * Makes the sample distance in screen space instead of world-space (helps having more detail up close).
140
+ *
141
+ * @type {UniformNode<bool>}
142
+ * @default false
143
+ */
144
+ this.useScreenSpaceSampling = uniform( true, 'bool' );
145
+
146
+ /**
147
+ * Controls samples distribution. It's an exponent applied at each step get increasing step size over the distance.
148
+ * Should be in the range `[1, 3]`.
149
+ *
150
+ * @type {UniformNode<float>}
151
+ * @default 2
152
+ */
153
+ this.expFactor = uniform( 2, 'float' );
154
+
155
+ /**
156
+ * Constant thickness value of objects on the screen in world units. Allows light to pass behind surfaces past that thickness value.
157
+ * Should be in the range `[0.01, 10]`.
158
+ *
159
+ * @type {UniformNode<float>}
160
+ * @default 1
161
+ */
162
+ this.thickness = uniform( 1, 'float' );
163
+
164
+ /**
165
+ * Whether to increase thickness linearly over distance or not (avoid losing detail over the distance).
166
+ *
167
+ * @type {UniformNode<bool>}
168
+ * @default false
169
+ */
170
+ this.useLinearThickness = uniform( false, 'bool' );
171
+
172
+ /**
173
+ * How much light backface surfaces emit.
174
+ * Should be in the range `[0, 1]`.
175
+ *
176
+ * @type {UniformNode<float>}
177
+ * @default 0
178
+ */
179
+ this.backfaceLighting = uniform( 0, 'float' );
180
+
181
+ /**
182
+ * Whether to use temporal filtering or not. Setting this property to
183
+ * `true` requires the usage of `TRAANode`. This will help to reduce noise
184
+ * although it introduces typical TAA artifacts like ghosting and temporal
185
+ * instabilities.
186
+ *
187
+ * If setting this property to `false`, a manual denoise via `DenoiseNode`
188
+ * is required.
189
+ *
190
+ * @type {boolean}
191
+ * @default true
192
+ */
193
+ this.useTemporalFiltering = true;
194
+
195
+ // private uniforms
196
+
197
+ /**
198
+ * The resolution of the effect.
199
+ *
200
+ * @type {UniformNode<vec2>}
201
+ */
202
+ this._resolution = uniform( new Vector2() );
203
+
204
+ /**
205
+ * Used to compute the effective step radius when viewSpaceSampling is `false`.
206
+ *
207
+ * @type {UniformNode<vec2>}
208
+ */
209
+ this._halfProjScale = uniform( 1 );
210
+
211
+ /**
212
+ * Temporal direction that influences the rotation angle for each slice.
213
+ *
214
+ * @type {UniformNode<float>}
215
+ */
216
+ this._temporalDirection = uniform( 0 );
217
+
218
+ /**
219
+ * Temporal offset added to the initial ray step.
220
+ *
221
+ * @type {UniformNode<float>}
222
+ */
223
+ this._temporalOffset = uniform( 0 );
224
+
225
+ /**
226
+ * Represents the projection matrix of the scene's camera.
227
+ *
228
+ * @private
229
+ * @type {UniformNode<mat4>}
230
+ */
231
+ this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
232
+
233
+ /**
234
+ * Represents the inverse projection matrix of the scene's camera.
235
+ *
236
+ * @private
237
+ * @type {UniformNode<mat4>}
238
+ */
239
+ this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
240
+
241
+ /**
242
+ * Represents the near value of the scene's camera.
243
+ *
244
+ * @private
245
+ * @type {ReferenceNode<float>}
246
+ */
247
+ this._cameraNear = reference( 'near', 'float', camera );
248
+
249
+ /**
250
+ * Represents the far value of the scene's camera.
251
+ *
252
+ * @private
253
+ * @type {ReferenceNode<float>}
254
+ */
255
+ this._cameraFar = reference( 'far', 'float', camera );
256
+
257
+ /**
258
+ * A reference to the scene's camera.
259
+ *
260
+ * @private
261
+ * @type {PerspectiveCamera}
262
+ */
263
+ this._camera = camera;
264
+
265
+ /**
266
+ * The render target the GI is rendered into.
267
+ *
268
+ * @private
269
+ * @type {RenderTarget}
270
+ */
271
+ this._ssgiRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
272
+ this._ssgiRenderTarget.texture.name = 'SSGI';
273
+
274
+ /**
275
+ * The material that is used to render the effect.
276
+ *
277
+ * @private
278
+ * @type {NodeMaterial}
279
+ */
280
+ this._material = new NodeMaterial();
281
+ this._material.name = 'SSGI';
282
+
283
+ /**
284
+ * The result of the effect is represented as a separate texture node.
285
+ *
286
+ * @private
287
+ * @type {PassTextureNode}
288
+ */
289
+ this._textureNode = passTexture( this, this._ssgiRenderTarget.texture );
290
+
291
+ }
292
+
293
+ /**
294
+ * Returns the result of the effect as a texture node.
295
+ *
296
+ * @return {PassTextureNode} A texture node that represents the result of the effect.
297
+ */
298
+ getTextureNode() {
299
+
300
+ return this._textureNode;
301
+
302
+ }
303
+
304
+ /**
305
+ * Sets the size of the effect.
306
+ *
307
+ * @param {number} width - The width of the effect.
308
+ * @param {number} height - The height of the effect.
309
+ */
310
+ setSize( width, height ) {
311
+
312
+ this._resolution.value.set( width, height );
313
+ this._ssgiRenderTarget.setSize( width, height );
314
+
315
+ this._halfProjScale.value = height / ( Math.tan( this._camera.fov * MathUtils.DEG2RAD * 0.5 ) * 2 ) * 0.5;
316
+
317
+ }
318
+
319
+ /**
320
+ * This method is used to render the effect once per frame.
321
+ *
322
+ * @param {NodeFrame} frame - The current node frame.
323
+ */
324
+ updateBefore( frame ) {
325
+
326
+ const { renderer } = frame;
327
+
328
+ _rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
329
+
330
+ //
331
+
332
+ const size = renderer.getDrawingBufferSize( _size );
333
+ this.setSize( size.width, size.height );
334
+
335
+ // update temporal uniforms
336
+
337
+ if ( this.useTemporalFiltering === true ) {
338
+
339
+ const frameId = frame.frameId;
340
+
341
+ this._temporalDirection.value = _temporalRotations[ frameId % 6 ] / 360;
342
+ this._temporalOffset.value = _spatialOffsets[ frameId % 4 ];
343
+
344
+ } else {
345
+
346
+ this._temporalDirection.value = 1;
347
+ this._temporalOffset.value = 1;
348
+
349
+ }
350
+
351
+ //
352
+
353
+ _quadMesh.material = this._material;
354
+ _quadMesh.name = 'SSGI';
355
+
356
+ // clear
357
+
358
+ renderer.setClearColor( 0x000000, 1 );
359
+
360
+ // gi
361
+
362
+ renderer.setRenderTarget( this._ssgiRenderTarget );
363
+ _quadMesh.render( renderer );
364
+
365
+ // restore
366
+
367
+ RendererUtils.restoreRendererState( renderer, _rendererState );
368
+
369
+ }
370
+
371
+ /**
372
+ * This method is used to setup the effect's TSL code.
373
+ *
374
+ * @param {NodeBuilder} builder - The current node builder.
375
+ * @return {PassTextureNode}
376
+ */
377
+ setup( builder ) {
378
+
379
+ const uvNode = uv();
380
+ const MAX_RAY = uint( 32 );
381
+ const globalOccludedBitfield = uint( 0 );
382
+
383
+ const sampleDepth = ( uv ) => {
384
+
385
+ const depth = this.depthNode.sample( uv ).r;
386
+
387
+ if ( builder.renderer.logarithmicDepthBuffer === true ) {
388
+
389
+ const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
390
+
391
+ return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
392
+
393
+ }
394
+
395
+ return depth;
396
+
397
+ };
398
+
399
+ const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.sample( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
400
+ const sampleBeauty = ( uv ) => this.beautyNode.sample( uv );
401
+
402
+ // From Activision GTAO paper: https://www.activision.com/cdn/research/s2016_pbs_activision_occlusion.pptx
403
+
404
+ const spatialOffsets = Fn( ( [ position ] ) => {
405
+
406
+ return float( 0.25 ).mul( sub( position.y, position.x ).bitAnd( 3 ) );
407
+
408
+ } ).setLayout( {
409
+ name: 'spatialOffsets',
410
+ type: 'float',
411
+ inputs: [
412
+ { name: 'position', type: 'vec2' }
413
+ ]
414
+ } );
415
+
416
+ const GTAOFastAcos = Fn( ( [ value ] ) => {
417
+
418
+ const outVal = abs( value ).mul( float( - 0.156583 ) ).add( HALF_PI );
419
+ outVal.mulAssign( sqrt( abs( value ).oneMinus() ) );
420
+
421
+ const x = value.x.greaterThanEqual( 0 ).select( outVal.x, PI.sub( outVal.x ) );
422
+ const y = value.y.greaterThanEqual( 0 ).select( outVal.y, PI.sub( outVal.y ) );
423
+
424
+ return vec2( x, y );
425
+
426
+ } ).setLayout( {
427
+ name: 'GTAOFastAcos',
428
+ type: 'vec2',
429
+ inputs: [
430
+ { name: 'value', type: 'vec2' }
431
+ ]
432
+ } );
433
+
434
+ const bitCount = Fn( ( [ value ] ) => {
435
+
436
+ const v = uint( value );
437
+ v.assign( v.sub( v.shiftRight( uint( 1 ) ).bitAnd( uint( 0x55555555 ) ) ) );
438
+ v.assign( v.bitAnd( uint( 0x33333333 ) ).add( v.shiftRight( uint( 2 ) ).bitAnd( uint( 0x33333333 ) ) ) );
439
+
440
+ return v.add( v.shiftRight( uint( 4 ) ) ).bitAnd( uint( 0xF0F0F0F ) ).mul( uint( 0x1010101 ) ).shiftRight( uint( 24 ) );
441
+
442
+ } ).setLayout( {
443
+ name: 'bitCount',
444
+ type: 'uint',
445
+ inputs: [
446
+ { name: 'value', type: 'uint' }
447
+ ]
448
+ } );
449
+
450
+ const horizonSampling = Fn( ( [ directionIsRight, RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ] ) => {
451
+
452
+ const STEP_COUNT = this.stepCount.toConst();
453
+ const EXP_FACTOR = this.expFactor.toConst();
454
+ const THICKNESS = this.thickness.toConst();
455
+ const BACKFACE_LIGHTING = this.backfaceLighting.toConst();
456
+
457
+ const stepRadius = float( 0 );
458
+
459
+ If( this.useScreenSpaceSampling.equal( true ), () => {
460
+
461
+ stepRadius.assign( RADIUS.mul( this._resolution.x.div( 2 ) ).div( float( 16 ) ) ); // SSRT3 has a bug where stepRadius is divided by STEP_COUNT twice; fix here
462
+
463
+ } ).Else( () => {
464
+
465
+ stepRadius.assign( max( RADIUS.mul( this._halfProjScale ).div( viewPosition.z.negate() ), float( STEP_COUNT ) ) ); // Port note: viewZ is negative so a negate is required
466
+
467
+ } );
468
+
469
+ stepRadius.divAssign( float( STEP_COUNT ).add( 1 ) );
470
+ const radiusVS = max( 1, float( STEP_COUNT.sub( 1 ) ) ).mul( stepRadius );
471
+ const uvDirection = directionIsRight.equal( true ).select( vec2( 1, - 1 ), vec2( - 1, 1 ) ); // Port note: Because of different uv conventions, uv-y has a different sign
472
+ const samplingDirection = directionIsRight.equal( true ).select( 1, - 1 );
473
+
474
+ const color = vec3( 0 );
475
+
476
+ const lastSampleViewPosition = vec3( viewPosition ).toVar();
477
+
478
+ Loop( { start: uint( 0 ), end: STEP_COUNT, type: 'uint', condition: '<' }, ( { i } ) => {
479
+
480
+ const offset = pow( abs( mul( stepRadius, float( i ).add( initialRayStep ) ).div( radiusVS ) ), EXP_FACTOR ).mul( radiusVS ).toConst();
481
+ const uvOffset = slideDirTexelSize.mul( max( offset, float( i ).add( 1 ) ) ).toConst();
482
+ const sampleUV = uvNode.add( uvOffset.mul( uvDirection ) ).toConst();
483
+
484
+ If( sampleUV.x.lessThanEqual( 0 ).or( sampleUV.y.lessThanEqual( 0 ) ).or( sampleUV.x.greaterThanEqual( 1 ) ).or( sampleUV.y.greaterThanEqual( 1 ) ), () => {
485
+
486
+ Break();
487
+
488
+ } );
489
+
490
+ const sampleViewPosition = getViewPosition( sampleUV, sampleDepth( sampleUV ), this._cameraProjectionMatrixInverse ).toConst();
491
+ const pixelToSample = sampleViewPosition.sub( viewPosition ).normalize().toConst();
492
+ const linearThicknessMultiplier = this.useLinearThickness.equal( true ).select( sampleViewPosition.z.negate().div( this._cameraFar ).clamp().mul( 100 ), float( 1 ) );
493
+ const pixelToSampleBackface = normalize( sampleViewPosition.sub( linearThicknessMultiplier.mul( viewDir ).mul( THICKNESS ) ).sub( viewPosition ) );
494
+
495
+ let frontBackHorizon = vec2( dot( pixelToSample, viewDir ), dot( pixelToSampleBackface, viewDir ) );
496
+ frontBackHorizon = GTAOFastAcos( clamp( frontBackHorizon, - 1, 1 ) );
497
+ frontBackHorizon = clamp( div( mul( samplingDirection, frontBackHorizon.negate() ).sub( n.sub( HALF_PI ) ), PI ) ); // Port note: subtract half pi instead of adding it
498
+ frontBackHorizon = directionIsRight.equal( true ).select( frontBackHorizon.yx, frontBackHorizon.xy ); // Front/Back get inverted depending on angle
499
+
500
+ // inline ComputeOccludedBitfield() for easier debugging
501
+
502
+ const minHorizon = frontBackHorizon.x.toConst();
503
+ const maxHorizon = frontBackHorizon.y.toConst();
504
+
505
+ const startHorizonInt = uint( frontBackHorizon.mul( float( MAX_RAY ) ) ).toConst();
506
+ const angleHorizonInt = uint( ceil( maxHorizon.sub( minHorizon ).mul( float( MAX_RAY ) ) ) ).toConst();
507
+ const angleHorizonBitfield = angleHorizonInt.greaterThan( uint( 0 ) ).select( uint( shiftRight( uint( 0xFFFFFFFF ), uint( 32 ).sub( MAX_RAY ).add( MAX_RAY.sub( angleHorizonInt ) ) ) ), uint( 0 ) ).toConst();
508
+ let currentOccludedBitfield = angleHorizonBitfield.shiftLeft( startHorizonInt );
509
+ currentOccludedBitfield = currentOccludedBitfield.bitAnd( globalOccludedBitfield.bitNot() );
510
+
511
+ globalOccludedBitfield.assign( globalOccludedBitfield.bitOr( currentOccludedBitfield ) );
512
+ const numOccludedZones = bitCount( currentOccludedBitfield );
513
+
514
+ //
515
+
516
+ If( numOccludedZones.greaterThan( 0 ), () => { // If a ray hit the sample, that sample is visible from shading point
517
+
518
+ const lightColor = sampleBeauty( sampleUV );
519
+
520
+ If( luminance( lightColor ).greaterThan( 0.001 ), () => { // Continue if there is light at that location (intensity > 0)
521
+
522
+ const lightDirectionVS = normalize( pixelToSample );
523
+ const normalDotLightDirection = clamp( dot( viewNormal, lightDirectionVS ) );
524
+
525
+ If( normalDotLightDirection.greaterThan( 0.001 ), () => { // Continue if light is facing surface normal
526
+
527
+ const lightNormalVS = sampleNormal( sampleUV );
528
+
529
+ // Intensity of outgoing light in the direction of the shading point
530
+
531
+ let lightNormalDotLightDirection = dot( lightNormalVS, lightDirectionVS.negate() );
532
+
533
+ const d = sign( lightNormalDotLightDirection ).lessThan( 0 ).select( abs( lightNormalDotLightDirection ).mul( BACKFACE_LIGHTING ), abs( lightNormalDotLightDirection ) );
534
+ lightNormalDotLightDirection = BACKFACE_LIGHTING.greaterThan( 0 ).and( dot( lightNormalVS, viewDir ).greaterThan( 0 ) ).select( d, clamp( lightNormalDotLightDirection ) );
535
+
536
+ color.rgb.addAssign( float( numOccludedZones ).div( float( MAX_RAY ) ).mul( lightColor ).mul( normalDotLightDirection ).mul( lightNormalDotLightDirection ) );
537
+
538
+ } );
539
+
540
+ } );
541
+
542
+ } );
543
+
544
+ lastSampleViewPosition.assign( sampleViewPosition );
545
+
546
+ } );
547
+
548
+ return vec3( color );
549
+
550
+ } );
551
+
552
+ const gi = Fn( () => {
553
+
554
+ const depth = sampleDepth( uvNode ).toVar();
555
+
556
+ depth.greaterThanEqual( 1.0 ).discard();
557
+
558
+ const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar();
559
+ const viewNormal = sampleNormal( uvNode ).toVar();
560
+ const viewDir = normalize( viewPosition.xyz.negate() ).toVar();
561
+
562
+ //
563
+
564
+ const noiseOffset = spatialOffsets( screenCoordinate );
565
+ const noiseDirection = interleavedGradientNoise( screenCoordinate );
566
+ const noiseJitterIdx = this._temporalDirection.mul( 0.02 ); // Port: Add noiseJitterIdx here for slightly better noise convergence with TRAA (see #31890 for more details)
567
+ const initialRayStep = fract( noiseOffset.add( this._temporalOffset ) ).add( rand( uvNode.add( noiseJitterIdx ).mul( 2 ).sub( 1 ) ) );
568
+
569
+ const ao = float( 0 );
570
+ const color = vec3( 0 );
571
+
572
+ const ROTATION_COUNT = this.sliceCount.toConst();
573
+ const AO_INTENSITY = this.aoIntensity.toConst();
574
+ const GI_INTENSITY = this.giIntensity.toConst();
575
+ const RADIUS = this.radius.toConst();
576
+
577
+ Loop( { start: uint( 0 ), end: ROTATION_COUNT, type: 'uint', condition: '<' }, ( { i } ) => {
578
+
579
+ const rotationAngle = mul( float( i ).add( noiseDirection ).add( this._temporalDirection ), PI.div( float( ROTATION_COUNT ) ) ).toConst();
580
+ const sliceDir = vec3( vec2( cos( rotationAngle ), sin( rotationAngle ) ), 0 ).toConst();
581
+ const slideDirTexelSize = sliceDir.xy.mul( float( 1 ).div( this._resolution ) ).toConst();
582
+
583
+ const planeNormal = normalize( cross( sliceDir, viewDir ) ).toConst();
584
+ const tangent = cross( viewDir, planeNormal ).toConst();
585
+ const projectedNormal = viewNormal.sub( planeNormal.mul( dot( viewNormal, planeNormal ) ) ).toConst();
586
+ const projectedNormalNormalized = normalize( projectedNormal ).toConst();
587
+
588
+ const cos_n = clamp( dot( projectedNormalNormalized, viewDir ), - 1, 1 ).toConst();
589
+ const n = sign( dot( projectedNormal, tangent ) ).negate().mul( acos( cos_n ) ).toConst();
590
+
591
+ globalOccludedBitfield.assign( 0 );
592
+
593
+ color.addAssign( horizonSampling( bool( true ), RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
594
+ color.addAssign( horizonSampling( bool( false ), RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
595
+
596
+ ao.addAssign( float( bitCount( globalOccludedBitfield ) ).div( float( MAX_RAY ) ) );
597
+
598
+ } );
599
+
600
+ ao.divAssign( float( ROTATION_COUNT ) );
601
+ ao.assign( pow( ao.clamp().oneMinus(), AO_INTENSITY ).clamp() );
602
+
603
+ color.divAssign( float( ROTATION_COUNT ) );
604
+ color.mulAssign( GI_INTENSITY );
605
+
606
+ // scale color based on luminance
607
+
608
+ const maxLuminance = float( 7 ).toConst(); // 7 represent a HDR luminance value
609
+ const currentLuminance = luminance( color );
610
+
611
+ const scale = currentLuminance.greaterThan( maxLuminance ).select( maxLuminance.div( currentLuminance ), float( 1 ) );
612
+ color.mulAssign( scale );
613
+
614
+ return vec4( color, ao );
615
+
616
+ } );
617
+
618
+ this._material.fragmentNode = gi().context( builder.getSharedContext() );
619
+ this._material.needsUpdate = true;
620
+
621
+ //
622
+
623
+ return this._textureNode;
624
+
625
+ }
626
+
627
+ /**
628
+ * Frees internal resources. This method should be called
629
+ * when the effect is no longer required.
630
+ */
631
+ dispose() {
632
+
633
+ this._ssgiRenderTarget.dispose();
634
+
635
+ this._material.dispose();
636
+
637
+ }
638
+
639
+ }
640
+
641
+ export default SSGINode;
642
+
643
+ /**
644
+ * TSL function for creating a SSGI effect.
645
+ *
646
+ * @tsl
647
+ * @function
648
+ * @param {TextureNode} beautyNode - The texture node that represents the input of the effect.
649
+ * @param {TextureNode} depthNode - A texture node that represents the scene's depth.
650
+ * @param {TextureNode} normalNode - A texture node that represents the scene's normals.
651
+ * @param {Camera} camera - The camera the scene is rendered with.
652
+ * @returns {SSGINode}
653
+ */
654
+ export const ssgi = ( beautyNode, depthNode, normalNode, camera ) => nodeObject( new SSGINode( convertToTexture( beautyNode ), depthNode, normalNode, camera ) );
@@ -347,6 +347,7 @@ class SSRNode extends TempNode {
347
347
  // ssr
348
348
 
349
349
  renderer.setRenderTarget( ssrRenderTarget );
350
+ _quadMesh.name = 'SSR [ Reflections ]';
350
351
  _quadMesh.render( renderer );
351
352
 
352
353
  // blur (optional)
@@ -361,6 +362,7 @@ class SSRNode extends TempNode {
361
362
 
362
363
  this._blurSpread.value = i;
363
364
  renderer.setRenderTarget( blurRenderTarget, 0, i );
365
+ _quadMesh.name = 'SSR [ Blur Level ' + i + ' ]';
364
366
  _quadMesh.render( renderer );
365
367
 
366
368
  }