@gnsx/three 0.185.16 → 0.186.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 (418) hide show
  1. package/build/three.cjs +10 -82600
  2. package/build/three.core.js +1309 -807
  3. package/build/three.module.js +439 -338
  4. package/build/three.tsl.js +74 -44
  5. package/build/three.webgpu.js +6036 -2184
  6. package/build/three.webgpu.nodes.js +6020 -2184
  7. package/examples/jsm/Addons.js +6 -6
  8. package/examples/jsm/controls/ArcballControls.js +1 -1
  9. package/examples/jsm/controls/FirstPersonControls.js +44 -20
  10. package/examples/jsm/controls/OrbitControls.js +9 -0
  11. package/examples/jsm/controls/TrackballControls.js +109 -4
  12. package/examples/jsm/csm/CSMShadowNode.js +13 -0
  13. package/examples/jsm/exporters/GLTFExporter.js +23 -7
  14. package/examples/jsm/exporters/USDZExporter.js +2 -2
  15. package/examples/jsm/generators/CityGenerator.js +377 -45
  16. package/examples/jsm/generators/ForestGenerator.js +12 -12
  17. package/examples/jsm/generators/TerrainGenerator.js +49 -37
  18. package/examples/jsm/generators/TreeGenerator.js +70 -76
  19. package/examples/jsm/generators/city/BenchGenerator.js +127 -0
  20. package/examples/jsm/generators/city/CarGenerator.js +479 -0
  21. package/examples/jsm/generators/city/CityGeneratorUtils.js +31 -0
  22. package/examples/jsm/generators/city/HydrantGenerator.js +106 -0
  23. package/examples/jsm/generators/city/InstancedMeshGenerator.js +86 -0
  24. package/examples/jsm/generators/city/PersonGenerator.js +447 -0
  25. package/examples/jsm/generators/city/SidewalkGenerator.js +33 -38
  26. package/examples/jsm/generators/city/SkyscraperGenerator.js +448 -48
  27. package/examples/jsm/generators/city/StreetTreeGenerator.js +231 -0
  28. package/examples/jsm/generators/city/StreetlightGenerator.js +100 -0
  29. package/examples/jsm/generators/city/TrafficlightGenerator.js +106 -0
  30. package/examples/jsm/generators/city/TrashcanGenerator.js +100 -0
  31. package/examples/jsm/geometries/BoxLineGeometry.js +1 -1
  32. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  33. package/examples/jsm/geometries/RoundedBoxGeometry.js +1 -1
  34. package/examples/jsm/gpgpu/CountingSort.js +271 -0
  35. package/examples/jsm/helpers/LightProbeGridHelper.js +60 -239
  36. package/examples/jsm/helpers/LightProbeGridHelperWebGL.js +221 -0
  37. package/examples/jsm/inspector/Extension.js +94 -0
  38. package/examples/jsm/inspector/Inspector.js +145 -41
  39. package/examples/jsm/inspector/RendererInspector.js +100 -52
  40. package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +2609 -0
  41. package/examples/jsm/inspector/extensions/color-grading/ColorWheel.js +352 -0
  42. package/examples/jsm/inspector/extensions/color-grading/CurveEditor.js +599 -0
  43. package/examples/jsm/inspector/extensions/color-grading/LUT3DStyle.js +1201 -0
  44. package/examples/jsm/inspector/extensions/color-grading/LUTMath.js +788 -0
  45. package/examples/jsm/inspector/extensions/color-grading/modules/BrightnessModule.js +72 -0
  46. package/examples/jsm/inspector/extensions/color-grading/modules/ColorWheelModule.js +112 -0
  47. package/examples/jsm/inspector/extensions/color-grading/modules/ContrastModule.js +82 -0
  48. package/examples/jsm/inspector/extensions/color-grading/modules/CurvesModule.js +109 -0
  49. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureHueModule.js +110 -0
  50. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureModule.js +73 -0
  51. package/examples/jsm/inspector/extensions/color-grading/modules/HueModule.js +78 -0
  52. package/examples/jsm/inspector/extensions/color-grading/modules/ImportedCubeModule.js +89 -0
  53. package/examples/jsm/inspector/extensions/color-grading/modules/Module.js +285 -0
  54. package/examples/jsm/inspector/extensions/color-grading/modules/OutputModule.js +101 -0
  55. package/examples/jsm/inspector/extensions/color-grading/modules/RendererModule.js +225 -0
  56. package/examples/jsm/inspector/extensions/color-grading/modules/SatVibranceModule.js +102 -0
  57. package/examples/jsm/inspector/extensions/color-grading/modules/SaturationModule.js +76 -0
  58. package/examples/jsm/inspector/extensions/color-grading/modules/VibranceModule.js +76 -0
  59. package/examples/jsm/inspector/extensions/color-grading/modules/WhiteBalanceModule.js +86 -0
  60. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +26 -31
  61. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -0
  62. package/examples/jsm/inspector/tabs/Memory.js +0 -2
  63. package/examples/jsm/inspector/tabs/Settings.js +4 -0
  64. package/examples/jsm/inspector/tabs/Timeline.js +223 -171
  65. package/examples/jsm/inspector/tabs/Viewer.js +515 -21
  66. package/examples/jsm/inspector/ui/List.js +15 -9
  67. package/examples/jsm/inspector/ui/Profiler.js +170 -14
  68. package/examples/jsm/inspector/ui/Style.js +269 -23
  69. package/examples/jsm/inspector/ui/Tab.js +2 -0
  70. package/examples/jsm/inspector/ui/Values.js +14 -2
  71. package/examples/jsm/interactive/HTMLMesh.js +19 -3
  72. package/examples/jsm/lighting/LightProbeGrid.js +484 -889
  73. package/examples/jsm/lighting/LightProbeGridUtils.js +107 -0
  74. package/examples/jsm/lighting/LightProbeGridWebGL.js +841 -0
  75. package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +194 -0
  76. package/examples/jsm/lighting/vxgi/VXGINode.js +660 -0
  77. package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +478 -0
  78. package/examples/jsm/lighting/vxgi/VXGIVolume.js +1430 -0
  79. package/examples/jsm/lights/SunLight.js +95 -0
  80. package/examples/jsm/lights/SunLightNode.js +56 -0
  81. package/examples/jsm/lights/SunLightShadow.js +319 -0
  82. package/examples/jsm/lights/SunShadowNode.js +312 -0
  83. package/examples/jsm/loaders/3DMLoader.js +150 -49
  84. package/examples/jsm/loaders/3MFLoader.js +202 -1
  85. package/examples/jsm/loaders/FBXLoader.js +81 -5
  86. package/examples/jsm/loaders/GLTFGaussianSplatLoaderExtension.js +330 -0
  87. package/examples/jsm/loaders/GLTFLoader.js +79 -14
  88. package/examples/jsm/loaders/GaussianSplatPLYLoader.js +386 -0
  89. package/examples/jsm/loaders/KSPLATLoader.js +463 -0
  90. package/examples/jsm/loaders/MaterialXLoader.js +111 -1010
  91. package/examples/jsm/loaders/PCDLoader.js +1 -1
  92. package/examples/jsm/loaders/SPLATLoader.js +139 -0
  93. package/examples/jsm/loaders/SPZLoader.js +561 -0
  94. package/examples/jsm/loaders/materialx/MaterialXArchive.js +108 -0
  95. package/examples/jsm/loaders/materialx/MaterialXDocument.js +878 -0
  96. package/examples/jsm/loaders/materialx/MaterialXHextile.js +183 -0
  97. package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +376 -0
  98. package/examples/jsm/loaders/materialx/MaterialXLog.js +75 -0
  99. package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +4 -0
  100. package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +1021 -0
  101. package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +661 -0
  102. package/examples/jsm/loaders/materialx/MaterialXUtils.js +57 -0
  103. package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +997 -0
  104. package/examples/jsm/loaders/materialx/parse/MaterialXParser.js +28 -0
  105. package/examples/jsm/loaders/usd/USDAParser.js +15 -2
  106. package/examples/jsm/loaders/usd/USDCParser.js +1 -4
  107. package/examples/jsm/loaders/usd/USDComposer.js +80 -42
  108. package/examples/jsm/materials/WoodNodeMaterial.js +6 -108
  109. package/examples/jsm/misc/RollerCoaster.js +2 -2
  110. package/examples/jsm/misc/SculptGL.LICENSE.txt +21 -0
  111. package/examples/jsm/misc/Sculptor.js +1679 -0
  112. package/examples/jsm/misc/SculptorMesh.js +1504 -0
  113. package/examples/jsm/misc/SculptorTools.js +1180 -0
  114. package/examples/jsm/misc/SculptorUtils.js +345 -0
  115. package/examples/jsm/misc/TubePainter.js +28 -16
  116. package/examples/jsm/misc/VolumeSlice.js +24 -24
  117. package/examples/jsm/modifiers/SimplifyModifier.js +63 -556
  118. package/examples/jsm/objects/GaussianSplat.js +1039 -0
  119. package/examples/jsm/objects/Sky.js +66 -45
  120. package/examples/jsm/objects/SkyMesh.js +70 -51
  121. package/examples/jsm/physics/JoltPhysics.js +1 -1
  122. package/examples/jsm/postprocessing/AfterimagePass.js +4 -2
  123. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  124. package/examples/jsm/postprocessing/GTAOPass.js +1 -1
  125. package/examples/jsm/postprocessing/OutlinePass.js +5 -5
  126. package/examples/jsm/postprocessing/SAOPass.js +1 -1
  127. package/examples/jsm/postprocessing/SSAOPass.js +1 -1
  128. package/examples/jsm/postprocessing/SSRPass.js +4 -2
  129. package/examples/jsm/postprocessing/SavePass.js +1 -1
  130. package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
  131. package/examples/jsm/postprocessing/UnrealBloomPass.js +30 -13
  132. package/examples/jsm/renderers/CSS2DRenderer.js +29 -5
  133. package/examples/jsm/shaders/DepthLimitedBlurShader.js +4 -1
  134. package/examples/jsm/shaders/ExposureShader.js +1 -1
  135. package/examples/jsm/shaders/FilmShader.js +2 -1
  136. package/examples/jsm/transpiler/AST.js +21 -2
  137. package/examples/jsm/transpiler/GLSLDecoder.js +498 -8
  138. package/examples/jsm/transpiler/TSLEncoder.js +82 -10
  139. package/examples/jsm/transpiler/WGSLEncoder.js +33 -4
  140. package/examples/jsm/tsl/WebGLNodesHandler.js +29 -39
  141. package/examples/jsm/tsl/display/AfterImageNode.js +2 -0
  142. package/examples/jsm/tsl/display/AnaglyphPassNode.js +3 -2
  143. package/examples/jsm/tsl/display/BilateralBlurNode.js +5 -2
  144. package/examples/jsm/tsl/display/BloomNode.js +55 -30
  145. package/examples/jsm/tsl/display/DenoiseNode.js +21 -1
  146. package/examples/jsm/tsl/display/DepthOfFieldNode.js +24 -6
  147. package/examples/jsm/tsl/display/DotScreenNode.js +11 -11
  148. package/examples/jsm/tsl/display/FSR1Node.js +8 -4
  149. package/examples/jsm/tsl/display/GTAONode.js +199 -86
  150. package/examples/jsm/tsl/display/GaussianBlurNode.js +65 -52
  151. package/examples/jsm/tsl/display/GodraysNode.js +5 -2
  152. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +2 -2
  153. package/examples/jsm/tsl/display/LensflareNode.js +5 -2
  154. package/examples/jsm/tsl/display/OITPassNode.js +352 -0
  155. package/examples/jsm/tsl/display/OutlineNode.js +2 -0
  156. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +3 -2
  157. package/examples/jsm/tsl/display/RGBShiftNode.js +9 -9
  158. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +7 -4
  159. package/examples/jsm/tsl/display/RetroPassNode.js +1 -1
  160. package/examples/jsm/tsl/display/SMAANode.js +22 -61
  161. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -4
  162. package/examples/jsm/tsl/display/SSAONode.js +436 -0
  163. package/examples/jsm/tsl/display/SSGINode.js +5 -2
  164. package/examples/jsm/tsl/display/SSRNode.js +7 -2
  165. package/examples/jsm/tsl/display/SSSNode.js +5 -2
  166. package/examples/jsm/tsl/display/SharpenNode.js +5 -4
  167. package/examples/jsm/tsl/display/StereoCompositePassNode.js +1 -3
  168. package/examples/jsm/tsl/display/StereoPassNode.js +1 -3
  169. package/examples/jsm/tsl/display/TAAUNode.js +22 -125
  170. package/examples/jsm/tsl/display/TRAANode.js +16 -142
  171. package/examples/jsm/tsl/display/TemporalReprojectNode.js +21 -15
  172. package/examples/jsm/tsl/display/depthAwareBlur.js +63 -0
  173. package/examples/jsm/tsl/display/hashBlur.js +3 -2
  174. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +38 -27
  175. package/examples/jsm/tsl/lighting/LightProbeGridNode.js +136 -0
  176. package/examples/jsm/tsl/math/voronoiNoise.js +112 -0
  177. package/examples/jsm/tsl/shadows/TileShadowNode.js +4 -6
  178. package/examples/jsm/tsl/utils/Raymarching.js +5 -5
  179. package/examples/jsm/tsl/utils/SoftParticles.js +60 -0
  180. package/examples/jsm/tsl/utils/TAAUtils.js +195 -0
  181. package/examples/jsm/utils/BufferGeometryUtils.js +14 -14
  182. package/examples/jsm/utils/GaussianSplatUtils.js +229 -0
  183. package/examples/jsm/utils/WebGLTextureUtils.js +1 -1
  184. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  185. package/examples/jsm/webxr/WebGLXRFallback.js +2 -16
  186. package/examples/jsm/webxr/XRControllerModelFactory.js +16 -4
  187. package/package.json +9 -16
  188. package/src/Three.Core.js +2 -1
  189. package/src/Three.TSL.js +73 -43
  190. package/src/Three.WebGPU.Nodes.js +1 -0
  191. package/src/Three.WebGPU.js +1 -0
  192. package/src/animation/AnimationClip.js +15 -2
  193. package/src/animation/AnimationObjectGroup.js +18 -6
  194. package/src/animation/AnimationUtils.js +26 -0
  195. package/src/animation/KeyframeTrack.js +37 -0
  196. package/src/constants.js +23 -1
  197. package/src/core/BufferAttribute.js +3 -2
  198. package/src/core/BufferGeometry.js +1 -1
  199. package/src/core/InterleavedBuffer.js +5 -1
  200. package/src/core/Object3D.js +40 -12
  201. package/src/core/Raycaster.js +4 -0
  202. package/src/core/RenderTarget.js +99 -9
  203. package/src/core/RenderTarget3D.js +12 -8
  204. package/src/extras/Controls.js +0 -8
  205. package/src/extras/PMREMGenerator.js +99 -205
  206. package/src/geometries/TorusGeometry.js +1 -1
  207. package/src/helpers/ArrowHelper.js +2 -0
  208. package/src/helpers/AxesHelper.js +2 -0
  209. package/src/helpers/Box3Helper.js +2 -0
  210. package/src/helpers/BoxHelper.js +2 -0
  211. package/src/helpers/CameraHelper.js +2 -0
  212. package/src/helpers/DirectionalLightHelper.js +2 -0
  213. package/src/helpers/GridHelper.js +2 -0
  214. package/src/helpers/HemisphereLightHelper.js +2 -0
  215. package/src/helpers/PlaneHelper.js +2 -0
  216. package/src/helpers/PointLightHelper.js +2 -0
  217. package/src/helpers/PolarGridHelper.js +2 -0
  218. package/src/helpers/SkeletonHelper.js +2 -0
  219. package/src/helpers/SpotLightHelper.js +2 -0
  220. package/src/lights/Light.js +0 -10
  221. package/src/lights/LightShadow.js +43 -12
  222. package/src/lights/SpotLightShadow.js +18 -0
  223. package/src/loaders/BufferGeometryLoader.js +5 -0
  224. package/src/loaders/ImageBitmapLoader.js +3 -1
  225. package/src/loaders/ObjectLoader.js +8 -5
  226. package/src/materials/Material.js +80 -57
  227. package/src/materials/MeshPhysicalMaterial.js +32 -0
  228. package/src/materials/nodes/Line2NodeMaterial.js +17 -8
  229. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +42 -5
  230. package/src/materials/nodes/NodeMaterial.js +19 -13
  231. package/src/materials/nodes/PointsNodeMaterial.js +2 -1
  232. package/src/materials/nodes/manager/NodeMaterialObserver.js +282 -55
  233. package/src/math/Frustum.js +9 -0
  234. package/src/math/FrustumArray.js +1 -1
  235. package/src/math/MathUtils.js +5 -3
  236. package/src/math/Matrix4.js +2 -9
  237. package/src/math/Plane.js +30 -1
  238. package/src/math/Quaternion.js +0 -10
  239. package/src/math/Ray.js +95 -45
  240. package/src/math/Triangle.js +0 -2
  241. package/src/math/Vector3.js +2 -2
  242. package/src/math/Vector4.js +0 -4
  243. package/src/math/interpolants/BezierInterpolant.js +36 -23
  244. package/src/nodes/Nodes.js +2 -0
  245. package/src/nodes/TSL.js +11 -3
  246. package/src/nodes/accessors/Batch.js +85 -13
  247. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  248. package/src/nodes/accessors/BuiltinNode.js +1 -1
  249. package/src/nodes/accessors/Instance.js +19 -18
  250. package/src/nodes/accessors/MaterialNode.js +9 -0
  251. package/src/nodes/accessors/ModelNode.js +85 -9
  252. package/src/nodes/accessors/ReferenceBaseNode.js +1 -70
  253. package/src/nodes/accessors/ReferenceElementNode.js +72 -0
  254. package/src/nodes/accessors/ReferenceNode.js +1 -70
  255. package/src/nodes/accessors/Skinning.js +124 -12
  256. package/src/nodes/accessors/StorageTextureNode.js +7 -3
  257. package/src/nodes/accessors/Texture3DNode.js +1 -1
  258. package/src/nodes/accessors/TextureNode.js +51 -21
  259. package/src/nodes/accessors/TextureSizeNode.js +4 -2
  260. package/src/nodes/accessors/UniformArrayNode.js +30 -5
  261. package/src/nodes/code/CodeNode.js +1 -1
  262. package/src/nodes/code/FunctionNode.js +12 -2
  263. package/src/nodes/core/ArrayNode.js +2 -2
  264. package/src/nodes/core/ContextNode.js +57 -4
  265. package/src/nodes/core/IndexNode.js +69 -4
  266. package/src/nodes/core/InspectorNode.js +2 -2
  267. package/src/nodes/core/MRTNode.js +44 -2
  268. package/src/nodes/core/Node.js +6 -3
  269. package/src/nodes/core/NodeBuilder.js +65 -50
  270. package/src/nodes/core/NodeFrame.js +11 -3
  271. package/src/nodes/core/NodeUtils.js +88 -0
  272. package/src/nodes/core/PropertyNode.js +8 -0
  273. package/src/nodes/core/StackNode.js +0 -1
  274. package/src/nodes/core/StructNode.js +4 -3
  275. package/src/nodes/core/UniformGroupNode.js +3 -2
  276. package/src/nodes/core/UniformNode.js +26 -12
  277. package/src/nodes/core/VarNode.js +0 -1
  278. package/src/nodes/display/BumpMapNode.js +2 -2
  279. package/src/nodes/display/ColorAdjustment.js +1 -1
  280. package/src/nodes/display/PassNode.js +76 -15
  281. package/src/nodes/display/ScreenNode.js +22 -65
  282. package/src/nodes/fog/Fog.js +4 -4
  283. package/src/nodes/functions/BSDF/BRDF_GGX.js +6 -6
  284. package/src/nodes/functions/BSDF/BRDF_Sheen.js +1 -1
  285. package/src/nodes/functions/BSDF/DFGLUT.js +2 -1
  286. package/src/nodes/functions/BSDF/LTC.js +1 -1
  287. package/src/nodes/functions/PhongLightingModel.js +1 -1
  288. package/src/nodes/functions/PhysicalLightingModel.js +83 -25
  289. package/src/nodes/functions/ToonLightingModel.js +2 -2
  290. package/src/nodes/functions/material/getParallaxCorrectNormal.js +3 -3
  291. package/src/nodes/gpgpu/AtomicFunctionNode.js +64 -13
  292. package/src/nodes/gpgpu/BarrierNode.js +13 -4
  293. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
  294. package/src/nodes/gpgpu/ComputeNode.js +20 -17
  295. package/src/nodes/gpgpu/SubgroupFunctionNode.js +165 -37
  296. package/src/nodes/gpgpu/WorkgroupInfoNode.js +44 -6
  297. package/src/nodes/lighting/EnvironmentNode.js +40 -4
  298. package/src/nodes/lighting/LightsNode.js +20 -4
  299. package/src/nodes/lighting/ShadowBaseNode.js +158 -1
  300. package/src/nodes/lighting/ShadowFilterNode.js +2 -106
  301. package/src/nodes/lighting/ShadowNode.js +22 -91
  302. package/src/nodes/materialx/{lib/mx_hsv.js → MaterialXColor.js} +3 -6
  303. package/src/nodes/materialx/{lib/mx_transform_color.js → MaterialXColorTransform.js} +3 -6
  304. package/src/nodes/materialx/MaterialXCore.js +37 -0
  305. package/src/nodes/materialx/MaterialXNodes.js +64 -72
  306. package/src/nodes/materialx/{lib/mx_noise.js → MaterialXNoise.js} +426 -197
  307. package/src/nodes/math/BitcountNode.js +24 -4
  308. package/src/nodes/math/MathNode.js +4 -4
  309. package/src/nodes/math/MathUtils.js +15 -4
  310. package/src/nodes/math/OperatorNode.js +2 -2
  311. package/src/nodes/math/PackFloatNode.js +29 -1
  312. package/src/nodes/math/Packed4x8IntegerNode.js +433 -0
  313. package/src/nodes/math/UnpackFloatNode.js +30 -2
  314. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  315. package/src/nodes/pmrem/PMREMNode.js +1 -1
  316. package/src/nodes/pmrem/PMREMUtils.js +31 -74
  317. package/src/nodes/shapes/Shapes.js +1 -1
  318. package/src/nodes/tsl/TSLCore.js +1 -31
  319. package/src/nodes/utils/EventNode.js +75 -0
  320. package/src/nodes/utils/LoopNode.js +54 -13
  321. package/src/nodes/utils/PostProcessingUtils.js +23 -2
  322. package/src/nodes/utils/RTTNode.js +97 -32
  323. package/src/nodes/utils/ReflectorNode.js +8 -4
  324. package/src/nodes/utils/RotateNode.js +85 -8
  325. package/src/nodes/utils/SpriteUtils.js +58 -23
  326. package/src/objects/BatchedMesh.js +6 -0
  327. package/src/objects/InstancedMesh.js +1 -1
  328. package/src/objects/LOD.js +1 -1
  329. package/src/objects/Line.js +12 -0
  330. package/src/objects/Mesh.js +12 -0
  331. package/src/objects/Points.js +12 -0
  332. package/src/objects/Sprite.js +12 -0
  333. package/src/renderers/WebGLRenderer.js +93 -27
  334. package/src/renderers/common/Animation.js +12 -2
  335. package/src/renderers/common/Backend.js +38 -10
  336. package/src/renderers/common/BindGroup.js +0 -1
  337. package/src/renderers/common/Bindings.js +50 -4
  338. package/src/renderers/common/BundleGroup.js +4 -0
  339. package/src/renderers/common/ClippingContext.js +11 -1
  340. package/src/renderers/common/Color4.js +9 -0
  341. package/src/renderers/common/Constants.js +0 -5
  342. package/src/renderers/common/DirectRenderPipeline.js +233 -0
  343. package/src/renderers/common/Geometries.js +24 -3
  344. package/src/renderers/common/Info.js +3 -3
  345. package/src/renderers/common/InspectorBase.js +37 -8
  346. package/src/renderers/common/Lighting.js +11 -4
  347. package/src/renderers/common/Pipelines.js +6 -4
  348. package/src/renderers/common/QuadMesh.js +16 -2
  349. package/src/renderers/common/RenderContext.js +8 -0
  350. package/src/renderers/common/RenderList.js +53 -19
  351. package/src/renderers/common/RenderLists.js +58 -11
  352. package/src/renderers/common/RenderObject.js +14 -0
  353. package/src/renderers/common/RenderObjects.js +14 -9
  354. package/src/renderers/common/RenderPipeline.js +52 -44
  355. package/src/renderers/common/Renderer.js +226 -55
  356. package/src/renderers/common/Storage3DTexture.js +16 -0
  357. package/src/renderers/common/Textures.js +3 -3
  358. package/src/renderers/common/XRManager.js +79 -72
  359. package/src/renderers/common/extras/PMREMGenerator.js +76 -144
  360. package/src/renderers/common/nodes/NodeManager.js +144 -6
  361. package/src/renderers/common/nodes/NodeStorageBuffer.js +3 -1
  362. package/src/renderers/common/nodes/NodeUniformBuffer.js +3 -1
  363. package/src/renderers/shaders/DFGLUTData.js +2 -1
  364. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +4 -2
  365. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +48 -0
  366. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +53 -4
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +20 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +20 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +61 -57
  371. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +82 -0
  372. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +9 -0
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +8 -1
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +15 -0
  375. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  376. package/src/renderers/shaders/ShaderLib.js +1 -0
  377. package/src/renderers/shaders/UniformsLib.js +16 -0
  378. package/src/renderers/webgl/WebGLAnimation.js +2 -2
  379. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  380. package/src/renderers/webgl/WebGLLights.js +74 -4
  381. package/src/renderers/webgl/WebGLMaterials.js +6 -0
  382. package/src/renderers/webgl/WebGLOutput.js +36 -24
  383. package/src/renderers/webgl/WebGLProgram.js +3 -0
  384. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  385. package/src/renderers/webgl/WebGLRenderLists.js +6 -10
  386. package/src/renderers/webgl/WebGLShadowMap.js +47 -44
  387. package/src/renderers/webgl/WebGLTextures.js +7 -7
  388. package/src/renderers/webgl-fallback/WebGLBackend.js +153 -45
  389. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +83 -29
  390. package/src/renderers/webgl-fallback/utils/WebGLState.js +163 -17
  391. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +32 -5
  392. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +11 -4
  393. package/src/renderers/webgpu/WebGPUBackend.js +513 -145
  394. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -20
  395. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -1
  396. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +3 -12
  397. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +24 -14
  398. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +80 -14
  399. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -7
  400. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +9 -3
  401. package/src/renderers/webgpu/utils/WebGPUUtils.js +16 -4
  402. package/src/renderers/webxr/WebXRManager.js +25 -2
  403. package/src/scenes/Scene.js +3 -3
  404. package/src/textures/CompressedArrayTexture.js +16 -0
  405. package/src/textures/Data3DTexture.js +16 -0
  406. package/src/textures/DataArrayTexture.js +16 -0
  407. package/src/textures/DepthTexture.js +3 -3
  408. package/src/textures/Texture.js +3 -3
  409. package/src/textures/{Source.js → TextureSource.js} +39 -8
  410. package/src/utils.js +6 -79
  411. package/build/three.core.min.js +0 -6
  412. package/build/three.module.min.js +0 -6
  413. package/build/three.tsl.min.js +0 -6
  414. package/build/three.webgpu.min.js +0 -6
  415. package/build/three.webgpu.nodes.min.js +0 -6
  416. package/examples/jsm/libs/ecsy.module.js +0 -1792
  417. package/examples/jsm/loaders/LottieLoader.js +0 -130
  418. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +0 -52
