@needle-tools/three 0.169.20-experimental.0 → 0.183.2-canary.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 (1051) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +5 -6
  3. package/build/three.cjs +54184 -56703
  4. package/build/three.core.js +59506 -0
  5. package/build/three.core.min.js +6 -0
  6. package/build/three.module.js +11645 -73000
  7. package/build/three.module.min.js +2 -2
  8. package/build/three.tsl.js +648 -0
  9. package/build/three.tsl.min.js +6 -0
  10. package/build/three.webgpu.js +53912 -51652
  11. package/build/three.webgpu.min.js +2 -2
  12. package/build/three.webgpu.nodes.js +53888 -51806
  13. package/build/three.webgpu.nodes.min.js +2 -2
  14. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  15. package/examples/fonts/MPLUSRounded1c/OFL.txt +91 -0
  16. package/examples/jsm/Addons.js +5 -15
  17. package/examples/jsm/animation/AnimationClipCreator.js +58 -6
  18. package/examples/jsm/animation/CCDIKSolver.js +152 -45
  19. package/examples/jsm/capabilities/WebGL.js +28 -29
  20. package/examples/jsm/capabilities/WebGPU.js +19 -17
  21. package/examples/jsm/controls/ArcballControls.js +474 -178
  22. package/examples/jsm/controls/DragControls.js +100 -58
  23. package/examples/jsm/controls/FirstPersonControls.js +116 -6
  24. package/examples/jsm/controls/FlyControls.js +50 -2
  25. package/examples/jsm/controls/MapControls.js +96 -8
  26. package/examples/jsm/controls/OrbitControls.js +496 -57
  27. package/examples/jsm/controls/PointerLockControls.js +115 -22
  28. package/examples/jsm/controls/TrackballControls.js +166 -14
  29. package/examples/jsm/controls/TransformControls.js +336 -26
  30. package/examples/jsm/csm/CSM.js +232 -18
  31. package/examples/jsm/csm/CSMFrustum.js +61 -4
  32. package/examples/jsm/csm/CSMHelper.js +50 -0
  33. package/examples/jsm/csm/CSMShader.js +13 -1
  34. package/examples/jsm/csm/CSMShadowNode.js +599 -0
  35. package/examples/jsm/curves/CurveExtras.js +303 -31
  36. package/examples/jsm/curves/NURBSCurve.js +91 -16
  37. package/examples/jsm/curves/NURBSSurface.js +52 -6
  38. package/examples/jsm/curves/NURBSUtils.js +102 -112
  39. package/examples/jsm/curves/NURBSVolume.js +24 -4
  40. package/examples/jsm/effects/AnaglyphEffect.js +134 -7
  41. package/examples/jsm/effects/AsciiEffect.js +69 -22
  42. package/examples/jsm/effects/OutlineEffect.js +61 -111
  43. package/examples/jsm/effects/ParallaxBarrierEffect.js +30 -0
  44. package/examples/jsm/effects/StereoEffect.js +31 -0
  45. package/examples/jsm/environments/ColorEnvironment.js +59 -0
  46. package/examples/jsm/environments/DebugEnvironment.js +50 -0
  47. package/examples/jsm/environments/RoomEnvironment.js +83 -42
  48. package/examples/jsm/exporters/DRACOExporter.js +56 -14
  49. package/examples/jsm/exporters/EXRExporter.js +40 -9
  50. package/examples/jsm/exporters/GLTFExporter.js +502 -169
  51. package/examples/jsm/exporters/OBJExporter.js +21 -1
  52. package/examples/jsm/exporters/PLYExporter.js +44 -12
  53. package/examples/jsm/exporters/STLExporter.js +27 -5
  54. package/examples/jsm/exporters/USDZExporter.js +781 -291
  55. package/examples/jsm/geometries/BoxLineGeometry.js +23 -0
  56. package/examples/jsm/geometries/ConvexGeometry.js +19 -0
  57. package/examples/jsm/geometries/DecalGeometry.js +91 -30
  58. package/examples/jsm/geometries/ParametricFunctions.js +100 -0
  59. package/examples/jsm/geometries/ParametricGeometry.js +38 -5
  60. package/examples/jsm/geometries/RoundedBoxGeometry.js +68 -7
  61. package/examples/jsm/geometries/TeapotGeometry.js +23 -38
  62. package/examples/jsm/geometries/TextGeometry.js +48 -29
  63. package/examples/jsm/gpgpu/BitonicSort.js +715 -0
  64. package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
  65. package/examples/jsm/helpers/LightProbeHelper.js +36 -0
  66. package/examples/jsm/helpers/LightProbeHelperGPU.js +38 -1
  67. package/examples/jsm/helpers/OctreeHelper.js +36 -0
  68. package/examples/jsm/helpers/PositionalAudioHelper.js +60 -0
  69. package/examples/jsm/helpers/RapierHelper.js +59 -0
  70. package/examples/jsm/helpers/RectAreaLightHelper.js +36 -3
  71. package/examples/jsm/helpers/TextureHelper.js +28 -0
  72. package/examples/jsm/helpers/TextureHelperGPU.js +214 -0
  73. package/examples/jsm/helpers/VertexNormalsHelper.js +61 -2
  74. package/examples/jsm/helpers/VertexTangentsHelper.js +47 -2
  75. package/examples/jsm/helpers/ViewHelper.js +181 -9
  76. package/examples/jsm/inspector/Inspector.js +487 -0
  77. package/examples/jsm/inspector/RendererInspector.js +425 -0
  78. package/examples/jsm/inspector/tabs/Console.js +238 -0
  79. package/examples/jsm/inspector/tabs/Parameters.js +348 -0
  80. package/examples/jsm/inspector/tabs/Performance.js +268 -0
  81. package/examples/jsm/inspector/tabs/Viewer.js +166 -0
  82. package/examples/jsm/inspector/ui/Graph.js +95 -0
  83. package/examples/jsm/inspector/ui/Item.js +170 -0
  84. package/examples/jsm/inspector/ui/List.js +75 -0
  85. package/examples/jsm/inspector/ui/Profiler.js +1975 -0
  86. package/examples/jsm/inspector/ui/Style.js +1613 -0
  87. package/examples/jsm/inspector/ui/Tab.js +233 -0
  88. package/examples/jsm/inspector/ui/Values.js +439 -0
  89. package/examples/jsm/inspector/ui/utils.js +56 -0
  90. package/examples/jsm/interactive/HTMLMesh.js +43 -12
  91. package/examples/jsm/interactive/InteractiveGroup.js +170 -52
  92. package/examples/jsm/interactive/SelectionBox.js +106 -9
  93. package/examples/jsm/interactive/SelectionHelper.js +76 -30
  94. package/examples/jsm/libs/demuxer_mp4.js +109 -0
  95. package/examples/jsm/libs/meshopt_decoder.module.js +76 -58
  96. package/examples/jsm/libs/motion-controllers.module.js +1 -1
  97. package/examples/jsm/lighting/TiledLighting.js +42 -0
  98. package/examples/jsm/lights/LightProbeGenerator.js +44 -7
  99. package/examples/jsm/lights/RectAreaLightTexturesLib.js +50 -14
  100. package/examples/jsm/lights/RectAreaLightUniformsLib.js +16 -0
  101. package/examples/jsm/lines/Line2.js +41 -4
  102. package/examples/jsm/lines/LineGeometry.js +80 -2
  103. package/examples/jsm/lines/LineMaterial.js +105 -5
  104. package/examples/jsm/lines/LineSegments2.js +54 -4
  105. package/examples/jsm/lines/LineSegmentsGeometry.js +65 -8
  106. package/examples/jsm/lines/Wireframe.js +41 -4
  107. package/examples/jsm/lines/WireframeGeometry2.js +27 -2
  108. package/examples/jsm/lines/webgpu/Line2.js +28 -2
  109. package/examples/jsm/lines/webgpu/LineSegments2.js +59 -24
  110. package/examples/jsm/lines/webgpu/Wireframe.js +86 -0
  111. package/examples/jsm/loaders/3DMLoader.js +78 -6
  112. package/examples/jsm/loaders/3MFLoader.js +148 -7
  113. package/examples/jsm/loaders/AMFLoader.js +34 -14
  114. package/examples/jsm/loaders/BVHLoader.js +59 -12
  115. package/examples/jsm/loaders/ColladaLoader.js +61 -4027
  116. package/examples/jsm/loaders/DDSLoader.js +68 -1
  117. package/examples/jsm/loaders/DRACOLoader.js +146 -22
  118. package/examples/jsm/loaders/EXRLoader.js +255 -34
  119. package/examples/jsm/loaders/FBXLoader.js +80 -42
  120. package/examples/jsm/loaders/FontLoader.js +83 -6
  121. package/examples/jsm/loaders/GCodeLoader.js +71 -14
  122. package/examples/jsm/loaders/GLTFLoader.js +381 -263
  123. package/examples/jsm/loaders/HDRCubeTextureLoader.js +52 -3
  124. package/examples/jsm/loaders/HDRLoader.js +485 -0
  125. package/examples/jsm/loaders/IESLoader.js +42 -0
  126. package/examples/jsm/loaders/KMZLoader.js +39 -6
  127. package/examples/jsm/loaders/KTX2Loader.js +124 -48
  128. package/examples/jsm/loaders/KTXLoader.js +31 -10
  129. package/examples/jsm/loaders/LDrawLoader.js +192 -145
  130. package/examples/jsm/loaders/LUT3dlLoader.js +47 -10
  131. package/examples/jsm/loaders/LUTCubeLoader.js +46 -9
  132. package/examples/jsm/loaders/LUTImageLoader.js +79 -38
  133. package/examples/jsm/loaders/LWOLoader.js +54 -59
  134. package/examples/jsm/loaders/LottieLoader.js +54 -1
  135. package/examples/jsm/loaders/MD2Loader.js +37 -1
  136. package/examples/jsm/loaders/MDDLoader.js +57 -12
  137. package/examples/jsm/loaders/MTLLoader.js +60 -35
  138. package/examples/jsm/loaders/MaterialXLoader.js +268 -34
  139. package/examples/jsm/loaders/NRRDLoader.js +40 -8
  140. package/examples/jsm/loaders/OBJLoader.js +51 -2
  141. package/examples/jsm/loaders/PCDLoader.js +173 -21
  142. package/examples/jsm/loaders/PDBLoader.js +41 -2
  143. package/examples/jsm/loaders/PLYLoader.js +70 -39
  144. package/examples/jsm/loaders/PVRLoader.js +25 -6
  145. package/examples/jsm/loaders/RGBELoader.js +6 -438
  146. package/examples/jsm/loaders/STLLoader.js +48 -38
  147. package/examples/jsm/loaders/SVGLoader.js +119 -25
  148. package/examples/jsm/loaders/TDSLoader.js +92 -74
  149. package/examples/jsm/loaders/TGALoader.js +23 -2
  150. package/examples/jsm/loaders/TIFFLoader.js +23 -0
  151. package/examples/jsm/loaders/TTFLoader.js +50 -3
  152. package/examples/jsm/loaders/USDLoader.js +279 -0
  153. package/examples/jsm/loaders/USDZLoader.js +4 -858
  154. package/examples/jsm/loaders/UltraHDRLoader.js +338 -166
  155. package/examples/jsm/loaders/VOXLoader.js +688 -87
  156. package/examples/jsm/loaders/VRMLLoader.js +121 -12
  157. package/examples/jsm/loaders/VTKLoader.js +77 -25
  158. package/examples/jsm/loaders/XYZLoader.js +36 -0
  159. package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
  160. package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
  161. package/examples/jsm/loaders/lwo/IFFParser.js +77 -77
  162. package/examples/jsm/loaders/usd/USDAParser.js +822 -0
  163. package/examples/jsm/loaders/usd/USDCParser.js +1852 -0
  164. package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
  165. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +183 -0
  166. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +154 -0
  167. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  168. package/examples/jsm/math/Capsule.js +91 -14
  169. package/examples/jsm/math/ColorConverter.js +22 -0
  170. package/examples/jsm/math/ColorSpaces.js +74 -2
  171. package/examples/jsm/math/ConvexHull.js +517 -93
  172. package/examples/jsm/math/ImprovedNoise.js +32 -15
  173. package/examples/jsm/math/Lut.js +113 -0
  174. package/examples/jsm/math/MeshSurfaceSampler.js +78 -13
  175. package/examples/jsm/math/OBB.js +141 -29
  176. package/examples/jsm/math/Octree.js +283 -7
  177. package/examples/jsm/math/SimplexNoise.js +68 -42
  178. package/examples/jsm/misc/ConvexObjectBreaker.js +45 -25
  179. package/examples/jsm/misc/GPUComputationRenderer.js +96 -20
  180. package/examples/jsm/misc/Gyroscope.js +12 -0
  181. package/examples/jsm/misc/MD2Character.js +117 -2
  182. package/examples/jsm/misc/MD2CharacterComplex.js +175 -11
  183. package/examples/jsm/misc/MorphAnimMesh.js +44 -0
  184. package/examples/jsm/misc/MorphBlendMesh.js +103 -0
  185. package/examples/jsm/misc/ProgressiveLightMap.js +100 -54
  186. package/examples/jsm/misc/ProgressiveLightMapGPU.js +322 -0
  187. package/examples/jsm/misc/RollerCoaster.js +57 -0
  188. package/examples/jsm/misc/TubePainter.js +437 -40
  189. package/examples/jsm/misc/Volume.js +123 -76
  190. package/examples/jsm/misc/VolumeSlice.js +95 -49
  191. package/examples/jsm/modifiers/CurveModifier.js +66 -38
  192. package/examples/jsm/modifiers/CurveModifierGPU.js +42 -19
  193. package/examples/jsm/modifiers/EdgeSplitModifier.js +20 -0
  194. package/examples/jsm/modifiers/SimplifyModifier.js +24 -10
  195. package/examples/jsm/modifiers/TessellateModifier.js +35 -2
  196. package/examples/jsm/objects/GroundedSkybox.js +25 -6
  197. package/examples/jsm/objects/Lensflare.js +94 -2
  198. package/examples/jsm/objects/LensflareMesh.js +64 -10
  199. package/examples/jsm/objects/MarchingCubes.js +90 -5
  200. package/examples/jsm/objects/Reflector.js +76 -2
  201. package/examples/jsm/objects/ReflectorForSSRPass.js +41 -0
  202. package/examples/jsm/objects/Refractor.js +62 -0
  203. package/examples/jsm/objects/ShadowMesh.js +54 -4
  204. package/examples/jsm/objects/Sky.js +106 -16
  205. package/examples/jsm/objects/SkyMesh.js +211 -38
  206. package/examples/jsm/objects/Water.js +49 -8
  207. package/examples/jsm/objects/Water2.js +49 -7
  208. package/examples/jsm/objects/Water2Mesh.js +50 -9
  209. package/examples/jsm/objects/WaterMesh.js +136 -43
  210. package/examples/jsm/physics/AmmoPhysics.js +60 -7
  211. package/examples/jsm/physics/JoltPhysics.js +65 -12
  212. package/examples/jsm/physics/RapierPhysics.js +217 -21
  213. package/examples/jsm/postprocessing/AfterimagePass.js +110 -29
  214. package/examples/jsm/postprocessing/BloomPass.js +128 -26
  215. package/examples/jsm/postprocessing/BokehPass.js +99 -22
  216. package/examples/jsm/postprocessing/ClearPass.js +54 -3
  217. package/examples/jsm/postprocessing/CubeTexturePass.js +82 -21
  218. package/examples/jsm/postprocessing/DotScreenPass.js +59 -10
  219. package/examples/jsm/postprocessing/EffectComposer.js +140 -6
  220. package/examples/jsm/postprocessing/FXAAPass.js +40 -0
  221. package/examples/jsm/postprocessing/FilmPass.js +54 -5
  222. package/examples/jsm/postprocessing/GTAOPass.js +202 -57
  223. package/examples/jsm/postprocessing/GlitchPass.js +86 -34
  224. package/examples/jsm/postprocessing/HalftonePass.js +65 -10
  225. package/examples/jsm/postprocessing/LUTPass.js +38 -8
  226. package/examples/jsm/postprocessing/MaskPass.js +91 -0
  227. package/examples/jsm/postprocessing/OutlinePass.js +272 -135
  228. package/examples/jsm/postprocessing/OutputPass.js +65 -14
  229. package/examples/jsm/postprocessing/Pass.js +100 -4
  230. package/examples/jsm/postprocessing/RenderPass.js +94 -0
  231. package/examples/jsm/postprocessing/RenderPixelatedPass.js +124 -45
  232. package/examples/jsm/postprocessing/RenderTransitionPass.js +120 -21
  233. package/examples/jsm/postprocessing/SAOPass.js +128 -55
  234. package/examples/jsm/postprocessing/SMAAPass.js +106 -75
  235. package/examples/jsm/postprocessing/SSAARenderPass.js +118 -35
  236. package/examples/jsm/postprocessing/SSAOPass.js +173 -60
  237. package/examples/jsm/postprocessing/SSRPass.js +268 -53
  238. package/examples/jsm/postprocessing/SavePass.js +69 -16
  239. package/examples/jsm/postprocessing/ShaderPass.js +65 -7
  240. package/examples/jsm/postprocessing/TAARenderPass.js +79 -24
  241. package/examples/jsm/postprocessing/TexturePass.js +72 -8
  242. package/examples/jsm/postprocessing/UnrealBloomPass.js +168 -59
  243. package/examples/jsm/renderers/CSS2DRenderer.js +98 -5
  244. package/examples/jsm/renderers/CSS3DRenderer.js +111 -7
  245. package/examples/jsm/renderers/Projector.js +288 -32
  246. package/examples/jsm/renderers/SVGRenderer.js +323 -61
  247. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +3 -1
  248. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +1 -1
  249. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +5 -1
  250. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +12 -5
  251. package/examples/jsm/shaders/AfterimageShader.js +8 -3
  252. package/examples/jsm/shaders/BasicShader.js +8 -1
  253. package/examples/jsm/shaders/BleachBypassShader.js +10 -3
  254. package/examples/jsm/shaders/BlendShader.js +8 -1
  255. package/examples/jsm/shaders/BokehShader.js +9 -3
  256. package/examples/jsm/shaders/BokehShader2.js +11 -4
  257. package/examples/jsm/shaders/BrightnessContrastShader.js +10 -4
  258. package/examples/jsm/shaders/ColorCorrectionShader.js +8 -1
  259. package/examples/jsm/shaders/ColorifyShader.js +8 -1
  260. package/examples/jsm/shaders/ConvolutionShader.js +9 -38
  261. package/examples/jsm/shaders/CopyShader.js +8 -1
  262. package/examples/jsm/shaders/DOFMipMapShader.js +10 -3
  263. package/examples/jsm/shaders/DepthLimitedBlurShader.js +10 -1
  264. package/examples/jsm/shaders/DigitalGlitch.js +10 -7
  265. package/examples/jsm/shaders/DotScreenShader.js +8 -3
  266. package/examples/jsm/shaders/ExposureShader.js +8 -1
  267. package/examples/jsm/shaders/FXAAShader.js +233 -221
  268. package/examples/jsm/shaders/FilmShader.js +13 -0
  269. package/examples/jsm/shaders/FocusShader.js +8 -3
  270. package/examples/jsm/shaders/FreiChenShader.js +10 -3
  271. package/examples/jsm/shaders/GTAOShader.js +55 -45
  272. package/examples/jsm/shaders/GammaCorrectionShader.js +11 -2
  273. package/examples/jsm/shaders/HalftoneShader.js +24 -4
  274. package/examples/jsm/shaders/HorizontalBlurShader.js +12 -3
  275. package/examples/jsm/shaders/HorizontalTiltShiftShader.js +9 -2
  276. package/examples/jsm/shaders/HueSaturationShader.js +10 -3
  277. package/examples/jsm/shaders/KaleidoShader.js +11 -4
  278. package/examples/jsm/shaders/LuminosityHighPassShader.js +8 -4
  279. package/examples/jsm/shaders/LuminosityShader.js +8 -2
  280. package/examples/jsm/shaders/MirrorShader.js +10 -4
  281. package/examples/jsm/shaders/NormalMapShader.js +7 -2
  282. package/examples/jsm/shaders/OutputShader.js +19 -1
  283. package/examples/jsm/shaders/PoissonDenoiseShader.js +30 -17
  284. package/examples/jsm/shaders/RGBShiftShader.js +8 -1
  285. package/examples/jsm/shaders/SAOShader.js +27 -5
  286. package/examples/jsm/shaders/SMAAShader.js +24 -1
  287. package/examples/jsm/shaders/SSAOShader.js +37 -6
  288. package/examples/jsm/shaders/SSRShader.js +32 -6
  289. package/examples/jsm/shaders/SepiaShader.js +8 -3
  290. package/examples/jsm/shaders/SobelOperatorShader.js +9 -3
  291. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +13 -8
  292. package/examples/jsm/shaders/TechnicolorShader.js +10 -4
  293. package/examples/jsm/shaders/ToonShader.js +29 -6
  294. package/examples/jsm/shaders/TriangleBlurShader.js +9 -4
  295. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +19 -6
  296. package/examples/jsm/shaders/VelocityShader.js +8 -1
  297. package/examples/jsm/shaders/VerticalBlurShader.js +9 -2
  298. package/examples/jsm/shaders/VerticalTiltShiftShader.js +8 -1
  299. package/examples/jsm/shaders/VignetteShader.js +8 -3
  300. package/examples/jsm/shaders/VolumeShader.js +11 -2
  301. package/examples/jsm/shaders/WaterRefractionShader.js +11 -0
  302. package/examples/jsm/textures/FlakesTexture.js +14 -0
  303. package/examples/jsm/transpiler/AST.js +436 -31
  304. package/examples/jsm/transpiler/GLSLDecoder.js +380 -135
  305. package/examples/jsm/transpiler/Linker.js +327 -0
  306. package/examples/jsm/transpiler/ShaderToyDecoder.js +3 -1
  307. package/examples/jsm/transpiler/TSLEncoder.js +363 -97
  308. package/examples/jsm/transpiler/Transpiler.js +50 -1
  309. package/examples/jsm/transpiler/TranspilerUtils.js +29 -0
  310. package/examples/jsm/transpiler/WGSLEncoder.js +839 -0
  311. package/examples/jsm/tsl/display/AfterImageNode.js +244 -0
  312. package/examples/jsm/tsl/display/AnaglyphPassNode.js +549 -0
  313. package/examples/jsm/tsl/display/AnamorphicNode.js +282 -0
  314. package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
  315. package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +11 -4
  316. package/examples/jsm/tsl/display/BloomNode.js +534 -0
  317. package/examples/jsm/tsl/display/CRT.js +150 -0
  318. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +207 -0
  319. package/examples/jsm/tsl/display/DenoiseNode.js +334 -0
  320. package/examples/jsm/tsl/display/DepthOfFieldNode.js +554 -0
  321. package/examples/jsm/tsl/display/DotScreenNode.js +104 -0
  322. package/examples/jsm/tsl/display/FXAANode.js +365 -0
  323. package/examples/jsm/tsl/display/FilmNode.js +101 -0
  324. package/examples/jsm/tsl/display/GTAONode.js +571 -0
  325. package/examples/jsm/tsl/display/GaussianBlurNode.js +389 -0
  326. package/examples/jsm/tsl/display/GodraysNode.js +624 -0
  327. package/examples/jsm/tsl/display/LensflareNode.js +279 -0
  328. package/examples/jsm/tsl/display/Lut3DNode.js +109 -0
  329. package/examples/jsm/tsl/display/MotionBlur.js +33 -0
  330. package/examples/jsm/tsl/display/OutlineNode.js +762 -0
  331. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +89 -0
  332. package/examples/jsm/tsl/display/PixelationPassNode.js +335 -0
  333. package/examples/jsm/tsl/display/RGBShiftNode.js +96 -0
  334. package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
  335. package/examples/jsm/tsl/display/SMAANode.js +768 -0
  336. package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +120 -49
  337. package/examples/jsm/tsl/display/SSGINode.js +642 -0
  338. package/examples/jsm/tsl/display/SSRNode.js +656 -0
  339. package/examples/jsm/tsl/display/SSSNode.js +490 -0
  340. package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +9 -2
  341. package/examples/jsm/tsl/display/Shape.js +29 -0
  342. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +61 -19
  343. package/examples/jsm/tsl/display/StereoCompositePassNode.js +192 -0
  344. package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +48 -12
  345. package/examples/jsm/tsl/display/TRAANode.js +726 -0
  346. package/examples/jsm/tsl/display/TransitionNode.js +141 -0
  347. package/examples/jsm/tsl/display/boxBlur.js +65 -0
  348. package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
  349. package/examples/jsm/tsl/display/hashBlur.js +54 -0
  350. package/examples/jsm/tsl/display/radialBlur.js +68 -0
  351. package/examples/jsm/tsl/lighting/TiledLightsNode.js +442 -0
  352. package/examples/jsm/tsl/math/Bayer.js +73 -0
  353. package/examples/jsm/tsl/shadows/TileShadowNode.js +456 -0
  354. package/examples/jsm/tsl/shadows/TileShadowNodeHelper.js +212 -0
  355. package/examples/jsm/tsl/utils/Raymarching.js +70 -0
  356. package/examples/jsm/utils/BufferGeometryUtils.js +91 -29
  357. package/examples/jsm/utils/CameraUtils.js +15 -6
  358. package/examples/jsm/utils/GeometryCompressionUtils.js +23 -30
  359. package/examples/jsm/utils/GeometryUtils.js +32 -27
  360. package/examples/jsm/utils/LDrawUtils.js +14 -5
  361. package/examples/jsm/utils/SceneOptimizer.js +458 -0
  362. package/examples/jsm/utils/SceneUtils.js +53 -3
  363. package/examples/jsm/utils/ShadowMapViewer.js +72 -33
  364. package/examples/jsm/utils/ShadowMapViewerGPU.js +61 -29
  365. package/examples/jsm/utils/SkeletonUtils.js +48 -0
  366. package/examples/jsm/utils/SortUtils.js +17 -5
  367. package/examples/jsm/utils/UVsDebug.js +12 -4
  368. package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +16 -0
  369. package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +20 -2
  370. package/examples/jsm/utils/WorkerPool.js +67 -2
  371. package/examples/jsm/webxr/ARButton.js +19 -0
  372. package/examples/jsm/webxr/OculusHandModel.js +84 -0
  373. package/examples/jsm/webxr/OculusHandPointerModel.js +148 -22
  374. package/examples/jsm/webxr/Text2D.js +20 -6
  375. package/examples/jsm/webxr/VRButton.js +31 -0
  376. package/examples/jsm/webxr/XRButton.js +23 -0
  377. package/examples/jsm/webxr/XRControllerModelFactory.js +94 -3
  378. package/examples/jsm/webxr/XREstimatedLight.js +35 -4
  379. package/examples/jsm/webxr/XRHandMeshModel.js +37 -0
  380. package/examples/jsm/webxr/XRHandModelFactory.js +96 -6
  381. package/examples/jsm/webxr/XRHandPrimitiveModel.js +44 -0
  382. package/examples/jsm/webxr/XRPlanes.js +18 -0
  383. package/package.json +29 -37
  384. package/src/Three.Core.js +198 -0
  385. package/src/Three.Legacy.js +0 -21
  386. package/src/Three.TSL.js +641 -0
  387. package/src/Three.WebGPU.Nodes.js +14 -186
  388. package/src/Three.WebGPU.js +16 -186
  389. package/src/Three.js +2 -197
  390. package/src/animation/AnimationAction.js +263 -31
  391. package/src/animation/AnimationClip.js +162 -7
  392. package/src/animation/AnimationMixer.js +105 -15
  393. package/src/animation/AnimationObjectGroup.js +45 -21
  394. package/src/animation/AnimationUtils.js +163 -24
  395. package/src/animation/KeyframeTrack.js +191 -17
  396. package/src/animation/PropertyBinding.js +91 -16
  397. package/src/animation/PropertyMixer.js +72 -5
  398. package/src/animation/tracks/BooleanKeyframeTrack.js +33 -6
  399. package/src/animation/tracks/ColorKeyframeTrack.js +26 -5
  400. package/src/animation/tracks/NumberKeyframeTrack.js +26 -2
  401. package/src/animation/tracks/QuaternionKeyframeTrack.js +30 -1
  402. package/src/animation/tracks/StringKeyframeTrack.js +33 -2
  403. package/src/animation/tracks/VectorKeyframeTrack.js +26 -2
  404. package/src/audio/Audio.js +386 -8
  405. package/src/audio/AudioAnalyser.js +58 -1
  406. package/src/audio/AudioContext.js +15 -0
  407. package/src/audio/AudioListener.js +94 -13
  408. package/src/audio/PositionalAudio.js +107 -0
  409. package/src/cameras/ArrayCamera.js +37 -0
  410. package/src/cameras/Camera.js +61 -0
  411. package/src/cameras/CubeCamera.js +86 -0
  412. package/src/cameras/OrthographicCamera.js +110 -1
  413. package/src/cameras/PerspectiveCamera.js +174 -35
  414. package/src/cameras/StereoCamera.js +48 -2
  415. package/src/constants.js +1546 -11
  416. package/src/core/BufferAttribute.js +417 -3
  417. package/src/core/BufferGeometry.js +407 -22
  418. package/src/core/Clock.js +69 -8
  419. package/src/core/EventDispatcher.js +52 -8
  420. package/src/core/GLBufferAttribute.js +113 -2
  421. package/src/core/InstancedBufferAttribute.js +29 -0
  422. package/src/core/InstancedBufferGeometry.js +20 -0
  423. package/src/core/InstancedInterleavedBuffer.js +26 -0
  424. package/src/core/InterleavedBuffer.js +141 -7
  425. package/src/core/InterleavedBufferAttribute.js +200 -2
  426. package/src/core/Layers.js +71 -10
  427. package/src/core/Object3D.js +673 -26
  428. package/src/core/Raycaster.js +136 -2
  429. package/src/core/RenderTarget.js +256 -27
  430. package/src/core/RenderTarget3D.js +48 -0
  431. package/src/core/Timer.js +184 -0
  432. package/src/core/Uniform.js +29 -0
  433. package/src/core/UniformsGroup.js +84 -2
  434. package/src/extras/Controls.js +89 -1
  435. package/src/extras/DataUtils.js +50 -9
  436. package/src/extras/Earcut.js +18 -779
  437. package/src/extras/ImageUtils.js +22 -14
  438. package/src/extras/PMREMGenerator.js +316 -67
  439. package/src/extras/ShapeUtils.js +24 -2
  440. package/src/extras/TextureUtils.js +101 -15
  441. package/src/extras/core/Curve.js +156 -55
  442. package/src/extras/core/CurvePath.js +63 -22
  443. package/src/extras/core/Interpolations.js +34 -2
  444. package/src/extras/core/Path.js +134 -1
  445. package/src/extras/core/Shape.js +66 -3
  446. package/src/extras/core/ShapePath.js +80 -4
  447. package/src/extras/curves/ArcCurve.js +22 -0
  448. package/src/extras/curves/CatmullRomCurve3.js +89 -18
  449. package/src/extras/curves/CubicBezierCurve.js +67 -0
  450. package/src/extras/curves/CubicBezierCurve3.js +50 -0
  451. package/src/extras/curves/EllipseCurve.js +102 -0
  452. package/src/extras/curves/LineCurve.js +36 -0
  453. package/src/extras/curves/LineCurve3.js +36 -0
  454. package/src/extras/curves/QuadraticBezierCurve.js +59 -0
  455. package/src/extras/curves/QuadraticBezierCurve3.js +43 -0
  456. package/src/extras/curves/SplineCurve.js +48 -0
  457. package/src/extras/lib/earcut.js +685 -0
  458. package/src/geometries/BoxGeometry.js +39 -0
  459. package/src/geometries/CapsuleGeometry.js +196 -11
  460. package/src/geometries/CircleGeometry.js +41 -0
  461. package/src/geometries/ConeGeometry.js +39 -0
  462. package/src/geometries/CylinderGeometry.js +42 -2
  463. package/src/geometries/DodecahedronGeometry.js +33 -0
  464. package/src/geometries/EdgesGeometry.js +30 -2
  465. package/src/geometries/ExtrudeGeometry.js +148 -52
  466. package/src/geometries/IcosahedronGeometry.js +33 -0
  467. package/src/geometries/LatheGeometry.js +44 -3
  468. package/src/geometries/OctahedronGeometry.js +33 -0
  469. package/src/geometries/PlaneGeometry.js +35 -0
  470. package/src/geometries/PolyhedronGeometry.js +30 -1
  471. package/src/geometries/RingGeometry.js +37 -0
  472. package/src/geometries/ShapeGeometry.js +38 -0
  473. package/src/geometries/SphereGeometry.js +38 -0
  474. package/src/geometries/TetrahedronGeometry.js +33 -0
  475. package/src/geometries/TorusGeometry.js +44 -3
  476. package/src/geometries/TorusKnotGeometry.js +39 -0
  477. package/src/geometries/TubeGeometry.js +50 -0
  478. package/src/geometries/WireframeGeometry.js +32 -0
  479. package/src/helpers/ArrowHelper.js +62 -5
  480. package/src/helpers/AxesHelper.js +28 -0
  481. package/src/helpers/Box3Helper.js +28 -0
  482. package/src/helpers/BoxHelper.js +43 -7
  483. package/src/helpers/CameraHelper.js +103 -27
  484. package/src/helpers/DirectionalLightHelper.js +55 -0
  485. package/src/helpers/GridHelper.js +26 -0
  486. package/src/helpers/HemisphereLightHelper.js +42 -0
  487. package/src/helpers/PlaneHelper.js +33 -0
  488. package/src/helpers/PointLightHelper.js +43 -24
  489. package/src/helpers/PolarGridHelper.js +30 -0
  490. package/src/helpers/SkeletonHelper.js +73 -7
  491. package/src/helpers/SpotLightHelper.js +43 -0
  492. package/src/lights/AmbientLight.js +25 -0
  493. package/src/lights/DirectionalLight.js +70 -0
  494. package/src/lights/DirectionalLightShadow.js +15 -0
  495. package/src/lights/HemisphereLight.js +42 -0
  496. package/src/lights/Light.js +37 -11
  497. package/src/lights/LightProbe.js +37 -9
  498. package/src/lights/LightShadow.js +202 -7
  499. package/src/lights/PointLight.js +74 -0
  500. package/src/lights/PointLightShadow.js +15 -80
  501. package/src/lights/RectAreaLight.js +59 -0
  502. package/src/lights/SpotLight.js +124 -1
  503. package/src/lights/SpotLightShadow.js +33 -3
  504. package/src/lights/webgpu/IESSpotLight.js +22 -0
  505. package/src/lights/webgpu/ProjectorLight.js +46 -0
  506. package/src/loaders/AnimationLoader.js +34 -2
  507. package/src/loaders/AudioLoader.js +34 -2
  508. package/src/loaders/BufferGeometryLoader.js +38 -13
  509. package/src/loaders/Cache.js +75 -2
  510. package/src/loaders/CompressedTextureLoader.js +36 -3
  511. package/src/loaders/CubeTextureLoader.js +45 -0
  512. package/src/loaders/DataTextureLoader.js +45 -4
  513. package/src/loaders/FileLoader.js +85 -5
  514. package/src/loaders/ImageBitmapLoader.js +113 -11
  515. package/src/loaders/ImageLoader.js +85 -8
  516. package/src/loaders/Loader.js +150 -0
  517. package/src/loaders/LoaderUtils.js +18 -36
  518. package/src/loaders/LoadingManager.js +187 -0
  519. package/src/loaders/MaterialLoader.js +62 -3
  520. package/src/loaders/ObjectLoader.js +131 -31
  521. package/src/loaders/TextureLoader.js +33 -0
  522. package/src/loaders/nodes/NodeLoader.js +68 -4
  523. package/src/loaders/nodes/NodeMaterialLoader.js +45 -0
  524. package/src/loaders/nodes/NodeObjectLoader.js +61 -0
  525. package/src/materials/LineBasicMaterial.js +74 -1
  526. package/src/materials/LineDashedMaterial.js +52 -1
  527. package/src/materials/Material.js +502 -8
  528. package/src/materials/MeshBasicMaterial.js +168 -2
  529. package/src/materials/MeshDepthMaterial.js +94 -0
  530. package/src/materials/MeshDistanceMaterial.js +76 -0
  531. package/src/materials/MeshLambertMaterial.js +283 -0
  532. package/src/materials/MeshMatcapMaterial.js +164 -0
  533. package/src/materials/MeshNormalMaterial.js +114 -0
  534. package/src/materials/MeshPhongMaterial.js +298 -0
  535. package/src/materials/MeshPhysicalMaterial.js +296 -4
  536. package/src/materials/MeshStandardMaterial.js +300 -2
  537. package/src/materials/MeshToonMaterial.js +219 -0
  538. package/src/materials/PointsMaterial.js +89 -0
  539. package/src/materials/RawShaderMaterial.js +25 -0
  540. package/src/materials/ShaderMaterial.js +234 -6
  541. package/src/materials/ShadowMaterial.js +54 -0
  542. package/src/materials/SpriteMaterial.js +82 -0
  543. package/src/materials/nodes/Line2NodeMaterial.js +158 -53
  544. package/src/materials/nodes/LineBasicNodeMaterial.js +17 -2
  545. package/src/materials/nodes/LineDashedNodeMaterial.js +81 -6
  546. package/src/materials/nodes/MeshBasicNodeMaterial.js +59 -2
  547. package/src/materials/nodes/MeshLambertNodeMaterial.js +35 -0
  548. package/src/materials/nodes/MeshMatcapNodeMaterial.js +23 -3
  549. package/src/materials/nodes/MeshNormalNodeMaterial.js +27 -4
  550. package/src/materials/nodes/MeshPhongNodeMaterial.js +64 -1
  551. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +276 -3
  552. package/src/materials/nodes/MeshSSSNodeMaterial.js +98 -10
  553. package/src/materials/nodes/MeshStandardNodeMaterial.js +83 -4
  554. package/src/materials/nodes/MeshToonNodeMaterial.js +28 -0
  555. package/src/materials/nodes/NodeMaterial.js +789 -74
  556. package/src/materials/nodes/NodeMaterials.js +0 -1
  557. package/src/materials/nodes/PointsNodeMaterial.js +180 -11
  558. package/src/materials/nodes/ShadowNodeMaterial.js +38 -0
  559. package/src/materials/nodes/SpriteNodeMaterial.js +86 -23
  560. package/src/materials/nodes/VolumeNodeMaterial.js +57 -84
  561. package/src/materials/nodes/manager/NodeMaterialObserver.js +329 -12
  562. package/src/math/Box2.js +177 -0
  563. package/src/math/Box3.js +271 -0
  564. package/src/math/Color.js +355 -11
  565. package/src/math/ColorManagement.js +158 -92
  566. package/src/math/Cylindrical.js +65 -6
  567. package/src/math/Euler.js +139 -5
  568. package/src/math/Frustum.js +108 -9
  569. package/src/math/FrustumArray.js +258 -0
  570. package/src/math/Interpolant.js +87 -8
  571. package/src/math/Line3.js +221 -2
  572. package/src/math/MathUtils.js +408 -20
  573. package/src/math/Matrix2.js +70 -0
  574. package/src/math/Matrix3.js +229 -4
  575. package/src/math/Matrix4.js +489 -94
  576. package/src/math/Plane.js +164 -2
  577. package/src/math/Quaternion.js +322 -90
  578. package/src/math/Ray.js +162 -0
  579. package/src/math/Sphere.js +175 -0
  580. package/src/math/Spherical.js +73 -11
  581. package/src/math/SphericalHarmonics3.js +112 -14
  582. package/src/math/Triangle.js +206 -2
  583. package/src/math/Vector2.js +396 -10
  584. package/src/math/Vector3.js +550 -15
  585. package/src/math/Vector4.js +415 -9
  586. package/src/math/interpolants/BezierInterpolant.js +108 -0
  587. package/src/math/interpolants/CubicInterpolant.js +10 -1
  588. package/src/math/interpolants/DiscreteInterpolant.js +10 -2
  589. package/src/math/interpolants/LinearInterpolant.js +13 -0
  590. package/src/math/interpolants/QuaternionLinearInterpolant.js +10 -1
  591. package/src/nodes/Nodes.js +91 -88
  592. package/src/nodes/TSL.js +32 -38
  593. package/src/nodes/accessors/AccessorsUtils.js +37 -9
  594. package/src/nodes/accessors/Arrays.js +68 -0
  595. package/src/nodes/accessors/BatchNode.js +49 -14
  596. package/src/nodes/accessors/Bitangent.js +82 -13
  597. package/src/nodes/accessors/BufferAttributeNode.js +269 -8
  598. package/src/nodes/accessors/BufferNode.js +91 -2
  599. package/src/nodes/accessors/BuiltinNode.js +63 -0
  600. package/src/nodes/accessors/Camera.js +400 -10
  601. package/src/nodes/accessors/ClippingNode.js +149 -45
  602. package/src/nodes/accessors/CubeTextureNode.js +137 -7
  603. package/src/nodes/accessors/InstanceNode.js +245 -40
  604. package/src/nodes/accessors/InstancedMeshNode.js +50 -0
  605. package/src/nodes/accessors/Lights.js +88 -0
  606. package/src/nodes/accessors/MaterialNode.js +355 -13
  607. package/src/nodes/accessors/MaterialProperties.js +57 -1
  608. package/src/nodes/accessors/MaterialReferenceNode.js +52 -14
  609. package/src/nodes/accessors/ModelNode.js +117 -5
  610. package/src/nodes/accessors/ModelViewProjectionNode.js +10 -39
  611. package/src/nodes/accessors/MorphNode.js +73 -26
  612. package/src/nodes/accessors/Normal.js +174 -19
  613. package/src/nodes/accessors/Object3DNode.js +146 -12
  614. package/src/nodes/accessors/PointUVNode.js +25 -0
  615. package/src/nodes/accessors/Position.js +119 -7
  616. package/src/nodes/accessors/ReferenceBaseNode.js +190 -4
  617. package/src/nodes/accessors/ReferenceNode.js +223 -8
  618. package/src/nodes/accessors/ReflectVector.js +29 -3
  619. package/src/nodes/accessors/RendererReferenceNode.js +45 -2
  620. package/src/nodes/accessors/SceneProperties.js +53 -0
  621. package/src/nodes/accessors/SkinningNode.js +180 -43
  622. package/src/nodes/accessors/StorageBufferNode.js +278 -26
  623. package/src/nodes/accessors/StorageTextureNode.js +205 -12
  624. package/src/nodes/accessors/Tangent.js +48 -10
  625. package/src/nodes/accessors/TangentUtils.js +46 -0
  626. package/src/nodes/accessors/Texture3DNode.js +104 -11
  627. package/src/nodes/accessors/TextureBicubic.js +31 -4
  628. package/src/nodes/accessors/TextureNode.js +564 -52
  629. package/src/nodes/accessors/TextureSizeNode.js +42 -1
  630. package/src/nodes/accessors/UV.js +9 -1
  631. package/src/nodes/accessors/UniformArrayNode.js +226 -34
  632. package/src/nodes/accessors/UserDataNode.js +46 -2
  633. package/src/nodes/accessors/VelocityNode.js +93 -3
  634. package/src/nodes/accessors/VertexColorNode.js +39 -4
  635. package/src/nodes/code/CodeNode.js +101 -8
  636. package/src/nodes/code/ExpressionNode.js +29 -2
  637. package/src/nodes/code/FunctionCallNode.js +98 -10
  638. package/src/nodes/code/FunctionNode.js +69 -2
  639. package/src/nodes/core/ArrayNode.js +174 -0
  640. package/src/nodes/core/AssignNode.js +80 -9
  641. package/src/nodes/core/AttributeNode.js +47 -4
  642. package/src/nodes/core/BypassNode.js +47 -3
  643. package/src/nodes/core/ConstNode.js +32 -0
  644. package/src/nodes/core/ContextNode.js +220 -14
  645. package/src/nodes/core/IndexNode.js +72 -7
  646. package/src/nodes/core/InputNode.js +50 -1
  647. package/src/nodes/core/InspectorNode.js +128 -0
  648. package/src/nodes/core/IsolateNode.js +133 -0
  649. package/src/nodes/core/LightingModel.js +65 -5
  650. package/src/nodes/core/MRTNode.js +113 -2
  651. package/src/nodes/core/Node.js +595 -36
  652. package/src/nodes/core/NodeAttribute.js +38 -0
  653. package/src/nodes/core/NodeBuilder.js +1840 -121
  654. package/src/nodes/core/NodeCache.js +41 -2
  655. package/src/nodes/core/NodeCode.js +31 -0
  656. package/src/nodes/core/NodeError.js +28 -0
  657. package/src/nodes/core/NodeFrame.js +153 -24
  658. package/src/nodes/core/NodeFunction.js +48 -1
  659. package/src/nodes/core/NodeFunctionInput.js +44 -0
  660. package/src/nodes/core/NodeParser.js +13 -1
  661. package/src/nodes/core/NodeUniform.js +53 -1
  662. package/src/nodes/core/NodeUtils.js +201 -51
  663. package/src/nodes/core/NodeVar.js +47 -1
  664. package/src/nodes/core/NodeVarying.js +47 -1
  665. package/src/nodes/core/OutputStructNode.js +54 -12
  666. package/src/nodes/core/ParameterNode.js +60 -2
  667. package/src/nodes/core/PropertyNode.js +286 -7
  668. package/src/nodes/core/StackNode.js +337 -20
  669. package/src/nodes/core/StackTrace.js +139 -0
  670. package/src/nodes/core/StructNode.js +134 -0
  671. package/src/nodes/core/StructType.js +13 -0
  672. package/src/nodes/core/StructTypeNode.js +126 -6
  673. package/src/nodes/core/SubBuildNode.js +89 -0
  674. package/src/nodes/core/TempNode.js +31 -5
  675. package/src/nodes/core/UniformGroupNode.js +85 -7
  676. package/src/nodes/core/UniformNode.js +163 -16
  677. package/src/nodes/core/VarNode.js +317 -10
  678. package/src/nodes/core/VaryingNode.js +115 -13
  679. package/src/nodes/core/constants.js +40 -0
  680. package/src/nodes/display/BlendModes.js +171 -0
  681. package/src/nodes/display/BumpMapNode.js +38 -2
  682. package/src/nodes/display/ColorAdjustment.js +118 -6
  683. package/src/nodes/display/ColorSpaceFunctions.js +22 -6
  684. package/src/nodes/display/ColorSpaceNode.js +97 -47
  685. package/src/nodes/display/FrontFacingNode.js +64 -7
  686. package/src/nodes/display/NormalMapNode.js +101 -54
  687. package/src/nodes/display/PassNode.js +690 -33
  688. package/src/nodes/display/RenderOutputNode.js +94 -4
  689. package/src/nodes/display/ScreenNode.js +138 -27
  690. package/src/nodes/display/ToneMappingFunctions.js +62 -10
  691. package/src/nodes/display/ToneMappingNode.js +88 -8
  692. package/src/nodes/display/ToonOutlinePassNode.js +84 -4
  693. package/src/nodes/display/ViewportDepthNode.js +227 -10
  694. package/src/nodes/display/ViewportDepthTextureNode.js +39 -5
  695. package/src/nodes/display/ViewportSharedTextureNode.js +35 -1
  696. package/src/nodes/display/ViewportTextureNode.js +171 -7
  697. package/src/nodes/fog/Fog.js +97 -0
  698. package/src/nodes/functions/BSDF/BRDF_GGX.js +2 -6
  699. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
  700. package/src/nodes/functions/BSDF/BRDF_Sheen.js +4 -4
  701. package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
  702. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  703. package/src/nodes/functions/BSDF/LTC.js +45 -1
  704. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +1 -1
  705. package/src/nodes/functions/BasicLightingModel.js +28 -6
  706. package/src/nodes/functions/PhongLightingModel.js +36 -6
  707. package/src/nodes/functions/PhysicalLightingModel.js +336 -91
  708. package/src/nodes/functions/ShadowMaskModel.js +30 -3
  709. package/src/nodes/functions/ToonLightingModel.js +21 -2
  710. package/src/nodes/functions/VolumetricLightingModel.js +183 -0
  711. package/src/nodes/functions/material/getAlphaHashThreshold.js +68 -0
  712. package/src/nodes/functions/material/getGeometryRoughness.js +10 -4
  713. package/src/nodes/functions/material/getParallaxCorrectNormal.js +37 -0
  714. package/src/nodes/geometry/RangeNode.js +97 -8
  715. package/src/nodes/gpgpu/AtomicFunctionNode.js +198 -23
  716. package/src/nodes/gpgpu/BarrierNode.js +52 -3
  717. package/src/nodes/gpgpu/ComputeBuiltinNode.js +135 -6
  718. package/src/nodes/gpgpu/ComputeNode.js +212 -16
  719. package/src/nodes/gpgpu/SubgroupFunctionNode.js +455 -0
  720. package/src/nodes/gpgpu/WorkgroupInfoNode.js +143 -9
  721. package/src/nodes/lighting/AONode.js +18 -0
  722. package/src/nodes/lighting/AmbientLightNode.js +10 -0
  723. package/src/nodes/lighting/AnalyticLightNode.js +186 -399
  724. package/src/nodes/lighting/BasicEnvironmentNode.js +19 -0
  725. package/src/nodes/lighting/BasicLightMapNode.js +17 -0
  726. package/src/nodes/lighting/DirectionalLightNode.js +12 -11
  727. package/src/nodes/lighting/EnvironmentNode.js +59 -19
  728. package/src/nodes/lighting/HemisphereLightNode.js +33 -2
  729. package/src/nodes/lighting/IESSpotLightNode.js +13 -1
  730. package/src/nodes/lighting/IrradianceNode.js +17 -0
  731. package/src/nodes/lighting/LightProbeNode.js +20 -0
  732. package/src/nodes/lighting/LightUtils.js +11 -3
  733. package/src/nodes/lighting/LightingContextNode.js +52 -4
  734. package/src/nodes/lighting/LightingNode.js +15 -6
  735. package/src/nodes/lighting/LightsNode.js +238 -35
  736. package/src/nodes/lighting/PointLightNode.js +60 -25
  737. package/src/nodes/lighting/PointShadowNode.js +325 -0
  738. package/src/nodes/lighting/ProjectorLightNode.js +91 -0
  739. package/src/nodes/lighting/RectAreaLightNode.js +50 -14
  740. package/src/nodes/lighting/ShadowBaseNode.js +81 -0
  741. package/src/nodes/lighting/ShadowFilterNode.js +264 -0
  742. package/src/nodes/lighting/ShadowNode.js +867 -0
  743. package/src/nodes/lighting/SpotLightNode.js +99 -18
  744. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  745. package/src/nodes/materialx/lib/mx_noise.js +166 -2
  746. package/src/nodes/math/BitcastNode.js +156 -0
  747. package/src/nodes/math/BitcountNode.js +433 -0
  748. package/src/nodes/math/ConditionalNode.js +110 -21
  749. package/src/nodes/math/Hash.js +8 -0
  750. package/src/nodes/math/MathNode.js +820 -97
  751. package/src/nodes/math/MathUtils.js +47 -1
  752. package/src/nodes/math/OperatorNode.js +517 -84
  753. package/src/nodes/math/PackFloatNode.js +98 -0
  754. package/src/nodes/math/TriNoise3D.js +17 -7
  755. package/src/nodes/math/UnpackFloatNode.js +96 -0
  756. package/src/nodes/parsers/GLSLNodeFunction.js +16 -0
  757. package/src/nodes/parsers/GLSLNodeParser.js +11 -0
  758. package/src/nodes/pmrem/PMREMNode.js +180 -23
  759. package/src/nodes/pmrem/PMREMUtils.js +114 -5
  760. package/src/nodes/procedural/Checker.js +8 -0
  761. package/src/nodes/shapes/Shapes.js +33 -0
  762. package/src/nodes/tsl/TSLBase.js +10 -4
  763. package/src/nodes/tsl/TSLCore.js +732 -160
  764. package/src/nodes/utils/ArrayElementNode.js +55 -4
  765. package/src/nodes/utils/ConvertNode.js +31 -0
  766. package/src/nodes/utils/CubeMapNode.js +79 -2
  767. package/src/nodes/utils/DebugNode.js +83 -0
  768. package/src/nodes/utils/Discard.js +18 -2
  769. package/src/nodes/utils/EquirectUV.js +27 -0
  770. package/src/nodes/utils/EventNode.js +118 -0
  771. package/src/nodes/utils/FlipNode.js +38 -0
  772. package/src/nodes/utils/FunctionOverloadingNode.js +91 -22
  773. package/src/nodes/utils/JoinNode.js +57 -4
  774. package/src/nodes/utils/LoopNode.js +193 -55
  775. package/src/nodes/utils/MatcapUV.js +22 -0
  776. package/src/nodes/utils/MaxMipLevelNode.js +49 -1
  777. package/src/nodes/utils/MemberNode.js +120 -0
  778. package/src/nodes/utils/Oscillators.js +41 -0
  779. package/src/nodes/utils/Packing.js +30 -1
  780. package/src/nodes/utils/PostProcessingUtils.js +154 -0
  781. package/src/nodes/utils/RTTNode.js +165 -9
  782. package/src/nodes/utils/ReflectorNode.js +407 -21
  783. package/src/nodes/utils/RemapNode.js +81 -2
  784. package/src/nodes/utils/RotateNode.js +41 -1
  785. package/src/nodes/utils/SampleNode.js +91 -0
  786. package/src/nodes/utils/SetNode.js +44 -1
  787. package/src/nodes/utils/SplitNode.js +66 -3
  788. package/src/nodes/utils/SpriteSheetUV.js +35 -0
  789. package/src/nodes/utils/SpriteUtils.js +16 -0
  790. package/src/nodes/utils/StorageArrayElementNode.js +56 -3
  791. package/src/nodes/utils/Timer.js +26 -0
  792. package/src/nodes/utils/TriplanarTextures.js +65 -0
  793. package/src/nodes/utils/UVUtils.js +48 -0
  794. package/src/nodes/utils/ViewportUtils.js +12 -0
  795. package/src/objects/BatchedMesh.js +798 -309
  796. package/src/objects/Bone.js +24 -0
  797. package/src/objects/ClippingGroup.js +68 -0
  798. package/src/objects/Group.js +24 -0
  799. package/src/objects/InstancedMesh.js +131 -2
  800. package/src/objects/LOD.js +99 -5
  801. package/src/objects/Line.js +90 -7
  802. package/src/objects/LineLoop.js +20 -0
  803. package/src/objects/LineSegments.js +20 -1
  804. package/src/objects/Mesh.js +84 -0
  805. package/src/objects/Points.js +60 -0
  806. package/src/objects/Skeleton.js +120 -5
  807. package/src/objects/SkinnedMesh.js +102 -6
  808. package/src/objects/Sprite.js +65 -1
  809. package/src/renderers/WebGL3DRenderTarget.js +26 -0
  810. package/src/renderers/WebGLArrayRenderTarget.js +26 -0
  811. package/src/renderers/WebGLCubeRenderTarget.js +41 -5
  812. package/src/renderers/WebGLRenderTarget.js +19 -0
  813. package/src/renderers/WebGLRenderer.js +1016 -278
  814. package/src/renderers/common/Animation.js +123 -14
  815. package/src/renderers/common/Attributes.js +41 -1
  816. package/src/renderers/common/Backend.js +623 -44
  817. package/src/renderers/common/Background.js +99 -16
  818. package/src/renderers/common/BindGroup.js +37 -2
  819. package/src/renderers/common/Binding.js +46 -0
  820. package/src/renderers/common/Bindings.js +211 -20
  821. package/src/renderers/common/BlendMode.js +143 -0
  822. package/src/renderers/common/Buffer.js +89 -0
  823. package/src/renderers/common/BufferUtils.js +25 -0
  824. package/src/renderers/common/BundleGroup.js +57 -0
  825. package/src/renderers/common/CanvasTarget.js +341 -0
  826. package/src/renderers/common/ChainMap.js +73 -10
  827. package/src/renderers/common/ClippingContext.js +172 -87
  828. package/src/renderers/common/Color4.js +40 -0
  829. package/src/renderers/common/ComputePipeline.js +24 -0
  830. package/src/renderers/common/Constants.js +2 -1
  831. package/src/renderers/common/CubeRenderTarget.js +77 -7
  832. package/src/renderers/common/DataMap.js +37 -1
  833. package/src/renderers/common/Geometries.js +163 -14
  834. package/src/renderers/common/IndirectStorageBufferAttribute.js +38 -0
  835. package/src/renderers/common/Info.js +81 -36
  836. package/src/renderers/common/InspectorBase.js +146 -0
  837. package/src/renderers/common/Lighting.js +57 -0
  838. package/src/renderers/common/Pipeline.js +22 -0
  839. package/src/renderers/common/Pipelines.js +150 -7
  840. package/src/renderers/common/PostProcessing.js +22 -84
  841. package/src/renderers/common/ProgrammableStage.js +60 -2
  842. package/src/renderers/common/QuadMesh.js +63 -6
  843. package/src/renderers/common/RenderBundle.js +14 -8
  844. package/src/renderers/common/RenderBundles.js +40 -10
  845. package/src/renderers/common/RenderContext.js +219 -4
  846. package/src/renderers/common/RenderContexts.js +54 -17
  847. package/src/renderers/common/RenderList.js +233 -24
  848. package/src/renderers/common/RenderLists.js +46 -6
  849. package/src/renderers/common/RenderObject.js +548 -46
  850. package/src/renderers/common/RenderObjectPipeline.js +40 -0
  851. package/src/renderers/common/RenderObjects.js +133 -15
  852. package/src/renderers/common/RenderPipeline.js +216 -6
  853. package/src/renderers/common/Renderer.js +2155 -332
  854. package/src/renderers/common/RendererUtils.js +200 -0
  855. package/src/renderers/common/SampledTexture.js +99 -39
  856. package/src/renderers/common/Sampler.js +148 -1
  857. package/src/renderers/common/Storage3DTexture.js +100 -0
  858. package/src/renderers/common/StorageArrayTexture.js +84 -0
  859. package/src/renderers/common/StorageBuffer.js +38 -2
  860. package/src/renderers/common/StorageBufferAttribute.js +31 -2
  861. package/src/renderers/common/StorageInstancedBufferAttribute.js +31 -2
  862. package/src/renderers/common/StorageTexture.js +65 -0
  863. package/src/renderers/common/Textures.js +273 -57
  864. package/src/renderers/common/TimestampQueryPool.js +163 -0
  865. package/src/renderers/common/Uniform.js +233 -3
  866. package/src/renderers/common/UniformBuffer.js +19 -0
  867. package/src/renderers/common/UniformsGroup.js +235 -26
  868. package/src/renderers/common/XRManager.js +1677 -0
  869. package/src/renderers/common/XRRenderTarget.js +91 -0
  870. package/src/renderers/common/extras/PMREMGenerator.js +371 -108
  871. package/src/renderers/common/nodes/NodeBuilderState.js +100 -6
  872. package/src/renderers/common/nodes/NodeLibrary.js +95 -17
  873. package/src/renderers/common/nodes/NodeManager.js +852 -0
  874. package/src/renderers/common/nodes/NodeSampledTexture.js +84 -8
  875. package/src/renderers/common/nodes/NodeSampler.js +41 -1
  876. package/src/renderers/common/nodes/NodeStorageBuffer.js +48 -3
  877. package/src/renderers/common/nodes/NodeUniform.js +285 -2
  878. package/src/renderers/common/nodes/NodeUniformBuffer.js +81 -0
  879. package/src/renderers/common/nodes/NodeUniformsGroup.js +31 -18
  880. package/src/renderers/shaders/DFGLUTData.js +49 -0
  881. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
  882. package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
  883. package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
  884. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
  885. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
  886. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  887. package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
  888. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  889. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
  890. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
  891. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
  892. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +5 -2
  893. package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
  894. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
  895. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
  896. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +154 -59
  897. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  898. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  899. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  900. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  901. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  902. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
  903. package/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl.js +1 -1
  904. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +230 -181
  905. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  906. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  907. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +7 -7
  908. package/src/renderers/shaders/ShaderChunk.js +3 -3
  909. package/src/renderers/shaders/ShaderLib/background.glsl.js +1 -1
  910. package/src/renderers/shaders/ShaderLib/depth.glsl.js +14 -2
  911. package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +1 -2
  912. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
  913. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
  914. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
  915. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
  916. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
  917. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -1
  918. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
  919. package/src/renderers/shaders/ShaderLib.js +7 -5
  920. package/src/renderers/shaders/UniformsLib.js +2 -7
  921. package/src/renderers/shaders/UniformsUtils.js +21 -2
  922. package/src/renderers/webgl/WebGLAttributes.js +4 -0
  923. package/src/renderers/webgl/WebGLBackground.js +30 -5
  924. package/src/renderers/webgl/WebGLBindingStates.js +99 -27
  925. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  926. package/src/renderers/webgl/WebGLCapabilities.js +7 -14
  927. package/src/renderers/webgl/WebGLEnvironments.js +228 -0
  928. package/src/renderers/webgl/WebGLExtensions.js +2 -25
  929. package/src/renderers/webgl/WebGLGeometries.js +10 -35
  930. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  931. package/src/renderers/webgl/WebGLInfo.js +3 -1
  932. package/src/renderers/webgl/WebGLLights.js +18 -1
  933. package/src/renderers/webgl/WebGLMaterials.js +12 -0
  934. package/src/renderers/webgl/WebGLObjects.js +3 -1
  935. package/src/renderers/webgl/WebGLOutput.js +267 -0
  936. package/src/renderers/webgl/WebGLProgram.js +87 -148
  937. package/src/renderers/webgl/WebGLPrograms.js +53 -51
  938. package/src/renderers/webgl/WebGLRenderLists.js +15 -0
  939. package/src/renderers/webgl/WebGLShadowMap.js +204 -28
  940. package/src/renderers/webgl/WebGLState.js +88 -56
  941. package/src/renderers/webgl/WebGLTextures.js +293 -59
  942. package/src/renderers/webgl/WebGLUniforms.js +40 -3
  943. package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
  944. package/src/renderers/webgl/WebGLUtils.js +7 -5
  945. package/src/renderers/webgl-fallback/WebGLBackend.js +1416 -293
  946. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +5 -10
  947. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +785 -92
  948. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +62 -1
  949. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +28 -0
  950. package/src/renderers/webgl-fallback/utils/WebGLConstants.js +3 -3
  951. package/src/renderers/webgl-fallback/utils/WebGLExtensions.js +45 -0
  952. package/src/renderers/webgl-fallback/utils/WebGLState.js +584 -20
  953. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +468 -80
  954. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +396 -0
  955. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +72 -24
  956. package/src/renderers/webgpu/WebGPUBackend.js +1517 -428
  957. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +31 -4
  958. package/src/renderers/webgpu/WebGPURenderer.js +55 -4
  959. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +23 -16
  960. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +37 -42
  961. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +1335 -241
  962. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +32 -4
  963. package/src/renderers/webgpu/nodes/WGSLNodeParser.js +11 -0
  964. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +144 -20
  965. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +460 -116
  966. package/src/renderers/webgpu/utils/WebGPUConstants.js +17 -4
  967. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +283 -69
  968. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +225 -178
  969. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +583 -191
  970. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +310 -0
  971. package/src/renderers/webgpu/utils/WebGPUUtils.js +150 -28
  972. package/src/renderers/webxr/WebXRController.js +87 -2
  973. package/src/renderers/webxr/WebXRDepthSensing.js +52 -7
  974. package/src/renderers/webxr/WebXRManager.js +275 -15
  975. package/src/scenes/Fog.js +60 -0
  976. package/src/scenes/FogExp2.js +51 -0
  977. package/src/scenes/Scene.js +88 -0
  978. package/src/textures/CanvasTexture.js +28 -0
  979. package/src/textures/CompressedArrayTexture.js +57 -0
  980. package/src/textures/CompressedCubeTexture.js +29 -0
  981. package/src/textures/CompressedTexture.js +64 -6
  982. package/src/textures/CubeDepthTexture.js +76 -0
  983. package/src/textures/CubeTexture.js +52 -4
  984. package/src/textures/Data3DTexture.js +79 -2
  985. package/src/textures/DataArrayTexture.js +93 -0
  986. package/src/textures/DataTexture.js +65 -0
  987. package/src/textures/DepthTexture.js +59 -11
  988. package/src/textures/ExternalTexture.js +56 -0
  989. package/src/textures/FramebufferTexture.js +62 -0
  990. package/src/textures/Source.js +106 -4
  991. package/src/textures/Texture.js +488 -6
  992. package/src/textures/VideoFrameTexture.js +72 -0
  993. package/src/textures/VideoTexture.js +78 -6
  994. package/src/utils.js +322 -3
  995. package/examples/jsm/animation/MMDAnimationHelper.js +0 -1207
  996. package/examples/jsm/animation/MMDPhysics.js +0 -1406
  997. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  998. package/examples/jsm/effects/PeppersGhostEffect.js +0 -153
  999. package/examples/jsm/exporters/MMDExporter.js +0 -217
  1000. package/examples/jsm/geometries/InstancedPointsGeometry.js +0 -174
  1001. package/examples/jsm/geometries/ParametricGeometries.js +0 -254
  1002. package/examples/jsm/libs/mmdparser.module.js +0 -11530
  1003. package/examples/jsm/loaders/GLTFLoaderAnimationPointer.js +0 -729
  1004. package/examples/jsm/loaders/MMDLoader.js +0 -2295
  1005. package/examples/jsm/loaders/RGBMLoader.js +0 -1081
  1006. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -432
  1007. package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -144
  1008. package/examples/jsm/misc/Timer.js +0 -128
  1009. package/examples/jsm/objects/InstancedPoints.js +0 -21
  1010. package/examples/jsm/shaders/GodRaysShader.js +0 -321
  1011. package/examples/jsm/shaders/MMDToonShader.js +0 -134
  1012. package/src/materials/nodes/InstancedPointsNodeMaterial.js +0 -156
  1013. package/src/nodes/accessors/InstancedPointsMaterialNode.js +0 -24
  1014. package/src/nodes/accessors/SceneNode.js +0 -55
  1015. package/src/nodes/code/ScriptableNode.js +0 -505
  1016. package/src/nodes/code/ScriptableValueNode.js +0 -170
  1017. package/src/nodes/core/CacheNode.js +0 -50
  1018. package/src/nodes/core/UniformGroup.js +0 -13
  1019. package/src/nodes/display/AfterImageNode.js +0 -158
  1020. package/src/nodes/display/AnaglyphPassNode.js +0 -67
  1021. package/src/nodes/display/AnamorphicNode.js +0 -151
  1022. package/src/nodes/display/BlendMode.js +0 -54
  1023. package/src/nodes/display/BloomNode.js +0 -341
  1024. package/src/nodes/display/DenoiseNode.js +0 -204
  1025. package/src/nodes/display/DepthOfFieldNode.js +0 -124
  1026. package/src/nodes/display/DotScreenNode.js +0 -66
  1027. package/src/nodes/display/FXAANode.js +0 -332
  1028. package/src/nodes/display/FilmNode.js +0 -56
  1029. package/src/nodes/display/GTAONode.js +0 -331
  1030. package/src/nodes/display/GaussianBlurNode.js +0 -213
  1031. package/src/nodes/display/Lut3DNode.js +0 -57
  1032. package/src/nodes/display/MotionBlur.js +0 -25
  1033. package/src/nodes/display/ParallaxBarrierPassNode.js +0 -58
  1034. package/src/nodes/display/PixelationPassNode.js +0 -213
  1035. package/src/nodes/display/PosterizeNode.js +0 -33
  1036. package/src/nodes/display/RGBShiftNode.js +0 -53
  1037. package/src/nodes/display/StereoCompositePassNode.js +0 -110
  1038. package/src/nodes/display/TransitionNode.js +0 -80
  1039. package/src/nodes/fog/FogExp2Node.js +0 -35
  1040. package/src/nodes/fog/FogNode.js +0 -50
  1041. package/src/nodes/fog/FogRangeNode.js +0 -36
  1042. package/src/nodes/functions/BSDF/DFGApprox.js +0 -30
  1043. package/src/nodes/utils/EquirectUVNode.js +0 -36
  1044. package/src/nodes/utils/MatcapUVNode.js +0 -33
  1045. package/src/nodes/utils/OscNode.js +0 -85
  1046. package/src/nodes/utils/SpriteSheetUVNode.js +0 -45
  1047. package/src/nodes/utils/TimerNode.js +0 -97
  1048. package/src/nodes/utils/TriplanarTexturesNode.js +0 -64
  1049. package/src/renderers/common/nodes/Nodes.js +0 -534
  1050. package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
  1051. package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -136
