@plastic-software/three 0.179.0 → 0.181.1

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 (430) hide show
  1. package/build/three.cjs +1108 -591
  2. package/build/three.core.js +616 -345
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +488 -250
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +37 -6
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +6576 -2152
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +6575 -2151
  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/Addons.js +1 -1
  15. package/examples/jsm/animation/CCDIKSolver.js +1 -1
  16. package/examples/jsm/controls/ArcballControls.js +8 -8
  17. package/examples/jsm/controls/DragControls.js +7 -57
  18. package/examples/jsm/controls/FirstPersonControls.js +3 -3
  19. package/examples/jsm/controls/FlyControls.js +1 -1
  20. package/examples/jsm/controls/OrbitControls.js +2 -2
  21. package/examples/jsm/controls/PointerLockControls.js +2 -10
  22. package/examples/jsm/controls/TrackballControls.js +1 -1
  23. package/examples/jsm/controls/TransformControls.js +1 -1
  24. package/examples/jsm/effects/AsciiEffect.js +8 -8
  25. package/examples/jsm/exporters/DRACOExporter.js +2 -2
  26. package/examples/jsm/exporters/EXRExporter.js +1 -1
  27. package/examples/jsm/exporters/GLTFExporter.js +33 -25
  28. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  29. package/examples/jsm/exporters/PLYExporter.js +1 -1
  30. package/examples/jsm/exporters/USDZExporter.js +9 -2
  31. package/examples/jsm/geometries/DecalGeometry.js +2 -2
  32. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  33. package/examples/jsm/geometries/TeapotGeometry.js +2 -2
  34. package/examples/jsm/geometries/TextGeometry.js +3 -2
  35. package/examples/jsm/gpgpu/BitonicSort.js +715 -0
  36. package/examples/jsm/helpers/ViewHelper.js +43 -5
  37. package/examples/jsm/inspector/Inspector.js +427 -0
  38. package/examples/jsm/inspector/RendererInspector.js +415 -0
  39. package/examples/jsm/inspector/tabs/Console.js +204 -0
  40. package/examples/jsm/inspector/tabs/Parameters.js +332 -0
  41. package/examples/jsm/inspector/tabs/Performance.js +268 -0
  42. package/examples/jsm/inspector/tabs/Viewer.js +166 -0
  43. package/examples/jsm/inspector/ui/Graph.js +95 -0
  44. package/examples/jsm/inspector/ui/Item.js +170 -0
  45. package/examples/jsm/inspector/ui/List.js +75 -0
  46. package/examples/jsm/inspector/ui/Profiler.js +170 -0
  47. package/examples/jsm/inspector/ui/Style.js +654 -0
  48. package/examples/jsm/inspector/ui/Tab.js +46 -0
  49. package/examples/jsm/inspector/ui/Values.js +423 -0
  50. package/examples/jsm/inspector/ui/utils.js +56 -0
  51. package/examples/jsm/interactive/HTMLMesh.js +6 -10
  52. package/examples/jsm/interactive/InteractiveGroup.js +1 -1
  53. package/examples/jsm/interactive/SelectionBox.js +30 -0
  54. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  55. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  56. package/examples/jsm/lines/Line2.js +3 -3
  57. package/examples/jsm/lines/LineGeometry.js +1 -1
  58. package/examples/jsm/lines/LineSegments2.js +2 -2
  59. package/examples/jsm/lines/Wireframe.js +2 -2
  60. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  61. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  62. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  63. package/examples/jsm/loaders/3MFLoader.js +1 -1
  64. package/examples/jsm/loaders/ColladaLoader.js +3 -3
  65. package/examples/jsm/loaders/DDSLoader.js +1 -1
  66. package/examples/jsm/loaders/DRACOLoader.js +73 -22
  67. package/examples/jsm/loaders/EXRLoader.js +5 -5
  68. package/examples/jsm/loaders/FBXLoader.js +2 -2
  69. package/examples/jsm/loaders/FontLoader.js +23 -5
  70. package/examples/jsm/loaders/GLTFLoader.js +14 -8
  71. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  72. package/examples/jsm/loaders/HDRLoader.js +486 -0
  73. package/examples/jsm/loaders/KTX2Loader.js +136 -49
  74. package/examples/jsm/loaders/KTXLoader.js +2 -2
  75. package/examples/jsm/loaders/LDrawLoader.js +1 -1
  76. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  77. package/examples/jsm/loaders/LUTCubeLoader.js +1 -1
  78. package/examples/jsm/loaders/LWOLoader.js +2 -2
  79. package/examples/jsm/loaders/MaterialXLoader.js +22 -5
  80. package/examples/jsm/loaders/OBJLoader.js +1 -1
  81. package/examples/jsm/loaders/PDBLoader.js +1 -1
  82. package/examples/jsm/loaders/RGBELoader.js +7 -473
  83. package/examples/jsm/loaders/SVGLoader.js +2 -2
  84. package/examples/jsm/loaders/TTFLoader.js +4 -4
  85. package/examples/jsm/loaders/UltraHDRLoader.js +2 -2
  86. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  87. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  88. package/examples/jsm/math/ColorSpaces.js +19 -1
  89. package/examples/jsm/math/ConvexHull.js +3 -3
  90. package/examples/jsm/math/ImprovedNoise.js +1 -1
  91. package/examples/jsm/math/Lut.js +2 -2
  92. package/examples/jsm/math/SimplexNoise.js +1 -1
  93. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  94. package/examples/jsm/misc/ProgressiveLightMap.js +9 -3
  95. package/examples/jsm/misc/ProgressiveLightMapGPU.js +7 -1
  96. package/examples/jsm/misc/TubePainter.js +383 -40
  97. package/examples/jsm/misc/Volume.js +1 -1
  98. package/examples/jsm/modifiers/SimplifyModifier.js +1 -1
  99. package/examples/jsm/objects/ReflectorForSSRPass.js +1 -0
  100. package/examples/jsm/objects/Sky.js +1 -1
  101. package/examples/jsm/objects/SkyMesh.js +1 -1
  102. package/examples/jsm/objects/Water.js +3 -3
  103. package/examples/jsm/objects/WaterMesh.js +6 -6
  104. package/examples/jsm/postprocessing/GlitchPass.js +2 -2
  105. package/examples/jsm/postprocessing/OutlinePass.js +1 -1
  106. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  107. package/examples/jsm/postprocessing/UnrealBloomPass.js +8 -6
  108. package/examples/jsm/renderers/CSS2DRenderer.js +16 -5
  109. package/examples/jsm/renderers/CSS3DRenderer.js +7 -6
  110. package/examples/jsm/renderers/SVGRenderer.js +1 -1
  111. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +1 -1
  112. package/examples/jsm/shaders/AfterimageShader.js +1 -1
  113. package/examples/jsm/shaders/BleachBypassShader.js +1 -1
  114. package/examples/jsm/shaders/BokehShader.js +1 -1
  115. package/examples/jsm/shaders/BokehShader2.js +1 -1
  116. package/examples/jsm/shaders/DotScreenShader.js +1 -1
  117. package/examples/jsm/shaders/FocusShader.js +1 -1
  118. package/examples/jsm/shaders/GTAOShader.js +2 -2
  119. package/examples/jsm/shaders/GodRaysShader.js +1 -1
  120. package/examples/jsm/shaders/KaleidoShader.js +1 -1
  121. package/examples/jsm/shaders/PoissonDenoiseShader.js +2 -2
  122. package/examples/jsm/shaders/SSRShader.js +1 -1
  123. package/examples/jsm/shaders/SepiaShader.js +1 -1
  124. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +1 -1
  125. package/examples/jsm/shaders/TriangleBlurShader.js +1 -1
  126. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +1 -1
  127. package/examples/jsm/shaders/VignetteShader.js +1 -1
  128. package/examples/jsm/transpiler/GLSLDecoder.js +22 -19
  129. package/examples/jsm/transpiler/TSLEncoder.js +9 -10
  130. package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
  131. package/examples/jsm/tsl/display/AfterImageNode.js +26 -24
  132. package/examples/jsm/tsl/display/AnamorphicNode.js +28 -4
  133. package/examples/jsm/tsl/display/BloomNode.js +7 -3
  134. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
  135. package/examples/jsm/tsl/display/DenoiseNode.js +2 -0
  136. package/examples/jsm/tsl/display/DepthOfFieldNode.js +446 -90
  137. package/examples/jsm/tsl/display/GTAONode.js +53 -5
  138. package/examples/jsm/tsl/display/GaussianBlurNode.js +49 -35
  139. package/examples/jsm/tsl/display/OutlineNode.js +13 -2
  140. package/examples/jsm/tsl/display/SSGINode.js +654 -0
  141. package/examples/jsm/tsl/display/SSRNode.js +182 -65
  142. package/examples/jsm/tsl/display/SSSNode.js +488 -0
  143. package/examples/jsm/tsl/display/TRAANode.js +124 -7
  144. package/examples/jsm/tsl/display/boxBlur.js +65 -0
  145. package/examples/jsm/tsl/display/hashBlur.js +16 -18
  146. package/examples/jsm/tsl/lighting/TiledLightsNode.js +21 -1
  147. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  148. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  149. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  150. package/examples/jsm/webxr/XRControllerModelFactory.js +1 -1
  151. package/examples/jsm/webxr/XRHandModelFactory.js +2 -6
  152. package/package.json +5 -10
  153. package/src/Three.Core.js +4 -2
  154. package/src/Three.TSL.js +36 -5
  155. package/src/Three.WebGPU.Nodes.js +2 -0
  156. package/src/Three.WebGPU.js +2 -0
  157. package/src/animation/AnimationClip.js +20 -4
  158. package/src/animation/AnimationMixer.js +3 -3
  159. package/src/animation/AnimationObjectGroup.js +2 -1
  160. package/src/animation/KeyframeTrack.js +7 -6
  161. package/src/animation/PropertyBinding.js +12 -11
  162. package/src/audio/Audio.js +10 -9
  163. package/src/audio/PositionalAudio.js +1 -1
  164. package/src/cameras/OrthographicCamera.js +1 -1
  165. package/src/cameras/PerspectiveCamera.js +1 -1
  166. package/src/cameras/StereoCamera.js +2 -2
  167. package/src/constants.js +11 -3
  168. package/src/core/BufferGeometry.js +10 -10
  169. package/src/core/EventDispatcher.js +1 -1
  170. package/src/core/InterleavedBuffer.js +1 -1
  171. package/src/core/InterleavedBufferAttribute.js +3 -2
  172. package/src/core/Object3D.js +3 -2
  173. package/src/core/Raycaster.js +2 -1
  174. package/src/core/RenderTarget.js +10 -1
  175. package/src/extras/Controls.js +5 -4
  176. package/src/extras/DataUtils.js +2 -1
  177. package/src/extras/Earcut.js +6 -0
  178. package/src/extras/ImageUtils.js +2 -2
  179. package/src/extras/PMREMGenerator.js +268 -55
  180. package/src/extras/TextureUtils.js +2 -1
  181. package/src/extras/core/Curve.js +2 -1
  182. package/src/extras/core/Interpolations.js +7 -1
  183. package/src/extras/core/ShapePath.js +4 -4
  184. package/src/extras/lib/earcut.js +8 -8
  185. package/src/geometries/BoxGeometry.js +1 -0
  186. package/src/geometries/CapsuleGeometry.js +1 -0
  187. package/src/geometries/CircleGeometry.js +1 -0
  188. package/src/geometries/ConeGeometry.js +1 -0
  189. package/src/geometries/CylinderGeometry.js +1 -0
  190. package/src/geometries/DodecahedronGeometry.js +1 -0
  191. package/src/geometries/ExtrudeGeometry.js +8 -6
  192. package/src/geometries/IcosahedronGeometry.js +1 -0
  193. package/src/geometries/LatheGeometry.js +1 -0
  194. package/src/geometries/OctahedronGeometry.js +1 -0
  195. package/src/geometries/PlaneGeometry.js +1 -0
  196. package/src/geometries/RingGeometry.js +1 -0
  197. package/src/geometries/ShapeGeometry.js +1 -0
  198. package/src/geometries/SphereGeometry.js +1 -0
  199. package/src/geometries/TetrahedronGeometry.js +1 -0
  200. package/src/geometries/TorusGeometry.js +1 -0
  201. package/src/geometries/TorusKnotGeometry.js +1 -0
  202. package/src/geometries/TubeGeometry.js +1 -0
  203. package/src/helpers/CameraHelper.js +1 -1
  204. package/src/lights/webgpu/ProjectorLight.js +1 -1
  205. package/src/loaders/AnimationLoader.js +2 -1
  206. package/src/loaders/AudioLoader.js +2 -1
  207. package/src/loaders/BufferGeometryLoader.js +2 -2
  208. package/src/loaders/Cache.js +2 -2
  209. package/src/loaders/DataTextureLoader.js +1 -1
  210. package/src/loaders/FileLoader.js +3 -2
  211. package/src/loaders/ImageBitmapLoader.js +5 -4
  212. package/src/loaders/ImageLoader.js +1 -1
  213. package/src/loaders/Loader.js +3 -3
  214. package/src/loaders/LoadingManager.js +25 -3
  215. package/src/loaders/MaterialLoader.js +3 -2
  216. package/src/loaders/ObjectLoader.js +13 -13
  217. package/src/loaders/TextureLoader.js +1 -1
  218. package/src/loaders/nodes/NodeLoader.js +3 -2
  219. package/src/materials/Material.js +16 -3
  220. package/src/materials/MeshBasicMaterial.js +1 -0
  221. package/src/materials/MeshDepthMaterial.js +1 -0
  222. package/src/materials/MeshDistanceMaterial.js +1 -1
  223. package/src/materials/MeshLambertMaterial.js +2 -1
  224. package/src/materials/MeshMatcapMaterial.js +22 -0
  225. package/src/materials/MeshNormalMaterial.js +1 -0
  226. package/src/materials/MeshPhongMaterial.js +2 -1
  227. package/src/materials/MeshPhysicalMaterial.js +2 -1
  228. package/src/materials/MeshStandardMaterial.js +8 -7
  229. package/src/materials/MeshToonMaterial.js +1 -0
  230. package/src/materials/PointsMaterial.js +1 -1
  231. package/src/materials/ShaderMaterial.js +2 -2
  232. package/src/materials/nodes/Line2NodeMaterial.js +2 -2
  233. package/src/materials/nodes/MeshSSSNodeMaterial.js +1 -1
  234. package/src/materials/nodes/NodeMaterial.js +62 -22
  235. package/src/materials/nodes/PointsNodeMaterial.js +81 -28
  236. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  237. package/src/materials/nodes/manager/NodeMaterialObserver.js +3 -2
  238. package/src/math/Color.js +6 -5
  239. package/src/math/ColorManagement.js +9 -3
  240. package/src/math/Cylindrical.js +1 -1
  241. package/src/math/Euler.js +2 -1
  242. package/src/math/MathUtils.js +13 -11
  243. package/src/math/Matrix2.js +1 -1
  244. package/src/math/Matrix3.js +2 -2
  245. package/src/math/Matrix4.js +7 -7
  246. package/src/math/Plane.js +1 -1
  247. package/src/math/Quaternion.js +68 -66
  248. package/src/math/Spherical.js +1 -1
  249. package/src/nodes/Nodes.js +4 -1
  250. package/src/nodes/TSL.js +4 -1
  251. package/src/nodes/accessors/BufferNode.js +1 -1
  252. package/src/nodes/accessors/Camera.js +133 -7
  253. package/src/nodes/accessors/ClippingNode.js +6 -5
  254. package/src/nodes/accessors/CubeTextureNode.js +5 -4
  255. package/src/nodes/accessors/InstanceNode.js +25 -5
  256. package/src/nodes/accessors/Lights.js +10 -0
  257. package/src/nodes/accessors/Normal.js +5 -4
  258. package/src/nodes/accessors/Object3DNode.js +1 -1
  259. package/src/nodes/accessors/Position.js +18 -2
  260. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  261. package/src/nodes/accessors/ReferenceNode.js +3 -2
  262. package/src/nodes/accessors/SceneNode.js +2 -1
  263. package/src/nodes/accessors/StorageBufferNode.js +2 -1
  264. package/src/nodes/accessors/StorageTextureNode.js +22 -0
  265. package/src/nodes/accessors/Texture3DNode.js +14 -1
  266. package/src/nodes/accessors/TextureNode.js +130 -44
  267. package/src/nodes/code/FunctionCallNode.js +24 -4
  268. package/src/nodes/code/FunctionNode.js +23 -0
  269. package/src/nodes/core/ArrayNode.js +1 -0
  270. package/src/nodes/core/AssignNode.js +4 -3
  271. package/src/nodes/core/AttributeNode.js +2 -1
  272. package/src/nodes/core/ContextNode.js +29 -10
  273. package/src/nodes/core/IndexNode.js +2 -2
  274. package/src/nodes/core/InputNode.js +2 -1
  275. package/src/nodes/core/InspectorNode.js +128 -0
  276. package/src/nodes/core/{CacheNode.js → IsolateNode.js} +40 -7
  277. package/src/nodes/core/Node.js +152 -31
  278. package/src/nodes/core/NodeBuilder.js +183 -35
  279. package/src/nodes/core/NodeFrame.js +21 -21
  280. package/src/nodes/core/NodeFunction.js +2 -1
  281. package/src/nodes/core/NodeParser.js +2 -1
  282. package/src/nodes/core/NodeUniform.js +1 -1
  283. package/src/nodes/core/NodeUtils.js +17 -91
  284. package/src/nodes/core/ParameterNode.js +31 -0
  285. package/src/nodes/core/PropertyNode.js +7 -0
  286. package/src/nodes/core/StackNode.js +43 -16
  287. package/src/nodes/core/StructNode.js +5 -5
  288. package/src/nodes/core/StructTypeNode.js +1 -0
  289. package/src/nodes/core/SubBuildNode.js +2 -2
  290. package/src/nodes/core/UniformNode.js +18 -10
  291. package/src/nodes/core/VarNode.js +70 -33
  292. package/src/nodes/core/VaryingNode.js +3 -2
  293. package/src/nodes/display/BlendModes.js +5 -4
  294. package/src/nodes/display/BumpMapNode.js +1 -1
  295. package/src/nodes/display/ColorAdjustment.js +1 -1
  296. package/src/nodes/display/FrontFacingNode.js +4 -8
  297. package/src/nodes/display/NormalMapNode.js +2 -1
  298. package/src/nodes/display/PassNode.js +52 -11
  299. package/src/nodes/display/RenderOutputNode.js +28 -2
  300. package/src/nodes/display/ScreenNode.js +44 -14
  301. package/src/nodes/display/ToneMappingNode.js +31 -4
  302. package/src/nodes/display/ToonOutlinePassNode.js +8 -0
  303. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  304. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  305. package/src/nodes/display/ViewportTextureNode.js +42 -12
  306. package/src/nodes/fog/Fog.js +3 -2
  307. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
  308. package/src/nodes/functions/BSDF/DFGApprox.js +60 -19
  309. package/src/nodes/functions/BasicLightingModel.js +2 -1
  310. package/src/nodes/functions/PhysicalLightingModel.js +3 -2
  311. package/src/nodes/functions/VolumetricLightingModel.js +5 -5
  312. package/src/nodes/geometry/RangeNode.js +40 -4
  313. package/src/nodes/gpgpu/ComputeBuiltinNode.js +2 -1
  314. package/src/nodes/gpgpu/ComputeNode.js +17 -5
  315. package/src/nodes/gpgpu/SubgroupFunctionNode.js +455 -0
  316. package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
  317. package/src/nodes/lighting/EnvironmentNode.js +6 -6
  318. package/src/nodes/lighting/LightsNode.js +3 -4
  319. package/src/nodes/lighting/PointShadowNode.js +6 -0
  320. package/src/nodes/lighting/ShadowFilterNode.js +2 -0
  321. package/src/nodes/lighting/ShadowNode.js +75 -8
  322. package/src/nodes/math/BitcastNode.js +156 -0
  323. package/src/nodes/math/ConditionalNode.js +24 -7
  324. package/src/nodes/math/MathNode.js +25 -19
  325. package/src/nodes/math/OperatorNode.js +7 -5
  326. package/src/nodes/pmrem/PMREMUtils.js +117 -2
  327. package/src/nodes/shapes/Shapes.js +1 -1
  328. package/src/nodes/tsl/TSLBase.js +5 -2
  329. package/src/nodes/tsl/TSLCore.js +460 -159
  330. package/src/nodes/utils/DebugNode.js +2 -1
  331. package/src/nodes/utils/EventNode.js +36 -0
  332. package/src/nodes/utils/FunctionOverloadingNode.js +37 -19
  333. package/src/nodes/utils/JoinNode.js +6 -3
  334. package/src/nodes/utils/LoopNode.js +20 -24
  335. package/src/nodes/utils/MemberNode.js +59 -7
  336. package/src/nodes/utils/PostProcessingUtils.js +28 -1
  337. package/src/nodes/utils/RTTNode.js +13 -3
  338. package/src/nodes/utils/ReflectorNode.js +58 -7
  339. package/src/nodes/utils/SampleNode.js +12 -2
  340. package/src/nodes/utils/SplitNode.js +11 -0
  341. package/src/nodes/utils/Timer.js +0 -47
  342. package/src/objects/BatchedMesh.js +2 -2
  343. package/src/objects/LOD.js +1 -1
  344. package/src/objects/Line.js +2 -1
  345. package/src/objects/LineSegments.js +2 -1
  346. package/src/objects/Skeleton.js +3 -2
  347. package/src/objects/SkinnedMesh.js +3 -1
  348. package/src/objects/Sprite.js +4 -3
  349. package/src/renderers/WebGLRenderer.js +48 -41
  350. package/src/renderers/common/Animation.js +13 -1
  351. package/src/renderers/common/Attributes.js +1 -1
  352. package/src/renderers/common/Backend.js +108 -27
  353. package/src/renderers/common/Background.js +2 -1
  354. package/src/renderers/common/Bindings.js +58 -2
  355. package/src/renderers/common/CanvasTarget.js +341 -0
  356. package/src/renderers/common/ChainMap.js +1 -1
  357. package/src/renderers/common/DataMap.js +1 -1
  358. package/src/renderers/common/Geometries.js +26 -0
  359. package/src/renderers/common/Info.js +4 -2
  360. package/src/renderers/common/InspectorBase.js +146 -0
  361. package/src/renderers/common/Pipelines.js +1 -1
  362. package/src/renderers/common/PostProcessing.js +6 -25
  363. package/src/renderers/common/QuadMesh.js +7 -1
  364. package/src/renderers/common/RenderContext.js +2 -2
  365. package/src/renderers/common/RenderList.js +7 -3
  366. package/src/renderers/common/RenderObject.js +16 -2
  367. package/src/renderers/common/RenderObjects.js +1 -1
  368. package/src/renderers/common/Renderer.js +473 -245
  369. package/src/renderers/common/RendererUtils.js +9 -0
  370. package/src/renderers/common/SampledTexture.js +9 -1
  371. package/src/renderers/common/Sampler.js +50 -12
  372. package/src/renderers/common/StorageTexture.js +9 -1
  373. package/src/renderers/common/Textures.js +121 -45
  374. package/src/renderers/common/TimestampQueryPool.js +65 -3
  375. package/src/renderers/common/UniformsGroup.js +2 -1
  376. package/src/renderers/common/XRManager.js +42 -22
  377. package/src/renderers/common/extras/PMREMGenerator.js +160 -65
  378. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  379. package/src/renderers/common/nodes/NodeLibrary.js +9 -7
  380. package/src/renderers/common/nodes/NodeSampler.js +13 -1
  381. package/src/renderers/common/nodes/Nodes.js +38 -16
  382. package/src/renderers/shaders/DFGLUTData.js +64 -0
  383. package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
  384. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
  385. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
  386. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +52 -18
  387. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  388. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  389. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  390. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  391. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +7 -15
  392. package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -1
  393. package/src/renderers/shaders/UniformsLib.js +1 -0
  394. package/src/renderers/shaders/UniformsUtils.js +25 -4
  395. package/src/renderers/webgl/WebGLCapabilities.js +2 -1
  396. package/src/renderers/webgl/WebGLExtensions.js +2 -25
  397. package/src/renderers/webgl/WebGLInfo.js +3 -1
  398. package/src/renderers/webgl/WebGLProgram.js +15 -14
  399. package/src/renderers/webgl/WebGLPrograms.js +2 -1
  400. package/src/renderers/webgl/WebGLShadowMap.js +3 -2
  401. package/src/renderers/webgl/WebGLState.js +15 -14
  402. package/src/renderers/webgl/WebGLTextures.js +19 -14
  403. package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
  404. package/src/renderers/webgl/WebGLUtils.js +3 -2
  405. package/src/renderers/webgl-fallback/WebGLBackend.js +199 -167
  406. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +181 -25
  407. package/src/renderers/webgl-fallback/utils/WebGLConstants.js +2 -3
  408. package/src/renderers/webgl-fallback/utils/WebGLState.js +7 -6
  409. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +169 -19
  410. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +51 -22
  411. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  412. package/src/renderers/webgpu/WebGPUBackend.js +153 -123
  413. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +2 -1
  414. package/src/renderers/webgpu/WebGPURenderer.js +3 -2
  415. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +142 -50
  416. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +2 -1
  417. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +5 -3
  418. package/src/renderers/webgpu/utils/WebGPUConstants.js +7 -2
  419. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +53 -34
  420. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +6 -8
  421. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +260 -99
  422. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +32 -9
  423. package/src/renderers/webgpu/utils/WebGPUUtils.js +22 -2
  424. package/src/renderers/webxr/WebXRManager.js +42 -26
  425. package/src/textures/ExternalTexture.js +15 -4
  426. package/src/textures/Source.js +3 -2
  427. package/src/textures/Texture.js +3 -2
  428. package/src/textures/VideoTexture.js +2 -3
  429. package/src/utils.js +67 -3
  430. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