@@ -1,5 +1,5 @@
1
1
  import { TempNode } from '@gnsx/three/webgpu';
2
- import { Fn, uv, uniform, vec2, sin, cos, vec4, convertToTexture } from '@gnsx/three/tsl';
2
+ import { nodeObject, Fn, uv, vec2, sin, cos, vec4, convertToTexture } from '@gnsx/three/tsl';
3
3
 
4
4
  /**
5
5
  * Post processing node for shifting/splitting RGB color channels. The effect
@@ -20,8 +20,8 @@ class RGBShiftNode extends TempNode {
20
20
  * Constructs a new RGB shift node.
21
21
  *
22
22
  * @param {TextureNode} textureNode - The texture node that represents the input of the effect.
23
- * @param {number} [amount=0.005] - The amount of the RGB shift.
24
- * @param {number} [angle=0] - Defines the orientation in which colors are shifted.
23
+ * @param {number|Node<float>} [amount=0.005] - The amount of the RGB shift.
24
+ * @param {number|Node<float>} [angle=0] - Defines the orientation in which colors are shifted.
25
25
  */
26
26
  constructor( textureNode, amount = 0.005, angle = 0 ) {
27
27
 
@@ -37,16 +37,16 @@ class RGBShiftNode extends TempNode {
37
37
  /**
38
38
  * The amount of the RGB shift.
39
39
  *
40
- * @type {UniformNode<float>}
40
+ * @type {Node<float>}
41
41
  */
42
- this.amount = uniform( amount );
42
+ this.amount = nodeObject( amount );
43
43
 
44
44
  /**
45
45
  * Defines in which direction colors are shifted.
46
46
  *
47
- * @type {UniformNode<float>}
47
+ * @type {Node<float>}
48
48
  */
49
- this.angle = uniform( angle );
49
+ this.angle = nodeObject( angle );
50
50
 
51
51
  }
52
52
 
@@ -89,8 +89,8 @@ export default RGBShiftNode;
89
89
  * @tsl
90
90
  * @function
91
91
  * @param {Node<vec4>} node - The node that represents the input of the effect.
92
- * @param {number} [amount=0.005] - The amount of the RGB shift.
93
- * @param {number} [angle=0] - Defines in which direction colors are shifted.
92
+ * @param {number|Node<float>} [amount=0.005] - The amount of the RGB shift.
93
+ * @param {number|Node<float>} [angle=0] - Defines in which direction colors are shifted.
94
94
  * @returns {RGBShiftNode}
95
95
  */
96
96
  export const rgbShift = ( node, amount, angle ) => new RGBShiftNode( convertToTexture( node ), amount, angle );
@@ -1,4 +1,4 @@
1
- import { abs, atan, bool, convertToTexture, cos, cross, Discard, dot, EPSILON, exp, float, Fn, getScreenPosition, getViewPosition, If, int, log, Loop, luminance, mat2, max, mix, nodeObject, NodeUpdateType, normalize, passTexture, PI, property, reflect, sin, smoothstep, sqrt, tan, texture, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4 } from '@gnsx/three/tsl';
1
+ import { abs, atan, bool, convertToTexture, cos, cross, Discard, dot, EPSILON, exp, float, Fn, getScreenPosition, getViewPosition, If, int, log, Loop, luminance, mat2, max, mix, nodeObject, NodeUpdateType, normalize, passTexture, PI, property, reflect, sin, smoothstep, sqrt, tan, texture, uniform, unpackRGBToNormal, uv, vec2, vec3, vec4, context } from '@gnsx/three/tsl';
2
2
  import { HalfFloatType, MathUtils, Matrix4, NodeMaterial, QuadMesh, RendererUtils, RenderTarget, TempNode, Vector2 } from '@gnsx/three/webgpu';
3
3
  import { bindAnalyticNoise } from '../utils/RNoise.js';
4
4
  import { ENV_RAY_LENGTH_THRESHOLD } from '../utils/SpecularHelpers.js';
@@ -606,7 +606,7 @@ class RecurrentDenoiseNode extends TempNode {
606
606
  const runDenoise = () => {
607
607
 
608
608
  const viewNormal = sampleNormal( uvCoord ).toConst();
609
- const worldNormal = viewNormal.transformDirection( this._viewMatrix ).toConst();
609
+ const worldNormal = viewNormal.transformNormalByInverseViewMatrix( this._viewMatrix ).toConst();
610
610
  const texel = sampleTexture( uvCoord ).max( 0 ).toConst();
611
611
 
612
612
  const viewPosition = getViewPosition( uvCoord, depth, this._cameraProjectionMatrixInverse ).toConst();
@@ -796,7 +796,7 @@ class RecurrentDenoiseNode extends TempNode {
796
796
  if ( this.mode === 'specular' ) kernelDiff.addAssign( ( abs( roughness.sub( sampleRoughnessMetalness( sampleUv ).g ) ).mul( this.roughnessPhi ) ) );
797
797
 
798
798
  const nViewNormal = sampleNormal( sampleUv );
799
- const nWorldNormal = nViewNormal.transformDirection( this._viewMatrix );
799
+ const nWorldNormal = nViewNormal.transformNormalByInverseViewMatrix( this._viewMatrix );
800
800
  const distToPlane = planeDistance( viewPosition, nViewPosition, viewNormal );
801
801
 
802
802
  // Geometric edge stopping (depth and normal)
@@ -880,7 +880,8 @@ class RecurrentDenoiseNode extends TempNode {
880
880
 
881
881
  } );
882
882
 
883
- this._material.fragmentNode = denoiseFn( uv() ).context( builder.getSharedContext() );
883
+ this._material.contextNode = context( builder.getSharedContext() );
884
+ this._material.fragmentNode = denoiseFn( uv() );
884
885
  this._material.needsUpdate = true;
885
886
 
886
887
  return this._textureNode;
@@ -889,6 +890,8 @@ class RecurrentDenoiseNode extends TempNode {
889
890
 
890
891
  dispose() {
891
892
 
893
+ super.dispose();
894
+
892
895
  this._renderTarget.dispose();
893
896
  this._material.dispose();
894
897
 
@@ -158,7 +158,7 @@ class RetroPassNode extends PassNode {
158
158
 
159
159
  let finalUV;
160
160
 
161
- if ( texture.isCubeTextureNode ) {
161
+ if ( texture.isCubeTextureNode ) {
162
162
 
163
163
  finalUV = reflectVector;
164
164
 
@@ -1,5 +1,5 @@
1
1
  import { HalfFloatType, LinearFilter, NearestFilter, RenderTarget, Texture, Vector2, QuadMesh, NodeMaterial, TempNode, RendererUtils } from '@gnsx/three/webgpu';
2
- import { abs, Fn, NodeUpdateType, uv, uniform, convertToTexture, varyingProperty, vec2, vec4, modelViewProjection, passTexture, max, step, dot, float, texture, If, Loop, int, Break, sqrt, sign, mix } from '@gnsx/three/tsl';
2
+ import { abs, Fn, NodeUpdateType, uv, uniform, convertToTexture, vec2, vec4, passTexture, max, step, dot, float, texture, If, Loop, int, Break, sqrt, sign, mix, context } from '@gnsx/three/tsl';
3
3
 
4
4
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
5
  const _size = /*@__PURE__*/ new Vector2();
@@ -292,25 +292,11 @@ class SMAANode extends TempNode {
292
292
 
293
293
  // edges
294
294
 
295
- const SMAAEdgeDetectionVS = Fn( () => {
295
+ const SMAAEdgeDetection = Fn( () => {
296
296
 
297
- const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 1.0, 0.0, 0.0, - 1.0 ) ) );
298
- const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) );
299
- const vOffset2 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 2.0, 0.0, 0.0, - 2.0 ) ) );
300
-
301
- varyingProperty( 'vec4', 'vOffset0' ).assign( vOffset0 );
302
- varyingProperty( 'vec4', 'vOffset1' ).assign( vOffset1 );
303
- varyingProperty( 'vec4', 'vOffset2' ).assign( vOffset2 );
304
-
305
- return modelViewProjection;
306
-
307
- } );
308
-
309
- const SMAAEdgeDetectionFS = Fn( () => {
310
-
311
- const vOffset0 = varyingProperty( 'vec4', 'vOffset0' );
312
- const vOffset1 = varyingProperty( 'vec4', 'vOffset1' );
313
- const vOffset2 = varyingProperty( 'vec4', 'vOffset2' );
297
+ const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 1.0, 0.0, 0.0, - 1.0 ) ) ).toVertexStage();
298
+ const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) ).toVertexStage();
299
+ const vOffset2 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 2.0, 0.0, 0.0, - 2.0 ) ) ).toVertexStage();
314
300
 