@@ -11,17 +11,32 @@ import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js';
11
11
  import { getFormat } from '../utils/WebGPUTextureUtils.js';
12
12
 
13
13
  import WGSLNodeParser from './WGSLNodeParser.js';
14
- import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js';
14
+ import { NodeAccess } from '../../../nodes/core/constants.js';
15
15
 
16
- import { NoColorSpace, FloatType } from '../../../constants.js';
16
+ import VarNode from '../../../nodes/core/VarNode.js';
17
+ import ExpressionNode from '../../../nodes/code/ExpressionNode.js';
17
18
 
18
- // GPUShaderStage is not defined in browsers not supporting WebGPU
19
- const GPUShaderStage = self.GPUShaderStage;
19
+ import { FloatType, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter, Compatibility } from '../../../constants.js';
20
+ import { warn, error } from '../../../utils.js';
21
+
22
+ import { GPUShaderStage } from '../utils/WebGPUConstants.js';
23
+
24
+ const accessNames = {
25
+ [ NodeAccess.READ_ONLY ]: 'read',
26
+ [ NodeAccess.WRITE_ONLY ]: 'write',
27
+ [ NodeAccess.READ_WRITE ]: 'read_write'
28
+ };
29
+
30
+ const wrapNames = {
31
+ [ RepeatWrapping ]: 'repeat',
32
+ [ ClampToEdgeWrapping ]: 'clamp',
33
+ [ MirroredRepeatWrapping ]: 'mirror'
34
+ };
20
35
 
