super-three 0.171.0 → 0.173.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 (455) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/build/three.cjs +594 -427
  4. package/build/three.core.js +515 -81
  5. package/build/three.core.min.js +2 -2
  6. package/build/three.module.js +79 -350
  7. package/build/three.module.min.js +2 -2
  8. package/build/three.tsl.js +20 -7
  9. package/build/three.tsl.min.js +2 -2
  10. package/build/three.webgpu.js +29362 -3427
  11. package/build/three.webgpu.min.js +2 -2
  12. package/build/three.webgpu.nodes.js +29361 -3427
  13. package/build/three.webgpu.nodes.min.js +2 -2
  14. package/examples/jsm/Addons.js +0 -5
  15. package/examples/jsm/animation/CCDIKSolver.js +9 -7
  16. package/examples/jsm/capabilities/WebGPU.js +1 -1
  17. package/examples/jsm/controls/ArcballControls.js +48 -37
  18. package/examples/jsm/controls/OrbitControls.js +5 -4
  19. package/examples/jsm/csm/CSMShadowNode.js +16 -11
  20. package/examples/jsm/curves/NURBSCurve.js +1 -1
  21. package/examples/jsm/curves/NURBSUtils.js +3 -0
  22. package/examples/jsm/effects/OutlineEffect.js +1 -1
  23. package/examples/jsm/exporters/GLTFExporter.js +34 -29
  24. package/examples/jsm/exporters/KTX2Exporter.js +1 -1
  25. package/examples/jsm/exporters/PLYExporter.js +2 -2
  26. package/examples/jsm/geometries/TextGeometry.js +1 -12
  27. package/examples/jsm/helpers/TextureHelperGPU.js +15 -5
  28. package/examples/jsm/helpers/VertexNormalsHelper.js +2 -0
  29. package/examples/jsm/interactive/InteractiveGroup.js +108 -51
  30. package/examples/jsm/libs/demuxer_mp4.js +109 -0
  31. package/examples/jsm/lights/LightProbeGenerator.js +3 -3
  32. package/examples/jsm/lines/webgpu/LineSegments2.js +15 -6
  33. package/examples/jsm/loaders/3MFLoader.js +6 -3
  34. package/examples/jsm/loaders/BVHLoader.js +1 -1
  35. package/examples/jsm/loaders/ColladaLoader.js +5 -5
  36. package/examples/jsm/loaders/DDSLoader.js +42 -0
  37. package/examples/jsm/loaders/GCodeLoader.js +4 -2
  38. package/examples/jsm/loaders/GLTFLoader.js +22 -4
  39. package/examples/jsm/loaders/KTX2Loader.js +6 -1
  40. package/examples/jsm/loaders/KTXLoader.js +4 -4
  41. package/examples/jsm/loaders/LDrawLoader.js +1 -1
  42. package/examples/jsm/loaders/LottieLoader.js +1 -1
  43. package/examples/jsm/loaders/MTLLoader.js +1 -0
  44. package/examples/jsm/loaders/NRRDLoader.js +1 -1
  45. package/examples/jsm/loaders/PLYLoader.js +7 -7
  46. package/examples/jsm/loaders/PVRLoader.js +1 -1
  47. package/examples/jsm/loaders/SVGLoader.js +2 -2
  48. package/examples/jsm/loaders/TDSLoader.js +1 -2
  49. package/examples/jsm/loaders/VRMLLoader.js +7 -7
  50. package/examples/jsm/loaders/lwo/IFFParser.js +4 -4
  51. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +1 -1
  52. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  53. package/examples/jsm/math/ConvexHull.js +1 -1
  54. package/examples/jsm/math/OBB.js +17 -0
  55. package/examples/jsm/misc/GPUComputationRenderer.js +6 -7
  56. package/examples/jsm/misc/ProgressiveLightMap.js +4 -3
  57. package/examples/jsm/misc/ProgressiveLightMapGPU.js +14 -13
  58. package/examples/jsm/misc/Volume.js +27 -17
  59. package/examples/jsm/misc/VolumeSlice.js +7 -5
  60. package/examples/jsm/modifiers/CurveModifier.js +10 -8
  61. package/examples/jsm/modifiers/CurveModifierGPU.js +9 -7
  62. package/examples/jsm/modifiers/SimplifyModifier.js +2 -2
  63. package/examples/jsm/objects/GroundedSkybox.js +4 -4
  64. package/examples/jsm/objects/Sky.js +2 -2
  65. package/examples/jsm/objects/SkyMesh.js +3 -3
  66. package/examples/jsm/objects/Water2.js +1 -1
  67. package/examples/jsm/objects/Water2Mesh.js +2 -2
  68. package/examples/jsm/objects/WaterMesh.js +29 -24
  69. package/examples/jsm/physics/JoltPhysics.js +7 -7
  70. package/examples/jsm/physics/RapierPhysics.js +4 -4
  71. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  72. package/examples/jsm/postprocessing/EffectComposer.js +1 -2
  73. package/examples/jsm/postprocessing/OutlinePass.js +4 -4
  74. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  75. package/examples/jsm/postprocessing/SAOPass.js +1 -2
  76. package/examples/jsm/postprocessing/SMAAPass.js +1 -3
  77. package/examples/jsm/postprocessing/SSAOPass.js +2 -4
  78. package/examples/jsm/postprocessing/SSRPass.js +2 -4
  79. package/examples/jsm/postprocessing/UnrealBloomPass.js +2 -2
  80. package/examples/jsm/renderers/SVGRenderer.js +6 -4
  81. package/examples/jsm/shaders/BokehShader2.js +1 -1
  82. package/examples/jsm/shaders/GodRaysShader.js +3 -3
  83. package/examples/jsm/shaders/OutputShader.js +5 -1
  84. package/examples/jsm/shaders/SobelOperatorShader.js +1 -1
  85. package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
  86. package/examples/jsm/transpiler/TSLEncoder.js +2 -0
  87. package/examples/jsm/tsl/display/AfterImageNode.js +93 -4
  88. package/examples/jsm/tsl/display/AnaglyphPassNode.js +46 -2
  89. package/examples/jsm/tsl/display/AnamorphicNode.js +118 -5
  90. package/examples/jsm/tsl/display/BleachBypass.js +10 -0
  91. package/examples/jsm/tsl/display/BloomNode.js +233 -26
  92. package/examples/jsm/tsl/display/DenoiseNode.js +141 -25
  93. package/examples/jsm/tsl/display/DepthOfFieldNode.js +80 -1
  94. package/examples/jsm/tsl/display/DotScreenNode.js +50 -5
  95. package/examples/jsm/tsl/display/FXAANode.js +52 -3
  96. package/examples/jsm/tsl/display/FilmNode.js +47 -1
  97. package/examples/jsm/tsl/display/GTAONode.js +210 -14
  98. package/examples/jsm/tsl/display/GaussianBlurNode.js +152 -8
  99. package/examples/jsm/tsl/display/LensflareNode.js +131 -13
  100. package/examples/jsm/tsl/display/Lut3DNode.js +55 -1
  101. package/examples/jsm/tsl/display/MotionBlur.js +12 -2
  102. package/examples/jsm/tsl/display/OutlineNode.js +343 -26
  103. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +36 -2
  104. package/examples/jsm/tsl/display/PixelationPassNode.js +142 -9
  105. package/examples/jsm/tsl/display/RGBShiftNode.js +49 -2
  106. package/examples/jsm/tsl/display/SMAANode.js +187 -46
  107. package/examples/jsm/tsl/display/SSAAPassNode.js +110 -25
  108. package/examples/jsm/tsl/display/SSRNode.js +194 -21
  109. package/examples/jsm/tsl/display/Sepia.js +9 -0
  110. package/examples/jsm/tsl/display/SobelOperatorNode.js +54 -4
  111. package/examples/jsm/tsl/display/StereoCompositePassNode.js +79 -3
  112. package/examples/jsm/tsl/display/StereoPassNode.js +41 -3
  113. package/examples/jsm/tsl/display/TRAAPassNode.js +116 -21
  114. package/examples/jsm/tsl/display/TransitionNode.js +71 -6
  115. package/examples/jsm/tsl/display/hashBlur.js +14 -3
  116. package/examples/jsm/tsl/lighting/TiledLightsNode.js +40 -34
  117. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  118. package/examples/jsm/utils/CameraUtils.js +4 -1
  119. package/examples/jsm/utils/GeometryUtils.js +22 -19
  120. package/examples/jsm/utils/SceneUtils.js +2 -2
  121. package/examples/jsm/webxr/XRControllerModelFactory.js +6 -1
  122. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  123. package/package.json +8 -3
  124. package/src/Three.Core.js +4 -0
  125. package/src/Three.Legacy.js +0 -21
  126. package/src/Three.TSL.js +18 -5
  127. package/src/Three.WebGPU.Nodes.js +2 -2
  128. package/src/Three.WebGPU.js +2 -2
  129. package/src/animation/PropertyBinding.js +2 -2
  130. package/src/cameras/ArrayCamera.js +1 -0
  131. package/src/cameras/PerspectiveCamera.js +18 -2
  132. package/src/constants.js +6 -1
  133. package/src/core/BufferAttribute.js +4 -0
  134. package/src/core/EventDispatcher.js +8 -6
  135. package/src/core/RenderTarget.js +18 -0
  136. package/src/core/RenderTarget3D.js +22 -0
  137. package/src/core/RenderTargetArray.js +22 -0
  138. package/src/extras/Earcut.js +1 -1
  139. package/src/extras/ImageUtils.js +1 -11
  140. package/src/extras/PMREMGenerator.js +20 -0
  141. package/src/extras/TextureUtils.js +6 -0
  142. package/src/helpers/CameraHelper.js +16 -13
  143. package/src/loaders/nodes/NodeLoader.js +59 -0
  144. package/src/loaders/nodes/NodeMaterialLoader.js +45 -0
  145. package/src/loaders/nodes/NodeObjectLoader.js +61 -0
  146. package/src/materials/nodes/Line2NodeMaterial.js +128 -34
  147. package/src/materials/nodes/LineBasicNodeMaterial.js +17 -2
  148. package/src/materials/nodes/LineDashedNodeMaterial.js +78 -5
  149. package/src/materials/nodes/MeshBasicNodeMaterial.js +56 -0
  150. package/src/materials/nodes/MeshLambertNodeMaterial.js +35 -0
  151. package/src/materials/nodes/MeshMatcapNodeMaterial.js +22 -2
  152. package/src/materials/nodes/MeshNormalNodeMaterial.js +21 -2
  153. package/src/materials/nodes/MeshPhongNodeMaterial.js +64 -1
  154. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +269 -0
  155. package/src/materials/nodes/MeshSSSNodeMaterial.js +97 -6
  156. package/src/materials/nodes/MeshStandardNodeMaterial.js +78 -0
  157. package/src/materials/nodes/MeshToonNodeMaterial.js +28 -0
  158. package/src/materials/nodes/NodeMaterial.js +476 -23
  159. package/src/materials/nodes/NodeMaterials.js +0 -1
  160. package/src/materials/nodes/PointsNodeMaterial.js +121 -10
  161. package/src/materials/nodes/ShadowNodeMaterial.js +29 -0
  162. package/src/materials/nodes/SpriteNodeMaterial.js +78 -20
  163. package/src/materials/nodes/VolumeNodeMaterial.js +80 -4
  164. package/src/materials/nodes/manager/NodeMaterialObserver.js +95 -0
  165. package/src/nodes/Nodes.js +5 -6
  166. package/src/nodes/TSL.js +6 -3
  167. package/src/nodes/accessors/AccessorsUtils.js +27 -0
  168. package/src/nodes/accessors/Arrays.js +47 -6
  169. package/src/nodes/accessors/BatchNode.js +42 -6
  170. package/src/nodes/accessors/Bitangent.js +37 -0
  171. package/src/nodes/accessors/BufferAttributeNode.js +178 -5
  172. package/src/nodes/accessors/BufferNode.js +63 -0
  173. package/src/nodes/accessors/BuiltinNode.js +38 -0
  174. package/src/nodes/accessors/Camera.js +113 -3
  175. package/src/nodes/accessors/ClippingNode.js +71 -2
  176. package/src/nodes/accessors/CubeTextureNode.js +64 -0
  177. package/src/nodes/accessors/InstanceNode.js +85 -2
  178. package/src/nodes/accessors/InstancedMeshNode.js +28 -3
  179. package/src/nodes/accessors/Lights.js +50 -1
  180. package/src/nodes/accessors/MaterialNode.js +306 -12
  181. package/src/nodes/accessors/MaterialProperties.js +7 -0
  182. package/src/nodes/accessors/MaterialReferenceNode.js +53 -13
  183. package/src/nodes/accessors/ModelNode.js +100 -5
  184. package/src/nodes/accessors/ModelViewProjectionNode.js +10 -38
  185. package/src/nodes/accessors/MorphNode.js +48 -4
  186. package/src/nodes/accessors/Normal.js +65 -5
  187. package/src/nodes/accessors/Object3DNode.js +101 -1
  188. package/src/nodes/accessors/PointUVNode.js +26 -0
  189. package/src/nodes/accessors/Position.js +56 -7
  190. package/src/nodes/accessors/ReferenceBaseNode.js +186 -0
  191. package/src/nodes/accessors/ReferenceNode.js +201 -2
  192. package/src/nodes/accessors/ReflectVector.js +24 -0
  193. package/src/nodes/accessors/RendererReferenceNode.js +46 -1
  194. package/src/nodes/accessors/SceneNode.js +54 -0
  195. package/src/nodes/accessors/SkinningNode.js +127 -1
  196. package/src/nodes/accessors/StorageBufferNode.js +209 -8
  197. package/src/nodes/accessors/StorageTextureNode.js +118 -0
  198. package/src/nodes/accessors/Tangent.js +38 -2
  199. package/src/nodes/accessors/Texture3DNode.js +91 -7
  200. package/src/nodes/accessors/TextureBicubic.js +12 -2
  201. package/src/nodes/accessors/TextureNode.js +316 -10
  202. package/src/nodes/accessors/TextureSizeNode.js +42 -0
  203. package/src/nodes/accessors/UV.js +10 -1
  204. package/src/nodes/accessors/UniformArrayNode.js +231 -25
  205. package/src/nodes/accessors/UserDataNode.js +46 -0
  206. package/src/nodes/accessors/VelocityNode.js +80 -0
  207. package/src/nodes/accessors/VertexColorNode.js +39 -2
  208. package/src/nodes/code/CodeNode.js +95 -1
  209. package/src/nodes/code/ExpressionNode.js +28 -0
  210. package/src/nodes/code/FunctionCallNode.js +37 -0
  211. package/src/nodes/code/FunctionNode.js +45 -0
  212. package/src/nodes/code/ScriptableNode.js +223 -1
  213. package/src/nodes/code/ScriptableValueNode.js +85 -1
  214. package/src/nodes/core/ArrayNode.js +125 -0
  215. package/src/nodes/core/AssignNode.js +48 -2
  216. package/src/nodes/core/AttributeNode.js +43 -0
  217. package/src/nodes/core/BypassNode.js +47 -2
  218. package/src/nodes/core/CacheNode.js +53 -2
  219. package/src/nodes/core/ConstNode.js +32 -0
  220. package/src/nodes/core/ContextNode.js +65 -0
  221. package/src/nodes/core/IndexNode.js +68 -7
  222. package/src/nodes/core/InputNode.js +48 -0
  223. package/src/nodes/core/LightingModel.js +60 -0
  224. package/src/nodes/core/MRTNode.js +66 -0
  225. package/src/nodes/core/Node.js +350 -12
  226. package/src/nodes/core/NodeAttribute.js +38 -0
  227. package/src/nodes/core/NodeBuilder.js +1166 -26
  228. package/src/nodes/core/NodeCache.js +41 -2
  229. package/src/nodes/core/NodeCode.js +31 -0
  230. package/src/nodes/core/NodeFrame.js +123 -2
  231. package/src/nodes/core/NodeFunction.js +46 -0
  232. package/src/nodes/core/NodeFunctionInput.js +44 -0
  233. package/src/nodes/core/NodeParser.js +11 -0
  234. package/src/nodes/core/NodeUniform.js +52 -0
  235. package/src/nodes/core/NodeUtils.js +152 -1
  236. package/src/nodes/core/NodeVar.js +47 -1
  237. package/src/nodes/core/NodeVarying.js +28 -0
  238. package/src/nodes/core/OutputStructNode.js +51 -10
  239. package/src/nodes/core/ParameterNode.js +28 -0
  240. package/src/nodes/core/PropertyNode.js +232 -0
  241. package/src/nodes/core/StackNode.js +98 -1
  242. package/src/nodes/core/StructNode.js +121 -0
  243. package/src/nodes/core/StructType.js +13 -0
  244. package/src/nodes/core/StructTypeNode.js +105 -6
  245. package/src/nodes/core/TempNode.js +31 -5
  246. package/src/nodes/core/UniformGroupNode.js +82 -7
  247. package/src/nodes/core/UniformNode.js +66 -0
  248. package/src/nodes/core/VarNode.js +146 -7
  249. package/src/nodes/core/VaryingNode.js +100 -3
  250. package/src/nodes/core/constants.js +36 -0
  251. package/src/nodes/display/BlendModes.js +88 -1
  252. package/src/nodes/display/BumpMapNode.js +37 -0
  253. package/src/nodes/display/ColorAdjustment.js +53 -11
  254. package/src/nodes/display/ColorSpaceFunctions.js +16 -0
  255. package/src/nodes/display/ColorSpaceNode.js +82 -0
  256. package/src/nodes/display/FrontFacingNode.js +29 -0
  257. package/src/nodes/display/NormalMapNode.js +43 -0
  258. package/src/nodes/display/PassNode.js +300 -7
  259. package/src/nodes/display/PosterizeNode.js +33 -0
  260. package/src/nodes/display/RenderOutputNode.js +66 -1
  261. package/src/nodes/display/ScreenNode.js +96 -0
  262. package/src/nodes/display/ToneMappingFunctions.js +58 -10
  263. package/src/nodes/display/ToneMappingNode.js +55 -2
  264. package/src/nodes/display/ToonOutlinePassNode.js +73 -0
  265. package/src/nodes/display/ViewportDepthNode.js +122 -8
  266. package/src/nodes/display/ViewportDepthTextureNode.js +23 -0
  267. package/src/nodes/display/ViewportSharedTextureNode.js +23 -0
  268. package/src/nodes/display/ViewportTextureNode.js +57 -0
  269. package/src/nodes/fog/Fog.js +110 -0
  270. package/src/nodes/functions/BasicLightingModel.js +24 -0
  271. package/src/nodes/functions/PhongLightingModel.js +34 -2
  272. package/src/nodes/functions/PhysicalLightingModel.js +167 -8
  273. package/src/nodes/functions/ShadowMaskModel.js +23 -0
  274. package/src/nodes/functions/ToonLightingModel.js +20 -0
  275. package/src/nodes/functions/material/getAlphaHashThreshold.js +1 -3
  276. package/src/nodes/functions/material/getParallaxCorrectNormal.js +16 -1
  277. package/src/nodes/geometry/RangeNode.js +54 -2
  278. package/src/nodes/gpgpu/AtomicFunctionNode.js +174 -2
  279. package/src/nodes/gpgpu/BarrierNode.js +47 -0
  280. package/src/nodes/gpgpu/ComputeBuiltinNode.js +134 -0
  281. package/src/nodes/gpgpu/ComputeNode.js +106 -2
  282. package/src/nodes/gpgpu/WorkgroupInfoNode.js +115 -6
  283. package/src/nodes/lighting/AONode.js +18 -0
  284. package/src/nodes/lighting/AmbientLightNode.js +10 -0
  285. package/src/nodes/lighting/AnalyticLightNode.js +97 -2
  286. package/src/nodes/lighting/BasicEnvironmentNode.js +19 -0
  287. package/src/nodes/lighting/BasicLightMapNode.js +17 -0
  288. package/src/nodes/lighting/DirectionalLightNode.js +10 -0
  289. package/src/nodes/lighting/EnvironmentNode.js +18 -0
  290. package/src/nodes/lighting/HemisphereLightNode.js +31 -0
  291. package/src/nodes/lighting/IESSpotLightNode.js +11 -0
  292. package/src/nodes/lighting/IrradianceNode.js +17 -0
  293. package/src/nodes/lighting/LightProbeNode.js +20 -0
  294. package/src/nodes/lighting/LightUtils.js +12 -0
  295. package/src/nodes/lighting/LightingContextNode.js +48 -0
  296. package/src/nodes/lighting/LightingNode.js +15 -6
  297. package/src/nodes/lighting/LightsNode.js +132 -1
  298. package/src/nodes/lighting/PointLightNode.js +32 -1
  299. package/src/nodes/lighting/PointShadowNode.js +54 -1
  300. package/src/nodes/lighting/RectAreaLightNode.js +44 -6
  301. package/src/nodes/lighting/ShadowBaseNode.js +93 -0
  302. package/src/nodes/lighting/ShadowNode.js +241 -35
  303. package/src/nodes/lighting/SpotLightNode.js +43 -0
  304. package/src/nodes/math/ConditionalNode.js +78 -4
  305. package/src/nodes/math/Hash.js +9 -0
  306. package/src/nodes/math/MathNode.js +627 -11
  307. package/src/nodes/math/MathUtils.js +45 -1
  308. package/src/nodes/math/OperatorNode.js +329 -18
  309. package/src/nodes/math/TriNoise3D.js +18 -7
  310. package/src/nodes/parsers/GLSLNodeFunction.js +16 -0
  311. package/src/nodes/parsers/GLSLNodeParser.js +11 -0
  312. package/src/nodes/pmrem/PMREMNode.js +133 -0
  313. package/src/nodes/pmrem/PMREMUtils.js +2 -2
  314. package/src/nodes/procedural/Checker.js +9 -0
  315. package/src/nodes/shapes/Shapes.js +33 -0
  316. package/src/nodes/tsl/TSLBase.js +3 -2
  317. package/src/nodes/tsl/TSLCore.js +22 -2
  318. package/src/nodes/utils/ArrayElementNode.js +39 -3
  319. package/src/nodes/utils/ConvertNode.js +31 -0
  320. package/src/nodes/utils/CubeMapNode.js +78 -0
  321. package/src/nodes/utils/Discard.js +16 -0
  322. package/src/nodes/utils/EquirectUVNode.js +31 -1
  323. package/src/nodes/utils/FlipNode.js +38 -0
  324. package/src/nodes/utils/FunctionOverloadingNode.js +53 -1
  325. package/src/nodes/utils/JoinNode.js +25 -0
  326. package/src/nodes/utils/LoopNode.js +82 -2
  327. package/src/nodes/utils/MatcapUVNode.js +17 -0
  328. package/src/nodes/utils/MaxMipLevelNode.js +49 -0
  329. package/src/nodes/utils/MemberNode.js +68 -0
  330. package/src/nodes/utils/Oscillators.js +33 -0
  331. package/src/nodes/utils/Packing.js +17 -0
  332. package/src/nodes/utils/PostProcessingUtils.js +28 -23
  333. package/src/nodes/utils/RTTNode.js +123 -2
  334. package/src/nodes/utils/ReflectorNode.js +174 -4
  335. package/src/nodes/utils/RemapNode.js +79 -0
  336. package/src/nodes/utils/RotateNode.js +41 -0
  337. package/src/nodes/utils/SetNode.js +44 -1
  338. package/src/nodes/utils/SplitNode.js +55 -3
  339. package/src/nodes/utils/SpriteSheetUVNode.js +46 -0
  340. package/src/nodes/utils/SpriteUtils.js +17 -0
  341. package/src/nodes/utils/StorageArrayElementNode.js +54 -0
  342. package/src/nodes/utils/Timer.js +40 -0
  343. package/src/nodes/utils/TriplanarTexturesNode.js +84 -0
  344. package/src/nodes/utils/UVUtils.js +20 -0
  345. package/src/nodes/utils/ViewportUtils.js +13 -0
  346. package/src/objects/BatchedMesh.js +2 -3
  347. package/src/objects/ClippingGroup.js +49 -0
  348. package/src/objects/Line.js +6 -6
  349. package/src/renderers/WebGLRenderer.js +30 -4
  350. package/src/renderers/common/Animation.js +85 -0
  351. package/src/renderers/common/Attributes.js +36 -0
  352. package/src/renderers/common/Backend.js +502 -44
  353. package/src/renderers/common/Background.js +48 -1
  354. package/src/renderers/common/BindGroup.js +43 -0
  355. package/src/renderers/common/Binding.js +35 -0
  356. package/src/renderers/common/Bindings.js +93 -1
  357. package/src/renderers/common/Buffer.js +49 -0
  358. package/src/renderers/common/BufferUtils.js +27 -0
  359. package/src/renderers/common/BundleGroup.js +57 -0
  360. package/src/renderers/common/ChainMap.js +45 -6
  361. package/src/renderers/common/ClippingContext.js +108 -15
  362. package/src/renderers/common/Color4.js +40 -0
  363. package/src/renderers/common/ComputePipeline.js +24 -0
  364. package/src/renderers/common/CubeRenderTarget.js +13 -0
  365. package/src/renderers/common/DataMap.js +37 -1
  366. package/src/renderers/common/Geometries.js +91 -14
  367. package/src/renderers/common/IndirectStorageBufferAttribute.js +25 -2
  368. package/src/renderers/common/Info.js +78 -35
  369. package/src/renderers/common/Lighting.js +34 -6
  370. package/src/renderers/common/Pipeline.js +22 -0
  371. package/src/renderers/common/Pipelines.js +148 -5
  372. package/src/renderers/common/PostProcessing.js +99 -11
  373. package/src/renderers/common/ProgrammableStage.js +60 -2
  374. package/src/renderers/common/QuadMesh.js +54 -5
  375. package/src/renderers/common/RenderBundle.js +14 -8
  376. package/src/renderers/common/RenderBundles.js +39 -10
  377. package/src/renderers/common/RenderContext.js +201 -2
  378. package/src/renderers/common/RenderContexts.js +59 -6
  379. package/src/renderers/common/RenderList.js +178 -0
  380. package/src/renderers/common/RenderLists.js +40 -3
  381. package/src/renderers/common/RenderObject.js +400 -17
  382. package/src/renderers/common/RenderObjects.js +103 -7
  383. package/src/renderers/common/RenderPipeline.js +24 -0
  384. package/src/renderers/common/Renderer.js +1170 -86
  385. package/src/renderers/common/RendererUtils.js +193 -0
  386. package/src/renderers/common/SampledTexture.js +120 -0
  387. package/src/renderers/common/Sampler.js +30 -0
  388. package/src/renderers/common/StorageBuffer.js +24 -0
  389. package/src/renderers/common/StorageBufferAttribute.js +31 -2
  390. package/src/renderers/common/StorageInstancedBufferAttribute.js +31 -2
  391. package/src/renderers/common/StorageTexture.js +38 -0
  392. package/src/renderers/common/Textures.js +97 -7
  393. package/src/renderers/common/TimestampQueryPool.js +39 -0
  394. package/src/renderers/common/Uniform.js +225 -3
  395. package/src/renderers/common/UniformBuffer.js +19 -0
  396. package/src/renderers/common/UniformsGroup.js +141 -2
  397. package/src/renderers/common/XRManager.js +1193 -0
  398. package/src/renderers/common/XRRenderTarget.js +74 -0
  399. package/src/renderers/common/extras/PMREMGenerator.js +76 -10
  400. package/src/renderers/common/nodes/NodeBuilderState.js +99 -5
  401. package/src/renderers/common/nodes/NodeLibrary.js +89 -0
  402. package/src/renderers/common/nodes/NodeSampledTexture.js +90 -2
  403. package/src/renderers/common/nodes/NodeSampler.js +28 -0
  404. package/src/renderers/common/nodes/NodeStorageBuffer.js +35 -0
  405. package/src/renderers/common/nodes/NodeUniform.js +243 -2
  406. package/src/renderers/common/nodes/NodeUniformBuffer.js +29 -0
  407. package/src/renderers/common/nodes/NodeUniformsGroup.js +31 -18
  408. package/src/renderers/common/nodes/Nodes.js +352 -78
  409. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +2 -2
  410. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +7 -7
  411. package/src/renderers/webgl/WebGLBackground.js +4 -0
  412. package/src/renderers/webgl-fallback/WebGLBackend.js +819 -116
  413. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +347 -18
  414. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +58 -1
  415. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +28 -0
  416. package/src/renderers/webgl-fallback/utils/WebGLExtensions.js +45 -0
  417. package/src/renderers/webgl-fallback/utils/WebGLState.js +323 -11
  418. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +168 -22
  419. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +359 -0
  420. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +43 -0
  421. package/src/renderers/webgpu/WebGPUBackend.js +578 -164
  422. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +36 -0
  423. package/src/renderers/webgpu/WebGPURenderer.js +36 -0
  424. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +20 -8
  425. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +21 -8
  426. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +674 -52
  427. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +17 -0
  428. package/src/renderers/webgpu/nodes/WGSLNodeParser.js +11 -0
  429. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +95 -14
  430. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +94 -1
  431. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +102 -3
  432. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +98 -1
  433. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +262 -18
  434. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +274 -0
  435. package/src/renderers/webgpu/utils/WebGPUUtils.js +116 -4
  436. package/src/renderers/webxr/WebXRDepthSensing.js +1 -1
  437. package/src/renderers/webxr/WebXRManager.js +19 -2
  438. package/src/textures/Data3DTexture.js +2 -2
  439. package/src/textures/Texture.js +4 -0
  440. package/src/textures/VideoFrameTexture.js +35 -0
  441. package/examples/jsm/animation/MMDAnimationHelper.js +0 -1209
  442. package/examples/jsm/animation/MMDPhysics.js +0 -1408
  443. package/examples/jsm/exporters/MMDExporter.js +0 -223
  444. package/examples/jsm/geometries/InstancedPointsGeometry.js +0 -176
  445. package/examples/jsm/libs/mmdparser.module.js +0 -11530
  446. package/examples/jsm/loaders/MMDLoader.js +0 -2298
  447. package/examples/jsm/objects/InstancedPoints.js +0 -19
  448. package/examples/jsm/shaders/MMDToonShader.js +0 -134
  449. package/src/materials/nodes/InstancedPointsNodeMaterial.js +0 -156
  450. package/src/nodes/accessors/InstancedPointsMaterialNode.js +0 -24
  451. package/src/nodes/core/UniformGroup.js +0 -13
  452. package/src/nodes/fog/FogExp2Node.js +0 -35
  453. package/src/nodes/fog/FogNode.js +0 -50
  454. package/src/nodes/fog/FogRangeNode.js +0 -36
  455. package/src/renderers/common/PostProcessingUtils.js +0 -86