315
301
  const threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );
316
302
 
@@ -513,32 +499,16 @@ class SMAANode extends TempNode {
513
499
 
514
500
  } );
515
501
 
516
- const SMAAWeightsVS = Fn( () => {
502
+ const SMAAWeights = Fn( () => {
517
503
 
518
- const vPixcoord = uvNode.xy.div( this._invSize );
504
+ const vPixcoord = uvNode.xy.div( this._invSize ).toVertexStage();
519
505
 
520
506
  // We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
521
- const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.25, - 0.125, 1.25, - 0.125 ) ) ).toVar();
522
- const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.125, - 0.25, - 0.125, 1.25 ) ) ).toVar();
507
+ const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.25, - 0.125, 1.25, - 0.125 ) ) ).toVertexStage();
508
+ const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 0.125, - 0.25, - 0.125, 1.25 ) ) ).toVertexStage();
523
509
 
524
510
  // And these for the searches, they indicate the ends of the loops:
525
- const vOffset2 = vec4( vOffset0.xz, vOffset1.yw ).add( vec4( - 2.0, 2.0, - 2.0, 2.0 ).mul( vec4( this._invSize.xx, this._invSize.yy ) ).mul( float( SMAA_MAX_SEARCH_STEPS ) ) ).toVar();
526
-
527
- varyingProperty( 'vec2', 'vPixcoord' ).assign( vPixcoord );
528
- varyingProperty( 'vec4', 'vOffset0' ).assign( vOffset0 );
529
- varyingProperty( 'vec4', 'vOffset1' ).assign( vOffset1 );
530
- varyingProperty( 'vec4', 'vOffset2' ).assign( vOffset2 );
531
-
532
- return modelViewProjection;
533
-
534
- } );
535
-
536
- const SMAAWeightsFS = Fn( () => {
537
-
538
- const vPixcoord = varyingProperty( 'vec2', 'vPixcoord' );
539
- const vOffset0 = varyingProperty( 'vec4', 'vOffset0' );
540
- const vOffset1 = varyingProperty( 'vec4', 'vOffset1' );
541
- const vOffset2 = varyingProperty( 'vec4', 'vOffset2' );
511
+ const vOffset2 = vec4( vOffset0.xz, vOffset1.yw ).add( vec4( - 2.0, 2.0, - 2.0, 2.0 ).mul( vec4( this._invSize.xx, this._invSize.yy ) ).mul( float( SMAA_MAX_SEARCH_STEPS ) ) ).toVertexStage();
542
512
 
543
513
  const weights = vec4( 0.0, 0.0, 0.0, 0.0 ).toVar();
544
514
  const subsampleIndices = vec4( 0.0, 0.0, 0.0, 0.0 ).toVar();
@@ -623,22 +593,9 @@ class SMAANode extends TempNode {
623
593
 
624
594
  // blend
625
595
 
626
- const SMAABlendVS = Fn( () => {
627
-
628
- //const vOffset0 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( - 1.0, 0.0, 0.0, - 1.0 ) ) );
629
- const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) );
630
-
631
- //varyingProperty( 'vec4', 'vOffset0' ).assign( vOffset0 );
632
- varyingProperty( 'vec4', 'vOffset1' ).assign( vOffset1 );
633
-
634
- return modelViewProjection;
596
+ const SMAABlend = Fn( () => {
635
597
 
636
- } );
637
-
638
- const SMAABlendFS = Fn( () => {
639
-
640
- //const vOffset0 = varyingProperty( 'vec4', 'vOffset0' );
641
- const vOffset1 = varyingProperty( 'vec4', 'vOffset1' );
598
+ const vOffset1 = vec4( uvNode.xy, uvNode.xy ).add( vec4( this._invSize.xy, this._invSize.xy ).mul( vec4( 1.0, 0.0, 0.0, 1.0 ) ) ).toVertexStage();
642
599
  const result = vec4().toVar();
643
600
 
644
601
  // Fetch the blending weights for current pixel:
@@ -694,16 +651,18 @@ class SMAANode extends TempNode {
694
651
 
695
652
  } );
696
653
 
697
- this._materialEdges.vertexNode = SMAAEdgeDetectionVS().context( builder.getSharedContext() );
698
- this._materialEdges.fragmentNode = SMAAEdgeDetectionFS().context( builder.getSharedContext() );
654
+ const sharedContext = context( builder.getSharedContext() );
655
+
656
+ this._materialEdges.contextNode = sharedContext;
657
+ this._materialEdges.fragmentNode = SMAAEdgeDetection();
699
658
  this._materialEdges.needsUpdate = true;
700
659
 
701
- this._materialWeights.vertexNode = SMAAWeightsVS().context( builder.getSharedContext() );
702
- this._materialWeights.fragmentNode = SMAAWeightsFS().context( builder.getSharedContext() );
660
+ this._materialWeights.contextNode = sharedContext;
661
+ this._materialWeights.fragmentNode = SMAAWeights();
703
662
  this._materialWeights.needsUpdate = true;
704
663
 
705
- this._materialBlend.vertexNode = SMAABlendVS().context( builder.getSharedContext() );
706
- this._materialBlend.fragmentNode = SMAABlendFS().context( builder.getSharedContext() );
664
+ this._materialBlend.contextNode = sharedContext;
665
+ this._materialBlend.fragmentNode = SMAABlend();
707
666
  this._materialBlend.needsUpdate = true;
708
667
 
709
668
  return this._textureNode;
@@ -716,6 +675,8 @@ class SMAANode extends TempNode {
716
675
  */
717
676
  dispose() {
718
677
 
678
+ super.dispose();
679
+
719
680
  this._renderTargetEdges.dispose();
720
681
  this._renderTargetWeights.dispose();
721
682
  this._renderTargetBlend.dispose();
@@ -32,7 +32,7 @@ class SSAAPassNode extends PassNode {
32
32
  */
33
33
  constructor( scene, camera ) {
34
34
 
35
- super( PassNode.COLOR, scene, camera );
35
+ super( PassNode.COLOR, scene, camera, { samples: 0 } );
36
36
 
37
37
  /**
38
38
  * This flag can be used for type testing.
@@ -99,9 +99,7 @@ class SSAAPassNode extends PassNode {
99
99
 
100
100
  //
101
101
 
102
- this._pixelRatio = renderer.getPixelRatio();
103
-
104
- const size = renderer.getSize( _size );
102
+ const size = renderer.getDrawingBufferSize( _size );
105
103
 
106
104
  this.setSize( size.width, size.height );
107
105
  this._sampleRenderTarget.setSize( this.renderTarget.width, this.renderTarget.height );
@@ -0,0 +1,436 @@
1
+ import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, RedFormat } from '@gnsx/three/webgpu';
2
+ import { reference, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, getScreenPositionFromClip, vogelDiskSample, interleavedGradientNoise, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec4, int, dot, max, clamp, length, screenCoordinate, PI2, texture, passTexture, context } from '@gnsx/three/tsl';
3
+ import { depthAwareBlur } from './depthAwareBlur.js';
4
+
5
+ const _quadMesh = /*@__PURE__*/ new QuadMesh();
6
+ const _size = /*@__PURE__*/ new Vector2();
7
+
8
+ let _rendererState;
9
+
10
+ /**
11
+ * Post processing node for a fast, screen-space ambient occlusion (SSAO).
12
+ *
13
+ * It point-samples a per-pixel rotated Vogel disk and estimates obscurance with a single depth tap
14
+ * per sample, trading the ground-truth accuracy of {@link GTAONode}'s horizon ray-marching for
15
+ * lower cost. A built-in separable, depth-aware blur denoises the result so it can be used without
16
+ * temporal accumulation.
17
+ * ```js
18
+ * const scenePass = pass( scene, camera );
19
+ * scenePass.setMRT( mrt( { output, normal: normalView } ) );
20
+ * const scenePassColor = scenePass.getTextureNode( 'output' );
21
+ * const scenePassDepth = scenePass.getTextureNode( 'depth' );
22
+ * const scenePassNormal = scenePass.getTextureNode( 'normal' );
23
+ *
24
+ * const aoPass = ssao( scenePassDepth, scenePassNormal, camera );
25
+ *
26
+ * renderPipeline.outputNode = scenePassColor.mul( aoPass.r );
27
+ * ```
28
+ *
29
+ * @augments TempNode
30
+ * @three_import import { ssao } from 'three/addons/tsl/display/SSAONode.js';
31
+ */
32
+ class SSAONode extends TempNode {
33
+
34
+ static get type() {
35
+
36
+ return 'SSAONode';
37
+
38
+ }
39
+
40
+ /**
41
+ * Constructs a new SSAO node.
42
+ *
43
+ * @param {Node<float>} depthNode - A node that represents the scene's depth.
44
+ * @param {Node<vec3>} normalNode - A node that represents the scene's normals.
45
+ * @param {Camera} camera - The camera the scene is rendered with.
46
+ */
47
+ constructor( depthNode, normalNode, camera ) {
48
+
49
+ super( 'float' );
50
+
51
+ /**
52
+ * A node that represents the scene's depth.
53
+ *
54
+ * @type {Node<float>}
55
+ */
56
+ this.depthNode = depthNode;
57
+
58
+ /**
59
+ * A node that represents the scene's normals.
60
+ *
61
+ * @type {Node<vec3>}
62
+ */
63
+ this.normalNode = normalNode;
64
+
65
+ /**
66
+ * The resolution scale. The effect renders at a fraction of the drawing buffer
67
+ * for extra speed; `0.5` is a good default for a low-frequency signal like AO.
68
+ *
69
+ * @type {number}
70
+ * @default 0.5
71
+ */
72
+ this.resolutionScale = 0.5;
73
+
74
+ /**
75
+ * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
76
+ * its effect once per frame in `updateBefore()`.
77
+ *
78
+ * @type {string}
79
+ * @default 'frame'
80
+ */
81
+ this.updateBeforeType = NodeUpdateType.FRAME;
82
+
83
+ /**
84
+ * The world-space radius the occlusion is gathered within.
85
+ *
86
+ * @type {UniformNode<float>}
87
+ */
88
+ this.radius = uniform( 0.5 );
89
+
90
+ /**
91
+ * The strength of the occlusion.
92
+ *
93
+ * @type {UniformNode<float>}
94
+ */
95
+ this.intensity = uniform( 1 );
96
+
97
+ /**
98
+ * An angle bias that suppresses self-occlusion on near-flat surfaces.
99
+ *
100
+ * @type {UniformNode<float>}
101
+ */
102
+ this.bias = uniform( 0.025 );
103
+
104
+ /**
105
+ * How many samples are used to estimate the occlusion. A higher value
106
+ * results in a smoother result at a higher runtime cost.
107
+ *
108
+ * @type {UniformNode<float>}
109
+ */
110
+ this.samples = uniform( 16 );
111
+
112
+ /**
113
+ * Whether the depth-aware blur that denoises the raw AO is applied or not.
114
+ *
115
+ * @type {boolean}
116
+ * @default true
117
+ */
118
+ this.blurEnabled = true;
119
+
120
+ /**
121
+ * How strongly the blur rejects samples across depth discontinuities,
122
+ * relative to the AO radius. A higher value keeps edges crisper.
123
+ *
124
+ * @type {UniformNode<float>}
125
+ */
126
+ this.blurSharpness = uniform( 2 );
127
+
128
+ /**
129
+ * The resolution of the effect. Set from the drawing buffer size and `resolutionScale`.
130
+ *
131
+ * @type {Vector2}
132
+ */
133
+ this.resolution = new Vector2();
134
+
135
+ /**
136
+ * The render target the raw ambient occlusion is rendered into. Also holds the
137
+ * final result after the separable blur has ping-ponged back into it.
138
+ *
139
+ * @private
140
+ * @type {RenderTarget}
141
+ */
142
+ this._aoRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, format: RedFormat } );
143
+ this._aoRenderTarget.texture.name = 'SSAONode.AO';
144
+
145
+ /**
146
+ * The render target the intermediate (horizontally blurred) result is rendered into.
147
+ *
148
+ * @private
149
+ * @type {RenderTarget}
150
+ */
151
+ this._blurRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, format: RedFormat } );
152
+ this._blurRenderTarget.texture.name = 'SSAONode.Blur';
153
+
154
+ /**
155
+ * Represents the projection matrix of the scene's camera.
156
+ *
157
+ * @private
158
+ * @type {UniformNode<mat4>}
159
+ */
160
+ this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
161
+
162
+ /**
163
+ * Represents the inverse projection matrix of the scene's camera.
164
+ *
165
+ * @private
166
+ * @type {UniformNode<mat4>}
167
+ */
168
+ this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
169
+
170
+ /**
171
+ * Represents the near value of the scene's camera.
172
+ *
173
+ * @private
174
+ * @type {ReferenceNode<float>}
175
+ */
176
+ this._cameraNear = reference( 'near', 'float', camera );
177
+
178
+ /**
179
+ * Represents the far value of the scene's camera.
180
+ *
181
+ * @private
182
+ * @type {ReferenceNode<float>}
183
+ */
184
+ this._cameraFar = reference( 'far', 'float', camera );
185
+
186
+ /**
187
+ * The camera the scene is rendered with.
188
+ *
189
+ * @private
190
+ * @type {Camera}
191
+ */
192
+ this._camera = camera;
193
+
194
+ /**
195
+ * The input texture the blur material reads from. Swapped between the two render
196
+ * targets to run the horizontal and vertical passes with a single material.
197
+ *
198
+ * @private
199
+ * @type {TextureNode}
200
+ */
201
+ this._blurInput = texture( this._aoRenderTarget.texture );
202
+
203
+ /**
204
+ * The blur direction (one texel along x or y).
205
+ *
206
+ * @private
207
+ * @type {UniformNode<vec2>}
208
+ */
209
+ this._blurDirection = uniform( new Vector2() );
210
+
211
+ /**
212
+ * The material that computes the raw ambient occlusion.
213
+ *
214
+ * @private
215
+ * @type {NodeMaterial}
216
+ */
217
+ this._aoMaterial = new NodeMaterial();
218
+ this._aoMaterial.name = 'SSAO.AO';
219
+
220
+ /**
221
+ * The material that applies the separable, depth-aware blur.
222
+ *
223
+ * @private
224
+ * @type {NodeMaterial}
225
+ */
226
+ this._blurMaterial = new NodeMaterial();
227
+ this._blurMaterial.name = 'SSAO.Blur';
228
+
229
+ /**
230
+ * The result of the effect is represented as a separate texture node.
231
+ *
232
+ * @private
233
+ * @type {PassTextureNode}
234
+ */
235
+ this._textureNode = passTexture( this, this._aoRenderTarget.texture );
236
+
237
+ }
238
+
239
+ /**
240
+ * Returns the result of the effect as a texture node.
241
+ *
242
+ * @return {PassTextureNode} A texture node that represents the result of the effect.
243
+ */
244
+ getTextureNode() {
245
+
246
+ return this._textureNode;
247
+
248
+ }
249
+
250
+ /**
251
+ * Sets the size of the effect.
252
+ *
253
+ * @param {number} width - The width of the effect.
254
+ * @param {number} height - The height of the effect.
255
+ */
256
+ setSize( width, height ) {
257
+
258
+ width = Math.max( 1, Math.round( this.resolutionScale * width ) );
259
+ height = Math.max( 1, Math.round( this.resolutionScale * height ) );
260
+
261
+ this.resolution.set( width, height );
262
+ this._aoRenderTarget.setSize( width, height );
263
+ this._blurRenderTarget.setSize( width, height );
264
+
265
+ }
266
+
267
+ /**
268
+ * This method is used to render the effect once per frame.
269
+ *
270
+ * @param {NodeFrame} frame - The current node frame.
271
+ */
272
+ updateBefore( frame ) {
273
+
274
+ const { renderer } = frame;
275
+
276
+ _rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
277
+
278
+ const size = renderer.getDrawingBufferSize( _size );
279
+ this.setSize( size.width, size.height );
280
+
281
+ renderer.setClearColor( 0xffffff, 1 );
282
+
283
+ // ambient occlusion
284
+
285
+ _quadMesh.material = this._aoMaterial;
286
+ _quadMesh.name = 'SSAO.AO';
287
+ renderer.setRenderTarget( this._aoRenderTarget );
288
+ _quadMesh.render( renderer );
289
+
290
+ // separable, depth-aware blur: horizontal ( AO -> blur ) then vertical ( blur -> AO )
291
+
292
+ if ( this.blurEnabled === true ) {
293
+
294
+ _quadMesh.material = this._blurMaterial;
295
+ _quadMesh.name = 'SSAO.Blur';
296
+
297
+ this._blurInput.value = this._aoRenderTarget.texture;
298
+ this._blurDirection.value.set( 1 / this.resolution.x, 0 );
299
+ renderer.setRenderTarget( this._blurRenderTarget );
300
+ _quadMesh.render( renderer );
301
+
302
+ this._blurInput.value = this._blurRenderTarget.texture;
303
+ this._blurDirection.value.set( 0, 1 / this.resolution.y );
304
+ renderer.setRenderTarget( this._aoRenderTarget );
305
+ _quadMesh.render( renderer );
306
+
307
+ }
308
+
309
+ RendererUtils.restoreRendererState( renderer, _rendererState );
310
+
311
+ }
312
+
313
+ /**
314
+ * This method is used to setup the effect's TSL code.
315
+ *
316
+ * @param {NodeBuilder} builder - The current node builder.
317
+ * @return {PassTextureNode}
318
+ */
319
+ setup( builder ) {
320
+
321
+ const uvNode = uv();
322
+
323
+ const sampleDepth = ( uv ) => {
324
+
325
+ const depth = this.depthNode.sample( uv ).r;
326
+
327
+ if ( builder.renderer.logarithmicDepthBuffer === true ) {
328
+
329
+ const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
330
+
331
+ return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
332
+
333
+ }
334
+
335
+ return depth;
336
+
337
+ };
338
+
339
+ // ambient occlusion
340
+
341
+ const ao = Fn( () => {
342
+
343
+ const depth = sampleDepth( uvNode ).toVar();
344
+
345
+ depth.greaterThanEqual( 1.0 ).discard();
346
+
347
+ const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar();
348
+ const viewNormal = this.normalNode.sample( uvNode ).rgb.normalize().toVar();
349
+
350
+ // a low-discrepancy Vogel disk rotated per-pixel decorrelates the samples spatially,
351
+ // so a small blur is enough to hide the sampling pattern
352
+
353
+ const phi = interleavedGradientNoise( screenCoordinate ).mul( PI2 ).toVar();
354
+ const samples = this.samples;
355
+
356
+ // the fragment's clip position is loop-invariant; projection is linear, so each
357
+ // sample only has to project its (view-plane) offset and add it
358
+
359
+ const clipPosition = this._cameraProjectionMatrix.mul( vec4( viewPosition, 1.0 ) ).toVar();
360
+
361
+ const occlusion = float( 0 ).toVar();
362
+
363
+ Loop( { start: int( 0 ), end: samples, type: 'int', condition: '<' }, ( { i } ) => {
364
+
365
+ // disk offset in the view-aligned plane at the fragment's depth, then reprojected
366
+
367
+ const offset = vogelDiskSample( i, samples, phi ).mul( this.radius );
368
+ const clipOffset = this._cameraProjectionMatrix.mul( vec4( offset, 0.0, 0.0 ) );
369
+ const sampleUv = getScreenPositionFromClip( clipPosition.add( clipOffset ) );
370
+
371
+ const sampleViewPosition = getViewPosition( sampleUv, sampleDepth( sampleUv ), this._cameraProjectionMatrixInverse );
372
+
373
+ // normalized obscurance: only occluders above the tangent plane count, faded by distance
374
+
375
+ const v = sampleViewPosition.sub( viewPosition ).toVar();
376
+ const dist = length( v ).toVar();
377
+ const cosAngle = dot( v, viewNormal ).div( max( dist, float( 0.0001 ) ) );
378
+ const falloff = this.radius.div( this.radius.add( dist ) );
379
+
380
+ occlusion.addAssign( max( cosAngle.sub( this.bias ), 0.0 ).mul( falloff ) );
381
+
382
+ } );
383
+
384
+ return clamp( occlusion.div( samples ).mul( this.intensity ).oneMinus(), 0.0, 1.0 );
385
+
386
+ } );
387
+
388
+ const sharedContext = context( builder.getSharedContext() );
389
+
390
+ // compute ambient occlusion
391
+
392
+ this._aoMaterial.contextNode = sharedContext;
393
+ this._aoMaterial.fragmentNode = ao();
394
+ this._aoMaterial.needsUpdate = true;
395
+
396
+ // separable, depth-aware blur ( run horizontally then vertically via `_blurDirection` )
397
+
398
+ this._blurMaterial.contextNode = sharedContext;
399
+ this._blurMaterial.fragmentNode = depthAwareBlur( this._blurInput, this.depthNode, this._blurDirection, this._camera, this.blurSharpness, this.radius );
400
+ this._blurMaterial.needsUpdate = true;
401
+
402
+ return this._textureNode;
403
+
404
+ }
405
+
406
+ /**
407
+ * Frees internal resources. This method should be called
408
+ * when the effect is no longer required.
409
+ */
410
+ dispose() {
411
+
412
+ super.dispose();
413
+
414
+ this._aoRenderTarget.dispose();
415
+ this._blurRenderTarget.dispose();
416
+
417
+ this._aoMaterial.dispose();
418
+ this._blurMaterial.dispose();
419
+
420
+ }
421
+
422
+ }
423
+
424
+ export default SSAONode;
425
+
426
+ /**
427
+ * TSL function for creating a fast screen-space ambient occlusion (SSAO) effect.
428
+ *
429
+ * @tsl
430
+ * @function
431
+ * @param {Node<float>} depthNode - A node that represents the scene's depth.
432
+ * @param {Node<vec3>} normalNode - A node that represents the scene's normals.
433
+ * @param {Camera} camera - The camera the scene is rendered with.
434
+ * @returns {SSAONode}
435
+ */
436
+ export const ssao = ( depthNode, normalNode, camera ) => new SSAONode( nodeObject( depthNode ), nodeObject( normalNode ), camera );