21
36
  const gpuShaderStageLib = {
22
- 'vertex': GPUShaderStage ? GPUShaderStage.VERTEX : 1,
23
- 'fragment': GPUShaderStage ? GPUShaderStage.FRAGMENT : 2,
24
- 'compute': GPUShaderStage ? GPUShaderStage.COMPUTE : 4
37
+ 'vertex': GPUShaderStage.VERTEX,
38
+ 'fragment': GPUShaderStage.FRAGMENT,
39
+ 'compute': GPUShaderStage.COMPUTE
25
40
  };
26
41
 
27
42
  const supports = {
@@ -57,21 +72,12 @@ const wgslTypeLib = {
57
72
  bvec4: 'vec4<bool>',
58
73
 
59
74
  mat2: 'mat2x2<f32>',
60
- imat2: 'mat2x2<i32>',
61
- umat2: 'mat2x2<u32>',
62
- bmat2: 'mat2x2<bool>',
63
-
64
75
  mat3: 'mat3x3<f32>',
65
- imat3: 'mat3x3<i32>',
66
- umat3: 'mat3x3<u32>',
67
- bmat3: 'mat3x3<bool>',
68
-
69
- mat4: 'mat4x4<f32>',
70
- imat4: 'mat4x4<i32>',
71
- umat4: 'mat4x4<u32>',
72
- bmat4: 'mat4x4<bool>'
76
+ mat4: 'mat4x4<f32>'
73
77
  };
74
78
 
79
+ const wgslCodeCache = {};
80
+
75
81
  const wgslPolyfill = {
76
82
  tsl_xor: new CodeNode( 'fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }' ),
77
83
  mod_float: new CodeNode( 'fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }' ),
@@ -82,19 +88,35 @@ const wgslPolyfill = {
82
88
  equals_bvec2: new CodeNode( 'fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2<bool> { return vec2<bool>( a.x == b.x, a.y == b.y ); }' ),
83
89
  equals_bvec3: new CodeNode( 'fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3<bool> { return vec3<bool>( a.x == b.x, a.y == b.y, a.z == b.z ); }' ),
84
90
  equals_bvec4: new CodeNode( 'fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4<bool> { return vec4<bool>( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }' ),
85
- repeatWrapping: new CodeNode( `
86
- fn tsl_repeatWrapping( uv : vec2<f32>, dimension : vec2<u32> ) -> vec2<u32> {
91
+ repeatWrapping_float: new CodeNode( 'fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }' ),
92
+ mirrorWrapping_float: new CodeNode( 'fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }' ),
93
+ clampWrapping_float: new CodeNode( 'fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }' ),
94
+ biquadraticTexture: new CodeNode( /* wgsl */`
95
+ fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f {
87
96
 
88
- let uvScaled = vec2<u32>( uv * vec2<f32>( dimension ) );
97
+ let res = vec2f( iRes );
89
98
 
90
- return ( ( uvScaled % dimension ) + dimension ) % dimension;
99
+ let uvScaled = coord * res;
100
+ let uvWrapping = ( ( uvScaled % res ) + res ) % res;
101
+
102
+ // https://www.shadertoy.com/view/WtyXRy
103
+
104
+ let uv = uvWrapping - 0.5;
105
+ let iuv = floor( uv );
106
+ let f = fract( uv );
107
+
108
+ let rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, level );
109
+ let rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, level );
110
+ let rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, level );
111
+ let rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, level );
112
+
113
+ return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );
91
114
 