@@ -0,0 +1,715 @@
1
+ import { Fn, uvec2, If, instancedArray, instanceIndex, invocationLocalIndex, Loop, workgroupArray, workgroupBarrier, workgroupId, uint, select, min, max } from 'three/tsl';
2
+
3
+ const StepType = {
4
+ NONE: 0,
5
+ // Swap all values within the local range of workgroupSize * 2
6
+ SWAP_LOCAL: 1,
7
+ DISPERSE_LOCAL: 2,
8
+ // Swap values within global data buffer.
9
+ FLIP_GLOBAL: 3,
10
+ DISPERSE_GLOBAL: 4,
11
+ };
12
+
13
+
14
+ /**
15
+ * Returns the indices that will be compared in a bitonic flip operation.
16
+ *
17
+ * @tsl
18
+ * @private
19
+ * @param {Node<uint>} index - The compute thread's invocation id.
20
+ * @param {Node<uint>} blockHeight - The height of the block within which elements are being swapped.
21
+ * @returns {Node<uvec2>} The indices of the elements in the data buffer being compared.
22
+ */
23
+ export const getBitonicFlipIndices = /*@__PURE__*/ Fn( ( [ index, blockHeight ] ) => {
24
+
25
+ const blockOffset = ( index.mul( 2 ).div( blockHeight ) ).mul( blockHeight );
26
+ const halfHeight = blockHeight.div( 2 );
27
+ const idx = uvec2(
28
+ index.mod( halfHeight ),
29
+ blockHeight.sub( index.mod( halfHeight ) ).sub( 1 )
30
+ );
31
+ idx.x.addAssign( blockOffset );
32
+ idx.y.addAssign( blockOffset );
33
+
34
+ return idx;
35
+
36
+ } ).setLayout( {
37
+ name: 'getBitonicFlipIndices',
38
+ type: 'uvec2',
39
+ inputs: [
40
+ { name: 'index', type: 'uint' },
41
+ { name: 'blockHeight', type: 'uint' }
42
+ ]
43
+ } );
44
+
45
+ /**
46
+ * Returns the indices that will be compared in a bitonic sort's disperse operation.
47
+ *
48
+ * @tsl
49
+ * @private
50
+ * @param {Node<uint>} index - The compute thread's invocation id.
51
+ * @param {Node<uint>} swapSpan - The maximum span over which elements are being swapped.
52
+ * @returns {Node<uvec2>} The indices of the elements in the data buffer being compared.
53
+ */
54
+ export const getBitonicDisperseIndices = /*@__PURE__*/ Fn( ( [ index, swapSpan ] ) => {
55
+
56
+ const blockOffset = ( ( index.mul( 2 ) ).div( swapSpan ) ).mul( swapSpan );
57
+ const halfHeight = swapSpan.div( 2 );
58
+ const idx = uvec2(
59
+ index.mod( halfHeight ),
60
+ ( index.mod( halfHeight ) ).add( halfHeight )
61
+ );
62
+
63
+ idx.x.addAssign( blockOffset );
64
+ idx.y.addAssign( blockOffset );
65
+
66
+ return idx;
67
+
68
+ } ).setLayout( {
69
+ name: 'getBitonicDisperseIndices',
70
+ type: 'uvec2',
71
+ inputs: [
72
+ { name: 'index', type: 'uint' },
73
+ { name: 'blockHeight', type: 'uint' }
74
+ ]
75
+ } );
76
+
77
+ export class BitonicSort {
78
+
79
+ /**
80
+ * Constructs a new light probe helper.
81
+ *
82
+ * @param {Renderer} renderer - The current scene's renderer.
83
+ * @param {StorageBufferNode} dataBuffer - The data buffer to sort.
84
+ * @param {Object} [options={}] - Options that modify the bitonic sort.
85
+ */
86
+ constructor( renderer, dataBuffer, options = {} ) {
87
+
88
+ /**
89
+ * A reference to the renderer.
90
+ *
91
+ * @type {Renderer}
92
+ */
93
+ this.renderer = renderer;
94
+
95
+ /**
96
+ * A reference to the StorageBufferNode holding the data that will be sorted .
97
+ *
98
+ * @type {StorageBufferNode}
99
+ */
100
+ this.dataBuffer = dataBuffer;
101
+
102
+ /**
103
+ * The size of the data.
104
+ *
105
+ * @type {StorageBufferNode}
106
+ */
107
+ this.count = dataBuffer.value.count;
108
+
109
+ /**
110
+ *
111
+ * The size of each compute dispatch.
112
+ * @type {number}
113
+ */
114
+
115
+ this.dispatchSize = this.count / 2;
116
+
117
+ /**
118
+ * The workgroup size of the compute shaders executed during the sort.
119
+ *
120
+ * @type {StorageBufferNode}
121
+ */
122
+ this.workgroupSize = options.workgroupSize ? Math.min( this.dispatchSize, options.workgroupSize ) : Math.min( this.dispatchSize, 64 );
123
+
124
+ /**
125
+ * A node representing a workgroup scoped buffer that holds locally sorted elements.
126
+ *
127
+ * @type {WorkgroupInfoNode}
128
+ */
129
+ this.localStorage = workgroupArray( dataBuffer.nodeType, this.workgroupSize * 2 );
130
+
131
+ this._tempArray = new Uint32Array( this.count );
132
+ for ( let i = 0; i < this.count; i ++ ) {
133
+
134
+ this._tempArray[ i ] = 0;
135
+
136
+ }
137
+
138
+ /**
139
+ * A node representing a storage buffer used for transferring the result of the global sort back to the original data buffer.
140
+ *
141
+ * @type {StorageBufferNode}
142
+ */
143
+ this.tempBuffer = instancedArray( this.count, dataBuffer.nodeType ).setName( 'TempStorage' );
144
+
145
+ /**
146
+ * A node containing the current algorithm type, the current swap span, and the highest swap span.
147
+ *
148
+ * @type {StorageBufferNode}
149
+ */
150
+ this.infoStorage = instancedArray( new Uint32Array( [ 1, 2, 2 ] ), 'uint' ).setName( 'BitonicSortInfo' );
151
+
152
+
153
+ /**
154
+ * The number of distinct swap operations ('flips' and 'disperses') executed in an in-place
155
+ * bitonic sort of the current data buffer.
156
+ *
157
+ * @type {number}
158
+ */
159
+ this.swapOpCount = this._getSwapOpCount();
160
+
161
+ /**
162
+ * The number of steps (i.e prepping and/or executing a swap) needed to fully execute an in-place bitonic sort of the current data buffer.
163
+ *
164
+ * @type {number}
165
+ */
166
+ this.stepCount = this._getStepCount();
167
+
168
+ /**
169
+ * The number of the buffer being read from.
170
+ *
171
+ * @type {string}
172
+ */
173
+ this.readBufferName = 'Data';
174
+
175
+ /**
176
+ * An object containing compute shaders that execute a 'flip' swap within a global address space on elements in the data buffer.
177
+ *
178
+ * @type {Object<string, ComputeNode>}
179
+ */
180
+ this.flipGlobalNodes = {
181
+ 'Data': this._getFlipGlobal( this.dataBuffer, this.tempBuffer ),
182
+ 'Temp': this._getFlipGlobal( this.tempBuffer, this.dataBuffer )
183
+ };
184
+
185
+ /**
186
+ * An object containing compute shaders that execute a 'disperse' swap within a global address space on elements in the data buffer.
187
+ *
188
+ * @type {Object<string, ComputeNode>}
189
+ */
190
+ this.disperseGlobalNodes = {
191
+ 'Data': this._getDisperseGlobal( this.dataBuffer, this.tempBuffer ),
192
+ 'Temp': this._getDisperseGlobal( this.tempBuffer, this.dataBuffer )
193
+ };
194
+
195
+ /**
196
+ * A compute shader that executes a sequence of flip and disperse swaps within a local address space on elements in the data buffer.
197
+ *
198
+ * @type {ComputeNode}
199
+ */
200
+ this.swapLocalFn = this._getSwapLocal();
201
+
202
+ /**
203
+ * A compute shader that executes a sequence of disperse swaps within a local address space on elements in the data buffer.
204
+ *
205
+ * @type {Object<string, ComputeNode>}
206
+ */
207
+ this.disperseLocalNodes = {
208
+ 'Data': this._getDisperseLocal( this.dataBuffer ),
209
+ 'Temp': this._getDisperseLocal( this.tempBuffer ),
210
+ };
211
+
212
+ // Utility functions
213
+
214
+ /**
215
+ * A compute shader that sets up the algorithm and the swap span for the next swap operation.
216
+ *
217
+ * @type {ComputeNode}
218
+ */
219
+ this.setAlgoFn = this._getSetAlgoFn();
220
+
221
+ /**
222
+ * A compute shader that aligns the result of the global swap operation with the current buffer.
223
+ *
224
+ * @type {ComputeNode}
225
+ */
226
+ this.alignFn = this._getAlignFn();
227
+
228
+
229
+ /**
230
+ * A compute shader that resets the algorithm and swap span information.
231
+ *
232
+ * @type {ComputeNode}
233
+ */
234
+ this.resetFn = this._getResetFn();
235
+
236
+
237
+ /**
238
+ * The current compute shader dispatch within the list of dispatches needed to complete the sort.
239
+ *
240
+ * @type {number}
241
+ */
242
+ this.currentDispatch = 0;
243
+
244
+ /**
245
+ * The number of global swap operations that must be executed before the sort
246
+ * can swap in local address space.
247
+ *
248
+ * @type {number}
249
+ */
250
+ this.globalOpsRemaining = 0;
251
+
252
+ /**
253
+ * The total number of global operations needed to sort elements within the current swap span.
254
+ *
255
+ * @type {number}
256
+ */
257
+ this.globalOpsInSpan = 0;
258
+
259
+
260
+ }
261
+
262
+ /**
263
+ * Get total number of distinct swaps that occur in a bitonic sort.
264
+ *
265
+ * @private
266
+ * @returns {number} - The total number of distinct swaps in a bitonic sort
267
+ */
268
+ _getSwapOpCount() {
269
+
270
+ const n = Math.log2( this.count );
271
+ return ( n * ( n + 1 ) ) / 2;
272
+
273
+ }
274
+
275
+ /**
276
+ * Get the number of steps it takes to execute a complete bitonic sort.
277
+ *
278
+ * @private
279
+ * @returns {number} The number of steps it takes to execute a complete bitonic sort.
280
+ */
281
+ _getStepCount() {
282
+
283
+ const logElements = Math.log2( this.count );
284
+ const logSwapSpan = Math.log2( this.workgroupSize * 2 );
285
+
286
+ const numGlobalFlips = logElements - logSwapSpan;
287
+
288
+ // Start with 1 for initial sort over all local elements
289
+ let numSteps = 1;
290
+ let numGlobalDisperses = 0;
291
+
292
+ for ( let i = 1; i <= numGlobalFlips; i ++ ) {
293
+
294
+ // Increment by the global flip that starts each global block
295
+ numSteps += 1;
296
+ // Increment by number of global disperses following the global flip
297
+ numSteps += numGlobalDisperses;
298
+ // Increment by local disperse that occurs after all global swaps are finished
299
+ numSteps += 1;
300
+
301
+ // Number of global disperse increases as swapSpan increases by factor of 2
302
+ numGlobalDisperses += 1;
303
+
304
+ }
305
+
306
+ return numSteps;
307
+
308
+ }
309
+
310
+ /**
311
+ * Compares and swaps two data points in the data buffer within the global address space.
312
+ * @param {Node<uint>} idxBefore - The index of the first data element in the data buffer.
313
+ * @param {Node<uint>} idxAfter - The index of the second data element in the data buffer.
314
+ * @param {StorageBufferNode} dataBuffer - The buffer of data to read from.
315
+ * @param {StorageBufferNode} tempBuffer - The buffer of data to write to.
316
+ * @private
317
+ *
318
+ */
319
+ _globalCompareAndSwapTSL( idxBefore, idxAfter, dataBuffer, tempBuffer ) {
320
+
321
+ const data1 = dataBuffer.element( idxBefore );
322
+ const data2 = dataBuffer.element( idxAfter );
323
+
324
+ tempBuffer.element( idxBefore ).assign( min( data1, data2 ) );
325
+ tempBuffer.element( idxAfter ).assign( max( data1, data2 ) );
326
+
327
+ }
328
+
329
+ /**
330
+ * Compares and swaps two data points in the data buffer within the local address space.
331
+ *
332
+ * @private
333
+ * @param {Node<uint>} idxBefore - The index of the first data element in the data buffer.
334
+ * @param {Node<uint>} idxAfter - The index of the second data element in the data buffer
335
+ */
336
+ _localCompareAndSwapTSL( idxBefore, idxAfter ) {
337
+
338
+ const { localStorage } = this;
339
+
340
+ const data1 = localStorage.element( idxBefore ).toVar();
341
+ const data2 = localStorage.element( idxAfter ).toVar();
342
+
343
+ localStorage.element( idxBefore ).assign( min( data1, data2 ) );
344
+ localStorage.element( idxAfter ).assign( max( data1, data2 ) );
345
+
346
+ }
347
+
348
+
349
+ /**
350
+ * Create the compute shader that performs a global disperse swap on the data buffer.
351
+ *
352
+ * @private
353
+ * @param {StorageBufferNode} readBuffer - The data buffer to read from.
354
+ * @param {StorageBufferNode} writeBuffer - The data buffer to read from.
355
+ * @returns {ComputeNode} - A compute shader that performs a global disperse swap on the data buffer.
356
+ */
357
+ _getDisperseGlobal( readBuffer, writeBuffer ) {
358
+
359
+ const { infoStorage } = this;
360
+
361
+ const currentSwapSpan = infoStorage.element( 1 );
362
+
363
+ const fnDef = Fn( () => {
364
+
365
+ const idx = getBitonicDisperseIndices( instanceIndex, currentSwapSpan );
366
+ this._globalCompareAndSwapTSL( idx.x, idx.y, readBuffer, writeBuffer );
367
+
368
+ } )().compute( this.dispatchSize, [ this.workgroupSize ] );
369
+
370
+ return fnDef;
371
+
372
+ }
373
+
374
+ /**
375
+ * Create the compute shader that performs a global flip swap on the data buffer.
376
+ *
377
+ * @private
378
+ * @param {StorageBufferNode} readBuffer - The data buffer to read from.
379
+ * @param {StorageBufferNode} writeBuffer - The data buffer to read from.
380
+ * @returns {ComputeNode} - A compute shader that executes a global flip swap.
381
+ */
382
+ _getFlipGlobal( readBuffer, writeBuffer ) {
383
+
384
+ const { infoStorage } = this;
385
+
386
+ const currentSwapSpan = infoStorage.element( 1 );
387
+
388
+ const fnDef = Fn( () => {
389
+
390
+ const idx = getBitonicFlipIndices( instanceIndex, currentSwapSpan );
391
+ this._globalCompareAndSwapTSL( idx.x, idx.y, readBuffer, writeBuffer );
392
+
393
+ } )().compute( this.dispatchSize, [ this.workgroupSize ] );
394
+
395
+ return fnDef;
396
+
397
+ }
398
+
399
+
400
+ /**
401
+ * Create the compute shader that performs a complete local swap on the data buffer.
402
+ *
403
+ * @private
404
+ * @returns {ComputeNode} - A compute shader that executes a full local swap.
405
+ */
406
+ _getSwapLocal() {
407
+
408
+ const { localStorage, dataBuffer, workgroupSize } = this;
409
+
410
+ const fnDef = Fn( () => {
411
+
412
+ // Get ids of indices needed to populate workgroup local buffer.
413
+ // Use .toVar() to prevent these values from being recalculated multiple times.
414
+ const localOffset = uint( workgroupSize ).mul( 2 ).mul( workgroupId.x ).toVar();
415
+
416
+ const localID1 = invocationLocalIndex.mul( 2 );
417
+ const localID2 = invocationLocalIndex.mul( 2 ).add( 1 );
418
+
419
+ localStorage.element( localID1 ).assign( dataBuffer.element( localOffset.add( localID1 ) ) );
420
+ localStorage.element( localID2 ).assign( dataBuffer.element( localOffset.add( localID2 ) ) );
421
+
422
+ // Ensure that all local data has been populated
423
+ workgroupBarrier();
424
+
425
+ // Perform a chunk of the sort in a single pass that operates entirely in workgroup local space
426
+ // SWAP_LOCAL will always be first pass, so we start with known block height of 2
427
+ const flipBlockHeight = uint( 2 );
428
+
429
+ Loop( { start: uint( 2 ), end: uint( workgroupSize * 2 ), type: 'uint', condition: '<=', update: '<<= 1' }, () => {
430
+
431
+ // Ensure that last dispatch block executed
432
+ workgroupBarrier();
433
+
434
+ const flipIdx = getBitonicFlipIndices( invocationLocalIndex, flipBlockHeight );
435
+
436
+ this._localCompareAndSwapTSL( flipIdx.x, flipIdx.y );
437
+
438
+ const localBlockHeight = flipBlockHeight.div( 2 );
439
+
440
+ Loop( { start: localBlockHeight, end: uint( 1 ), type: 'uint', condition: '>', update: '>>= 1' }, () => {
441
+
442
+ // Ensure that last dispatch op executed
443
+ workgroupBarrier();
444
+
445
+ const disperseIdx = getBitonicDisperseIndices( invocationLocalIndex, localBlockHeight );
446
+ this._localCompareAndSwapTSL( disperseIdx.x, disperseIdx.y );
447
+
448
+ localBlockHeight.divAssign( 2 );
449
+
450
+ } );
451
+
452
+ // flipBlockHeight *= 2;
453
+ flipBlockHeight.shiftLeftAssign( 1 );
454
+
455
+ } );
456
+
457
+ // Ensure that all invocations have swapped their own regions of data
458
+ workgroupBarrier();
459
+
460
+ dataBuffer.element( localOffset.add( localID1 ) ).assign( localStorage.element( localID1 ) );
461
+ dataBuffer.element( localOffset.add( localID2 ) ).assign( localStorage.element( localID2 ) );
462
+
463
+ } )().compute( this.dispatchSize, [ this.workgroupSize ] );
464
+
465
+ return fnDef;
466
+
467
+ }
468
+
469
+ /**
470
+ * Create the compute shader that performs a local disperse swap on the data buffer.
471
+ *
472
+ * @private
473
+ * @param {StorageBufferNode} readWriteBuffer - The data buffer to read from and write to.
474
+ * @returns {ComputeNode} - A compute shader that executes a local disperse swap.
475
+ */
476
+ _getDisperseLocal( readWriteBuffer ) {
477
+
478
+ const { localStorage, workgroupSize } = this;
479
+
480
+ const fnDef = Fn( () => {
481
+
482
+ // Get ids of indices needed to populate workgroup local buffer.
483
+ // Use .toVar() to prevent these values from being recalculated multiple times.
484
+ const localOffset = uint( workgroupSize ).mul( 2 ).mul( workgroupId.x ).toVar();
485
+
486
+ const localID1 = invocationLocalIndex.mul( 2 );
487
+ const localID2 = invocationLocalIndex.mul( 2 ).add( 1 );
488
+
489
+ localStorage.element( localID1 ).assign( readWriteBuffer.element( localOffset.add( localID1 ) ) );
490
+ localStorage.element( localID2 ).assign( readWriteBuffer.element( localOffset.add( localID2 ) ) );
491
+
492
+ // Ensure that all local data has been populated
493
+ workgroupBarrier();
494
+
495
+ const localBlockHeight = uint( workgroupSize * 2 );
496
+
497
+ Loop( { start: localBlockHeight, end: uint( 1 ), type: 'uint', condition: '>', update: '>>= 1' }, () => {
498
+
499
+ // Ensure that last dispatch op executed
500
+ workgroupBarrier();
501
+
502
+ const disperseIdx = getBitonicDisperseIndices( invocationLocalIndex, localBlockHeight );
503
+ this._localCompareAndSwapTSL( disperseIdx.x, disperseIdx.y );
504
+
505
+ localBlockHeight.divAssign( 2 );
506
+
507
+ } );
508
+
509
+ // Ensure that all invocations have swapped their own regions of data
510
+ workgroupBarrier();
511
+
512
+ readWriteBuffer.element( localOffset.add( localID1 ) ).assign( localStorage.element( localID1 ) );
513
+ readWriteBuffer.element( localOffset.add( localID2 ) ).assign( localStorage.element( localID2 ) );
514
+
515
+ } )().compute( this.dispatchSize, [ this.workgroupSize ] );
516
+
517
+ return fnDef;
518
+
519
+ }
520
+
521
+ /**
522
+ * Create the compute shader that resets the sort's algorithm information.
523
+ *
524
+ * @private
525
+ * @returns {ComputeNode} - A compute shader that resets the bitonic sort's algorithm information.
526
+ */
527
+ _getResetFn() {
528
+
529
+ const fnDef = Fn( () => {
530
+
531
+ const { infoStorage } = this;
532
+
533
+ const currentAlgo = infoStorage.element( 0 );
534
+ const currentSwapSpan = infoStorage.element( 1 );
535
+ const maxSwapSpan = infoStorage.element( 2 );
536
+
537
+ currentAlgo.assign( StepType.SWAP_LOCAL );
538
+ currentSwapSpan.assign( 2 );
539
+ maxSwapSpan.assign( 2 );
540
+
541
+ } )().compute( 1 );
542
+
543
+ return fnDef;
544
+
545
+ }
546
+
547
+ /**
548
+ * Create the compute shader that copies the state of the last global swap to the data buffer.
549
+ *
550
+ * @private
551
+ * @returns {ComputeNode} - A compute shader that copies the state of the last global swap to the data buffer.
552
+ */
553
+ _getAlignFn() {
554
+
555
+ const { dataBuffer, tempBuffer } = this;
556
+
557
+ // TODO: Only do this in certain instances by ping-ponging which buffer gets sorted
558
+ // And only aligning if numDispatches % 2 === 1
559
+ const fnDef = Fn( () => {
560
+
561
+ dataBuffer.element( instanceIndex ).assign( tempBuffer.element( instanceIndex ) );
562
+
563
+ } )().compute( this.count, [ this.workgroupSize ] );
564
+
565
+ return fnDef;
566
+
567
+ }
568
+
569
+ /**
570
+ * Create the compute shader that sets the bitonic sort algorithm's information.
571
+ *
572
+ * @private
573
+ * @returns {ComputeNode} - A compute shader that sets the bitonic sort algorithm's information.
574
+ */
575
+ _getSetAlgoFn() {
576
+
577
+ const fnDef = Fn( () => {
578
+
579
+ const { infoStorage, workgroupSize } = this;
580
+
581
+ const currentAlgo = infoStorage.element( 0 );
582
+ const currentSwapSpan = infoStorage.element( 1 );
583
+ const maxSwapSpan = infoStorage.element( 2 );
584
+
585
+ If( currentAlgo.equal( StepType.SWAP_LOCAL ), () => {
586
+
587
+ const nextHighestSwapSpan = uint( workgroupSize * 4 );
588
+
589
+ currentAlgo.assign( StepType.FLIP_GLOBAL );
590
+ currentSwapSpan.assign( nextHighestSwapSpan );
591
+ maxSwapSpan.assign( nextHighestSwapSpan );
592
+
593
+ } ).ElseIf( currentAlgo.equal( StepType.DISPERSE_LOCAL ), () => {
594
+
595
+ currentAlgo.assign( StepType.FLIP_GLOBAL );
596
+
597
+ const nextHighestSwapSpan = maxSwapSpan.mul( 2 );
598
+
599
+ currentSwapSpan.assign( nextHighestSwapSpan );
600
+ maxSwapSpan.assign( nextHighestSwapSpan );
601
+
602
+ } ).Else( () => {
603
+
604
+ const nextSwapSpan = currentSwapSpan.div( 2 );
605
+ currentAlgo.assign(
606
+ select(
607
+ nextSwapSpan.lessThanEqual( uint( workgroupSize * 2 ) ),
608
+ StepType.DISPERSE_LOCAL,
609
+ StepType.DISPERSE_GLOBAL
610
+ ).uniformFlow()
611
+ );
612
+ currentSwapSpan.assign( nextSwapSpan );
613
+
614
+ } );
615
+
616
+ } )().compute( 1 );
617
+
618
+ return fnDef;
619
+
620
+ }
621
+
622
+ /**
623
+ * Executes a step of the bitonic sort operation.
624
+ *
625
+ * @param {Renderer} renderer - The current scene's renderer.
626
+ */
627
+ computeStep( renderer ) {
628
+
629
+ // Swap local only runs once
630
+ if ( this.currentDispatch === 0 ) {
631
+
632
+ renderer.compute( this.swapLocalFn );
633
+
634
+ this.globalOpsRemaining = 1;
635
+ this.globalOpsInSpan = 1;
636
+
637
+ } else if ( this.globalOpsRemaining > 0 ) {
638
+
639
+ const swapType = this.globalOpsRemaining === this.globalOpsInSpan ? 'Flip' : 'Disperse';
640
+
641
+ renderer.compute( swapType === 'Flip' ? this.flipGlobalNodes[ this.readBufferName ] : this.disperseGlobalNodes[ this.readBufferName ] );
642
+
643
+ if ( this.readBufferName === 'Data' ) {
644
+
645
+ this.readBufferName = 'Temp';
646
+
647
+ } else {
648
+
649
+ this.readBufferName = 'Data';
650
+
651
+ }
652
+
653
+ this.globalOpsRemaining -= 1;
654
+
655
+ } else {
656
+
657
+ // Then run local disperses when we've finished all global swaps
658
+ renderer.compute( this.disperseLocalNodes[ this.readBufferName ] );
659
+
660
+ const nextSpanGlobalOps = this.globalOpsInSpan + 1;
661
+ this.globalOpsInSpan = nextSpanGlobalOps;
662
+ this.globalOpsRemaining = nextSpanGlobalOps;
663
+
664
+ }
665
+
666
+
667
+ this.currentDispatch += 1;
668
+
669
+ if ( this.currentDispatch === this.stepCount ) {
670
+
671
+ // If our last swap addressed only addressed the temp buffer, then re-align it with the data buffer
672
+ // to fulfill the requirement of an in-place sort.
673
+ if ( this.readBufferName === 'Temp' ) {
674
+
675
+ renderer.compute( this.alignFn );
676
+ this.readBufferName = 'Data';
677
+
678
+ }
679
+
680
+ // Just reset the algorithm information
681
+ renderer.compute( this.resetFn );
682
+
683
+ this.currentDispatch = 0;
684
+ this.globalOpsRemaining = 0;
685
+ this.globalOpsInSpan = 0;
686
+
687
+ } else {
688
+
689
+ // Otherwise, determine what next swap span is
690
+ renderer.compute( this.setAlgoFn );
691
+
692
+ }
693
+
694
+ }
695
+
696
+ /**
697
+ * Executes a complete bitonic sort on the data buffer.
698
+ *
699
+ * @param {Renderer} renderer - The current scene's renderer.
700
+ */
701
+ compute( renderer ) {
702
+
703
+ this.globalOpsRemaining = 0;
704
+ this.globalOpsInSpan = 0;
705
+ this.currentDispatch = 0;
706
+
707
+ for ( let i = 0; i < this.stepCount; i ++ ) {
708
+
709
+ this.computeStep( renderer );
710
+
711
+ }
712
+
713
+ }
714
+
715
+ }