@@ -157,30 +157,83 @@ if ( ( typeof navigator !== 'undefined' && /Firefox|Deno/g.test( navigator.userA
157
157
 
158
158
  }
159
159
 
160
- //
161
-
160
+ /**
161
+ * A node builder targeting WGSL.
162
+ *
163
+ * This module generates WGSL shader code from node materials and also
164
+ * generates the respective bindings and vertex buffer definitions. These
165
+ * data are later used by the renderer to create render and compute pipelines
166
+ * for render objects.
167
+ *
168
+ * @augments NodeBuilder
169
+ */
162
170
  class WGSLNodeBuilder extends NodeBuilder {
163
171
 
172
+ /**
173
+ * Constructs a new WGSL node builder renderer.
174
+ *
175
+ * @param {Object3D} object - The 3D object.
176
+ * @param {Renderer} renderer - The renderer.
177
+ */
164
178
  constructor( object, renderer ) {
165
179
 
166
180
  super( object, renderer, new WGSLNodeParser() );
167
181
 
182
+ /**
183
+ * A dictionary that holds for each shader stage ('vertex', 'fragment', 'compute')
184
+ * another dictionary which manages UBOs per group ('render','frame','object').
185
+ *
186
+ * @type {Object<String,Object<String,NodeUniformsGroup>>}
187
+ */
168
188
  this.uniformGroups = {};
169
189
 
190
+ /**
191
+ * A dictionary that holds for each shader stage a Map of builtins.
192
+ *
193
+ * @type {Object<String,Map<String,Object>>}
194
+ */
170
195
  this.builtins = {};
171
196
 
197
+ /**
198
+ * A dictionary that holds for each shader stage a Set of directives.
199
+ *
200
+ * @type {Object<String,Set<String>>}
201
+ */
172
202
  this.directives = {};
173
203
 
204
+ /**
205
+ * A map for managing scope arrays. Only relevant for when using
206
+ * {@link module:WorkgroupInfoNode} in context of compute shaders.
207
+ *
208
+ * @type {Map<String,Object>}
209
+ */
174
210
  this.scopedArrays = new Map();
175
211
 
176
212
  }
177
213
 
214
+ /**
215
+ * Checks if the given texture requires a manual conversion to the working color space.
216
+ *
217
+ * @param {Texture} texture - The texture to check.
218
+ * @return {Boolean} Whether the given texture requires a conversion to working color space or not.
219
+ */
178
220
  needsToWorkingColorSpace( texture ) {
179
221
 
180
222
  return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace;
181
223
 
182
224
  }
183
225
 
226
+ /**
227
+ * Generates the WGSL snippet for sampled textures.
228
+ *
229
+ * @private
230
+ * @param {Texture} texture - The texture.
231
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
232
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
233
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
234
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
235
+ * @return {String} The WGSL snippet.
236
+ */
184
237
  _generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
185
238
 
186
239
  if ( shaderStage === 'fragment' ) {
@@ -207,6 +260,15 @@ class WGSLNodeBuilder extends NodeBuilder {
207
260
 
208
261
  }
209
262
 
263
+ /**
264
+ * Generates the WGSL snippet when sampling video textures.
265
+ *
266
+ * @private
267
+ * @param {String} textureProperty - The name of the video texture uniform in the shader.
268
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
269
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
270
+ * @return {String} The WGSL snippet.
271
+ */
210
272
  _generateVideoSample( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
211
273
 
212
274
  if ( shaderStage === 'fragment' ) {
@@ -221,9 +283,21 @@ class WGSLNodeBuilder extends NodeBuilder {
221
283
 
222
284
  }
223
285
 
286
+ /**
287
+ * Generates the WGSL snippet when sampling textures with explicit mip level.
288
+ *
289
+ * @private
290
+ * @param {Texture} texture - The texture.
291
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
292
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
293
+ * @param {String} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
294
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
295
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
296
+ * @return {String} The WGSL snippet.
297
+ */
224
298
  _generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage ) {
225
299
 
226
- if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false ) {
300
+ if ( ( shaderStage === 'fragment' || shaderStage === 'compute' ) && this.isUnfilterable( texture ) === false ) {
227
301
 
228
302
  return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
229
303
 
@@ -239,9 +313,15 @@ class WGSLNodeBuilder extends NodeBuilder {
239
313
 
240
314
  }
241
315
 
316
+ /**
317
+ * Generates a wrap function used in context of textures.
318
+ *
319
+ * @param {Texture} texture - The texture to generate the function for.
320
+ * @return {String} The name of the generated function.
321
+ */
242
322
  generateWrapFunction( texture ) {
243
323
 
244
- const functionName = `tsl_coord_${ wrapNames[ texture.wrapS ] }S_${ wrapNames[ texture.wrapT ] }T`;
324
+ const functionName = `tsl_coord_${ wrapNames[ texture.wrapS ] }S_${ wrapNames[ texture.wrapT ] }_${texture.isData3DTexture ? '3d' : '2d'}T`;
245
325
 
246
326
  let nodeCode = wgslCodeCache[ functionName ];
247
327
 
@@ -249,7 +329,9 @@ class WGSLNodeBuilder extends NodeBuilder {
249
329
 
250
330
  const includes = [];
251
331
 
252
- let code = `fn ${ functionName }( coord : vec2f ) -> vec2f {\n\n\treturn vec2f(\n`;
332
+ // For 3D textures, use vec3f; for texture arrays, keep vec2f since array index is separate
333
+ const coordType = texture.isData3DTexture ? 'vec3f' : 'vec2f';
334
+ let code = `fn ${functionName}( coord : ${coordType} ) -> ${coordType} {\n\n\treturn ${coordType}(\n`;
253
335
 
254
336
  const addWrapSnippet = ( wrap, axis ) => {
255
337
 
@@ -287,6 +369,13 @@ class WGSLNodeBuilder extends NodeBuilder {
287
369
 
288
370
  addWrapSnippet( texture.wrapT, 'y' );
289
371
 
372
+ if ( texture.isData3DTexture ) {
373
+
374
+ code += ',\n';
375
+ addWrapSnippet( texture.wrapR, 'z' );
376
+
377
+ }
378
+
290
379
  code += '\n\t);\n\n}\n';
291
380
 
292
381
  wgslCodeCache[ functionName ] = nodeCode = new CodeNode( code, includes );
@@ -299,6 +388,29 @@ class WGSLNodeBuilder extends NodeBuilder {
299
388
 
300
389
  }
301
390
 
391
+ /**
392
+ * Generates the array declaration string.
393
+ *
394
+ * @param {String} type - The type.
395
+ * @param {Number?} [count] - The count.
396
+ * @return {String} The generated value as a shader string.
397
+ */
398
+ generateArrayDeclaration( type, count ) {
399
+
400
+ return `array< ${ this.getType( type ) }, ${ count } >`;
401
+
402
+ }
403
+
404
+ /**
405
+ * Generates a WGSL variable that holds the texture dimension of the given texture.
406
+ * It also returns information about the the number of layers (elements) of an arrayed
407
+ * texture as well as the cube face count of cube textures.
408
+ *
409
+ * @param {Texture} texture - The texture to generate the function for.
410
+ * @param {String} textureProperty - The name of the video texture uniform in the shader.
411
+ * @param {String} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
412
+ * @return {String} The name of the dimension variable.
413
+ */
302
414
  generateTextureDimension( texture, textureProperty, levelSnippet ) {
303
415
 
304
416
  const textureData = this.getDataFromNode( texture, this.shaderStage, this.globalCache );
@@ -310,27 +422,72 @@ class WGSLNodeBuilder extends NodeBuilder {
310
422
  if ( textureData.dimensionsSnippet[ levelSnippet ] === undefined ) {
311
423
 
312
424
  let textureDimensionsParams;
425
+ let dimensionType;
313
426
 
314
- if ( texture.isMultisampleRenderTargetTexture === true ) {
427
+ const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
428
+ const isMultisampled = primarySamples > 1;
429
+
430
+ if ( texture.isData3DTexture ) {
431
+
432
+ dimensionType = 'vec3<u32>';
433
+
434
+ } else {
435
+
436
+ // Regular 2D textures, depth textures, etc.
437
+ dimensionType = 'vec2<u32>';
438
+
439
+ }
440
+
441
+ // Build parameters string based on texture type and multisampling
442
+ if ( isMultisampled || texture.isVideoTexture || texture.isStorageTexture ) {
315
443
 
316
444
  textureDimensionsParams = textureProperty;
317
445
 
318
446
  } else {
319
447
 
320
- textureDimensionsParams = `${ textureProperty }, u32( ${ levelSnippet } )`;
448
+ textureDimensionsParams = `${textureProperty}${levelSnippet ? `, u32( ${ levelSnippet } )` : ''}`;
321
449
 
322
450
  }
323
451
 
324
- textureDimensionNode = new VarNode( new ExpressionNode( `textureDimensions( ${ textureDimensionsParams } )`, 'uvec2' ) );
452
+ textureDimensionNode = new VarNode( new ExpressionNode( `textureDimensions( ${ textureDimensionsParams } )`, dimensionType ) );
325
453
 
326
454
  textureData.dimensionsSnippet[ levelSnippet ] = textureDimensionNode;
327
455
 
456
+ if ( texture.isDataArrayTexture || texture.isData3DTexture ) {
457
+
458
+ textureData.arrayLayerCount = new VarNode(
459
+ new ExpressionNode(
460
+ `textureNumLayers(${textureProperty})`,
461
+ 'u32'
462
+ )
463
+ );
464
+
465
+ }
466
+
467
+ // For cube textures, we know it's always 6 faces
468
+ if ( texture.isTextureCube ) {
469
+
470
+ textureData.cubeFaceCount = new VarNode(
471
+ new ExpressionNode( '6u', 'u32' )
472
+ );
473
+
474
+ }
475
+
328
476
  }
329
477
 
330
478
  return textureDimensionNode.build( this );
331
479
 
332
480
  }
333
481
 
482
+ /**
483
+ * Generates the WGSL snippet for a manual filtered texture.
484
+ *
485
+ * @param {Texture} texture - The texture.
486
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
487
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
488
+ * @param {String} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
489
+ * @return {String} The WGSL snippet.
490
+ */
334
491
  generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet = '0u' ) {
335
492
 
336
493
  this._include( 'biquadraticTexture' );
@@ -342,17 +499,39 @@ class WGSLNodeBuilder extends NodeBuilder {
342
499
 
343
500
  }
344
501
 
502
+ /**
503
+ * Generates the WGSL snippet for a texture lookup with explicit level-of-detail.
504
+ * Since it's a lookup, no sampling or filtering is applied.
505
+ *
506
+ * @param {Texture} texture - The texture.
507
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
508
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
509
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
510
+ * @param {String} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
511
+ * @return {String} The WGSL snippet.
512
+ */
345
513
  generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet = '0u' ) {
346
514
 
347
515
  const wrapFunction = this.generateWrapFunction( texture );
348
516
  const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
349
517
 
350
- const coordSnippet = `vec2u( ${ wrapFunction }( ${ uvSnippet } ) * vec2f( ${ textureDimension } ) )`;
518
+ const vecType = texture.isData3DTexture ? 'vec3' : 'vec2';
519
+ const coordSnippet = `${vecType}<u32>(${wrapFunction}(${uvSnippet}) * ${vecType}<f32>(${textureDimension}))`;
351
520
 
352
521
  return this.generateTextureLoad( texture, textureProperty, coordSnippet, depthSnippet, levelSnippet );
353
522
 
354
523
  }
355
524
 
525
+ /**
526
+ * Generates the WGSL snippet that reads a single texel from a texture without sampling or filtering.
527
+ *
528
+ * @param {Texture} texture - The texture.
529
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
530
+ * @param {String} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
531
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
532
+ * @param {String} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
533
+ * @return {String} The WGSL snippet.
534
+ */
356
535
  generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u' ) {
357
536
 
358
537
  if ( texture.isVideoTexture === true || texture.isStorageTexture === true ) {
@@ -371,27 +550,58 @@ class WGSLNodeBuilder extends NodeBuilder {
371
550
 
372
551
  }
373
552
 
553
+ /**
554
+ * Generates the WGSL snippet that writes a single texel to a texture.
555
+ *
556
+ * @param {Texture} texture - The texture.
557
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
558
+ * @param {String} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
559
+ * @param {String} valueSnippet - A WGSL snippet that represent the new texel value.
560
+ * @return {String} The WGSL snippet.
561
+ */
374
562
  generateTextureStore( texture, textureProperty, uvIndexSnippet, valueSnippet ) {
375
563
 
376
564
  return `textureStore( ${ textureProperty }, ${ uvIndexSnippet }, ${ valueSnippet } )`;
377
565
 
378
566
  }
379
567
 
568
+ /**
569
+ * Returns `true` if the sampled values of the given texture should be compared against a reference value.
570
+ *
571
+ * @param {Texture} texture - The texture.
572
+ * @return {Boolean} Whether the sampled values of the given texture should be compared against a reference value or not.
573
+ */
380
574
  isSampleCompare( texture ) {
381
575
 
382
576
  return texture.isDepthTexture === true && texture.compareFunction !== null;
383
577
 
384
578
  }
385
579
 
580
+ /**
581
+ * Returns `true` if the given texture is unfilterable.
582
+ *
583
+ * @param {Texture} texture - The texture.
584
+ * @return {Boolean} Whether the given texture is unfilterable or not.
585
+ */
386
586
  isUnfilterable( texture ) {
387
587
 
388
588
  return this.getComponentTypeFromTexture( texture ) !== 'float' ||
389
589
  ( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) ||
390
590
  ( this.isSampleCompare( texture ) === false && texture.minFilter === NearestFilter && texture.magFilter === NearestFilter ) ||
391
- texture.isMultisampleRenderTargetTexture === true;
591
+ this.renderer.backend.utils.getTextureSampleData( texture ).primarySamples > 1;
392
592
 
393
593
  }
394
594
 
595
+ /**
596
+ * Generates the WGSL snippet for sampling/loading the given texture.
597
+ *
598
+ * @param {Texture} texture - The texture.
599
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
600
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
601
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
602
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
603
+ * @return {String} The WGSL snippet.
604
+ */
395
605
  generateTexture( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
396
606
 
397
607
  let snippet = null;
@@ -414,6 +624,17 @@ class WGSLNodeBuilder extends NodeBuilder {
414
624
 
415
625
  }
416
626
 
627
+ /**
628
+ * Generates the WGSL snippet for sampling/loading the given texture using explicit gradients.
629
+ *
630
+ * @param {Texture} texture - The texture.
631
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
632
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
633
+ * @param {Array<String>} gradSnippet - An array holding both gradient WGSL snippets.
634
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
635
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
636
+ * @return {String} The WGSL snippet.
637
+ */
417
638
  generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, shaderStage = this.shaderStage ) {
418
639
 
419
640
  if ( shaderStage === 'fragment' ) {
@@ -429,6 +650,18 @@ class WGSLNodeBuilder extends NodeBuilder {
429
650
 
430
651
  }
431
652
 
653
+ /**
654
+ * Generates the WGSL snippet for sampling a depth texture and comparing the sampled depth values
655
+ * against a reference value.
656
+ *
657
+ * @param {Texture} texture - The texture.
658
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
659
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
660
+ * @param {String} compareSnippet - A WGSL snippet that represents the reference value.
661
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
662
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
663
+ * @return {String} The WGSL snippet.
664
+ */
432
665
  generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage ) {
433
666
 
434
667
  if ( shaderStage === 'fragment' ) {
@@ -443,6 +676,17 @@ class WGSLNodeBuilder extends NodeBuilder {
443
676
 
444
677
  }
445
678
 
679
+ /**
680
+ * Generates the WGSL snippet when sampling textures with explicit mip level.
681
+ *
682
+ * @param {Texture} texture - The texture.
683
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
684
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
685
+ * @param {String} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
686
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
687
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
688
+ * @return {String} The WGSL snippet.
689
+ */
446
690
  generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage ) {
447
691
 
448
692
  let snippet = null;
@@ -461,6 +705,17 @@ class WGSLNodeBuilder extends NodeBuilder {
461
705
 
462
706
  }
463
707
 
708
+ /**
709
+ * Generates the WGSL snippet when sampling textures with a bias to the mip level.
710
+ *
711
+ * @param {Texture} texture - The texture.
712
+ * @param {String} textureProperty - The name of the texture uniform in the shader.
713
+ * @param {String} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
714
+ * @param {String} biasSnippet - A WGSL snippet that represents the bias to apply to the mip level before sampling.
715
+ * @param {String?} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
716
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
717
+ * @return {String} The WGSL snippet.
718
+ */
464
719
  generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, shaderStage = this.shaderStage ) {
465
720
 
466
721
  if ( shaderStage === 'fragment' ) {
@@ -475,6 +730,13 @@ class WGSLNodeBuilder extends NodeBuilder {
475
730
 
476
731
  }
477
732
 
733
+ /**
734
+ * Returns a WGSL snippet that represents the property name of the given node.
735
+ *
736
+ * @param {Node} node - The node.
737
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
738
+ * @return {String} The property name.
739
+ */
478
740
  getPropertyName( node, shaderStage = this.shaderStage ) {
479
741
 
480
742
  if ( node.isNodeVarying === true && node.needsInterpolation === true ) {
@@ -496,7 +758,13 @@ class WGSLNodeBuilder extends NodeBuilder {
496
758
 
497
759
  } else if ( type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer' ) {
498
760
 
499
- return `NodeBuffer_${ node.id }.${name}`;
761
+ if ( this.isCustomStruct( node ) ) {
762
+
763
+ return name;
764
+
765
+ }
766
+
767
+ return name + '.value';
500
768
 
501
769
  } else {
502
770
 
@@ -510,18 +778,36 @@ class WGSLNodeBuilder extends NodeBuilder {
510
778
 
511
779
  }
512
780
 
781
+ /**
782
+ * Returns the output struct name.
783
+ *
784
+ * @return {String} The name of the output struct.
785
+ */
513
786
  getOutputStructName() {
514
787
 
515
788
  return 'output';
516
789
 
517
790
  }
518
791
 
792
+ /**
793
+ * Returns uniforms group count for the given shader stage.
794
+ *
795
+ * @private
796
+ * @param {String} shaderStage - The shader stage.
797
+ * @return {Number} The uniforms group count for the given shader stage.
798
+ */
519
799
  _getUniformGroupCount( shaderStage ) {
520
800
 
521
801
  return Object.keys( this.uniforms[ shaderStage ] ).length;
522
802
 
523
803
  }
524
804
 
805
+ /**
806
+ * Returns the native shader operator name for a given generic name.
807
+ *
808
+ * @param {String} op - The operator name to resolve.
809
+ * @return {String} The resolved operator name.
810
+ */
525
811
  getFunctionOperator( op ) {
526
812
 
527
813
  const fnOp = wgslFnOpLib[ op ];
@@ -538,6 +824,13 @@ class WGSLNodeBuilder extends NodeBuilder {
538
824
 
539
825
  }
540
826
 
827
+ /**
828
+ * Returns the node access for the given node and shader stage.
829
+ *
830
+ * @param {StorageTextureNode|StorageBufferNode} node - The storage node.
831
+ * @param {String} shaderStage - The shader stage.
832
+ * @return {String} The node access.
833
+ */
541
834
  getNodeAccess( node, shaderStage ) {
542
835
 
543
836
  if ( shaderStage !== 'compute' )
@@ -547,12 +840,32 @@ class WGSLNodeBuilder extends NodeBuilder {
547
840
 
548
841
  }
549
842
 
843
+ /**
844
+ * Returns A WGSL snippet representing the storage access.
845
+ *
846
+ * @param {StorageTextureNode|StorageBufferNode} node - The storage node.
847
+ * @param {String} shaderStage - The shader stage.
848
+ * @return {String} The WGSL snippet representing the storage access.
849
+ */
550
850
  getStorageAccess( node, shaderStage ) {
551
851
 
552
852
  return accessNames[ this.getNodeAccess( node, shaderStage ) ];
553
853
 
554
854
  }
555
855
 
856
+ /**
857
+ * This method is one of the more important ones since it's responsible
858
+ * for generating a matching binding instance for the given uniform node.
859
+ *
860
+ * These bindings are later used in the renderer to create bind groups
861
+ * and layouts.
862
+ *
863
+ * @param {UniformNode} node - The uniform node.
864
+ * @param {String} type - The node data type.
865
+ * @param {String} shaderStage - The shader stage.
866
+ * @param {String?} [name=null] - An optional uniform name.
867
+ * @return {NodeUniform} The node uniform object.
868
+ */
556
869
  getUniformFromNode( node, type, shaderStage, name = null ) {
557
870
 
558
871
  const uniformNode = super.getUniformFromNode( node, type, shaderStage, name );
@@ -590,9 +903,9 @@ class WGSLNodeBuilder extends NodeBuilder {
590
903
  texture.store = node.isStorageTextureNode === true;
591
904
  texture.setVisibility( gpuShaderStageLib[ shaderStage ] );
592
905
 
593
- if ( shaderStage === 'fragment' && this.isUnfilterable( node.value ) === false && texture.store === false ) {
906
+ if ( ( shaderStage === 'fragment' || shaderStage === 'compute' ) && this.isUnfilterable( node.value ) === false && texture.store === false ) {
594
907
 
595
- const sampler = new NodeSampler( `${uniformNode.name}_sampler`, uniformNode.node, group );
908
+ const sampler = new NodeSampler( `${ uniformNode.name }_sampler`, uniformNode.node, group );
596
909
  sampler.setVisibility( gpuShaderStageLib[ shaderStage ] );
597
910
 
598
911
  bindings.push( sampler, texture );
@@ -618,6 +931,8 @@ class WGSLNodeBuilder extends NodeBuilder {
618
931
 
619
932
  uniformGPU = buffer;
620
933
 
934
+ uniformNode.name = name ? name : 'NodeBuffer_' + uniformNode.id;
935
+
621
936
  } else {
622
937
 
623
938
  const uniformsStage = this.uniformGroups[ shaderStage ] || ( this.uniformGroups[ shaderStage ] = {} );
@@ -649,6 +964,17 @@ class WGSLNodeBuilder extends NodeBuilder {
649
964
 
650
965
  }
651
966
 
967
+ /**
968
+ * This method should be used whenever builtins are required in nodes.
969
+ * The internal builtins data structure will make sure builtins are
970
+ * defined in the WGSL source.
971
+ *
972
+ * @param {String} name - The builtin name.
973
+ * @param {String} property - The property name.
974
+ * @param {String} type - The node data type.
975
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
976
+ * @return {String} The property name.
977
+ */
652
978
  getBuiltin( name, property, type, shaderStage = this.shaderStage ) {
653
979
 
654
980
  const map = this.builtins[ shaderStage ] || ( this.builtins[ shaderStage ] = new Map() );
@@ -667,12 +993,24 @@ class WGSLNodeBuilder extends NodeBuilder {
667
993
 
668
994
  }
669
995
 
996
+ /**
997
+ * Returns `true` if the given builtin is defined in the given shader stage.
998
+ *
999
+ * @param {String} name - The builtin name.
1000
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
1001
+ * @return {String} Whether the given builtin is defined in the given shader stage or not.
1002
+ */
670
1003
  hasBuiltin( name, shaderStage = this.shaderStage ) {
671
1004
 
672
1005
  return ( this.builtins[ shaderStage ] !== undefined && this.builtins[ shaderStage ].has( name ) );
673
1006
 
674
1007
  }
675
1008
 
1009
+ /**
1010
+ * Returns the vertex index builtin.
1011
+ *
1012
+ * @return {String} The vertex index.
1013
+ */
676
1014
  getVertexIndex() {
677
1015
 
678
1016
  if ( this.shaderStage === 'vertex' ) {
@@ -685,6 +1023,12 @@ class WGSLNodeBuilder extends NodeBuilder {
685
1023
 
686
1024
  }
687
1025
 
1026
+ /**
1027
+ * Builds the given shader node.
1028
+ *
1029
+ * @param {ShaderNodeInternal} shaderNode - The shader node.
1030
+ * @return {String} The WGSL function code.
1031
+ */
688
1032
  buildFunctionCode( shaderNode ) {
689
1033
 
690
1034
  const layout = shaderNode.layout;
@@ -719,6 +1063,11 @@ ${ flowData.code }
719
1063
 
720
1064
  }
721
1065
 
1066
+ /**
1067
+ * Returns the instance index builtin.
1068
+ *
1069
+ * @return {String} The instance index.
1070
+ */
722
1071
  getInstanceIndex() {
723
1072
 
724
1073
  if ( this.shaderStage === 'vertex' ) {
@@ -731,12 +1080,22 @@ ${ flowData.code }
731
1080
 
732
1081
  }
733
1082
 
1083
+ /**
1084
+ * Returns the invocation local index builtin.
1085
+ *
1086
+ * @return {String} The invocation local index.
1087
+ */
734
1088
  getInvocationLocalIndex() {
735
1089
 
736
1090
  return this.getBuiltin( 'local_invocation_index', 'invocationLocalIndex', 'u32', 'attribute' );
737
1091
 
738
1092
  }
739
1093
 
1094
+ /**
1095
+ * Returns the subgroup size builtin.
1096
+ *
1097
+ * @return {String} The subgroup size.
1098
+ */
740
1099
  getSubgroupSize() {
741
1100
 
742
1101
  this.enableSubGroups();
@@ -745,6 +1104,11 @@ ${ flowData.code }
745
1104
 
746
1105
  }
747
1106
 
1107
+ /**
1108
+ * Returns the invocation subgroup index builtin.
1109
+ *
1110
+ * @return {String} The invocation subgroup index.
1111
+ */
748
1112
  getInvocationSubgroupIndex() {
749
1113
 
750
1114
  this.enableSubGroups();
@@ -753,6 +1117,11 @@ ${ flowData.code }
753
1117
 
754
1118
  }
755
1119
 
1120
+ /**
1121
+ * Returns the subgroup index builtin.
1122
+ *
1123
+ * @return {String} The subgroup index.
1124
+ */
756
1125
  getSubgroupIndex() {
757
1126
 
758
1127
  this.enableSubGroups();
@@ -761,42 +1130,78 @@ ${ flowData.code }
761
1130
 
762
1131
  }
763
1132
 
1133
+ /**
1134
+ * Overwritten as a NOP since this method is intended for the WebGL 2 backend.
1135
+ *
1136
+ * @return {null} Null.
1137
+ */
764
1138
  getDrawIndex() {
765
1139
 
766
1140
  return null;
767
1141
 
768
1142
  }
769
1143
 
1144
+ /**
1145
+ * Returns the front facing builtin.
1146
+ *
1147
+ * @return {String} The front facing builtin.
1148
+ */
770
1149
  getFrontFacing() {
771
1150
 
772
1151
  return this.getBuiltin( 'front_facing', 'isFront', 'bool' );
773
1152
 
774
1153
  }
775
1154
 
1155
+ /**
1156
+ * Returns the frag coord builtin.
1157
+ *
1158
+ * @return {String} The frag coord builtin.
1159
+ */
776
1160
  getFragCoord() {
777
1161
 
778
1162
  return this.getBuiltin( 'position', 'fragCoord', 'vec4<f32>' ) + '.xy';
779
1163
 
780
1164
  }
781
1165
 
1166
+ /**
1167
+ * Returns the frag depth builtin.
1168
+ *
1169
+ * @return {String} The frag depth builtin.
1170
+ */
782
1171
  getFragDepth() {
783
1172
 
784
1173
  return 'output.' + this.getBuiltin( 'frag_depth', 'depth', 'f32', 'output' );
785
1174
 
786
1175
  }
787
1176
 
1177
+ /**
1178
+ * Returns the clip distances builtin.
1179
+ *
1180
+ * @return {String} The clip distances builtin.
1181
+ */
788
1182
  getClipDistance() {
789
1183
 
790
1184
  return 'varyings.hw_clip_distances';
791
1185
 
792
1186
  }
793
1187
 
1188
+ /**
1189
+ * Whether to flip texture data along its vertical axis or not.
1190
+ *
1191
+ * @return {Boolean} Returns always `false` in context of WGSL.
1192
+ */
794
1193
  isFlipY() {
795
1194
 
796
1195
  return false;
797
1196
 
798
1197
  }
799
1198
 
1199
+ /**
1200
+ * Enables the given directive for the given shader stage.
1201
+ *
1202
+ * @param {String} name - The directive name.
1203
+ * @param {String} [shaderStage=this.shaderStage] - The shader stage to enable the directive for.
1204
+ */
800
1205
  enableDirective( name, shaderStage = this.shaderStage ) {
801
1206
 
802
1207
  const stage = this.directives[ shaderStage ] || ( this.directives[ shaderStage ] = new Set() );
@@ -804,6 +1209,12 @@ ${ flowData.code }
804
1209
 
805
1210
  }
806
1211
 
1212
+ /**
1213
+ * Returns the directives of the given shader stage as a WGSL string.
1214
+ *
1215
+ * @param {String} shaderStage - The shader stage.
1216
+ * @return {String} A WGSL snippet that enables the directives of the given stage.
1217
+ */
807
1218
  getDirectives( shaderStage ) {
808
1219
 
809
1220
  const snippets = [];
@@ -823,36 +1234,56 @@ ${ flowData.code }
823
1234
 
824
1235
  }
825
1236
 
1237
+ /**
1238
+ * Enables the 'subgroups' directive.
1239
+ */
826
1240
  enableSubGroups() {
827
1241
 
828
1242
  this.enableDirective( 'subgroups' );
829
1243
 
830
1244
  }
831
1245
 
1246
+ /**
1247
+ * Enables the 'subgroups-f16' directive.
1248
+ */
832
1249
  enableSubgroupsF16() {
833
1250
 
834
1251
  this.enableDirective( 'subgroups-f16' );
835
1252
 
836
1253
  }
837
1254
 
1255
+ /**
1256
+ * Enables the 'clip_distances' directive.
1257
+ */
838
1258
  enableClipDistances() {
839
1259
 
840
1260
  this.enableDirective( 'clip_distances' );
841
1261
 
842
1262
  }
843
1263
 
1264
+ /**
1265
+ * Enables the 'f16' directive.
1266
+ */
844
1267
  enableShaderF16() {
845
1268
 
846
1269
  this.enableDirective( 'f16' );
847
1270
 
848
1271
  }
849
1272
 
1273
+ /**
1274
+ * Enables the 'dual_source_blending' directive.
1275
+ */
850
1276
  enableDualSourceBlending() {
851
1277
 
852
1278
  this.enableDirective( 'dual_source_blending' );
853
1279
 
854
1280
  }
855
1281
 
1282
+ /**
1283
+ * Enables hardware clipping.
1284
+ *
1285
+ * @param {String} planeCount - The clipping plane count.
1286
+ */
856
1287
  enableHardwareClipping( planeCount ) {
857
1288
 
858
1289
  this.enableClipDistances();
@@ -860,6 +1291,12 @@ ${ flowData.code }
860
1291
 
861
1292
  }
862
1293
 
1294
+ /**
1295
+ * Returns the builtins of the given shader stage as a WGSL string.
1296
+ *
1297
+ * @param {String} shaderStage - The shader stage.
1298
+ * @return {String} A WGSL snippet that represents the builtins of the given stage.
1299
+ */
863
1300
  getBuiltins( shaderStage ) {
864
1301
 
865
1302
  const snippets = [];
@@ -879,6 +1316,17 @@ ${ flowData.code }
879
1316
 
880
1317
  }
881
1318
 
1319
+ /**
1320
+ * This method should be used when a new scoped buffer is used in context of
1321
+ * compute shaders. It adds the array to the internal data structure which is
1322
+ * later used to generate the respective WGSL.
1323
+ *
1324
+ * @param {String} name - The array name.
1325
+ * @param {String} scope - The scope.
1326
+ * @param {String} bufferType - The buffer type.
1327
+ * @param {String} bufferCount - The buffer count.
1328
+ * @return {String} The array name.
1329
+ */
882
1330
  getScopedArray( name, scope, bufferType, bufferCount ) {
883
1331
 
884
1332
  if ( this.scopedArrays.has( name ) === false ) {
@@ -896,6 +1344,13 @@ ${ flowData.code }
896
1344
 
897
1345
  }
898
1346
 
1347
+ /**
1348
+ * Returns the scoped arrays of the given shader stage as a WGSL string.
1349
+ *
1350
+ * @param {String} shaderStage - The shader stage.
1351
+ * @return {String|undefined} The WGSL snippet that defines the scoped arrays.
1352
+ * Returns `undefined` when used in the vertex or fragment stage.
1353
+ */
899
1354
  getScopedArrays( shaderStage ) {
900
1355
 
901
1356
  if ( shaderStage !== 'compute' ) {
@@ -918,13 +1373,19 @@ ${ flowData.code }
918
1373
 
919
1374
  }
920
1375
 
1376
+ /**
1377
+ * Returns the shader attributes of the given shader stage as a WGSL string.
1378
+ *
1379
+ * @param {String} shaderStage - The shader stage.
1380
+ * @return {String} The WGSL snippet that defines the shader attributes.
1381
+ */
921
1382
  getAttributes( shaderStage ) {
922
1383
 
923
1384
  const snippets = [];
924
1385
 
925
1386
  if ( shaderStage === 'compute' ) {
926
1387
 
927
- this.getBuiltin( 'global_invocation_id', 'id', 'vec3<u32>', 'attribute' );
1388
+ this.getBuiltin( 'global_invocation_id', 'globalId', 'vec3<u32>', 'attribute' );
928
1389
  this.getBuiltin( 'workgroup_id', 'workgroupId', 'vec3<u32>', 'attribute' );
929
1390
  this.getBuiltin( 'local_invocation_id', 'localId', 'vec3<u32>', 'attribute' );
930
1391
  this.getBuiltin( 'num_workgroups', 'numWorkgroups', 'vec3<u32>', 'attribute' );
@@ -962,57 +1423,102 @@ ${ flowData.code }
962
1423
 
963
1424
  }
964
1425
 
1426
+ /**
1427
+ * Returns the members of the given struct type node as a WGSL string.
1428
+ *
1429
+ * @param {StructTypeNode} struct - The struct type node.
1430
+ * @return {String} The WGSL snippet that defines the struct members.
1431
+ */
965
1432
  getStructMembers( struct ) {
966
1433
 
967
1434
  const snippets = [];
968
- const members = struct.getMemberTypes();
969
1435
 
970
- for ( let i = 0; i < members.length; i ++ ) {
1436
+ for ( const member of struct.members ) {
971
1437
 
972
- const member = members[ i ];
973
- snippets.push( `\t@location( ${i} ) m${i} : ${ member }<f32>` );
1438
+ const prefix = struct.output ? '@location( ' + member.index + ' ) ' : '';
974
1439
 
975
- }
1440
+ let type = this.getType( member.type );
1441
+
1442
+ if ( member.atomic ) {
1443
+
1444
+ type = 'atomic< ' + type + ' >';
1445
+
1446
+ }
976
1447
 
977
- const builtins = this.getBuiltins( 'output' );
1448
+ snippets.push( `\t${ prefix + member.name } : ${ type }` );
978
1449
 
979
- if ( builtins ) snippets.push( '\t' + builtins );
1450
+ }
980
1451
 
981
1452
  return snippets.join( ',\n' );
982
1453
 
983
1454
  }
984
1455
 
1456
+ /**
1457
+ * Returns the structs of the given shader stage as a WGSL string.
1458
+ *
1459
+ * @param {String} shaderStage - The shader stage.
1460
+ * @return {String} The WGSL snippet that defines the structs.
1461
+ */
985
1462
  getStructs( shaderStage ) {
986
1463
 
987
- const snippets = [];
1464
+ let result = '';
1465
+
988
1466
  const structs = this.structs[ shaderStage ];
989
1467
 
990
- for ( let index = 0, length = structs.length; index < length; index ++ ) {
1468
+ if ( structs.length > 0 ) {
991
1469
 
992
- const struct = structs[ index ];
993
- const name = struct.name;
1470
+ const snippets = [];
994
1471
 
995
- let snippet = `\struct ${ name } {\n`;
996
- snippet += this.getStructMembers( struct );
997
- snippet += '\n}';
1472
+ for ( const struct of structs ) {
998
1473
 
1474
+ let snippet = `struct ${ struct.name } {\n`;
1475
+ snippet += this.getStructMembers( struct );
1476
+ snippet += '\n};';
999
1477
 
1000
- snippets.push( snippet );
1478
+ snippets.push( snippet );
1001
1479
 
1002
- snippets.push( `\nvar<private> output : ${ name };\n\n` );
1480
+ }
1481
+
1482
+ result = '\n' + snippets.join( '\n\n' ) + '\n';
1003
1483
 
1004
1484
  }
1005
1485
 
1006
- return snippets.join( '\n\n' );
1486
+ return result;
1007
1487
 
1008
1488
  }
1009
1489
 
1010
- getVar( type, name ) {
1490
+ /**
1491
+ * Returns a WGSL string representing a variable.
1492
+ *
1493
+ * @param {String} type - The variable's type.
1494
+ * @param {String} name - The variable's name.
1495
+ * @param {Number?} [count=null] - The array length.
1496
+ * @return {String} The WGSL snippet that defines a variable.
1497
+ */
1498
+ getVar( type, name, count = null ) {
1499
+
1500
+ let snippet = `var ${ name } : `;
1501
+
1502
+ if ( count !== null ) {
1503
+
1504
+ snippet += this.generateArrayDeclaration( type, count );
1505
+
1506
+ } else {
1507
+
1508
+ snippet += this.getType( type );
1509
+
1510
+ }
1011
1511
 
1012
- return `var ${ name } : ${ this.getType( type ) }`;
1512
+ return snippet;
1013
1513
 
1014
1514
  }
1015
1515
 
1516
+ /**
1517
+ * Returns the variables of the given shader stage as a WGSL string.
1518
+ *
1519
+ * @param {String} shaderStage - The shader stage.
1520
+ * @return {String} The WGSL snippet that defines the variables.
1521
+ */
1016
1522
  getVars( shaderStage ) {
1017
1523
 
1018
1524
  const snippets = [];
@@ -1022,7 +1528,7 @@ ${ flowData.code }
1022
1528
 
1023
1529
  for ( const variable of vars ) {
1024
1530
 
1025
- snippets.push( `\t${ this.getVar( variable.type, variable.name ) };` );
1531
+ snippets.push( `\t${ this.getVar( variable.type, variable.name, variable.count ) };` );
1026
1532
 
1027
1533
  }
1028
1534
 
@@ -1032,6 +1538,12 @@ ${ flowData.code }
1032
1538
 
1033
1539
  }
1034
1540
 
1541
+ /**
1542
+ * Returns the varyings of the given shader stage as a WGSL string.
1543
+ *
1544
+ * @param {String} shaderStage - The shader stage.
1545
+ * @return {String} The WGSL snippet that defines the varyings.
1546
+ */
1035
1547
  getVaryings( shaderStage ) {
1036
1548
 
1037
1549
  const snippets = [];
@@ -1084,6 +1596,18 @@ ${ flowData.code }
1084
1596
 
1085
1597
  }
1086
1598
 
1599
+ isCustomStruct( nodeUniform ) {
1600
+
1601
+ return nodeUniform.value.isStorageBufferAttribute && nodeUniform.node.structTypeNode !== null;
1602
+
1603
+ }
1604
+
1605
+ /**
1606
+ * Returns the uniforms of the given shader stage as a WGSL string.
1607
+ *
1608
+ * @param {String} shaderStage - The shader stage.
1609
+ * @return {String} The WGSL snippet that defines the uniforms.
1610
+ */
1087
1611
  getUniforms( shaderStage ) {
1088
1612
 
1089
1613
  const uniforms = this.uniforms[ shaderStage ];
@@ -1102,7 +1626,7 @@ ${ flowData.code }
1102
1626
 
1103
1627
  const texture = uniform.node.value;
1104
1628
 
1105
- if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false && uniform.node.isStorageTextureNode !== true ) {
1629
+ if ( ( shaderStage === 'fragment' || shaderStage === 'compute' ) && this.isUnfilterable( texture ) === false && uniform.node.isStorageTextureNode !== true ) {
1106
1630
 
1107
1631
  if ( this.isSampleCompare( texture ) ) {
1108
1632
 
@@ -1120,7 +1644,9 @@ ${ flowData.code }
1120
1644
 
1121
1645
  let multisampled = '';
1122
1646
 
1123
- if ( texture.isMultisampleRenderTargetTexture === true ) {
1647
+ const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
1648
+
1649
+ if ( primarySamples > 1 ) {
1124
1650
 
1125
1651
  multisampled = '_multisampled';
1126
1652
 
@@ -1157,7 +1683,7 @@ ${ flowData.code }
1157
1683
 
1158
1684
  const componentPrefix = this.getComponentTypeFromTexture( texture ).charAt( 0 );
1159
1685
 
1160
- textureType = `texture${multisampled}_2d<${ componentPrefix }32>`;
1686
+ textureType = `texture${ multisampled }_2d<${ componentPrefix }32>`;
1161
1687
 
1162
1688
  }
1163
1689
 
@@ -1166,15 +1692,23 @@ ${ flowData.code }
1166
1692
  } else if ( uniform.type === 'buffer' || uniform.type === 'storageBuffer' || uniform.type === 'indirectStorageBuffer' ) {
1167
1693
 
1168
1694
  const bufferNode = uniform.node;
1169
- const bufferType = this.getType( bufferNode.bufferType );
1695
+ const bufferType = this.getType( bufferNode.getNodeType( this ) );
1170
1696
  const bufferCount = bufferNode.bufferCount;
1171
-
1172
1697
  const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : '';
1173
- const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`;
1174
- const bufferSnippet = `\t${ uniform.name } : array< ${ bufferTypeSnippet }${ bufferCountSnippet } >\n`;
1175
1698
  const bufferAccessMode = bufferNode.isStorageBufferNode ? `storage, ${ this.getStorageAccess( bufferNode, shaderStage ) }` : 'uniform';
1176
1699
 
1177
- bufferSnippets.push( this._getWGSLStructBinding( 'NodeBuffer_' + bufferNode.id, bufferSnippet, bufferAccessMode, uniformIndexes.binding ++, uniformIndexes.group ) );
1700
+ if ( this.isCustomStruct( uniform ) ) {
1701
+
1702
+ bufferSnippets.push( `@binding( ${ uniformIndexes.binding ++ } ) @group( ${ uniformIndexes.group } ) var<${ bufferAccessMode }> ${ uniform.name } : ${ bufferType };` );
1703
+
1704
+ } else {
1705
+
1706
+ const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${ bufferType }>` : `${ bufferType }`;
1707
+ const bufferSnippet = `\tvalue : array< ${ bufferTypeSnippet }${ bufferCountSnippet } >`;
1708
+
1709
+ bufferSnippets.push( this._getWGSLStructBinding( uniform.name, bufferSnippet, bufferAccessMode, uniformIndexes.binding ++, uniformIndexes.group ) );
1710
+
1711
+ }
1178
1712
 
1179
1713
  } else {
1180
1714
 
@@ -1209,6 +1743,9 @@ ${ flowData.code }
1209
1743
 
1210
1744
  }
1211
1745
 
1746
+ /**
1747
+ * Controls the code build of the shader stages.
1748
+ */
1212
1749
  buildCode() {
1213
1750
 
1214
1751
  const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} };
@@ -1217,6 +1754,8 @@ ${ flowData.code }
1217
1754
 
1218
1755
  for ( const shaderStage in shadersData ) {
1219
1756
 
1757
+ this.shaderStage = shaderStage;
1758
+
1220
1759
  const stageData = shadersData[ shaderStage ];
1221
1760
  stageData.uniforms = this.getUniforms( shaderStage );
1222
1761
  stageData.attributes = this.getAttributes( shaderStage );
@@ -1247,7 +1786,7 @@ ${ flowData.code }
1247
1786
 
1248
1787
  if ( flow.length > 0 ) flow += '\n';
1249
1788
 
1250
- flow += `\t// flow -> ${ slotName }\n\t`;
1789
+ flow += `\t// flow -> ${ slotName }\n`;
1251
1790
 
1252
1791
  }
1253
1792
 
@@ -1265,7 +1804,8 @@ ${ flowData.code }
1265
1804
 
1266
1805
  if ( isOutputStruct ) {
1267
1806
 
1268
- stageData.returnType = outputNode.nodeType;
1807
+ stageData.returnType = outputNode.getNodeType( this );
1808
+ stageData.structs += 'var<private> output : ' + stageData.returnType + ';';
1269
1809
 
1270
1810
  flow += `return ${ flowSlotData.result };`;
1271
1811
 
@@ -1279,7 +1819,7 @@ ${ flowData.code }
1279
1819
 
1280
1820
  stageData.returnType = 'OutputStruct';
1281
1821
  stageData.structs += this._getWGSLStruct( 'OutputStruct', structSnippet );
1282
- stageData.structs += '\nvar<private> output : OutputStruct;\n\n';
1822
+ stageData.structs += '\nvar<private> output : OutputStruct;';
1283
1823
 
1284
1824
  flow += `output.color = ${ flowSlotData.result };\n\n\treturn output;`;
1285
1825
 
@@ -1293,9 +1833,10 @@ ${ flowData.code }
1293
1833
 
1294
1834
  stageData.flow = flow;
1295
1835
 
1296
-
1297
1836
  }
1298
1837
 
1838
+ this.shaderStage = null;
1839
+
1299
1840
  if ( this.material !== null ) {
1300
1841
 
1301
1842
  this.vertexShader = this._getWGSLVertexCode( shadersData.vertex );
@@ -1309,6 +1850,13 @@ ${ flowData.code }
1309
1850
 
1310
1851
  }
1311
1852
 
1853
+ /**
1854
+ * Returns the native shader method name for a given generic name.
1855
+ *
1856
+ * @param {String} method - The method name to resolve.
1857
+ * @param {String} [output=null] - An optional output.
1858
+ * @return {String} The resolved WGSL method name.
1859
+ */
1312
1860
  getMethod( method, output = null ) {
1313
1861
 
1314
1862
  let wgslMethod;
@@ -1329,12 +1877,24 @@ ${ flowData.code }
1329
1877
 
1330
1878
  }
1331
1879
 
1880
+ /**
1881
+ * Returns the WGSL type of the given node data type.
1882
+ *
1883
+ * @param {String} type - The node data type.
1884
+ * @return {String} The WGSL type.
1885
+ */
1332
1886
  getType( type ) {
1333
1887
 
1334
1888
  return wgslTypeLib[ type ] || type;
1335
1889
 
1336
1890
  }
1337
1891
 
1892
+ /**
1893
+ * Whether the requested feature is available or not.
1894
+ *
1895
+ * @param {String} name - The requested feature.
1896
+ * @return {Boolean} Whether the requested feature is supported or not.
1897
+ */
1338
1898
  isAvailable( name ) {
1339
1899
 
1340
1900
  let result = supports[ name ];
@@ -1359,6 +1919,13 @@ ${ flowData.code }
1359
1919
 
1360
1920
  }
1361
1921
 
1922
+ /**
1923
+ * Returns the native shader method name for a given generic name.
1924
+ *
1925
+ * @private
1926
+ * @param {String} method - The method name to resolve.
1927
+ * @return {String} The resolved WGSL method name.
1928
+ */
1362
1929
  _getWGSLMethod( method ) {
1363
1930
 
1364
1931
  if ( wgslPolyfill[ method ] !== undefined ) {
@@ -1371,6 +1938,14 @@ ${ flowData.code }
1371
1938
 
1372
1939
  }
1373
1940
 
1941
+ /**
1942
+ * Includes the given method name into the current
1943
+ * function node.
1944
+ *
1945
+ * @private
1946
+ * @param {String} name - The method name to include.
1947
+ * @return {CodeNode} The respective code node.
1948
+ */
1374
1949
  _include( name ) {
1375
1950
 
1376
1951
  const codeNode = wgslPolyfill[ name ];
@@ -1386,12 +1961,22 @@ ${ flowData.code }
1386
1961
 
1387
1962
  }
1388
1963
 
1964
+ /**
1965
+ * Returns a WGSL vertex shader based on the given shader data.
1966
+ *
1967
+ * @private
1968
+ * @param {Object} shaderData - The shader data.
1969
+ * @return {String} The vertex shader.
1970
+ */
1389
1971
  _getWGSLVertexCode( shaderData ) {
1390
1972
 
1391
1973
  return `${ this.getSignature() }
1392
1974
  // directives
1393
1975
  ${shaderData.directives}
1394
1976
 
1977
+ // structs
1978
+ ${shaderData.structs}
1979
+
1395
1980
  // uniforms
1396
1981
  ${shaderData.uniforms}
1397
1982
 
@@ -1418,18 +2003,25 @@ fn main( ${shaderData.attributes} ) -> VaryingsStruct {
1418
2003
 
1419
2004
  }
1420
2005
 
2006
+ /**
2007
+ * Returns a WGSL fragment shader based on the given shader data.
2008
+ *
2009
+ * @private
2010
+ * @param {Object} shaderData - The shader data.
2011
+ * @return {String} The vertex shader.
2012
+ */
1421
2013
  _getWGSLFragmentCode( shaderData ) {
1422
2014
 
1423
2015
  return `${ this.getSignature() }
1424
2016
  // global
1425
2017
  ${ diagnostics }
1426
2018
 
1427
- // uniforms
1428
- ${shaderData.uniforms}
1429
-
1430
2019
  // structs
1431
2020
  ${shaderData.structs}
1432
2021
 
2022
+ // uniforms
2023
+ ${shaderData.uniforms}
2024
+
1433
2025
  // codes
1434
2026
  ${shaderData.codes}
1435
2027
 
@@ -1447,6 +2039,14 @@ fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} {
1447
2039
 
1448
2040
  }
1449
2041
 
2042
+ /**
2043
+ * Returns a WGSL compute shader based on the given shader data.
2044
+ *
2045
+ * @private
2046
+ * @param {Object} shaderData - The shader data.
2047
+ * @param {String} workgroupSize - The workgroup size.
2048
+ * @return {String} The vertex shader.
2049
+ */
1450
2050
  _getWGSLComputeCode( shaderData, workgroupSize ) {
1451
2051
 
1452
2052
  return `${ this.getSignature() }
@@ -1459,6 +2059,9 @@ var<private> instanceIndex : u32;
1459
2059
  // locals
1460
2060
  ${shaderData.scopedArrays}
1461
2061
 
2062
+ // structs
2063
+ ${shaderData.structs}
2064
+
1462
2065
  // uniforms
1463
2066
  ${shaderData.uniforms}
1464
2067
 
@@ -1469,7 +2072,7 @@ ${shaderData.codes}
1469
2072
  fn main( ${shaderData.attributes} ) {
1470
2073
 
1471
2074
  // system
1472
- instanceIndex = id.x + id.y * numWorkgroups.x * u32(${workgroupSize}) + id.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize});
2075
+ instanceIndex = globalId.x + globalId.y * numWorkgroups.x * u32(${workgroupSize}) + globalId.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize});
1473
2076
 
1474
2077
  // vars
1475
2078
  ${shaderData.vars}
@@ -1482,6 +2085,14 @@ fn main( ${shaderData.attributes} ) {
1482
2085
 
1483
2086
  }
1484
2087
 
2088
+ /**
2089
+ * Returns a WGSL struct based on the given name and variables.
2090
+ *
2091
+ * @private
2092
+ * @param {String} name - The struct name.
2093
+ * @param {String} vars - The struct variables.
2094
+ * @return {String} The WGSL snippet representing a struct.
2095
+ */
1485
2096
  _getWGSLStruct( name, vars ) {
1486
2097
 
1487
2098
  return `
@@ -1491,14 +2102,25 @@ ${vars}
1491
2102
 
1492
2103
  }
1493
2104
 
2105
+ /**
2106
+ * Returns a WGSL struct binding.
2107
+ *
2108
+ * @private
2109
+ * @param {String} name - The struct name.
2110
+ * @param {String} vars - The struct variables.
2111
+ * @param {String} access - The access.
2112
+ * @param {Number} [binding=0] - The binding index.
2113
+ * @param {Number} [group=0] - The group index.
2114
+ * @return {String} The WGSL snippet representing a struct binding.
2115
+ */
1494
2116
  _getWGSLStructBinding( name, vars, access, binding = 0, group = 0 ) {
1495
2117
 
1496
2118
  const structName = name + 'Struct';
1497
2119
  const structSnippet = this._getWGSLStruct( structName, vars );
1498
2120
 
1499
2121
  return `${structSnippet}
1500
- @binding( ${binding} ) @group( ${group} )
1501
- var<${access}> ${name} : ${structName};`;
2122
+ @binding( ${ binding } ) @group( ${ group } )
2123
+ var<${access}> ${ name } : ${ structName };`;
1502
2124
 
1503
2125
  }
1504
2126