92
115
  }
93
116
  ` ),
94
- biquadraticTexture: new CodeNode( `
95
- fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, level : i32 ) -> vec4f {
117
+ biquadraticTextureArray: new CodeNode( /* wgsl */`
118
+ fn tsl_biquadraticTexture_array( map : texture_2d_array<f32>, coord : vec2f, iRes : vec2u, layer : u32, level : u32 ) -> vec4f {
96
119
 
97
- let iRes = vec2i( textureDimensions( map, level ) );
98
120
  let res = vec2f( iRes );
99
121
 
100
122
  let uvScaled = coord * res;
@@ -106,10 +128,10 @@ fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, level : i32 ) -
106
128
  let iuv = floor( uv );
107
129
  let f = fract( uv );
108
130
 
109
- let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ) % iRes, level );
110
- let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ) % iRes, level );
111
- let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ) % iRes, level );
112
- let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ) % iRes, level );
131
+ let rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, layer, level );
132
+ let rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, layer, level );
133
+ let rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, layer, level );
134
+ let rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, layer, level );
113
135
 
114
136
  return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );
115
137
 
@@ -129,176 +151,591 @@ const wgslMethods = {
129
151
  equals_bvec3: 'tsl_equals_bvec3',
130
152
  equals_bvec4: 'tsl_equals_bvec4',
131
153
  inversesqrt: 'inverseSqrt',
132
- bitcast: 'bitcast<f32>'
154
+ bitcast: 'bitcast<f32>',
155
+ floatpack_snorm_2x16: 'pack2x16snorm',
156
+ floatpack_unorm_2x16: 'pack2x16unorm',
157
+ floatpack_float16_2x16: 'pack2x16float',
158
+ floatunpack_snorm_2x16: 'unpack2x16snorm',
159
+ floatunpack_unorm_2x16: 'unpack2x16unorm',
160
+ floatunpack_float16_2x16: 'unpack2x16float'
133
161
  };
134
162
 
135
- // WebGPU issue: does not support pow() with negative base on Windows
136
-
137
- if ( /Windows/g.test( navigator.userAgent ) ) {
138
-
139
- wgslPolyfill.pow_float = new CodeNode( 'fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }' );
140
- wgslPolyfill.pow_vec2 = new CodeNode( 'fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }', [ wgslPolyfill.pow_float ] );
141
- wgslPolyfill.pow_vec3 = new CodeNode( 'fn tsl_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ) ); }', [ wgslPolyfill.pow_float ] );
142
- wgslPolyfill.pow_vec4 = new CodeNode( 'fn tsl_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ), tsl_pow_float( a.w, b.w ) ); }', [ wgslPolyfill.pow_float ] );
143
-
144
- wgslMethods.pow_float = 'tsl_pow_float';
145
- wgslMethods.pow_vec2 = 'tsl_pow_vec2';
146
- wgslMethods.pow_vec3 = 'tsl_pow_vec3';
147
- wgslMethods.pow_vec4 = 'tsl_pow_vec4';
148
-
149
- }
150
-
151
163
  //
152
164
 
153
165
  let diagnostics = '';
154
166
 
155
- if ( /Firefox/g.test( navigator.userAgent ) !== true ) {
167
+ if ( ( typeof navigator !== 'undefined' && /Firefox|Deno/g.test( navigator.userAgent ) ) !== true ) {
156
168
 
157
169
  diagnostics += 'diagnostic( off, derivative_uniformity );\n';
158
170
 
159
171
  }
160
172
 
161
- //
162
-
173
+ /**
174
+ * A node builder targeting WGSL.
175
+ *
176
+ * This module generates WGSL shader code from node materials and also
177
+ * generates the respective bindings and vertex buffer definitions. These
178
+ * data are later used by the renderer to create render and compute pipelines
179
+ * for render objects.
180
+ *
181
+ * @augments NodeBuilder
182
+ */
163
183
  class WGSLNodeBuilder extends NodeBuilder {
164
184
 
185
+ /**
186
+ * Constructs a new WGSL node builder renderer.
187
+ *
188
+ * @param {Object3D} object - The 3D object.
189
+ * @param {Renderer} renderer - The renderer.
190
+ */
165
191
  constructor( object, renderer ) {
166
192
 
167
193
  super( object, renderer, new WGSLNodeParser() );
168
194
 
195
+ /**
196
+ * A dictionary that holds for each shader stage ('vertex', 'fragment', 'compute')
197
+ * another dictionary which manages UBOs per group ('render','frame','object').
198
+ *
199
+ * @type {Object<string,Object<string,NodeUniformsGroup>>}
200
+ */
169
201
  this.uniformGroups = {};
170
202
 
203
+ /**
204
+ * A dictionary that holds the assigned binding indices for each uniform group.
205
+ * This ensures the same binding index is used across all shader stages.
206
+ *
207
+ * @type {Object<string,{index: number, id: number}>}
208
+ */
209
+ this.uniformGroupsBindings = {};
210
+
211
+ /**
212
+ * A dictionary that holds for each shader stage a Map of builtins.
213
+ *
214
+ * @type {Object<string,Map<string,Object>>}
215
+ */
171
216
  this.builtins = {};
172
217
 
218
+ /**
219
+ * A dictionary that holds for each shader stage a Set of directives.
220
+ *
221
+ * @type {Object<string,Set<string>>}
222
+ */
173
223
  this.directives = {};
174
224
 
225
+ /**
226
+ * A map for managing scope arrays. Only relevant for when using
227
+ * {@link WorkgroupInfoNode} in context of compute shaders.
228
+ *
229
+ * @type {Map<string,Object>}
230
+ */
175
231
  this.scopedArrays = new Map();
176
232
 
177
233
  }
178
234
 
179
- needsToWorkingColorSpace( texture ) {
235
+ /**
236
+ * Generates the WGSL snippet for sampled textures.
237
+ *
238
+ * @private
239
+ * @param {Texture} texture - The texture.
240
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
241
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
242
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
243
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
244
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
245
+ * @return {string} The WGSL snippet.
246
+ */
247
+ _generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
180
248
 
181
- return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace;
249
+ if ( shaderStage === 'fragment' ) {
182
250
 
183
- }
251
+ if ( depthSnippet ) {
184
252
 
185
- _generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
253
+ if ( offsetSnippet ) {
186
254
 
187
- if ( shaderStage === 'fragment' ) {
255
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ offsetSnippet } )`;
188
256
 
189
- if ( depthSnippet ) {
257
+ }
190
258
 
191
259
  return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet } )`;
192
260
 
193
261
  } else {
194
262
 
263
+ if ( offsetSnippet ) {
264
+
265
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ offsetSnippet } )`;
266
+
267
+ }
268
+
195
269
  return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet } )`;
196
270
 
197
271
  }
198
272
 
273
+ } else {
274
+
275
+ return this.generateTextureSampleLevel( texture, textureProperty, uvSnippet, '0', depthSnippet );
276
+
277
+ }
278
+
279
+ }
280
+
281
+ /**
282
+ * Generates the WGSL snippet when sampling textures with explicit mip level.
283
+ *
284
+ * @private
285
+ * @param {Texture} texture - The texture.
286
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
287
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
288
+ * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
289
+ * @param {string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
290
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
291
+ * @return {string} The WGSL snippet.
292
+ */
293
+ generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
294
+
295
+ if ( this.isUnfilterable( texture ) === false ) {
296
+
297
+ if ( depthSnippet ) {
298
+
299
+ if ( offsetSnippet ) {
300
+
301
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
302
+
303
+ }
304
+
305
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet } )`;
306
+
307
+ } else {
308
+
309
+ if ( offsetSnippet ) {
310
+
311
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
312
+
313
+ }
314
+
315
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
316
+
317
+ }
318
+
199
319
  } else if ( this.isFilteredTexture( texture ) ) {
200
320
 
201
- return this.generateFilteredTexture( texture, textureProperty, uvSnippet );
321
+ return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet, depthSnippet );
202
322
 
203
323
  } else {
204
324
 
205
- return this.generateTextureLod( texture, textureProperty, uvSnippet, '0' );
325
+ return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet );
206
326
 
207
327
  }
208
328
 
209
329
  }
210
330
 
211
- _generateVideoSample( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
331
+ /**
332
+ * Generates a wrap function used in context of textures.
333
+ *
334
+ * @param {Texture} texture - The texture to generate the function for.
335
+ * @return {string} The name of the generated function.
336
+ */
337
+ generateWrapFunction( texture ) {
212
338
 
213
- if ( shaderStage === 'fragment' ) {
339
+ const functionName = `tsl_coord_${ wrapNames[ texture.wrapS ] }S_${ wrapNames[ texture.wrapT ] }_${ texture.is3DTexture || texture.isData3DTexture ? '3d' : '2d' }T`;
214
340
 
215
- return `textureSampleBaseClampToEdge( ${ textureProperty }, ${ textureProperty }_sampler, vec2<f32>( ${ uvSnippet }.x, 1.0 - ${ uvSnippet }.y ) )`;
341
+ let nodeCode = wgslCodeCache[ functionName ];
216
342
 
217
- } else {
343
+ if ( nodeCode === undefined ) {
344
+
345
+ const includes = [];
346
+
347
+ // For 3D textures, use vec3f; for texture arrays, keep vec2f since array index is separate
348
+ const coordType = texture.is3DTexture || texture.isData3DTexture ? 'vec3f' : 'vec2f';
349
+ let code = `fn ${ functionName }( coord : ${ coordType } ) -> ${ coordType } {\n\n\treturn ${ coordType }(\n`;
350
+
351
+ const addWrapSnippet = ( wrap, axis ) => {
352
+
353
+ if ( wrap === RepeatWrapping ) {
354
+
355
+ includes.push( wgslPolyfill.repeatWrapping_float );
356
+
357
+ code += `\t\ttsl_repeatWrapping_float( coord.${ axis } )`;
358
+
359
+ } else if ( wrap === ClampToEdgeWrapping ) {
360
+
361
+ includes.push( wgslPolyfill.clampWrapping_float );
362
+
363
+ code += `\t\ttsl_clampWrapping_float( coord.${ axis } )`;
364
+
365
+ } else if ( wrap === MirroredRepeatWrapping ) {
366
+
367
+ includes.push( wgslPolyfill.mirrorWrapping_float );
368
+
369
+ code += `\t\ttsl_mirrorWrapping_float( coord.${ axis } )`;
370
+
371
+ } else {
372
+
373
+ code += `\t\tcoord.${ axis }`;
374
+
375
+ warn( `WebGPURenderer: Unsupported texture wrap type "${ wrap }" for vertex shader.` );
376
+
377
+ }
218
378
 
219
- console.error( `WebGPURenderer: THREE.VideoTexture does not support ${ shaderStage } shader.` );
379
+ };
380
+
381
+ addWrapSnippet( texture.wrapS, 'x' );
382
+
383
+ code += ',\n';
384
+
385
+ addWrapSnippet( texture.wrapT, 'y' );
386
+
387
+ if ( texture.is3DTexture || texture.isData3DTexture ) {
388
+
389
+ code += ',\n';
390
+ addWrapSnippet( texture.wrapR, 'z' );
391
+
392
+ }
393
+
394
+ code += '\n\t);\n\n}\n';
395
+
396
+ wgslCodeCache[ functionName ] = nodeCode = new CodeNode( code, includes );
220
397
 
221
398
  }
222
399
 
400
+ nodeCode.build( this );
401
+
402
+ return functionName;
403
+
223
404
  }
224
405
 
225
- _generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage ) {
406
+ /**
407
+ * Generates the array declaration string.
408
+ *
409
+ * @param {string} type - The type.
410
+ * @param {?number} [count] - The count.
411
+ * @return {string} The generated value as a shader string.
412
+ */
413
+ generateArrayDeclaration( type, count ) {
226
414
 
227
- if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false ) {
415
+ return `array< ${ this.getType( type ) }, ${ count } >`;
228
416
 
229
- return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
417
+ }
230
418
 
231
- } else if ( this.isFilteredTexture( texture ) ) {
419
+ /**
420
+ * Generates a WGSL variable that holds the texture dimension of the given texture.
421
+ * It also returns information about the number of layers (elements) of an arrayed
422
+ * texture as well as the cube face count of cube textures.
423
+ *
424
+ * @param {Texture} texture - The texture to generate the function for.
425
+ * @param {string} textureProperty - The name of the video texture uniform in the shader.
426
+ * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
427
+ * @return {string} The name of the dimension variable.
428
+ */
429
+ generateTextureDimension( texture, textureProperty, levelSnippet ) {
232
430
 
233
- return this.generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet );
431
+ const textureData = this.getDataFromNode( texture, this.shaderStage, this.globalCache );
234
432
 
235
- } else {
433
+ if ( textureData.dimensionsSnippet === undefined ) textureData.dimensionsSnippet = {};
434
+
435
+ let textureDimensionNode = textureData.dimensionsSnippet[ levelSnippet ];
436
+
437
+ if ( textureData.dimensionsSnippet[ levelSnippet ] === undefined ) {
438
+
439
+ let textureDimensionsParams;
440
+ let dimensionType;
441
+
442
+ const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
443
+ const isMultisampled = primarySamples > 1;
444
+
445
+ if ( texture.is3DTexture || texture.isData3DTexture ) {
446
+
447
+ dimensionType = 'vec3<u32>';
448
+
449
+ } else {
450
+
451
+ // Regular 2D textures, depth textures, etc.
452
+ dimensionType = 'vec2<u32>';
453
+
454
+ }
455
+
456
+ // Build parameters string based on texture type and multisampling
457
+ if ( isMultisampled || texture.isStorageTexture ) {
458
+
459
+ textureDimensionsParams = textureProperty;
236
460
 
237
- return this.generateTextureLod( texture, textureProperty, uvSnippet, levelSnippet );
461
+ } else {
462
+
463
+ textureDimensionsParams = `${textureProperty}${levelSnippet ? `, u32( ${ levelSnippet } )` : ''}`;
464
+
465
+ }
466
+
467
+ textureDimensionNode = new VarNode( new ExpressionNode( `textureDimensions( ${ textureDimensionsParams } )`, dimensionType ) );
468
+
469
+ textureData.dimensionsSnippet[ levelSnippet ] = textureDimensionNode;
470
+
471
+ if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.is3DTexture || texture.isData3DTexture ) {
472
+
473
+ textureData.arrayLayerCount = new VarNode(
474
+ new ExpressionNode(
475
+ `textureNumLayers(${textureProperty})`,
476
+ 'u32'
477
+ )
478
+ );
479
+
480
+ }
481
+
482
+ // For cube textures, we know it's always 6 faces
483
+ if ( texture.isTextureCube ) {
484
+
485
+ textureData.cubeFaceCount = new VarNode(
486
+ new ExpressionNode( '6u', 'u32' )
487
+ );
488
+
489
+ }
238
490
 
239
491
  }
240
492
 
493
+ return textureDimensionNode.build( this );
494
+
241
495
  }
242
496
 
243
- generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet = '0' ) {
497
+ /**
498
+ * Generates the WGSL snippet for a manual filtered texture.
499
+ *
500
+ * @param {Texture} texture - The texture.
501
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
502
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
503
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
504
+ * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
505
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
506
+ * @return {string} The WGSL snippet.
507
+ */
508
+ generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet = '0u', depthSnippet ) {
509
+
510
+ const wrapFunction = this.generateWrapFunction( texture );
511
+ const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
512
+
513
+ if ( offsetSnippet ) {
514
+
515
+ uvSnippet = `${ uvSnippet } + vec2<f32>(${ offsetSnippet }) / ${ textureDimension }`;
516
+
517
+ }
518
+
519
+ if ( depthSnippet ) {
520
+
521
+ this._include( 'biquadraticTextureArray' );
522
+
523
+ return `tsl_biquadraticTexture_array( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, u32( ${ depthSnippet } ), u32( ${ levelSnippet } ) )`;
524
+
525
+ }
244
526
 
245
527
  this._include( 'biquadraticTexture' );
246
528
 
247
- return `tsl_biquadraticTexture( ${ textureProperty }, ${ uvSnippet }, i32( ${ levelSnippet } ) )`;
529
+ return `tsl_biquadraticTexture( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, u32( ${ levelSnippet } ) )`;
530
+
531
+ }
532
+
533
+ /**
534
+ * Generates the WGSL snippet for a texture lookup with explicit level-of-detail.
535
+ * Since it's a lookup, no sampling or filtering is applied.
536
+ *
537
+ * @param {Texture} texture - The texture.
538
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
539
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
540
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
541
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
542
+ * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
543
+ * @return {string} The WGSL snippet.
544
+ */
545
+ generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet = '0u' ) {
546
+
547
+ // Cube textures cannot use textureLoad in WGSL, must use textureSampleLevel
548
+ if ( texture.isCubeTexture === true ) {
549
+
550
+ if ( offsetSnippet ) {
551
+
552
+ uvSnippet = `${ uvSnippet } + vec3<f32>(${ offsetSnippet })`;
553
+
554
+ }
555
+
556
+ // Depth textures require integer level, regular textures use float
557
+ const levelType = texture.isDepthTexture ? 'u32' : 'f32';
558
+
559
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelType }( ${ levelSnippet } ) )`;
560
+
561
+ }
562
+
563
+ const wrapFunction = this.generateWrapFunction( texture );
564
+ const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
565
+
566
+ const vecType = texture.is3DTexture || texture.isData3DTexture ? 'vec3' : 'vec2';
567
+ const textureDimensionMargin = ( vecType === 'vec3' ) ? 'vec3<u32>( 1, 1, 1 )' : 'vec2<u32>( 1, 1 )';
568
+
569
+ if ( offsetSnippet ) {
570
+
571
+ uvSnippet = `${ uvSnippet } + ${ vecType }<f32>(${ offsetSnippet }) / ${ vecType }<f32>( ${ textureDimension } )`;
572
+
573
+ }
574
+
575
+ const clampMin = `${ vecType }<f32>( 0 )`;
576
+ const clampMax = `${ vecType }<f32>( ${ textureDimension } - ${ textureDimensionMargin } )`;
577
+
578
+ uvSnippet = `${ vecType }<u32>( clamp( floor( ${ wrapFunction }( ${ uvSnippet } ) * ${ vecType }<f32>( ${ textureDimension } ) ), ${ clampMin }, ${ clampMax } ) )`;
579
+
580
+ return this.generateTextureLoad( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, null );
581
+
582
+ }
583
+
584
+ /**
585
+ * Generates the WGSL snippet that reads a single texel from a storage texture.
586
+ *
587
+ * @param {Texture} texture - The texture.
588
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
589
+ * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
590
+ * @param {?string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
591
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
592
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
593
+ * @return {string} The WGSL snippet.
594
+ */
595
+ generateStorageTextureLoad( texture, textureProperty, uvIndexSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
596
+
597
+ if ( offsetSnippet ) {
598
+
599
+ uvIndexSnippet = `${ uvIndexSnippet } + ${ offsetSnippet }`;
600
+
601
+ }
602
+
603
+ let snippet;
604
+
605
+ if ( depthSnippet ) {
606
+
607
+ snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet } )`;
608
+
609
+ } else {
610
+
611
+ snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet } )`;
612
+
613
+ }
614
+
615
+ return snippet;
248
616
 
249
617
  }
250
618
 
251
- generateTextureLod( texture, textureProperty, uvSnippet, levelSnippet = '0' ) {
619
+ /**
620
+ * Generates the WGSL snippet that reads a single texel from a texture without sampling or filtering.
621
+ *
622
+ * @param {Texture} texture - The texture.
623
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
624
+ * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
625
+ * @param {?string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
626
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
627
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
628
+ * @return {string} The WGSL snippet.
629
+ */
630
+ generateTextureLoad( texture, textureProperty, uvIndexSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
252
631
 
253
- this._include( 'repeatWrapping' );
632
+ if ( levelSnippet === null ) levelSnippet = '0u';
254
633
 
255
- const dimension = texture.isMultisampleRenderTargetTexture === true ? `textureDimensions( ${ textureProperty } )` : `textureDimensions( ${ textureProperty }, 0 )`;
634
+ if ( offsetSnippet ) {
635
+
636
+ uvIndexSnippet = `${ uvIndexSnippet } + ${ offsetSnippet }`;
637
+
638
+ }
639
+
640
+ let snippet;
641
+
642
+ if ( depthSnippet ) {
643
+
644
+ snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, u32( ${ levelSnippet } ) )`;
645
+
646
+ } else {
647
+
648
+ snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, u32( ${ levelSnippet } ) )`;
649
+
650
+ if ( this.renderer.backend.compatibilityMode && texture.isDepthTexture ) {
651
+
652
+ snippet += '.x';
653
+
654
+ }
655
+
656
+ }
256
657
 
257
- return `textureLoad( ${ textureProperty }, tsl_repeatWrapping( ${ uvSnippet }, ${ dimension } ), i32( ${ levelSnippet } ) )`;
658
+ return snippet;
258
659
 
259
660
  }
260
661
 
261
- generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u' ) {
662
+ /**
663
+ * Generates the WGSL snippet that writes a single texel to a texture.
664
+ *
665
+ * @param {Texture} texture - The texture.
666
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
667
+ * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
668
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
669
+ * @param {string} valueSnippet - A WGSL snippet that represent the new texel value.
670
+ * @return {string} The WGSL snippet.
671
+ */
672
+ generateTextureStore( texture, textureProperty, uvIndexSnippet, depthSnippet, valueSnippet ) {
673
+
674
+ let snippet;
262
675
 
263
676
  if ( depthSnippet ) {
264
677
 
265
- return `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, ${ levelSnippet } )`;
678
+ snippet = `textureStore( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, ${ valueSnippet } )`;
266
679
 
267
680
  } else {
268
681
 
269
- return `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ levelSnippet } )`;
682
+ snippet = `textureStore( ${ textureProperty }, ${ uvIndexSnippet }, ${ valueSnippet } )`;
270
683
 
271
684
  }
272
685
 
686
+ return snippet;
687
+
273
688
  }
274
689
 
275
- generateTextureStore( texture, textureProperty, uvIndexSnippet, valueSnippet ) {
690
+ /**
691
+ * Returns `true` if the sampled values of the given texture should be compared against a reference value.
692
+ *
693
+ * @param {Texture} texture - The texture.
694
+ * @return {boolean} Whether the sampled values of the given texture should be compared against a reference value or not.
695
+ */
696
+ isSampleCompare( texture ) {
276
697
 
277
- return `textureStore( ${ textureProperty }, ${ uvIndexSnippet }, ${ valueSnippet } )`;
698
+ return texture.isDepthTexture === true && texture.compareFunction !== null && this.renderer.hasCompatibility( Compatibility.TEXTURE_COMPARE );
278
699
 
279
700
  }
280
701
 
702
+ /**
703
+ * Returns `true` if the given texture is unfilterable.
704
+ *
705
+ * @param {Texture} texture - The texture.
706
+ * @return {boolean} Whether the given texture is unfilterable or not.
707
+ */
281
708
  isUnfilterable( texture ) {
282
709
 
283
- return this.getComponentTypeFromTexture( texture ) !== 'float' || ( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) || texture.isMultisampleRenderTargetTexture === true;
710
+ return this.getComponentTypeFromTexture( texture ) !== 'float' ||
711
+ ( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) ||
712
+ ( this.isSampleCompare( texture ) === false && texture.minFilter === NearestFilter && texture.magFilter === NearestFilter ) ||
713
+ this.renderer.backend.utils.getTextureSampleData( texture ).primarySamples > 1;
284
714
 
285
715
  }
286
716
 
287
- generateTexture( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
717
+ /**
718
+ * Generates the WGSL snippet for sampling/loading the given texture.
719
+ *
720
+ * @param {Texture} texture - The texture.
721
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
722
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
723
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
724
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
725
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
726
+ * @return {string} The WGSL snippet.
727
+ */
728
+ generateTexture( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
288
729
 
289
730
  let snippet = null;
290
731
 
291
- if ( texture.isVideoTexture === true ) {
732
+ if ( this.isUnfilterable( texture ) ) {
292
733
 
293
- snippet = this._generateVideoSample( textureProperty, uvSnippet, shaderStage );
294
-
295
- } else if ( this.isUnfilterable( texture ) ) {
296
-
297
- snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage );
734
+ snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, '0', shaderStage );
298
735
 
299
736
  } else {
300
737
 
301
- snippet = this._generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, shaderStage );
738
+ snippet = this._generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage );
302
739
 
303
740
  }
304
741
 
@@ -306,67 +743,200 @@ class WGSLNodeBuilder extends NodeBuilder {
306
743
 
307
744
  }
308
745
 
309
- generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, shaderStage = this.shaderStage ) {
746
+ /**
747
+ * Generates the WGSL snippet for sampling/loading the given texture using explicit gradients.
748
+ *
749
+ * @param {Texture} texture - The texture.
750
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
751
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
752
+ * @param {Array<string>} gradSnippet - An array holding both gradient WGSL snippets.
753
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
754
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
755
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
756
+ * @return {string} The WGSL snippet.
757
+ */
758
+ generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
310
759
 
311
760
  if ( shaderStage === 'fragment' ) {
312
761
 
313
- // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy
314
- return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
762
+ if ( depthSnippet ) {
763
+
764
+ if ( offsetSnippet ) {
765
+
766
+ return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;
767
+
768
+ }
769
+
770
+ return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
771
+
772
+ } else {
773
+
774
+ if ( offsetSnippet ) {
775
+
776
+ return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;
777
+
778
+ }
779
+
780
+ return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
781
+
782
+ }
315
783
 
316
784
  } else {
317
785
 
318
- console.error( `WebGPURenderer: THREE.TextureNode.gradient() does not support ${ shaderStage } shader.` );
786
+ error( `WebGPURenderer: THREE.TextureNode.gradient() does not support ${ shaderStage } shader.` );
319
787
 
320
788
  }
321
789
 
322
790
  }
323
791
 
324
- generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage ) {
792
+ /**
793
+ * Generates the WGSL snippet for sampling a depth texture and comparing the sampled depth values
794
+ * against a reference value.
795
+ *
796
+ * @param {Texture} texture - The texture.
797
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
798
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
799
+ * @param {string} compareSnippet - A WGSL snippet that represents the reference value.
800
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
801
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
802
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
803
+ * @return {string} The WGSL snippet.
804
+ */
805
+ generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
325
806
 
326
807
  if ( shaderStage === 'fragment' ) {
327
808
 
809
+ if ( texture.isDepthTexture === true && texture.isArrayTexture === true ) {
810
+
811
+ if ( offsetSnippet ) {
812
+
813
+ return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet }, ${ offsetSnippet } )`;
814
+
815
+ }
816
+
817
+ return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet } )`;
818
+
819
+ }
820
+
821
+ if ( offsetSnippet ) {
822
+
823
+ return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ compareSnippet }, ${ offsetSnippet } )`;
824
+
825
+ }
826
+
328
827
  return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ compareSnippet } )`;
329
828
 
330
829
  } else {
331
830
 
332
- console.error( `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${ shaderStage } shader.` );
831
+ error( `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${ shaderStage } shader.` );
333
832
 
334
833
  }
335
834
 
336
835
  }
337
836
 
338
- generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage ) {
837
+ /**
838
+ * Generates the WGSL snippet when sampling textures with explicit mip level.
839
+ *
840
+ * @param {Texture} texture - The texture.
841
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
842
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
843
+ * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
844
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
845
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
846
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
847
+ * @return {string} The WGSL snippet.
848
+ */
849
+ generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
850
+
851
+ if ( this.isUnfilterable( texture ) === false ) {
339
852
 
340
- let snippet = null;
853
+ if ( depthSnippet ) {
854
+
855
+ if ( offsetSnippet ) {
341
856
 
342
- if ( texture.isVideoTexture === true ) {
857
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
858
+
859
+ }
860
+
861
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet } )`;
862
+
863
+ } else {
343
864
 
344
- snippet = this._generateVideoSample( textureProperty, uvSnippet, shaderStage );
865
+ if ( offsetSnippet ) {
866
+
867
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
868
+
869
+ }
870
+
871
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
872
+
873
+ }
874
+
875
+ } else if ( this.isFilteredTexture( texture ) ) {
876
+
877
+ return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet, depthSnippet );
345
878
 
346
879
  } else {
347
880
 
348
- snippet = this._generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage );
881
+ return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet );
349
882
 
350
883
  }
351
884
 
352
- return snippet;
353
-
354
885
  }
355
886
 
356
- generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, shaderStage = this.shaderStage ) {
887
+ /**
888
+ * Generates the WGSL snippet when sampling textures with a bias to the mip level.
889
+ *
890
+ * @param {Texture} texture - The texture.
891
+ * @param {string} textureProperty - The name of the texture uniform in the shader.
892
+ * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
893
+ * @param {string} biasSnippet - A WGSL snippet that represents the bias to apply to the mip level before sampling.
894
+ * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
895
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
896
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
897
+ * @return {string} The WGSL snippet.
898
+ */
899
+ generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
357
900
 
358
901
  if ( shaderStage === 'fragment' ) {
359
902
 
360
- return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet } )`;
903
+ if ( depthSnippet ) {
904
+
905
+ if ( offsetSnippet ) {
906
+
907
+ return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ biasSnippet }, ${ offsetSnippet } )`;
908
+
909
+ }
910
+
911
+ return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ biasSnippet } )`;
912
+
913
+ } else {
914
+
915
+ if ( offsetSnippet ) {
916
+
917
+ return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet }, ${ offsetSnippet } )`;
918
+
919
+ }
920
+
921
+ return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet } )`;
922
+
923
+ }
361
924
 
362
925
  } else {
363
926
 
364
- console.error( `WebGPURenderer: THREE.TextureNode.biasNode does not support ${ shaderStage } shader.` );
927
+ error( `WebGPURenderer: THREE.TextureNode.biasNode does not support ${ shaderStage } shader.` );
365
928
 
366
929
  }
367
930
 
368
931
  }
369
932
 
933
+ /**
934
+ * Returns a WGSL snippet that represents the property name of the given node.
935
+ *
936
+ * @param {Node} node - The node.
937
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
938
+ * @return {string} The property name.
939
+ */
370
940
  getPropertyName( node, shaderStage = this.shaderStage ) {
371
941
 
372
942
  if ( node.isNodeVarying === true && node.needsInterpolation === true ) {
@@ -382,13 +952,19 @@ class WGSLNodeBuilder extends NodeBuilder {
382
952
  const name = node.name;
383
953
  const type = node.type;
384
954
 
385
- if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D' ) {
955
+ if ( type === 'texture' || type === 'cubeTexture' || type === 'cubeDepthTexture' || type === 'storageTexture' || type === 'texture3D' ) {
386
956
 
387
957
  return name;
388
958
 
389
- } else if ( type === 'buffer' || type === 'storageBuffer' ) {
959
+ } else if ( type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer' ) {
960
+
961
+ if ( this.isCustomStruct( node ) ) {
390
962
 
391
- return `NodeBuffer_${ node.id }.${name}`;
963
+ return name;
964
+
965
+ }
966
+
967
+ return name + '.value';
392
968
 
393
969
  } else {
394
970
 
@@ -402,18 +978,23 @@ class WGSLNodeBuilder extends NodeBuilder {
402
978
 
403
979
  }
404
980
 
981
+ /**
982
+ * Returns the output struct name.
983
+ *
984
+ * @return {string} The name of the output struct.
985
+ */
405
986
  getOutputStructName() {
406
987
 
407
988
  return 'output';
408
989
 
409
990
  }
410
991
 
411
- _getUniformGroupCount( shaderStage ) {
412
-
413
- return Object.keys( this.uniforms[ shaderStage ] ).length;
414
-
415
- }
416
-
992
+ /**
993
+ * Returns the native shader operator name for a given generic name.
994
+ *
995
+ * @param {string} op - The operator name to resolve.
996
+ * @return {?string} The resolved operator name.
997
+ */
417
998
  getFunctionOperator( op ) {
418
999
 
419
1000
  const fnOp = wgslFnOpLib[ op ];
@@ -430,49 +1011,59 @@ class WGSLNodeBuilder extends NodeBuilder {
430
1011
 
431
1012
  }
432
1013
 
433
- getStorageAccess( node ) {
1014
+ /**
1015
+ * Returns the node access for the given node and shader stage.
1016
+ *
1017
+ * @param {StorageTextureNode|StorageBufferNode} node - The storage node.
1018
+ * @param {string} shaderStage - The shader stage.
1019
+ * @return {string} The node access.
1020
+ */
1021
+ getNodeAccess( node, shaderStage ) {
434
1022
 
435
- if ( node.isStorageTextureNode ) {
436
-
437
- switch ( node.access ) {
438
-
439
- case GPUStorageTextureAccess.ReadOnly:
440
-
441
- return 'read';
442
-
443
- case GPUStorageTextureAccess.WriteOnly:
1023
+ if ( shaderStage !== 'compute' ) {
444
1024
 
445
- return 'write';
1025
+ if ( node.isAtomic === true ) {
446
1026
 
447
- default:
1027
+ warn( 'WebGPURenderer: Atomic operations are only supported in compute shaders.' );
448
1028
 
449
- return 'read_write';
1029
+ return NodeAccess.READ_WRITE;
450
1030
 
451
1031
  }
452
1032
 
453
- } else {
454
-
455
- switch ( node.access ) {
456
-
457
- case GPUBufferBindingType.Storage:
458
-
459
- return 'read_write';
460
-
1033
+ return NodeAccess.READ_ONLY;
461
1034
 
462
- case GPUBufferBindingType.ReadOnlyStorage:
463
-
464
- return 'read';
1035
+ }
465
1036
 
466
- default:
1037
+ return node.access;
467
1038
 
468
- return 'write';
1039
+ }
469
1040
 
470
- }
1041
+ /**
1042
+ * Returns A WGSL snippet representing the storage access.
1043
+ *
1044
+ * @param {StorageTextureNode|StorageBufferNode} node - The storage node.
1045
+ * @param {string} shaderStage - The shader stage.
1046
+ * @return {string} The WGSL snippet representing the storage access.
1047
+ */
1048
+ getStorageAccess( node, shaderStage ) {
471
1049
 
472
- }
1050
+ return accessNames[ this.getNodeAccess( node, shaderStage ) ];
473
1051
 
474
1052
  }
475
1053
 
1054
+ /**
1055
+ * This method is one of the more important ones since it's responsible
1056
+ * for generating a matching binding instance for the given uniform node.
1057
+ *
1058
+ * These bindings are later used in the renderer to create bind groups
1059
+ * and layouts.
1060
+ *
1061
+ * @param {UniformNode} node - The uniform node.
1062
+ * @param {string} type - The node data type.
1063
+ * @param {string} shaderStage - The shader stage.
1064
+ * @param {?string} [name=null] - An optional uniform name.
1065
+ * @return {NodeUniform} The node uniform object.
1066
+ */
476
1067
  getUniformFromNode( node, type, shaderStage, name = null ) {
477
1068
 
478
1069
  const uniformNode = super.getUniformFromNode( node, type, shaderStage, name );
@@ -487,30 +1078,44 @@ class WGSLNodeBuilder extends NodeBuilder {
487
1078
 
488
1079
  const bindings = this.getBindGroupArray( groupName, shaderStage );
489
1080
 
490
- if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D' ) {
1081
+ if ( type === 'texture' || type === 'cubeTexture' || type === 'cubeDepthTexture' || type === 'storageTexture' || type === 'texture3D' ) {
491
1082
 
492
1083
  let texture = null;
493
1084
 
1085
+ const access = this.getNodeAccess( node, shaderStage );
1086
+
494
1087
  if ( type === 'texture' || type === 'storageTexture' ) {
495
1088
 
496
- texture = new NodeSampledTexture( uniformNode.name, uniformNode.node, group, node.access ? node.access : null );
1089
+ if ( node.value.is3DTexture === true ) {
497
1090
 
498
- } else if ( type === 'cubeTexture' ) {
1091
+ texture = new NodeSampledTexture3D( uniformNode.name, uniformNode.node, group, access );
499
1092
 
500
- texture = new NodeSampledCubeTexture( uniformNode.name, uniformNode.node, group, node.access ? node.access : null );
1093
+ } else {
1094
+
1095
+ texture = new NodeSampledTexture( uniformNode.name, uniformNode.node, group, access );
1096
+
1097
+ }
1098
+
1099
+ } else if ( type === 'cubeTexture' || type === 'cubeDepthTexture' ) {
1100
+
1101
+ texture = new NodeSampledCubeTexture( uniformNode.name, uniformNode.node, group, access );
501
1102
 
502
1103
  } else if ( type === 'texture3D' ) {
503
1104
 
504
- texture = new NodeSampledTexture3D( uniformNode.name, uniformNode.node, group, node.access ? node.access : null );
1105
+ texture = new NodeSampledTexture3D( uniformNode.name, uniformNode.node, group, access );
505
1106
 
506
1107
  }
507
1108
 
508
1109
  texture.store = node.isStorageTextureNode === true;
1110
+ texture.mipLevel = texture.store ? node.mipLevel : 0;
509
1111
  texture.setVisibility( gpuShaderStageLib[ shaderStage ] );
510
1112
 
511
- if ( shaderStage === 'fragment' && this.isUnfilterable( node.value ) === false && texture.store === false ) {
1113
+ // Cube textures always need samplers (they use textureSampleLevel, not textureLoad)
1114
+ const needsSampler = node.value.isCubeTexture === true || ( this.isUnfilterable( node.value ) === false && texture.store === false );
512
1115
 
513
- const sampler = new NodeSampler( `${uniformNode.name}_sampler`, uniformNode.node, group );
1116
+ if ( needsSampler ) {
1117
+
1118
+ const sampler = new NodeSampler( `${ uniformNode.name }_sampler`, uniformNode.node, group );
514
1119
  sampler.setVisibility( gpuShaderStageLib[ shaderStage ] );
515
1120
 
516
1121
  bindings.push( sampler, texture );
@@ -525,28 +1130,45 @@ class WGSLNodeBuilder extends NodeBuilder {
525
1130
 
526
1131
  }
527
1132
 
528
- } else if ( type === 'buffer' || type === 'storageBuffer' ) {
1133
+ } else if ( type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer' ) {
1134
+
1135
+ const sharedData = this.getSharedDataFromNode( node );
1136
+
1137
+ let buffer = sharedData.buffer;
1138
+
1139
+ if ( buffer === undefined ) {
1140
+
1141
+ const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer;
529
1142
 
530
- const bufferClass = type === 'storageBuffer' ? NodeStorageBuffer : NodeUniformBuffer;
531
- const buffer = new bufferClass( node, group );
532
- buffer.setVisibility( gpuShaderStageLib[ shaderStage ] );
1143
+ buffer = new bufferClass( node, group );
1144
+
1145
+ sharedData.buffer = buffer;
1146
+
1147
+ }
1148
+
1149
+ buffer.setVisibility( buffer.getVisibility() | gpuShaderStageLib[ shaderStage ] );
533
1150
 
534
1151
  bindings.push( buffer );
535
1152
 
536
1153
  uniformGPU = buffer;
537
1154
 
538
- } else {
1155
+ uniformNode.name = name ? name : 'NodeBuffer_' + uniformNode.id;
539
1156
 
540
- const uniformsStage = this.uniformGroups[ shaderStage ] || ( this.uniformGroups[ shaderStage ] = {} );
1157
+ } else {
541
1158
 
542
- let uniformsGroup = uniformsStage[ groupName ];
1159
+ let uniformsGroup = this.uniformGroups[ groupName ];
543
1160
 
544
1161
  if ( uniformsGroup === undefined ) {
545
1162
 
546
1163
  uniformsGroup = new NodeUniformsGroup( groupName, group );
547
- uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] );
1164
+ uniformsGroup.setVisibility( GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE );
548
1165
 
549
- uniformsStage[ groupName ] = uniformsGroup;
1166
+ this.uniformGroups[ groupName ] = uniformsGroup;
1167
+
1168
+ }
1169
+
1170
+ // Add to bindings for this stage if not already present
1171
+ if ( bindings.indexOf( uniformsGroup ) === - 1 ) {
550
1172
 
551
1173
  bindings.push( uniformsGroup );
552
1174
 
@@ -554,7 +1176,15 @@ class WGSLNodeBuilder extends NodeBuilder {
554
1176
 
555
1177
  uniformGPU = this.getNodeUniform( uniformNode, type );
556
1178
 
557
- uniformsGroup.addUniform( uniformGPU );
1179
+ // Only add uniform if not already present in the group (check by name to avoid duplicates across stages)
1180
+ const uniformName = uniformGPU.name;
1181
+ const alreadyExists = uniformsGroup.uniforms.some( u => u.name === uniformName );
1182
+
1183
+ if ( ! alreadyExists ) {
1184
+
1185
+ uniformsGroup.addUniform( uniformGPU );
1186
+
1187
+ }
558
1188
 
559
1189
  }
560
1190
 
@@ -566,6 +1196,17 @@ class WGSLNodeBuilder extends NodeBuilder {
566
1196
 
567
1197
  }
568
1198
 
1199
+ /**
1200
+ * This method should be used whenever builtins are required in nodes.
1201
+ * The internal builtins data structure will make sure builtins are
1202
+ * defined in the WGSL source.
1203
+ *
1204
+ * @param {string} name - The builtin name.
1205
+ * @param {string} property - The property name.
1206
+ * @param {string} type - The node data type.
1207
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
1208
+ * @return {string} The property name.
1209
+ */
569
1210
  getBuiltin( name, property, type, shaderStage = this.shaderStage ) {
570
1211
 
571
1212
  const map = this.builtins[ shaderStage ] || ( this.builtins[ shaderStage ] = new Map() );
@@ -584,12 +1225,24 @@ class WGSLNodeBuilder extends NodeBuilder {
584
1225
 
585
1226
  }
586
1227
 
1228
+ /**
1229
+ * Returns `true` if the given builtin is defined in the given shader stage.
1230
+ *
1231
+ * @param {string} name - The builtin name.
1232
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
1233
+ * @return {boolean} Whether the given builtin is defined in the given shader stage or not.
1234
+ */
587
1235
  hasBuiltin( name, shaderStage = this.shaderStage ) {
588
1236
 
589
1237
  return ( this.builtins[ shaderStage ] !== undefined && this.builtins[ shaderStage ].has( name ) );
590
1238
 
591
1239
  }
592
1240
 
1241
+ /**
1242
+ * Returns the vertex index builtin.
1243
+ *
1244
+ * @return {string} The vertex index.
1245
+ */
593
1246
  getVertexIndex() {
594
1247
 
595
1248
  if ( this.shaderStage === 'vertex' ) {
@@ -602,6 +1255,12 @@ class WGSLNodeBuilder extends NodeBuilder {
602
1255
 
603
1256
  }
604
1257
 
1258
+ /**
1259
+ * Builds the given shader node.
1260
+ *
1261
+ * @param {ShaderNodeInternal} shaderNode - The shader node.
1262
+ * @return {string} The WGSL function code.
1263
+ */
605
1264
  buildFunctionCode( shaderNode ) {
606
1265
 
607
1266
  const layout = shaderNode.layout;
@@ -636,6 +1295,12 @@ ${ flowData.code }
636
1295
 
637
1296
  }
638
1297
 
1298
+ /**
1299
+ * Contextually returns either the vertex stage instance index builtin
1300
+ * or the linearized index of an compute invocation within a grid of workgroups.
1301
+ *
1302
+ * @return {string} The instance index.
1303
+ */
639
1304
  getInstanceIndex() {
640
1305
 
641
1306
  if ( this.shaderStage === 'vertex' ) {
@@ -648,12 +1313,23 @@ ${ flowData.code }
648
1313
 
649
1314
  }
650
1315
 
1316
+
1317
+ /**
1318
+ * Returns a builtin representing the index of a compute invocation within the scope of a workgroup load.
1319
+ *
1320
+ * @return {string} The invocation local index.
1321
+ */
651
1322
  getInvocationLocalIndex() {
652
1323
 
653
1324
  return this.getBuiltin( 'local_invocation_index', 'invocationLocalIndex', 'u32', 'attribute' );
654
1325
 
655
1326
  }
656
1327
 
1328
+ /**
1329
+ * Returns a builtin representing the size of a subgroup within the current shader.
1330
+ *
1331
+ * @return {string} The subgroup size.
1332
+ */
657
1333
  getSubgroupSize() {
658
1334
 
659
1335
  this.enableSubGroups();
@@ -662,6 +1338,11 @@ ${ flowData.code }
662
1338
 
663
1339
  }
664
1340
 
1341
+ /**
1342
+ * Returns a builtin representing the index of a compute invocation within the scope of a subgroup.
1343
+ *
1344
+ * @return {string} The invocation subgroup index.
1345
+ */
665
1346
  getInvocationSubgroupIndex() {
666
1347
 
667
1348
  this.enableSubGroups();
@@ -670,6 +1351,11 @@ ${ flowData.code }
670
1351
 
671
1352
  }
672
1353
 
1354
+ /**
1355
+ * Returns a builtin representing the index of a compute invocation's subgroup within its workgroup.
1356
+ *
1357
+ * @return {string} The subgroup index.
1358
+ */
673
1359
  getSubgroupIndex() {
674
1360
 
675
1361
  this.enableSubGroups();
@@ -678,36 +1364,78 @@ ${ flowData.code }
678
1364
 
679
1365
  }
680
1366
 
1367
+ /**
1368
+ * Overwritten as a NOP since this method is intended for the WebGL 2 backend.
1369
+ *
1370
+ * @return {null} Null.
1371
+ */
681
1372
  getDrawIndex() {
682
1373
 
683
1374
  return null;
684
1375
 
685
1376
  }
686
1377
 
1378
+ /**
1379
+ * Returns the front facing builtin.
1380
+ *
1381
+ * @return {string} The front facing builtin.
1382
+ */
687
1383
  getFrontFacing() {
688
1384
 
689
1385
  return this.getBuiltin( 'front_facing', 'isFront', 'bool' );
690
1386
 
691
1387
  }
692
1388
 
1389
+ /**
1390
+ * Returns the frag coord builtin.
1391
+ *
1392
+ * @return {string} The frag coord builtin.
1393
+ */
693
1394
  getFragCoord() {
694
1395
 
695
1396
  return this.getBuiltin( 'position', 'fragCoord', 'vec4<f32>' ) + '.xy';
696
1397
 
697
1398
  }
698
1399
 
1400
+ /**
1401
+ * Returns the frag depth builtin.
1402
+ *
1403
+ * @return {string} The frag depth builtin.
1404
+ */
699
1405
  getFragDepth() {
700
1406
 
701
1407
  return 'output.' + this.getBuiltin( 'frag_depth', 'depth', 'f32', 'output' );
702
1408
 
703
1409
  }
704
1410
 
1411
+ /**
1412
+ * Returns the clip distances builtin.
1413
+ *
1414
+ * @return {string} The clip distances builtin.
1415
+ */
1416
+ getClipDistance() {
1417
+
1418
+ return 'varyings.hw_clip_distances';
1419
+
1420
+ }
1421
+
1422
+ /**
1423
+ * Whether to flip texture data along its vertical axis or not.
1424
+ *
1425
+ * @return {boolean} Returns always `false` in context of WGSL.
1426
+ */
705
1427
  isFlipY() {
706
1428
 
707
1429
  return false;
708
1430
 
709
1431
  }
710
1432
 
1433
+ /**
1434
+ * Enables the given directive for the given shader stage.
1435
+ *
1436
+ * @param {string} name - The directive name.
1437
+ * @param {string} [shaderStage=this.shaderStage] - The shader stage to enable the directive for.
1438
+ */
711
1439
  enableDirective( name, shaderStage = this.shaderStage ) {
712
1440
 
713
1441
  const stage = this.directives[ shaderStage ] || ( this.directives[ shaderStage ] = new Set() );
@@ -715,6 +1443,12 @@ ${ flowData.code }
715
1443
 
716
1444
  }
717
1445
 
1446
+ /**
1447
+ * Returns the directives of the given shader stage as a WGSL string.
1448
+ *
1449
+ * @param {string} shaderStage - The shader stage.
1450
+ * @return {string} A WGSL snippet that enables the directives of the given stage.
1451
+ */
718
1452
  getDirectives( shaderStage ) {
719
1453
 
720
1454
  const snippets = [];
@@ -734,36 +1468,69 @@ ${ flowData.code }
734
1468
 
735
1469
  }
736
1470
 
1471
+ /**
1472
+ * Enables the 'subgroups' directive.
1473
+ */
737
1474
  enableSubGroups() {
738
1475
 
739
1476
  this.enableDirective( 'subgroups' );
740
1477
 
741
1478
  }
742
1479
 
1480
+ /**
1481
+ * Enables the 'subgroups-f16' directive.
1482
+ */
743
1483
  enableSubgroupsF16() {
744
1484
 
745
1485
  this.enableDirective( 'subgroups-f16' );
746
1486
 
747
1487
  }
748
1488
 
1489
+ /**
1490
+ * Enables the 'clip_distances' directive.
1491
+ */
749
1492
  enableClipDistances() {
750
1493
 
751
1494
  this.enableDirective( 'clip_distances' );
752
1495
 
753
1496
  }
754
1497
 
1498
+ /**
1499
+ * Enables the 'f16' directive.
1500
+ */
755
1501
  enableShaderF16() {
756
1502
 
757
1503
  this.enableDirective( 'f16' );
758
1504
 
759
1505
  }
760
1506
 
1507
+ /**
1508
+ * Enables the 'dual_source_blending' directive.
1509
+ */
761
1510
  enableDualSourceBlending() {
762
1511
 
763
1512
  this.enableDirective( 'dual_source_blending' );
764
1513
 
765
1514
  }
766
1515
 
1516
+ /**
1517
+ * Enables hardware clipping.
1518
+ *
1519
+ * @param {string} planeCount - The clipping plane count.
1520
+ */
1521
+ enableHardwareClipping( planeCount ) {
1522
+
1523
+ this.enableClipDistances();
1524
+ this.getBuiltin( 'clip_distances', 'hw_clip_distances', `array<f32, ${ planeCount } >`, 'vertex' );
1525
+
1526
+ }
1527
+
1528
+ /**
1529
+ * Returns the builtins of the given shader stage as a WGSL string.
1530
+ *
1531
+ * @param {string} shaderStage - The shader stage.
1532
+ * @return {string} A WGSL snippet that represents the builtins of the given stage.
1533
+ */
767
1534
  getBuiltins( shaderStage ) {
768
1535
 
769
1536
  const snippets = [];
@@ -783,6 +1550,17 @@ ${ flowData.code }
783
1550
 
784
1551
  }
785
1552
 
1553
+ /**
1554
+ * This method should be used when a new scoped buffer is used in context of
1555
+ * compute shaders. It adds the array to the internal data structure which is
1556
+ * later used to generate the respective WGSL.
1557
+ *
1558
+ * @param {string} name - The array name.
1559
+ * @param {string} scope - The scope.
1560
+ * @param {string} bufferType - The buffer type.
1561
+ * @param {string} bufferCount - The buffer count.
1562
+ * @return {string} The array name.
1563
+ */
786
1564
  getScopedArray( name, scope, bufferType, bufferCount ) {
787
1565
 
788
1566
  if ( this.scopedArrays.has( name ) === false ) {
@@ -800,6 +1578,13 @@ ${ flowData.code }
800
1578
 
801
1579
  }
802
1580
 
1581
+ /**
1582
+ * Returns the scoped arrays of the given shader stage as a WGSL string.
1583
+ *
1584
+ * @param {string} shaderStage - The shader stage.
1585
+ * @return {string|undefined} The WGSL snippet that defines the scoped arrays.
1586
+ * Returns `undefined` when used in the vertex or fragment stage.
1587
+ */
803
1588
  getScopedArrays( shaderStage ) {
804
1589
 
805
1590
  if ( shaderStage !== 'compute' ) {
@@ -822,13 +1607,19 @@ ${ flowData.code }
822
1607
 
823
1608
  }
824
1609
 
1610
+ /**
1611
+ * Returns the shader attributes of the given shader stage as a WGSL string.
1612
+ *
1613
+ * @param {string} shaderStage - The shader stage.
1614
+ * @return {string} The WGSL snippet that defines the shader attributes.
1615
+ */
825
1616
  getAttributes( shaderStage ) {
826
1617
 
827
1618
  const snippets = [];
828
1619
 
829
1620
  if ( shaderStage === 'compute' ) {
830
1621
 
831
- this.getBuiltin( 'global_invocation_id', 'id', 'vec3<u32>', 'attribute' );
1622
+ this.getBuiltin( 'global_invocation_id', 'globalId', 'vec3<u32>', 'attribute' );
832
1623
  this.getBuiltin( 'workgroup_id', 'workgroupId', 'vec3<u32>', 'attribute' );
833
1624
  this.getBuiltin( 'local_invocation_id', 'localId', 'vec3<u32>', 'attribute' );
834
1625
  this.getBuiltin( 'num_workgroups', 'numWorkgroups', 'vec3<u32>', 'attribute' );
@@ -866,57 +1657,108 @@ ${ flowData.code }
866
1657
 
867
1658
  }
868
1659
 
1660
+ /**
1661
+ * Returns the members of the given struct type node as a WGSL string.
1662
+ *
1663
+ * @param {StructTypeNode} struct - The struct type node.
1664
+ * @return {string} The WGSL snippet that defines the struct members.
1665
+ */
869
1666
  getStructMembers( struct ) {
870
1667
 
871
1668
  const snippets = [];
872
- const members = struct.getMemberTypes();
873
1669
 
874
- for ( let i = 0; i < members.length; i ++ ) {
1670
+ for ( const member of struct.members ) {
1671
+
1672
+ const prefix = struct.output ? '@location( ' + member.index + ' ) ' : '';
1673
+
1674
+ let type = this.getType( member.type );
875
1675
 
876
- const member = members[ i ];
877
- snippets.push( `\t@location( ${i} ) m${i} : ${ member }<f32>` );
1676
+ if ( member.atomic ) {
1677
+
1678
+ type = 'atomic< ' + type + ' >';
1679
+
1680
+ }
1681
+
1682
+ snippets.push( `\t${ prefix + member.name } : ${ type }` );
878
1683
 
879
1684
  }
880
1685
 
881
- const builtins = this.getBuiltins( 'output' );
1686
+ if ( struct.output ) {
1687
+
1688
+ snippets.push( `\t${ this.getBuiltins( 'output' ) }` );
882
1689
 
883
- if ( builtins ) snippets.push( '\t' + builtins );
1690
+ }
884
1691
 
885
1692
  return snippets.join( ',\n' );
886
1693
 
887
1694
  }
888
1695
 
1696
+ /**
1697
+ * Returns the structs of the given shader stage as a WGSL string.
1698
+ *
1699
+ * @param {string} shaderStage - The shader stage.
1700
+ * @return {string} The WGSL snippet that defines the structs.
1701
+ */
889
1702
  getStructs( shaderStage ) {
890
1703
 
891
- const snippets = [];
1704
+ let result = '';
1705
+
892
1706
  const structs = this.structs[ shaderStage ];
893
1707
 
894
- for ( let index = 0, length = structs.length; index < length; index ++ ) {
1708
+ if ( structs.length > 0 ) {
1709
+
1710
+ const snippets = [];
895
1711
 
896
- const struct = structs[ index ];
897
- const name = struct.name;
1712
+ for ( const struct of structs ) {
898
1713
 
899
- let snippet = `\struct ${ name } {\n`;
900
- snippet += this.getStructMembers( struct );
901
- snippet += '\n}';
1714
+ let snippet = `struct ${ struct.name } {\n`;
1715
+ snippet += this.getStructMembers( struct );
1716
+ snippet += '\n};';
902
1717
 
1718
+ snippets.push( snippet );
903
1719
 
904
- snippets.push( snippet );
1720
+ }
905
1721
 
906
- snippets.push( `\nvar<private> output : ${ name };\n\n` );
1722
+ result = '\n' + snippets.join( '\n\n' ) + '\n';
907
1723
 
908
1724
  }
909
1725
 
910
- return snippets.join( '\n\n' );
1726
+ return result;
911
1727
 
912
1728
  }
913
1729
 
914
- getVar( type, name ) {
1730
+ /**
1731
+ * Returns a WGSL string representing a variable.
1732
+ *
1733
+ * @param {string} type - The variable's type.
1734
+ * @param {string} name - The variable's name.
1735
+ * @param {?number} [count=null] - The array length.
1736
+ * @return {string} The WGSL snippet that defines a variable.
1737
+ */
1738
+ getVar( type, name, count = null ) {
1739
+
1740
+ let snippet = `var ${ name } : `;
1741
+
1742
+ if ( count !== null ) {
1743
+
1744
+ snippet += this.generateArrayDeclaration( type, count );
1745
+
1746
+ } else {
1747
+
1748
+ snippet += this.getType( type );
1749
+
1750
+ }
915
1751
 
916
- return `var ${ name } : ${ this.getType( type ) }`;
1752
+ return snippet;
917
1753
 
918
1754
  }
919
1755
 
1756
+ /**
1757
+ * Returns the variables of the given shader stage as a WGSL string.
1758
+ *
1759
+ * @param {string} shaderStage - The shader stage.
1760
+ * @return {string} The WGSL snippet that defines the variables.
1761
+ */
920
1762
  getVars( shaderStage ) {
921
1763
 
922
1764
  const snippets = [];
@@ -926,7 +1768,7 @@ ${ flowData.code }
926
1768
 
927
1769
  for ( const variable of vars ) {
928
1770
 
929
- snippets.push( `\t${ this.getVar( variable.type, variable.name ) };` );
1771
+ snippets.push( `\t${ this.getVar( variable.type, variable.name, variable.count ) };` );
930
1772
 
931
1773
  }
932
1774
 
@@ -936,13 +1778,19 @@ ${ flowData.code }
936
1778
 
937
1779
  }
938
1780
 
1781
+ /**
1782
+ * Returns the varyings of the given shader stage as a WGSL string.
1783
+ *
1784
+ * @param {string} shaderStage - The shader stage.
1785
+ * @return {string} The WGSL snippet that defines the varyings.
1786
+ */
939
1787
  getVaryings( shaderStage ) {
940
1788
 
941
1789
  const snippets = [];
942
1790
 
943
1791
  if ( shaderStage === 'vertex' ) {
944
1792
 
945
- this.getBuiltin( 'position', 'Vertex', 'vec4<f32>', 'vertex' );
1793
+ this.getBuiltin( 'position', 'builtinClipSpace', 'vec4<f32>', 'vertex' );
946
1794
 
947
1795
  }
948
1796
 
@@ -959,10 +1807,17 @@ ${ flowData.code }
959
1807
 
960
1808
  let attributesSnippet = `@location( ${index} )`;
961
1809
 
962
- if ( /^(int|uint|ivec|uvec)/.test( varying.type ) ) {
1810
+ if ( varying.interpolationType ) {
1811
+
1812
+ const samplingSnippet = varying.interpolationSampling !== null ? `, ${ varying.interpolationSampling } )` : ' )';
1813
+
1814
+ attributesSnippet += ` @interpolate( ${ varying.interpolationType }${ samplingSnippet }`;
1815
+
1816
+ // Otherwise, optimize interpolation when sensible
963
1817
 
964
- attributesSnippet += ' @interpolate( flat )';
1818
+ } else if ( /^(int|uint|ivec|uvec)/.test( varying.type ) ) {
965
1819
 
1820
+ attributesSnippet += ' @interpolate(flat, either)';
966
1821
 
967
1822
  }
968
1823
 
@@ -988,6 +1843,27 @@ ${ flowData.code }
988
1843
 
989
1844
  }
990
1845
 
1846
+ isCustomStruct( nodeUniform ) {
1847
+
1848
+ const attribute = nodeUniform.value;
1849
+ const bufferNode = nodeUniform.node;
1850
+
1851
+ const isAttributeStructType = ( attribute.isBufferAttribute || attribute.isInstancedBufferAttribute ) && bufferNode.structTypeNode !== null;
1852
+
1853
+ const isStructArray =
1854
+ ( bufferNode.value && bufferNode.value.array ) &&
1855
+ ( typeof bufferNode.value.itemSize === 'number' && bufferNode.value.array.length > bufferNode.value.itemSize );
1856
+
1857
+ return isAttributeStructType && ! isStructArray;
1858
+
1859
+ }
1860
+
1861
+ /**
1862
+ * Returns the uniforms of the given shader stage as a WGSL string.
1863
+ *
1864
+ * @param {string} shaderStage - The shader stage.
1865
+ * @return {string} The WGSL snippet that defines the uniforms.
1866
+ */
991
1867
  getUniforms( shaderStage ) {
992
1868
 
993
1869
  const uniforms = this.uniforms[ shaderStage ];
@@ -1002,13 +1878,16 @@ ${ flowData.code }
1002
1878
  const groupName = uniform.groupNode.name;
1003
1879
  const uniformIndexes = this.bindingsIndexes[ groupName ];
1004
1880
 
1005
- if ( uniform.type === 'texture' || uniform.type === 'cubeTexture' || uniform.type === 'storageTexture' || uniform.type === 'texture3D' ) {
1881
+ if ( uniform.type === 'texture' || uniform.type === 'cubeTexture' || uniform.type === 'cubeDepthTexture' || uniform.type === 'storageTexture' || uniform.type === 'texture3D' ) {
1006
1882
 
1007
1883
  const texture = uniform.node.value;
1008
1884
 
1009
- if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false && uniform.node.isStorageTextureNode !== true ) {
1885
+ // Cube textures always need samplers (they use textureSampleLevel, not textureLoad)
1886
+ const needsSampler = texture.isCubeTexture === true || ( this.isUnfilterable( texture ) === false && uniform.node.isStorageTextureNode !== true );
1010
1887
 
1011
- if ( texture.isDepthTexture === true && texture.compareFunction !== null ) {
1888
+ if ( needsSampler ) {
1889
+
1890
+ if ( this.isSampleCompare( texture ) ) {
1012
1891
 
1013
1892
  bindingSnippets.push( `@binding( ${ uniformIndexes.binding ++ } ) @group( ${ uniformIndexes.group } ) var ${ uniform.name }_sampler : sampler_comparison;` );
1014
1893
 
@@ -1024,74 +1903,132 @@ ${ flowData.code }
1024
1903
 
1025
1904
  let multisampled = '';
1026
1905
 
1027
- if ( texture.isMultisampleRenderTargetTexture === true ) {
1906
+ const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
1907
+
1908
+ if ( primarySamples > 1 ) {
1028
1909
 
1029
1910
  multisampled = '_multisampled';
1030
1911
 
1031
1912
  }
1032
1913
 
1033
- if ( texture.isCubeTexture === true ) {
1914
+ if ( texture.isCubeTexture === true && texture.isDepthTexture === true ) {
1034
1915
 
1035
- textureType = 'texture_cube<f32>';
1916
+ textureType = 'texture_depth_cube';
1036
1917
 
1037
- } else if ( texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true ) {
1918
+ } else if ( texture.isCubeTexture === true ) {
1038
1919
 
1039
- textureType = 'texture_2d_array<f32>';
1920
+ textureType = 'texture_cube<f32>';
1040
1921
 
1041
1922
  } else if ( texture.isDepthTexture === true ) {
1042
1923
 
1043
- textureType = `texture_depth${multisampled}_2d`;
1924
+ if ( this.renderer.backend.compatibilityMode && texture.compareFunction === null ) {
1044
1925
 
1045
- } else if ( texture.isVideoTexture === true ) {
1926
+ textureType = `texture${ multisampled }_2d<f32>`;
1046
1927
 
1047
- textureType = 'texture_external';
1928
+ } else {
1048
1929
 
1049
- } else if ( texture.isData3DTexture === true ) {
1930
+ textureType = `texture_depth${ multisampled }_2d${ texture.isArrayTexture === true ? '_array' : '' }`;
1050
1931
 
1051
- textureType = 'texture_3d<f32>';
1932
+ }
1052
1933
 
1053
1934
  } else if ( uniform.node.isStorageTextureNode === true ) {
1054
1935
 
1055
1936
  const format = getFormat( texture );
1056
- const access = this.getStorageAccess( uniform.node );
1937
+ const access = this.getStorageAccess( uniform.node, shaderStage );
1938
+
1939
+ const is3D = uniform.node.value.is3DTexture;
1940
+ const isArrayTexture = uniform.node.value.isArrayTexture;
1941
+
1942
+ const dimension = is3D ? '3d' : `2d${ isArrayTexture ? '_array' : '' }`;
1943
+
1944
+ textureType = `texture_storage_${ dimension }<${ format }, ${ access }>`;
1945
+
1946
+ } else if ( texture.isArrayTexture === true || texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true ) {
1947
+
1948
+ textureType = 'texture_2d_array<f32>';
1949
+
1950
+ } else if ( texture.is3DTexture === true || texture.isData3DTexture === true ) {
1057
1951
 
1058
- textureType = `texture_storage_2d<${ format }, ${ access }>`;
1952
+ textureType = 'texture_3d<f32>';
1059
1953
 
1060
1954
  } else {
1061
1955
 
1062
1956
  const componentPrefix = this.getComponentTypeFromTexture( texture ).charAt( 0 );
1063
1957
 
1064
- textureType = `texture${multisampled}_2d<${ componentPrefix }32>`;
1958
+ textureType = `texture${ multisampled }_2d<${ componentPrefix }32>`;
1065
1959
 
1066
1960
  }
1067
1961
 
1068
1962
  bindingSnippets.push( `@binding( ${ uniformIndexes.binding ++ } ) @group( ${ uniformIndexes.group } ) var ${ uniform.name } : ${ textureType };` );
1069
1963
 
1070
- } else if ( uniform.type === 'buffer' || uniform.type === 'storageBuffer' ) {
1964
+ } else if ( uniform.type === 'buffer' || uniform.type === 'storageBuffer' || uniform.type === 'indirectStorageBuffer' ) {
1071
1965
 
1072
1966
  const bufferNode = uniform.node;
1073
- const bufferType = this.getType( bufferNode.bufferType );
1967
+ const bufferType = this.getType( bufferNode.getNodeType( this ) );
1074
1968
  const bufferCount = bufferNode.bufferCount;
1969
+ const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : '';
1970
+ const bufferAccessMode = bufferNode.isStorageBufferNode ? `storage, ${ this.getStorageAccess( bufferNode, shaderStage ) }` : 'uniform';
1971
+
1972
+ if ( this.isCustomStruct( uniform ) ) {
1973
+
1974
+ bufferSnippets.push( `@binding( ${ uniformIndexes.binding ++ } ) @group( ${ uniformIndexes.group } ) var<${ bufferAccessMode }> ${ uniform.name } : ${ bufferType };` );
1975
+
1976
+ } else {
1075
1977
 
1076
- const bufferCountSnippet = bufferCount > 0 ? ', ' + bufferCount : '';
1077
- const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`;
1078
- const bufferSnippet = `\t${ uniform.name } : array< ${ bufferTypeSnippet }${ bufferCountSnippet } >\n`;
1079
- const bufferAccessMode = bufferNode.isStorageBufferNode ? `storage, ${ this.getStorageAccess( bufferNode ) }` : 'uniform';
1978
+ const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${ bufferType }>` : `${ bufferType }`;
1979
+ const bufferSnippet = `\tvalue : array< ${ bufferTypeSnippet }${ bufferCountSnippet } >`;
1080
1980
 
1081
- bufferSnippets.push( this._getWGSLStructBinding( 'NodeBuffer_' + bufferNode.id, bufferSnippet, bufferAccessMode, uniformIndexes.binding ++, uniformIndexes.group ) );
1981
+ bufferSnippets.push( this._getWGSLStructBinding( uniform.name, bufferSnippet, bufferAccessMode, uniformIndexes.binding ++, uniformIndexes.group ) );
1982
+
1983
+ }
1082
1984
 
1083
1985
  } else {
1084
1986
 
1085
- const vectorType = this.getType( this.getVectorType( uniform.type ) );
1086
1987
  const groupName = uniform.groupNode.name;
1087
1988
 
1088
- const group = uniformGroups[ groupName ] || ( uniformGroups[ groupName ] = {
1089
- index: uniformIndexes.binding ++,
1090
- id: uniformIndexes.group,
1091
- snippets: []
1092
- } );
1989
+ // Check if this group has already been processed in this shader stage
1990
+ if ( uniformGroups[ groupName ] === undefined ) {
1991
+
1992
+ // Get the shared uniform group that contains uniforms from all stages
1993
+ const sharedUniformGroup = this.uniformGroups[ groupName ];
1994
+
1995
+ if ( sharedUniformGroup !== undefined ) {
1996
+
1997
+ // Generate snippets for ALL uniforms in this shared group
1998
+ const snippets = [];
1999
+
2000
+ for ( const sharedUniform of sharedUniformGroup.uniforms ) {
2001
+
2002
+ const type = sharedUniform.getType();
2003
+ const vectorType = this.getType( this.getVectorType( type ) );
2004
+ snippets.push( `\t${ sharedUniform.name } : ${ vectorType }` );
2005
+
2006
+ }
2007
+
2008
+ // Check if this group already has an assigned binding index (from another shader stage)
2009
+ let groupBinding = this.uniformGroupsBindings[ groupName ];
2010
+
2011
+ if ( groupBinding === undefined ) {
2012
+
2013
+ // First time processing this group - assign a new binding index
2014
+ groupBinding = {
2015
+ index: uniformIndexes.binding ++,
2016
+ id: uniformIndexes.group
2017
+ };
2018
+
2019
+ this.uniformGroupsBindings[ groupName ] = groupBinding;
1093
2020
 
1094
- group.snippets.push( `\t${ uniform.name } : ${ vectorType }` );
2021
+ }
2022
+
2023
+ uniformGroups[ groupName ] = {
2024
+ index: groupBinding.index,
2025
+ id: groupBinding.id,
2026
+ snippets: snippets
2027
+ };
2028
+
2029
+ }
2030
+
2031
+ }
1095
2032
 
1096
2033
  }
1097
2034
 
@@ -1105,14 +2042,15 @@ ${ flowData.code }
1105
2042
 
1106
2043
  }
1107
2044
 
1108
- let code = bindingSnippets.join( '\n' );
1109
- code += bufferSnippets.join( '\n' );
1110
- code += structSnippets.join( '\n' );
2045
+ const code = [ ...bindingSnippets, ...bufferSnippets, ...structSnippets ].join( '\n' );
1111
2046
 
1112
2047
  return code;
1113
2048
 
1114
2049
  }
1115
2050
 
2051
+ /**
2052
+ * Controls the code build of the shader stages.
2053
+ */
1116
2054
  buildCode() {
1117
2055
 
1118
2056
  const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} };
@@ -1121,6 +2059,8 @@ ${ flowData.code }
1121
2059
 
1122
2060
  for ( const shaderStage in shadersData ) {
1123
2061
 
2062
+ this.shaderStage = shaderStage;
2063
+
1124
2064
  const stageData = shadersData[ shaderStage ];
1125
2065
  stageData.uniforms = this.getUniforms( shaderStage );
1126
2066
  stageData.attributes = this.getAttributes( shaderStage );
@@ -1151,7 +2091,7 @@ ${ flowData.code }
1151
2091
 
1152
2092
  if ( flow.length > 0 ) flow += '\n';
1153
2093
 
1154
- flow += `\t// flow -> ${ slotName }\n\t`;
2094
+ flow += `\t// flow -> ${ slotName }\n`;
1155
2095
 
1156
2096
  }
1157
2097
 
@@ -1163,13 +2103,14 @@ ${ flowData.code }
1163
2103
 
1164
2104
  if ( shaderStage === 'vertex' ) {
1165
2105
 
1166
- flow += `varyings.Vertex = ${ flowSlotData.result };`;
2106
+ flow += `varyings.builtinClipSpace = ${ flowSlotData.result };`;
1167
2107
 
1168
2108
  } else if ( shaderStage === 'fragment' ) {
1169
2109
 
1170
2110
  if ( isOutputStruct ) {
1171
2111
 
1172
- stageData.returnType = outputNode.nodeType;
2112
+ stageData.returnType = outputNode.getNodeType( this );
2113
+ stageData.structs += 'var<private> output : ' + stageData.returnType + ';';
1173
2114
 
1174
2115
  flow += `return ${ flowSlotData.result };`;
1175
2116
 
@@ -1183,7 +2124,7 @@ ${ flowData.code }
1183
2124
 
1184
2125
  stageData.returnType = 'OutputStruct';
1185
2126
  stageData.structs += this._getWGSLStruct( 'OutputStruct', structSnippet );
1186
- stageData.structs += '\nvar<private> output : OutputStruct;\n\n';
2127
+ stageData.structs += '\nvar<private> output : OutputStruct;';
1187
2128
 
1188
2129
  flow += `output.color = ${ flowSlotData.result };\n\n\treturn output;`;
1189
2130
 
@@ -1197,9 +2138,10 @@ ${ flowData.code }
1197
2138
 
1198
2139
  stageData.flow = flow;
1199
2140
 
1200
-
1201
2141
  }
1202
2142
 
2143
+ this.shaderStage = null;
2144
+
1203
2145
  if ( this.material !== null ) {
1204
2146
 
1205
2147
  this.vertexShader = this._getWGSLVertexCode( shadersData.vertex );
@@ -1207,12 +2149,23 @@ ${ flowData.code }
1207
2149
 
1208
2150
  } else {
1209
2151
 
1210
- this.computeShader = this._getWGSLComputeCode( shadersData.compute, ( this.object.workgroupSize || [ 64 ] ).join( ', ' ) );
2152
+ // Early strictly validated in computeNode
2153
+
2154
+ const workgroupSize = this.object.workgroupSize;
2155
+
2156
+ this.computeShader = this._getWGSLComputeCode( shadersData.compute, workgroupSize );
1211
2157
 
1212
2158
  }
1213
2159
 
1214
2160
  }
1215
2161
 
2162
+ /**
2163
+ * Returns the native shader method name for a given generic name.
2164
+ *
2165
+ * @param {string} method - The method name to resolve.
2166
+ * @param {?string} [output=null] - An optional output.
2167
+ * @return {string} The resolved WGSL method name.
2168
+ */
1216
2169
  getMethod( method, output = null ) {
1217
2170
 
1218
2171
  let wgslMethod;
@@ -1233,12 +2186,76 @@ ${ flowData.code }
1233
2186
 
1234
2187
  }
1235
2188
 
2189
+ /**
2190
+ * Returns the bitcast method name for a given input and outputType.
2191
+ *
2192
+ * @param {string} type - The output type to bitcast to.
2193
+ * @return {string} The resolved WGSL bitcast invocation.
2194
+ */
2195
+ getBitcastMethod( type ) {
2196
+
2197
+ const dataType = this.getType( type );
2198
+
2199
+ return `bitcast<${ dataType }>`;
2200
+
2201
+ }
2202
+
2203
+ /**
2204
+ * Returns the float packing method name for a given numeric encoding.
2205
+ *
2206
+ * @param {string} encoding - The numeric encoding that describes how the float values are mapped to the integer range.
2207
+ * @returns {string} The resolve WGSL float packing method name.
2208
+ */
2209
+ getFloatPackingMethod( encoding ) {
2210
+
2211
+ return this.getMethod( `floatpack_${ encoding }_2x16` );
2212
+
2213
+ }
2214
+
2215
+ /**
2216
+ * Returns the float unpacking method name for a given numeric encoding.
2217
+ *
2218
+ * @param {string} encoding - The numeric encoding that describes how the integer values are mapped to the float range.
2219
+ * @returns {string} The resolve WGSL float unpacking method name.
2220
+ */
2221
+ getFloatUnpackingMethod( encoding ) {
2222
+
2223
+ return this.getMethod( `floatunpack_${ encoding }_2x16` );
2224
+
2225
+ }
2226
+
2227
+ /**
2228
+ * Returns the native snippet for a ternary operation.
2229
+ *
2230
+ * @param {string} condSnippet - The condition determining which expression gets resolved.
2231
+ * @param {string} ifSnippet - The expression to resolve to if the condition is true.
2232
+ * @param {string} elseSnippet - The expression to resolve to if the condition is false.
2233
+ * @return {string} The resolved method name.
2234
+ */
2235
+ getTernary( condSnippet, ifSnippet, elseSnippet ) {
2236
+
2237
+ return `select( ${elseSnippet}, ${ifSnippet}, ${condSnippet} )`;
2238
+
2239
+ }
2240
+
2241
+ /**
2242
+ * Returns the WGSL type of the given node data type.
2243
+ *
2244
+ * @param {string} type - The node data type.
2245
+ * @return {string} The WGSL type.
2246
+ */
1236
2247
  getType( type ) {
1237
2248
 
1238
2249
  return wgslTypeLib[ type ] || type;
1239
2250
 
1240
2251
  }
1241
2252
 
2253
+ /**
2254
+ * Whether the requested feature is available or not.
2255
+ *
2256
+ * @param {string} name - The requested feature.
2257
+ * @return {boolean} Whether the requested feature is supported or not.
2258
+ */
1242
2259
  isAvailable( name ) {
1243
2260
 
1244
2261
  let result = supports[ name ];
@@ -1249,6 +2266,10 @@ ${ flowData.code }
1249
2266
 
1250
2267
  result = this.renderer.hasFeature( 'float32-filterable' );
1251
2268
 
2269
+ } else if ( name === 'clipDistance' ) {
2270
+
2271
+ result = this.renderer.hasFeature( 'clip-distances' );
2272
+
1252
2273
  }
1253
2274
 
1254
2275
  supports[ name ] = result;
@@ -1259,6 +2280,24 @@ ${ flowData.code }
1259
2280
 
1260
2281
  }
1261
2282
 
2283
+ /**
2284
+ * Returns the maximum uniform buffer size limit.
2285
+ *
2286
+ * @return {number} The maximum uniform buffer size in bytes.
2287
+ */
2288
+ getUniformBufferLimit() {
2289
+
2290
+ return this.renderer.backend.device.limits.maxUniformBufferBindingSize;
2291
+
2292
+ }
2293
+
2294
+ /**
2295
+ * Returns the native shader method name for a given generic name.
2296
+ *
2297
+ * @private
2298
+ * @param {string} method - The method name to resolve.
2299
+ * @return {string} The resolved WGSL method name.
2300
+ */
1262
2301
  _getWGSLMethod( method ) {
1263
2302
 
1264
2303
  if ( wgslPolyfill[ method ] !== undefined ) {
@@ -1271,27 +2310,41 @@ ${ flowData.code }
1271
2310
 
1272
2311
  }
1273
2312
 
2313
+ /**
2314
+ * Includes the given method name into the current
2315
+ * function node.
2316
+ *
2317
+ * @private
2318
+ * @param {string} name - The method name to include.
2319
+ * @return {CodeNode} The respective code node.
2320
+ */
1274
2321
  _include( name ) {
1275
2322
 
1276
2323
  const codeNode = wgslPolyfill[ name ];
1277
2324
  codeNode.build( this );
1278
2325
 
1279
- if ( this.currentFunctionNode !== null ) {
1280
-
1281
- this.currentFunctionNode.includes.push( codeNode );
1282
-
1283
- }
2326
+ this.addInclude( codeNode );
1284
2327
 
1285
2328
  return codeNode;
1286
2329
 
1287
2330
  }
1288
2331
 
2332
+ /**
2333
+ * Returns a WGSL vertex shader based on the given shader data.
2334
+ *
2335
+ * @private
2336
+ * @param {Object} shaderData - The shader data.
2337
+ * @return {string} The vertex shader.
2338
+ */
1289
2339
  _getWGSLVertexCode( shaderData ) {
1290
2340
 
1291
2341
  return `${ this.getSignature() }
1292
2342
  // directives
1293
2343
  ${shaderData.directives}
1294
2344
 
2345
+ // structs
2346
+ ${shaderData.structs}
2347
+
1295
2348
  // uniforms
1296
2349
  ${shaderData.uniforms}
1297
2350
 
@@ -1318,18 +2371,25 @@ fn main( ${shaderData.attributes} ) -> VaryingsStruct {
1318
2371
 
1319
2372
  }
1320
2373
 
2374
+ /**
2375
+ * Returns a WGSL fragment shader based on the given shader data.
2376
+ *
2377
+ * @private
2378
+ * @param {Object} shaderData - The shader data.
2379
+ * @return {string} The vertex shader.
2380
+ */
1321
2381
  _getWGSLFragmentCode( shaderData ) {
1322
2382
 
1323
2383
  return `${ this.getSignature() }
1324
2384
  // global
1325
2385
  ${ diagnostics }
1326
2386
 
1327
- // uniforms
1328
- ${shaderData.uniforms}
1329
-
1330
2387
  // structs
1331
2388
  ${shaderData.structs}
1332
2389
 
2390
+ // uniforms
2391
+ ${shaderData.uniforms}
2392
+
1333
2393
  // codes
1334
2394
  ${shaderData.codes}
1335
2395
 
@@ -1347,41 +2407,64 @@ fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} {
1347
2407
 
1348
2408
  }
1349
2409
 
2410
+ /**
2411
+ * Returns a WGSL compute shader based on the given shader data.
2412
+ *
2413
+ * @private
2414
+ * @param {Object} shaderData - The shader data.
2415
+ * @param {string} workgroupSize - The workgroup size.
2416
+ * @return {string} The vertex shader.
2417
+ */
1350
2418
  _getWGSLComputeCode( shaderData, workgroupSize ) {
1351
2419
 
2420
+ const [ workgroupSizeX, workgroupSizeY, workgroupSizeZ ] = workgroupSize;
2421
+
1352
2422
  return `${ this.getSignature() }
1353
2423
  // directives
1354
- ${shaderData.directives}
2424
+ ${ shaderData.directives }
1355
2425
 
1356
2426
  // system
1357
2427
  var<private> instanceIndex : u32;
1358
2428
 
1359
2429
  // locals
1360
- ${shaderData.scopedArrays}
2430
+ ${ shaderData.scopedArrays }
2431
+
2432
+ // structs
2433
+ ${ shaderData.structs }
1361
2434
 
1362
2435
  // uniforms
1363
- ${shaderData.uniforms}
2436
+ ${ shaderData.uniforms }
1364
2437
 
1365
2438
  // codes
1366
- ${shaderData.codes}
2439
+ ${ shaderData.codes }
1367
2440
 
1368
- @compute @workgroup_size( ${workgroupSize} )
1369
- fn main( ${shaderData.attributes} ) {
2441
+ @compute @workgroup_size( ${ workgroupSizeX }, ${ workgroupSizeY }, ${ workgroupSizeZ } )
2442
+ fn main( ${ shaderData.attributes } ) {
1370
2443
 
1371
2444
  // system
1372
- instanceIndex = id.x + id.y * numWorkgroups.x * u32(${workgroupSize}) + id.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize});
2445
+ instanceIndex = globalId.x
2446
+ + globalId.y * ( ${ workgroupSizeX } * numWorkgroups.x )
2447
+ + globalId.z * ( ${ workgroupSizeX } * numWorkgroups.x ) * ( ${ workgroupSizeY } * numWorkgroups.y );
1373
2448
 
1374
2449
  // vars
1375
- ${shaderData.vars}
2450
+ ${ shaderData.vars }
1376
2451
 
1377
2452
  // flow
1378
- ${shaderData.flow}
2453
+ ${ shaderData.flow }
1379
2454
 
1380
2455
  }
1381
2456
  `;
1382
2457
 
1383
2458
  }
1384
2459
 
2460
+ /**
2461
+ * Returns a WGSL struct based on the given name and variables.
2462
+ *
2463
+ * @private
2464
+ * @param {string} name - The struct name.
2465
+ * @param {string} vars - The struct variables.
2466
+ * @return {string} The WGSL snippet representing a struct.
2467
+ */
1385
2468
  _getWGSLStruct( name, vars ) {
1386
2469
 
1387
2470
  return `
@@ -1391,14 +2474,25 @@ ${vars}
1391
2474
 
1392
2475
  }
1393
2476
 
2477
+ /**
2478
+ * Returns a WGSL struct binding.
2479
+ *
2480
+ * @private
2481
+ * @param {string} name - The struct name.
2482
+ * @param {string} vars - The struct variables.
2483
+ * @param {string} access - The access.
2484
+ * @param {number} [binding=0] - The binding index.
2485
+ * @param {number} [group=0] - The group index.
2486
+ * @return {string} The WGSL snippet representing a struct binding.
2487
+ */
1394
2488
  _getWGSLStructBinding( name, vars, access, binding = 0, group = 0 ) {
1395
2489
 
1396
2490
  const structName = name + 'Struct';
1397
2491
  const structSnippet = this._getWGSLStruct( structName, vars );
1398
2492
 
1399
2493
  return `${structSnippet}
1400
- @binding( ${binding} ) @group( ${group} )
1401
- var<${access}> ${name} : ${structName};`;
2494
+ @binding( ${ binding } ) @group( ${ group } )
2495
+ var<${access}> ${ name } : ${ structName };`;
1402
2496
 
1403
2497
  }
1404
2498