@gnsx/three 0.185.16 → 0.186.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/build/three.cjs +10 -82600
  2. package/build/three.core.js +1309 -807
  3. package/build/three.module.js +439 -338
  4. package/build/three.tsl.js +74 -44
  5. package/build/three.webgpu.js +6036 -2184
  6. package/build/three.webgpu.nodes.js +6020 -2184
  7. package/examples/jsm/Addons.js +6 -6
  8. package/examples/jsm/controls/ArcballControls.js +1 -1
  9. package/examples/jsm/controls/FirstPersonControls.js +44 -20
  10. package/examples/jsm/controls/OrbitControls.js +9 -0
  11. package/examples/jsm/controls/TrackballControls.js +109 -4
  12. package/examples/jsm/csm/CSMShadowNode.js +13 -0
  13. package/examples/jsm/exporters/GLTFExporter.js +23 -7
  14. package/examples/jsm/exporters/USDZExporter.js +2 -2
  15. package/examples/jsm/generators/CityGenerator.js +377 -45
  16. package/examples/jsm/generators/ForestGenerator.js +12 -12
  17. package/examples/jsm/generators/TerrainGenerator.js +49 -37
  18. package/examples/jsm/generators/TreeGenerator.js +70 -76
  19. package/examples/jsm/generators/city/BenchGenerator.js +127 -0
  20. package/examples/jsm/generators/city/CarGenerator.js +479 -0
  21. package/examples/jsm/generators/city/CityGeneratorUtils.js +31 -0
  22. package/examples/jsm/generators/city/HydrantGenerator.js +106 -0
  23. package/examples/jsm/generators/city/InstancedMeshGenerator.js +86 -0
  24. package/examples/jsm/generators/city/PersonGenerator.js +447 -0
  25. package/examples/jsm/generators/city/SidewalkGenerator.js +33 -38
  26. package/examples/jsm/generators/city/SkyscraperGenerator.js +448 -48
  27. package/examples/jsm/generators/city/StreetTreeGenerator.js +231 -0
  28. package/examples/jsm/generators/city/StreetlightGenerator.js +100 -0
  29. package/examples/jsm/generators/city/TrafficlightGenerator.js +106 -0
  30. package/examples/jsm/generators/city/TrashcanGenerator.js +100 -0
  31. package/examples/jsm/geometries/BoxLineGeometry.js +1 -1
  32. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  33. package/examples/jsm/geometries/RoundedBoxGeometry.js +1 -1
  34. package/examples/jsm/gpgpu/CountingSort.js +271 -0
  35. package/examples/jsm/helpers/LightProbeGridHelper.js +60 -239
  36. package/examples/jsm/helpers/LightProbeGridHelperWebGL.js +221 -0
  37. package/examples/jsm/inspector/Extension.js +94 -0
  38. package/examples/jsm/inspector/Inspector.js +145 -41
  39. package/examples/jsm/inspector/RendererInspector.js +100 -52
  40. package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +2609 -0
  41. package/examples/jsm/inspector/extensions/color-grading/ColorWheel.js +352 -0
  42. package/examples/jsm/inspector/extensions/color-grading/CurveEditor.js +599 -0
  43. package/examples/jsm/inspector/extensions/color-grading/LUT3DStyle.js +1201 -0
  44. package/examples/jsm/inspector/extensions/color-grading/LUTMath.js +788 -0
  45. package/examples/jsm/inspector/extensions/color-grading/modules/BrightnessModule.js +72 -0
  46. package/examples/jsm/inspector/extensions/color-grading/modules/ColorWheelModule.js +112 -0
  47. package/examples/jsm/inspector/extensions/color-grading/modules/ContrastModule.js +82 -0
  48. package/examples/jsm/inspector/extensions/color-grading/modules/CurvesModule.js +109 -0
  49. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureHueModule.js +110 -0
  50. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureModule.js +73 -0
  51. package/examples/jsm/inspector/extensions/color-grading/modules/HueModule.js +78 -0
  52. package/examples/jsm/inspector/extensions/color-grading/modules/ImportedCubeModule.js +89 -0
  53. package/examples/jsm/inspector/extensions/color-grading/modules/Module.js +285 -0
  54. package/examples/jsm/inspector/extensions/color-grading/modules/OutputModule.js +101 -0
  55. package/examples/jsm/inspector/extensions/color-grading/modules/RendererModule.js +225 -0
  56. package/examples/jsm/inspector/extensions/color-grading/modules/SatVibranceModule.js +102 -0
  57. package/examples/jsm/inspector/extensions/color-grading/modules/SaturationModule.js +76 -0
  58. package/examples/jsm/inspector/extensions/color-grading/modules/VibranceModule.js +76 -0
  59. package/examples/jsm/inspector/extensions/color-grading/modules/WhiteBalanceModule.js +86 -0
  60. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +26 -31
  61. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -0
  62. package/examples/jsm/inspector/tabs/Memory.js +0 -2
  63. package/examples/jsm/inspector/tabs/Settings.js +4 -0
  64. package/examples/jsm/inspector/tabs/Timeline.js +223 -171
  65. package/examples/jsm/inspector/tabs/Viewer.js +515 -21
  66. package/examples/jsm/inspector/ui/List.js +15 -9
  67. package/examples/jsm/inspector/ui/Profiler.js +170 -14
  68. package/examples/jsm/inspector/ui/Style.js +269 -23
  69. package/examples/jsm/inspector/ui/Tab.js +2 -0
  70. package/examples/jsm/inspector/ui/Values.js +14 -2
  71. package/examples/jsm/interactive/HTMLMesh.js +19 -3
  72. package/examples/jsm/lighting/LightProbeGrid.js +484 -889
  73. package/examples/jsm/lighting/LightProbeGridUtils.js +107 -0
  74. package/examples/jsm/lighting/LightProbeGridWebGL.js +841 -0
  75. package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +194 -0
  76. package/examples/jsm/lighting/vxgi/VXGINode.js +660 -0
  77. package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +478 -0
  78. package/examples/jsm/lighting/vxgi/VXGIVolume.js +1430 -0
  79. package/examples/jsm/lights/SunLight.js +95 -0
  80. package/examples/jsm/lights/SunLightNode.js +56 -0
  81. package/examples/jsm/lights/SunLightShadow.js +319 -0
  82. package/examples/jsm/lights/SunShadowNode.js +312 -0
  83. package/examples/jsm/loaders/3DMLoader.js +150 -49
  84. package/examples/jsm/loaders/3MFLoader.js +202 -1
  85. package/examples/jsm/loaders/FBXLoader.js +81 -5
  86. package/examples/jsm/loaders/GLTFGaussianSplatLoaderExtension.js +330 -0
  87. package/examples/jsm/loaders/GLTFLoader.js +79 -14
  88. package/examples/jsm/loaders/GaussianSplatPLYLoader.js +386 -0
  89. package/examples/jsm/loaders/KSPLATLoader.js +463 -0
  90. package/examples/jsm/loaders/MaterialXLoader.js +111 -1010
  91. package/examples/jsm/loaders/PCDLoader.js +1 -1
  92. package/examples/jsm/loaders/SPLATLoader.js +139 -0
  93. package/examples/jsm/loaders/SPZLoader.js +561 -0
  94. package/examples/jsm/loaders/materialx/MaterialXArchive.js +108 -0
  95. package/examples/jsm/loaders/materialx/MaterialXDocument.js +878 -0
  96. package/examples/jsm/loaders/materialx/MaterialXHextile.js +183 -0
  97. package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +376 -0
  98. package/examples/jsm/loaders/materialx/MaterialXLog.js +75 -0
  99. package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +4 -0
  100. package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +1021 -0
  101. package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +661 -0
  102. package/examples/jsm/loaders/materialx/MaterialXUtils.js +57 -0
  103. package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +997 -0
  104. package/examples/jsm/loaders/materialx/parse/MaterialXParser.js +28 -0
  105. package/examples/jsm/loaders/usd/USDAParser.js +15 -2
  106. package/examples/jsm/loaders/usd/USDCParser.js +1 -4
  107. package/examples/jsm/loaders/usd/USDComposer.js +80 -42
  108. package/examples/jsm/materials/WoodNodeMaterial.js +6 -108
  109. package/examples/jsm/misc/RollerCoaster.js +2 -2
  110. package/examples/jsm/misc/SculptGL.LICENSE.txt +21 -0
  111. package/examples/jsm/misc/Sculptor.js +1679 -0
  112. package/examples/jsm/misc/SculptorMesh.js +1504 -0
  113. package/examples/jsm/misc/SculptorTools.js +1180 -0
  114. package/examples/jsm/misc/SculptorUtils.js +345 -0
  115. package/examples/jsm/misc/TubePainter.js +28 -16
  116. package/examples/jsm/misc/VolumeSlice.js +24 -24
  117. package/examples/jsm/modifiers/SimplifyModifier.js +63 -556
  118. package/examples/jsm/objects/GaussianSplat.js +1039 -0
  119. package/examples/jsm/objects/Sky.js +66 -45
  120. package/examples/jsm/objects/SkyMesh.js +70 -51
  121. package/examples/jsm/physics/JoltPhysics.js +1 -1
  122. package/examples/jsm/postprocessing/AfterimagePass.js +4 -2
  123. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  124. package/examples/jsm/postprocessing/GTAOPass.js +1 -1
  125. package/examples/jsm/postprocessing/OutlinePass.js +5 -5
  126. package/examples/jsm/postprocessing/SAOPass.js +1 -1
  127. package/examples/jsm/postprocessing/SSAOPass.js +1 -1
  128. package/examples/jsm/postprocessing/SSRPass.js +4 -2
  129. package/examples/jsm/postprocessing/SavePass.js +1 -1
  130. package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
  131. package/examples/jsm/postprocessing/UnrealBloomPass.js +30 -13
  132. package/examples/jsm/renderers/CSS2DRenderer.js +29 -5
  133. package/examples/jsm/shaders/DepthLimitedBlurShader.js +4 -1
  134. package/examples/jsm/shaders/ExposureShader.js +1 -1
  135. package/examples/jsm/shaders/FilmShader.js +2 -1
  136. package/examples/jsm/transpiler/AST.js +21 -2
  137. package/examples/jsm/transpiler/GLSLDecoder.js +498 -8
  138. package/examples/jsm/transpiler/TSLEncoder.js +82 -10
  139. package/examples/jsm/transpiler/WGSLEncoder.js +33 -4
  140. package/examples/jsm/tsl/WebGLNodesHandler.js +29 -39
  141. package/examples/jsm/tsl/display/AfterImageNode.js +2 -0
  142. package/examples/jsm/tsl/display/AnaglyphPassNode.js +3 -2
  143. package/examples/jsm/tsl/display/BilateralBlurNode.js +5 -2
  144. package/examples/jsm/tsl/display/BloomNode.js +55 -30
  145. package/examples/jsm/tsl/display/DenoiseNode.js +21 -1
  146. package/examples/jsm/tsl/display/DepthOfFieldNode.js +24 -6
  147. package/examples/jsm/tsl/display/DotScreenNode.js +11 -11
  148. package/examples/jsm/tsl/display/FSR1Node.js +8 -4
  149. package/examples/jsm/tsl/display/GTAONode.js +199 -86
  150. package/examples/jsm/tsl/display/GaussianBlurNode.js +65 -52
  151. package/examples/jsm/tsl/display/GodraysNode.js +5 -2
  152. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +2 -2
  153. package/examples/jsm/tsl/display/LensflareNode.js +5 -2
  154. package/examples/jsm/tsl/display/OITPassNode.js +352 -0
  155. package/examples/jsm/tsl/display/OutlineNode.js +2 -0
  156. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +3 -2
  157. package/examples/jsm/tsl/display/RGBShiftNode.js +9 -9
  158. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +7 -4
  159. package/examples/jsm/tsl/display/RetroPassNode.js +1 -1
  160. package/examples/jsm/tsl/display/SMAANode.js +22 -61
  161. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -4
  162. package/examples/jsm/tsl/display/SSAONode.js +436 -0
  163. package/examples/jsm/tsl/display/SSGINode.js +5 -2
  164. package/examples/jsm/tsl/display/SSRNode.js +7 -2
  165. package/examples/jsm/tsl/display/SSSNode.js +5 -2
  166. package/examples/jsm/tsl/display/SharpenNode.js +5 -4
  167. package/examples/jsm/tsl/display/StereoCompositePassNode.js +1 -3
  168. package/examples/jsm/tsl/display/StereoPassNode.js +1 -3
  169. package/examples/jsm/tsl/display/TAAUNode.js +22 -125
  170. package/examples/jsm/tsl/display/TRAANode.js +16 -142
  171. package/examples/jsm/tsl/display/TemporalReprojectNode.js +21 -15
  172. package/examples/jsm/tsl/display/depthAwareBlur.js +63 -0
  173. package/examples/jsm/tsl/display/hashBlur.js +3 -2
  174. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +38 -27
  175. package/examples/jsm/tsl/lighting/LightProbeGridNode.js +136 -0
  176. package/examples/jsm/tsl/math/voronoiNoise.js +112 -0
  177. package/examples/jsm/tsl/shadows/TileShadowNode.js +4 -6
  178. package/examples/jsm/tsl/utils/Raymarching.js +5 -5
  179. package/examples/jsm/tsl/utils/SoftParticles.js +60 -0
  180. package/examples/jsm/tsl/utils/TAAUtils.js +195 -0
  181. package/examples/jsm/utils/BufferGeometryUtils.js +14 -14
  182. package/examples/jsm/utils/GaussianSplatUtils.js +229 -0
  183. package/examples/jsm/utils/WebGLTextureUtils.js +1 -1
  184. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  185. package/examples/jsm/webxr/WebGLXRFallback.js +2 -16
  186. package/examples/jsm/webxr/XRControllerModelFactory.js +16 -4
  187. package/package.json +9 -16
  188. package/src/Three.Core.js +2 -1
  189. package/src/Three.TSL.js +73 -43
  190. package/src/Three.WebGPU.Nodes.js +1 -0
  191. package/src/Three.WebGPU.js +1 -0
  192. package/src/animation/AnimationClip.js +15 -2
  193. package/src/animation/AnimationObjectGroup.js +18 -6
  194. package/src/animation/AnimationUtils.js +26 -0
  195. package/src/animation/KeyframeTrack.js +37 -0
  196. package/src/constants.js +23 -1
  197. package/src/core/BufferAttribute.js +3 -2
  198. package/src/core/BufferGeometry.js +1 -1
  199. package/src/core/InterleavedBuffer.js +5 -1
  200. package/src/core/Object3D.js +40 -12
  201. package/src/core/Raycaster.js +4 -0
  202. package/src/core/RenderTarget.js +99 -9
  203. package/src/core/RenderTarget3D.js +12 -8
  204. package/src/extras/Controls.js +0 -8
  205. package/src/extras/PMREMGenerator.js +99 -205
  206. package/src/geometries/TorusGeometry.js +1 -1
  207. package/src/helpers/ArrowHelper.js +2 -0
  208. package/src/helpers/AxesHelper.js +2 -0
  209. package/src/helpers/Box3Helper.js +2 -0
  210. package/src/helpers/BoxHelper.js +2 -0
  211. package/src/helpers/CameraHelper.js +2 -0
  212. package/src/helpers/DirectionalLightHelper.js +2 -0
  213. package/src/helpers/GridHelper.js +2 -0
  214. package/src/helpers/HemisphereLightHelper.js +2 -0
  215. package/src/helpers/PlaneHelper.js +2 -0
  216. package/src/helpers/PointLightHelper.js +2 -0
  217. package/src/helpers/PolarGridHelper.js +2 -0
  218. package/src/helpers/SkeletonHelper.js +2 -0
  219. package/src/helpers/SpotLightHelper.js +2 -0
  220. package/src/lights/Light.js +0 -10
  221. package/src/lights/LightShadow.js +43 -12
  222. package/src/lights/SpotLightShadow.js +18 -0
  223. package/src/loaders/BufferGeometryLoader.js +5 -0
  224. package/src/loaders/ImageBitmapLoader.js +3 -1
  225. package/src/loaders/ObjectLoader.js +8 -5
  226. package/src/materials/Material.js +80 -57
  227. package/src/materials/MeshPhysicalMaterial.js +32 -0
  228. package/src/materials/nodes/Line2NodeMaterial.js +17 -8
  229. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +42 -5
  230. package/src/materials/nodes/NodeMaterial.js +19 -13
  231. package/src/materials/nodes/PointsNodeMaterial.js +2 -1
  232. package/src/materials/nodes/manager/NodeMaterialObserver.js +282 -55
  233. package/src/math/Frustum.js +9 -0
  234. package/src/math/FrustumArray.js +1 -1
  235. package/src/math/MathUtils.js +5 -3
  236. package/src/math/Matrix4.js +2 -9
  237. package/src/math/Plane.js +30 -1
  238. package/src/math/Quaternion.js +0 -10
  239. package/src/math/Ray.js +95 -45
  240. package/src/math/Triangle.js +0 -2
  241. package/src/math/Vector3.js +2 -2
  242. package/src/math/Vector4.js +0 -4
  243. package/src/math/interpolants/BezierInterpolant.js +36 -23
  244. package/src/nodes/Nodes.js +2 -0
  245. package/src/nodes/TSL.js +11 -3
  246. package/src/nodes/accessors/Batch.js +85 -13
  247. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  248. package/src/nodes/accessors/BuiltinNode.js +1 -1
  249. package/src/nodes/accessors/Instance.js +19 -18
  250. package/src/nodes/accessors/MaterialNode.js +9 -0
  251. package/src/nodes/accessors/ModelNode.js +85 -9
  252. package/src/nodes/accessors/ReferenceBaseNode.js +1 -70
  253. package/src/nodes/accessors/ReferenceElementNode.js +72 -0
  254. package/src/nodes/accessors/ReferenceNode.js +1 -70
  255. package/src/nodes/accessors/Skinning.js +124 -12
  256. package/src/nodes/accessors/StorageTextureNode.js +7 -3
  257. package/src/nodes/accessors/Texture3DNode.js +1 -1
  258. package/src/nodes/accessors/TextureNode.js +51 -21
  259. package/src/nodes/accessors/TextureSizeNode.js +4 -2
  260. package/src/nodes/accessors/UniformArrayNode.js +30 -5
  261. package/src/nodes/code/CodeNode.js +1 -1
  262. package/src/nodes/code/FunctionNode.js +12 -2
  263. package/src/nodes/core/ArrayNode.js +2 -2
  264. package/src/nodes/core/ContextNode.js +57 -4
  265. package/src/nodes/core/IndexNode.js +69 -4
  266. package/src/nodes/core/InspectorNode.js +2 -2
  267. package/src/nodes/core/MRTNode.js +44 -2
  268. package/src/nodes/core/Node.js +6 -3
  269. package/src/nodes/core/NodeBuilder.js +65 -50
  270. package/src/nodes/core/NodeFrame.js +11 -3
  271. package/src/nodes/core/NodeUtils.js +88 -0
  272. package/src/nodes/core/PropertyNode.js +8 -0
  273. package/src/nodes/core/StackNode.js +0 -1
  274. package/src/nodes/core/StructNode.js +4 -3
  275. package/src/nodes/core/UniformGroupNode.js +3 -2
  276. package/src/nodes/core/UniformNode.js +26 -12
  277. package/src/nodes/core/VarNode.js +0 -1
  278. package/src/nodes/display/BumpMapNode.js +2 -2
  279. package/src/nodes/display/ColorAdjustment.js +1 -1
  280. package/src/nodes/display/PassNode.js +76 -15
  281. package/src/nodes/display/ScreenNode.js +22 -65
  282. package/src/nodes/fog/Fog.js +4 -4
  283. package/src/nodes/functions/BSDF/BRDF_GGX.js +6 -6
  284. package/src/nodes/functions/BSDF/BRDF_Sheen.js +1 -1
  285. package/src/nodes/functions/BSDF/DFGLUT.js +2 -1
  286. package/src/nodes/functions/BSDF/LTC.js +1 -1
  287. package/src/nodes/functions/PhongLightingModel.js +1 -1
  288. package/src/nodes/functions/PhysicalLightingModel.js +83 -25
  289. package/src/nodes/functions/ToonLightingModel.js +2 -2
  290. package/src/nodes/functions/material/getParallaxCorrectNormal.js +3 -3
  291. package/src/nodes/gpgpu/AtomicFunctionNode.js +64 -13
  292. package/src/nodes/gpgpu/BarrierNode.js +13 -4
  293. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
  294. package/src/nodes/gpgpu/ComputeNode.js +20 -17
  295. package/src/nodes/gpgpu/SubgroupFunctionNode.js +165 -37
  296. package/src/nodes/gpgpu/WorkgroupInfoNode.js +44 -6
  297. package/src/nodes/lighting/EnvironmentNode.js +40 -4
  298. package/src/nodes/lighting/LightsNode.js +20 -4
  299. package/src/nodes/lighting/ShadowBaseNode.js +158 -1
  300. package/src/nodes/lighting/ShadowFilterNode.js +2 -106
  301. package/src/nodes/lighting/ShadowNode.js +22 -91
  302. package/src/nodes/materialx/{lib/mx_hsv.js → MaterialXColor.js} +3 -6
  303. package/src/nodes/materialx/{lib/mx_transform_color.js → MaterialXColorTransform.js} +3 -6
  304. package/src/nodes/materialx/MaterialXCore.js +37 -0
  305. package/src/nodes/materialx/MaterialXNodes.js +64 -72
  306. package/src/nodes/materialx/{lib/mx_noise.js → MaterialXNoise.js} +426 -197
  307. package/src/nodes/math/BitcountNode.js +24 -4
  308. package/src/nodes/math/MathNode.js +4 -4
  309. package/src/nodes/math/MathUtils.js +15 -4
  310. package/src/nodes/math/OperatorNode.js +2 -2
  311. package/src/nodes/math/PackFloatNode.js +29 -1
  312. package/src/nodes/math/Packed4x8IntegerNode.js +433 -0
  313. package/src/nodes/math/UnpackFloatNode.js +30 -2
  314. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  315. package/src/nodes/pmrem/PMREMNode.js +1 -1
  316. package/src/nodes/pmrem/PMREMUtils.js +31 -74
  317. package/src/nodes/shapes/Shapes.js +1 -1
  318. package/src/nodes/tsl/TSLCore.js +1 -31
  319. package/src/nodes/utils/EventNode.js +75 -0
  320. package/src/nodes/utils/LoopNode.js +54 -13
  321. package/src/nodes/utils/PostProcessingUtils.js +23 -2
  322. package/src/nodes/utils/RTTNode.js +97 -32
  323. package/src/nodes/utils/ReflectorNode.js +8 -4
  324. package/src/nodes/utils/RotateNode.js +85 -8
  325. package/src/nodes/utils/SpriteUtils.js +58 -23
  326. package/src/objects/BatchedMesh.js +6 -0
  327. package/src/objects/InstancedMesh.js +1 -1
  328. package/src/objects/LOD.js +1 -1
  329. package/src/objects/Line.js +12 -0
  330. package/src/objects/Mesh.js +12 -0
  331. package/src/objects/Points.js +12 -0
  332. package/src/objects/Sprite.js +12 -0
  333. package/src/renderers/WebGLRenderer.js +93 -27
  334. package/src/renderers/common/Animation.js +12 -2
  335. package/src/renderers/common/Backend.js +38 -10
  336. package/src/renderers/common/BindGroup.js +0 -1
  337. package/src/renderers/common/Bindings.js +50 -4
  338. package/src/renderers/common/BundleGroup.js +4 -0
  339. package/src/renderers/common/ClippingContext.js +11 -1
  340. package/src/renderers/common/Color4.js +9 -0
  341. package/src/renderers/common/Constants.js +0 -5
  342. package/src/renderers/common/DirectRenderPipeline.js +233 -0
  343. package/src/renderers/common/Geometries.js +24 -3
  344. package/src/renderers/common/Info.js +3 -3
  345. package/src/renderers/common/InspectorBase.js +37 -8
  346. package/src/renderers/common/Lighting.js +11 -4
  347. package/src/renderers/common/Pipelines.js +6 -4
  348. package/src/renderers/common/QuadMesh.js +16 -2
  349. package/src/renderers/common/RenderContext.js +8 -0
  350. package/src/renderers/common/RenderList.js +53 -19
  351. package/src/renderers/common/RenderLists.js +58 -11
  352. package/src/renderers/common/RenderObject.js +14 -0
  353. package/src/renderers/common/RenderObjects.js +14 -9
  354. package/src/renderers/common/RenderPipeline.js +52 -44
  355. package/src/renderers/common/Renderer.js +226 -55
  356. package/src/renderers/common/Storage3DTexture.js +16 -0
  357. package/src/renderers/common/Textures.js +3 -3
  358. package/src/renderers/common/XRManager.js +79 -72
  359. package/src/renderers/common/extras/PMREMGenerator.js +76 -144
  360. package/src/renderers/common/nodes/NodeManager.js +144 -6
  361. package/src/renderers/common/nodes/NodeStorageBuffer.js +3 -1
  362. package/src/renderers/common/nodes/NodeUniformBuffer.js +3 -1
  363. package/src/renderers/shaders/DFGLUTData.js +2 -1
  364. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +4 -2
  365. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +48 -0
  366. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +53 -4
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +20 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +20 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +61 -57
  371. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +82 -0
  372. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +9 -0
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +8 -1
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +15 -0
  375. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  376. package/src/renderers/shaders/ShaderLib.js +1 -0
  377. package/src/renderers/shaders/UniformsLib.js +16 -0
  378. package/src/renderers/webgl/WebGLAnimation.js +2 -2
  379. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  380. package/src/renderers/webgl/WebGLLights.js +74 -4
  381. package/src/renderers/webgl/WebGLMaterials.js +6 -0
  382. package/src/renderers/webgl/WebGLOutput.js +36 -24
  383. package/src/renderers/webgl/WebGLProgram.js +3 -0
  384. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  385. package/src/renderers/webgl/WebGLRenderLists.js +6 -10
  386. package/src/renderers/webgl/WebGLShadowMap.js +47 -44
  387. package/src/renderers/webgl/WebGLTextures.js +7 -7
  388. package/src/renderers/webgl-fallback/WebGLBackend.js +153 -45
  389. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +83 -29
  390. package/src/renderers/webgl-fallback/utils/WebGLState.js +163 -17
  391. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +32 -5
  392. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +11 -4
  393. package/src/renderers/webgpu/WebGPUBackend.js +513 -145
  394. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -20
  395. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -1
  396. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +3 -12
  397. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +24 -14
  398. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +80 -14
  399. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -7
  400. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +9 -3
  401. package/src/renderers/webgpu/utils/WebGPUUtils.js +16 -4
  402. package/src/renderers/webxr/WebXRManager.js +25 -2
  403. package/src/scenes/Scene.js +3 -3
  404. package/src/textures/CompressedArrayTexture.js +16 -0
  405. package/src/textures/Data3DTexture.js +16 -0
  406. package/src/textures/DataArrayTexture.js +16 -0
  407. package/src/textures/DepthTexture.js +3 -3
  408. package/src/textures/Texture.js +3 -3
  409. package/src/textures/{Source.js → TextureSource.js} +39 -8
  410. package/src/utils.js +6 -79
  411. package/build/three.core.min.js +0 -6
  412. package/build/three.module.min.js +0 -6
  413. package/build/three.tsl.min.js +0 -6
  414. package/build/three.webgpu.min.js +0 -6
  415. package/build/three.webgpu.nodes.min.js +0 -6
  416. package/examples/jsm/libs/ecsy.module.js +0 -1792
  417. package/examples/jsm/loaders/LottieLoader.js +0 -130
  418. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +0 -52
@@ -13,9 +13,10 @@ import WebGPUCapabilities from './utils/WebGPUCapabilities.js';
13
13
  import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js';
14
14
  import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js';
15
15
 
16
- import { WebGPUCoordinateSystem, TimestampQuery, REVISION, HalfFloatType, Compatibility } from '../../constants.js';
16
+ import { WebGPUCoordinateSystem, TimestampQuery, REVISION, HalfFloatType, Compatibility, CustomBlending } from '../../constants.js';
17
+ import { Color } from '../../math/Color.js';
17
18
  import WebGPUTimestampQueryPool from './utils/WebGPUTimestampQueryPool.js';
18
- import { error } from '../../utils.js';
19
+ import { error, warnOnce } from '../../utils.js';
19
20
 
20
21
  import GPUBufferDescriptor from './descriptors/GPUBufferDescriptor.js';
21
22
  import GPUCommandEncoderDescriptor from './descriptors/GPUCommandEncoderDescriptor.js';
@@ -27,10 +28,12 @@ import GPURenderPassDepthStencilAttachment from './descriptors/GPURenderPassDept
27
28
  import GPURenderPassDescriptor from './descriptors/GPURenderPassDescriptor.js';
28
29
  // import GPURenderPassTimestampWrites from './descriptors/GPURenderPassTimestampWrites.js';
29
30
  import GPUTexelCopyTextureInfo from './descriptors/GPUTexelCopyTextureInfo.js';
31
+ import GPUTextureDescriptor from './descriptors/GPUTextureDescriptor.js';
30
32
  import GPUTextureViewDescriptor from './descriptors/GPUTextureViewDescriptor.js';
31
33
  import GPUExtent3D from './descriptors/GPUExtent3D.js';
32
34
 
33
35
  const _clearValue = { r: 0, g: 0, b: 0, a: 1 };
36
+ const _blendConstant = { r: 0, g: 0, b: 0, a: 0 };
34
37
  const _bufferDescriptor = new GPUBufferDescriptor();
35
38
  const _commandEncoderDescriptor = new GPUCommandEncoderDescriptor();
36
39
  const _computePassDescriptor = new GPUComputePassDescriptor();
@@ -39,6 +42,7 @@ const _shaderModuleDescriptor = new GPUShaderModuleDescriptor();
39
42
  // const _renderPassTimestampWrites = new GPURenderPassTimestampWrites();
40
43
  const _texelCopyTextureInfoSrc = new GPUTexelCopyTextureInfo();
41
44
  const _texelCopyTextureInfoDst = new GPUTexelCopyTextureInfo();
45
+ const _textureDescriptor = new GPUTextureDescriptor();
42
46
  const _viewDescriptor = new GPUTextureViewDescriptor();
43
47
  const _extent3D = new GPUExtent3D();
44
48
 
@@ -306,13 +310,14 @@ class WebGPUBackend extends Backend {
306
310
  */
307
311
  setXRRenderTargetTextures( renderTarget, colorTexture, viewDescriptors = null ) {
308
312
 
309
- this.set( renderTarget.texture, {
310
- texture: colorTexture,
311
- format: colorTexture.format,
312
- externalTexture: true,
313
- xrViewDescriptors: viewDescriptors,
314
- initialized: true
315
- } );
313
+ // Update the external XR texture without replacing the cached MSAA attachments.
314
+ const textureData = this.get( renderTarget.texture );
315
+
316
+ textureData.texture = colorTexture;
317
+ textureData.format = colorTexture.format;
318
+ textureData.externalTexture = true;
319
+ textureData.xrViewDescriptors = viewDescriptors;
320
+ textureData.initialized = true;
316
321
 
317
322
  }
318
323
 
@@ -430,7 +435,7 @@ class WebGPUBackend extends Backend {
430
435
  * pass descriptor even when rendering directly to screen.
431
436
  *
432
437
  * @private
433
- * @return {Object} The render pass descriptor.
438
+ * @return {GPURenderPassDescriptor} The render pass descriptor.
434
439
  */
435
440
  _getDefaultRenderPassDescriptor() {
436
441
 
@@ -528,6 +533,81 @@ class WebGPUBackend extends Backend {
528
533
 
529
534
  }
530
535
 
536
+ /**
537
+ * Returns multisampled color textures for an external render target.
538
+ *
539
+ * @private
540
+ * @param {RenderContext} renderContext - The render context.
541
+ * @param {Object} textureData - The backend data for the external texture.
542
+ * @param {number} count - The number of textures to create.
543
+ * @return {?Array<GPUTexture>} The multisampled textures.
544
+ */
545
+ _getExternalMSAATextures( renderContext, textureData, count ) {
546
+
547
+ const samples = this.utils.getSampleCount( renderContext.sampleCount );
548
+
549
+ if ( samples === 1 ) {
550
+
551
+ if ( textureData.msaaTextures !== undefined ) {
552
+
553
+ for ( const texture of textureData.msaaTextures ) texture.destroy();
554
+
555
+ textureData.msaaTextures = undefined;
556
+
557
+ }
558
+
559
+ return null;
560
+
561
+ }
562
+
563
+ const renderTarget = renderContext.renderTarget;
564
+ const width = renderTarget.width;
565
+ const height = renderTarget.height;
566
+ const format = textureData.format;
567
+
568
+ if ( textureData.msaaTextures === undefined ||
569
+ textureData.msaaTextures.length !== count ||
570
+ textureData.msaaWidth !== width ||
571
+ textureData.msaaHeight !== height ||
572
+ textureData.msaaSamples !== samples ||
573
+ textureData.msaaFormat !== format ) {
574
+
575
+ if ( textureData.msaaTextures !== undefined ) {
576
+
577
+ for ( const texture of textureData.msaaTextures ) texture.destroy();
578
+
579
+ }
580
+
581
+ _textureDescriptor.size.width = width;
582
+ _textureDescriptor.size.height = height;
583
+ _textureDescriptor.sampleCount = samples;
584
+ _textureDescriptor.format = format;
585
+ // Layered rendering can resume after a framebuffer copy,
586
+ // so these attachments must support loading.
587
+ _textureDescriptor.usage = GPUTextureUsage.RENDER_ATTACHMENT;
588
+
589
+ textureData.msaaTextures = [];
590
+
591
+ for ( let i = 0; i < count; i ++ ) {
592
+
593
+ _textureDescriptor.label = renderTarget.texture.name + '-msaa-' + i;
594
+ textureData.msaaTextures.push( this.device.createTexture( _textureDescriptor ) );
595
+
596
+ }
597
+
598
+ _textureDescriptor.reset();
599
+
600
+ textureData.msaaWidth = width;
601
+ textureData.msaaHeight = height;
602
+ textureData.msaaSamples = samples;
603
+ textureData.msaaFormat = format;
604
+
605
+ }
606
+
607
+ return textureData.msaaTextures;
608
+
609
+ }
610
+
531
611
  /**
532
612
  * Creates attachment views for an external texture render target.
533
613
  *
@@ -540,14 +620,19 @@ class WebGPUBackend extends Backend {
540
620
 
541
621
  const textureViews = [];
542
622
  const camera = renderContext.camera;
623
+ const viewDescriptors = textureData.xrViewDescriptors;
624
+ const viewCount = Math.max( viewDescriptors?.length || 0, renderContext.activeCubeFace + 1, 1 );
625
+ const msaaTextures = this._getExternalMSAATextures( renderContext, textureData, viewCount );
626
+
627
+ if ( viewDescriptors && camera !== null && camera.isArrayCamera === true ) {
543
628
 
544
- if ( textureData.xrViewDescriptors && camera !== null && camera.isArrayCamera === true ) {
629
+ for ( let i = 0; i < viewDescriptors.length; i ++ ) {
545
630
 
546
- for ( let i = 0; i < textureData.xrViewDescriptors.length; i ++ ) {
631
+ const textureView = textureData.texture.createView( viewDescriptors[ i ] );
547
632
 
548
633
  textureViews.push( {
549
- view: textureData.texture.createView( textureData.xrViewDescriptors[ i ] ),
550
- resolveTarget: undefined,
634
+ view: msaaTextures !== null ? msaaTextures[ i ].createView() : textureView,
635
+ resolveTarget: msaaTextures !== null && renderContext.renderTarget.resolveColorBuffer === true ? textureView : undefined,
551
636
  depthSlice: undefined
552
637
  } );
553
638
 
@@ -555,13 +640,16 @@ class WebGPUBackend extends Backend {
555
640
 
556
641
  } else {
557
642
 
643
+ const layer = renderContext.activeCubeFace;
644
+ const textureView = textureData.texture.createView( {
645
+ dimension: GPUTextureViewDimension.TwoD,
646
+ baseArrayLayer: layer,
647
+ arrayLayerCount: 1
648
+ } );
649
+
558
650
  textureViews.push( {
559
- view: textureData.texture.createView( {
560
- dimension: GPUTextureViewDimension.TwoD,
561
- baseArrayLayer: renderContext.activeCubeFace,
562
- arrayLayerCount: 1
563
- } ),
564
- resolveTarget: undefined,
651
+ view: msaaTextures !== null ? msaaTextures[ layer ].createView() : textureView,
652
+ resolveTarget: msaaTextures !== null && renderContext.renderTarget.resolveColorBuffer === true ? textureView : undefined,
565
653
  depthSlice: undefined
566
654
  } );
567
655
 
@@ -649,9 +737,10 @@ class WebGPUBackend extends Backend {
649
737
  _viewDescriptor.dimension = GPUTextureViewDimension.TwoD;
650
738
 
651
739
  const textureView = textureData.texture.createView( _viewDescriptor );
740
+ const msaaTexture = textureData.msaaTextures?.[ layer ];
652
741
  textureViews.push( {
653
- view: textureView,
654
- resolveTarget: undefined,
742
+ view: msaaTexture !== undefined ? msaaTexture.createView() : textureView,
743
+ resolveTarget: msaaTexture !== undefined && renderTarget.resolveColorBuffer === true ? textureView : undefined,
655
744
  depthSlice: undefined
656
745
  } );
657
746
 
@@ -674,7 +763,12 @@ class WebGPUBackend extends Backend {
674
763
  if ( textureData.msaaTexture !== undefined ) {
675
764
 
676
765
  view = textureData.msaaTexture.createView();
677
- resolveTarget = textureView;
766
+ resolveTarget = renderTarget.resolveColorBuffer === true ? textureView : undefined;
767
+
768
+ } else if ( textureData.msaaTextures !== undefined ) {
769
+
770
+ view = textureData.msaaTextures[ renderContext.activeCubeFace ].createView();
771
+ resolveTarget = renderTarget.resolveColorBuffer === true ? textureView : undefined;
678
772
 
679
773
  } else {
680
774
 
@@ -727,7 +821,8 @@ class WebGPUBackend extends Backend {
727
821
  }
728
822
 
729
823
  const depthStencilAttachment = new GPURenderPassDepthStencilAttachment();
730
- depthStencilAttachment.view = depthTextureData.texture.createView( _viewDescriptor );
824
+ const msaaDepthTexture = depthTextureData.msaaTextures?.[ renderContext.activeCubeFace ];
825
+ depthStencilAttachment.view = msaaDepthTexture !== undefined ? msaaDepthTexture.createView() : depthTextureData.texture.createView( _viewDescriptor );
731
826
  descriptorBase.depthStencilAttachment = depthStencilAttachment;
732
827
 
733
828
  _viewDescriptor.reset();
@@ -822,6 +917,15 @@ class WebGPUBackend extends Backend {
822
917
 
823
918
  renderContextData.lastOcclusionObject = null;
824
919
 
920
+ } else if ( renderContextData.lastOcclusionObject !== undefined ) {
921
+
922
+ // invalidate if there is a stale query
923
+
924
+ renderContextData.lastOcclusionObject = undefined;
925
+
926
+ renderContextData.occlusionQuerySet.destroy();
927
+ renderContextData.occlusionQuerySet = undefined;
928
+
825
929
  }
826
930
 
827
931
  let descriptor;
@@ -844,6 +948,13 @@ class WebGPUBackend extends Backend {
844
948
  descriptor.occlusionQuerySet = occlusionQuerySet;
845
949
 
846
950
  const depthStencilAttachment = descriptor.depthStencilAttachment;
951
+ const renderTarget = renderContext.renderTarget;
952
+ const discardColor = renderContext.sampleCount > 1 && renderTarget?.storeMultisampledColorBuffer === false;
953
+ const discardDepth = renderContext.sampleCount > 1 && renderTarget?.storeMultisampledDepthBuffer === false;
954
+ const discardStencil = renderContext.sampleCount > 1 && renderTarget?.storeMultisampledStencilBuffer === false;
955
+
956
+ // A fullscreen pass overwrites the external texture, so its previous contents do not need to be loaded.
957
+ const clearExternalColor = renderContext.fullscreenPass === true && this._hasExternalTexture( renderContext );
847
958
 
848
959
  if ( renderContext.textures !== null ) {
849
960
 
@@ -853,9 +964,15 @@ class WebGPUBackend extends Backend {
853
964
 
854
965
  const colorAttachment = colorAttachments[ i ];
855
966
 
856
- if ( renderContext.clearColor ) {
967
+ if ( renderContext.clearColor || discardColor || clearExternalColor ) {
968
+
969
+ const clearColor = renderContext.mrt ? renderContext.mrt.getClearColor( renderContext.textures[ i ].name ) : null;
970
+
971
+ if ( clearColor !== null ) {
972
+
973
+ colorAttachment.clearValue = clearColor;
857
974
 
858
- if ( i === 0 ) {
975
+ } else if ( i === 0 ) {
859
976
 
860
977
  colorAttachment.clearValue = renderContext.clearColorValue;
861
978
 
@@ -878,7 +995,15 @@ class WebGPUBackend extends Backend {
878
995
 
879
996
  }
880
997
 
881
- colorAttachment.storeOp = GPUStoreOp.Store;
998
+ if ( discardColor ) {
999
+
1000
+ colorAttachment.storeOp = GPUStoreOp.Discard;
1001
+
1002
+ } else {
1003
+
1004
+ colorAttachment.storeOp = GPUStoreOp.Store;
1005
+
1006
+ }
882
1007
 
883
1008
  }
884
1009
 
@@ -905,7 +1030,7 @@ class WebGPUBackend extends Backend {
905
1030
 
906
1031
  if ( renderContext.depth ) {
907
1032
 
908
- if ( renderContext.clearDepth ) {
1033
+ if ( renderContext.clearDepth || discardDepth ) {
909
1034
 
910
1035
  depthStencilAttachment.depthClearValue = renderContext.clearDepthValue;
911
1036
  depthStencilAttachment.depthLoadOp = GPULoadOp.Clear;
@@ -916,13 +1041,21 @@ class WebGPUBackend extends Backend {
916
1041
 
917
1042
  }
918
1043
 
919
- depthStencilAttachment.depthStoreOp = GPUStoreOp.Store;
1044
+ if ( discardDepth ) {
1045
+
1046
+ depthStencilAttachment.depthStoreOp = GPUStoreOp.Discard;
1047
+
1048
+ } else {
1049
+
1050
+ depthStencilAttachment.depthStoreOp = GPUStoreOp.Store;
1051
+
1052
+ }
920
1053
 
921
1054
  }
922
1055
 
923
1056
  if ( renderContext.stencil ) {
924
1057
 
925
- if ( renderContext.clearStencil ) {
1058
+ if ( renderContext.clearStencil || discardStencil ) {
926
1059
 
927
1060
  depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue;
928
1061
  depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear;
@@ -933,7 +1066,15 @@ class WebGPUBackend extends Backend {
933
1066
 
934
1067
  }
935
1068
 
936
- depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store;
1069
+ if ( discardStencil ) {
1070
+
1071
+ depthStencilAttachment.stencilStoreOp = GPUStoreOp.Discard;
1072
+
1073
+ } else {
1074
+
1075
+ depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store;
1076
+
1077
+ }
937
1078
 
938
1079
  }
939
1080
 
@@ -955,40 +1096,22 @@ class WebGPUBackend extends Backend {
955
1096
 
956
1097
  } else {
957
1098
 
958
- this._updateArrayCameraLayerDescriptors( renderContext, renderContextData, cameras );
1099
+ this._updateArrayCameraLayerDescriptors( renderContext, renderContextData, descriptor, cameras );
959
1100
 
960
1101
  }
961
1102
 
962
- // Create bundle encoders for each layer
963
- renderContextData.bundleEncoders = [];
964
- renderContextData.bundleSets = [];
965
-
966
- // Create separate bundle encoders for each camera in the array
967
- for ( let i = 0; i < cameras.length; i ++ ) {
968
-
969
- const bundleEncoder = this.pipelineUtils.createBundleEncoder(
970
- renderContext,
971
- 'renderBundleArrayCamera_' + i
972
- );
973
-
974
- // Initialize state tracking for this bundle
975
- const bundleSets = {
976
- attributes: {},
977
- bindingGroups: [],
978
- pipeline: null,
979
- index: null
980
- };
981
-
982
- renderContextData.bundleEncoders.push( bundleEncoder );
983
- renderContextData.bundleSets.push( bundleSets );
984
-
985
- }
1103
+ this._createArrayCameraBundleEncoders( renderContext, renderContextData );
1104
+ renderContextData.arrayCameraRenderStages = [];
986
1105
 
987
1106
  // We'll complete the bundles in finishRender
988
1107
  renderContextData.currentPass = null;
989
1108
 
990
1109
  } else {
991
1110
 
1111
+ renderContextData.bundleEncoders = undefined;
1112
+ renderContextData.bundleSets = undefined;
1113
+ renderContextData.arrayCameraRenderStages = undefined;
1114
+
992
1115
  const currentPass = encoder.beginRenderPass( descriptor );
993
1116
  renderContextData.currentPass = currentPass;
994
1117
 
@@ -1010,9 +1133,87 @@ class WebGPUBackend extends Backend {
1010
1133
 
1011
1134
  renderContextData.descriptor = descriptor;
1012
1135
  renderContextData.encoder = encoder;
1013
- renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null };
1014
1136
  renderContextData.renderBundles = [];
1015
1137
 
1138
+ this._resetRenderContextData( renderContextData );
1139
+
1140
+ }
1141
+
1142
+ /**
1143
+ * Resets the state cache of the given render context data.
1144
+ *
1145
+ * A new render pass encoder starts with a blend constant and a stencil reference
1146
+ * of zero so the cached values must be reset as well.
1147
+ *
1148
+ * @private
1149
+ * @param {Object} renderContextData - The render context data.
1150
+ */
1151
+ _resetRenderContextData( renderContextData ) {
1152
+
1153
+ renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null };
1154
+
1155
+ if ( renderContextData.currentBlendColor === undefined ) renderContextData.currentBlendColor = new Color();
1156
+
1157
+ renderContextData.currentBlendColor.setRGB( 0, 0, 0 );
1158
+ renderContextData.currentBlendAlpha = 0;
1159
+ renderContextData.currentStencilRef = 0;
1160
+
1161
+ }
1162
+
1163
+ /**
1164
+ * Creates a render bundle encoder and state cache for each camera layer.
1165
+ *
1166
+ * @param {RenderContext} renderContext - The render context.
1167
+ * @param {Object} renderContextData - The render context data.
1168
+ * @private
1169
+ */
1170
+ _createArrayCameraBundleEncoders( renderContext, renderContextData ) {
1171
+
1172
+ const cameras = renderContext.camera.cameras;
1173
+
1174
+ renderContextData.bundleEncoders = [];
1175
+ renderContextData.bundleSets = [];
1176
+
1177
+ for ( let i = 0; i < cameras.length; i ++ ) {
1178
+
1179
+ const bundleEncoder = this.pipelineUtils.createBundleEncoder(
1180
+ renderContext,
1181
+ 'renderBundleArrayCamera_' + i
1182
+ );
1183
+
1184
+ const bundleSets = {
1185
+ attributes: {},
1186
+ bindingGroups: [],
1187
+ pipeline: null,
1188
+ index: null
1189
+ };
1190
+
1191
+ renderContextData.bundleEncoders.push( bundleEncoder );
1192
+ renderContextData.bundleSets.push( bundleSets );
1193
+
1194
+ }
1195
+
1196
+ }
1197
+
1198
+ /**
1199
+ * Finishes the render bundle encoders for all camera layers.
1200
+ *
1201
+ * @param {Object} renderContextData - The render context data.
1202
+ * @return {Array<GPURenderBundle>} The completed render bundles.
1203
+ * @private
1204
+ */
1205
+ _finishArrayCameraBundleEncoders( renderContextData ) {
1206
+
1207
+ const bundles = [];
1208
+
1209
+ for ( const bundleEncoder of renderContextData.bundleEncoders ) {
1210
+
1211
+ bundles.push( bundleEncoder.finish() );
1212
+
1213
+ }
1214
+
1215
+ return bundles;
1216
+
1016
1217
  }
1017
1218
 
1018
1219
  /**
@@ -1040,11 +1241,12 @@ class WebGPUBackend extends Backend {
1040
1241
  for ( let i = 0; i < cameras.length; i ++ ) {
1041
1242
 
1042
1243
  const sourceAttachment = descriptor.colorAttachments[ 0 ];
1244
+ const layerAttachment = descriptor.colorAttachments[ i ];
1043
1245
 
1044
1246
  const layerColorAttachment = new GPURenderPassColorAttachment();
1045
- layerColorAttachment.view = descriptor.colorAttachments[ i ].view;
1046
- layerColorAttachment.depthSlice = sourceAttachment.depthSlice;
1047
- layerColorAttachment.resolveTarget = sourceAttachment.resolveTarget;
1247
+ layerColorAttachment.view = layerAttachment.view;
1248
+ layerColorAttachment.depthSlice = layerAttachment.depthSlice;
1249
+ layerColorAttachment.resolveTarget = layerAttachment.resolveTarget;
1048
1250
  layerColorAttachment.loadOp = sourceAttachment.loadOp;
1049
1251
  layerColorAttachment.storeOp = sourceAttachment.storeOp;
1050
1252
  layerColorAttachment.clearValue = sourceAttachment.clearValue;
@@ -1061,11 +1263,21 @@ class WebGPUBackend extends Backend {
1061
1263
 
1062
1264
  if ( ! depthTextureData.viewCache[ layerIndex ] ) {
1063
1265
 
1064
- _viewDescriptor.dimension = GPUTextureViewDimension.TwoD;
1065
- _viewDescriptor.baseArrayLayer = i;
1066
- _viewDescriptor.arrayLayerCount = 1;
1266
+ const msaaTexture = depthTextureData.msaaTextures?.[ layerIndex ];
1267
+
1268
+ if ( msaaTexture !== undefined ) {
1269
+
1270
+ depthTextureData.viewCache[ layerIndex ] = msaaTexture.createView();
1271
+
1272
+ } else {
1273
+
1274
+ _viewDescriptor.dimension = GPUTextureViewDimension.TwoD;
1275
+ _viewDescriptor.baseArrayLayer = i;
1276
+ _viewDescriptor.arrayLayerCount = 1;
1067
1277
 
1068
- depthTextureData.viewCache[ layerIndex ] = depthTextureData.texture.createView( _viewDescriptor );
1278
+ depthTextureData.viewCache[ layerIndex ] = depthTextureData.texture.createView( _viewDescriptor );
1279
+
1280
+ }
1069
1281
 
1070
1282
  _viewDescriptor.reset();
1071
1283
 
@@ -1114,14 +1326,29 @@ class WebGPUBackend extends Backend {
1114
1326
  *
1115
1327
  * @param {RenderContext} renderContext - The render context.
1116
1328
  * @param {Object} renderContextData - The render context data.
1329
+ * @param {Object} descriptor - The render pass descriptor.
1117
1330
  * @param {ArrayCamera} cameras - The array camera.
1118
1331
  *
1119
1332
  */
1120
- _updateArrayCameraLayerDescriptors( renderContext, renderContextData, cameras ) {
1333
+ _updateArrayCameraLayerDescriptors( renderContext, renderContextData, descriptor, cameras ) {
1334
+
1335
+ const renderTarget = renderContext.renderTarget;
1336
+ const discardDepth = renderContext.sampleCount > 1 && renderTarget?.storeMultisampledDepthBuffer === false;
1337
+ const discardStencil = renderContext.sampleCount > 1 && renderTarget?.storeMultisampledStencilBuffer === false;
1121
1338
 
1122
1339
  for ( let i = 0; i < cameras.length; i ++ ) {
1123
1340
 
1124
1341
  const layerDescriptor = renderContextData.layerDescriptors[ i ];
1342
+ const sourceColorAttachment = descriptor.colorAttachments[ 0 ];
1343
+ const layerColorAttachment = descriptor.colorAttachments[ i ];
1344
+ const colorAttachment = layerDescriptor.colorAttachments[ 0 ];
1345
+
1346
+ colorAttachment.view = layerColorAttachment.view;
1347
+ colorAttachment.resolveTarget = layerColorAttachment.resolveTarget;
1348
+ colorAttachment.depthSlice = layerColorAttachment.depthSlice;
1349
+ colorAttachment.loadOp = sourceColorAttachment.loadOp;
1350
+ colorAttachment.storeOp = sourceColorAttachment.storeOp;
1351
+ colorAttachment.clearValue = sourceColorAttachment.clearValue;
1125
1352
 
1126
1353
  if ( layerDescriptor.depthStencilAttachment ) {
1127
1354
 
@@ -1129,7 +1356,7 @@ class WebGPUBackend extends Backend {
1129
1356
 
1130
1357
  if ( renderContext.depth ) {
1131
1358
 
1132
- if ( renderContext.clearDepth ) {
1359
+ if ( renderContext.clearDepth || discardDepth ) {
1133
1360
 
1134
1361
  depthAttachment.depthClearValue = renderContext.clearDepthValue;
1135
1362
  depthAttachment.depthLoadOp = GPULoadOp.Clear;
@@ -1144,7 +1371,7 @@ class WebGPUBackend extends Backend {
1144
1371
 
1145
1372
  if ( renderContext.stencil ) {
1146
1373
 
1147
- if ( renderContext.clearStencil ) {
1374
+ if ( renderContext.clearStencil || discardStencil ) {
1148
1375
 
1149
1376
  depthAttachment.stencilClearValue = renderContext.clearStencilValue;
1150
1377
  depthAttachment.stencilLoadOp = GPULoadOp.Clear;
@@ -1180,7 +1407,9 @@ class WebGPUBackend extends Backend {
1180
1407
 
1181
1408
  }
1182
1409
 
1183
- if ( occlusionQueryCount > renderContextData.occlusionQueryIndex ) {
1410
+ const lastOcclusionObject = renderContextData.lastOcclusionObject;
1411
+
1412
+ if ( lastOcclusionObject && lastOcclusionObject.occlusionTest === true ) {
1184
1413
 
1185
1414
  renderContextData.currentPass.endOcclusionQuery();
1186
1415
 
@@ -1192,20 +1421,49 @@ class WebGPUBackend extends Backend {
1192
1421
 
1193
1422
  if ( this._isRenderCameraDepthArray( renderContext ) === true ) {
1194
1423
 
1195
- const bundles = [];
1424
+ const bundles = this._finishArrayCameraBundleEncoders( renderContextData );
1425
+ const renderStages = renderContextData.arrayCameraRenderStages;
1426
+ renderStages.push( { bundles } );
1196
1427
 
1197
- for ( let i = 0; i < renderContextData.bundleEncoders.length; i ++ ) {
1428
+ // A viewport texture is 2D, so each layer must be captured immediately before that layer samples it.
1429
+ for ( let i = 0; i < renderContextData.layerDescriptors.length; i ++ ) {
1198
1430
 
1199
- const bundleEncoder = renderContextData.bundleEncoders[ i ];
1200
- bundles.push( bundleEncoder.finish() );
1431
+ const layerDescriptor = renderContextData.layerDescriptors[ i ];
1432
+ const colorLoadOps = layerDescriptor.colorAttachments.map( attachment => attachment.loadOp );
1433
+ const colorStoreOps = layerDescriptor.colorAttachments.map( attachment => attachment.storeOp );
1434
+ const depthLoadOp = layerDescriptor.depthStencilAttachment?.depthLoadOp;
1435
+ const depthStoreOp = layerDescriptor.depthStencilAttachment?.depthStoreOp;
1436
+ const stencilLoadOp = layerDescriptor.depthStencilAttachment?.stencilLoadOp;
1437
+ const stencilStoreOp = layerDescriptor.depthStencilAttachment?.stencilStoreOp;
1201
1438
 
1202
- }
1439
+ for ( let stageIndex = 0; stageIndex < renderStages.length; stageIndex ++ ) {
1440
+
1441
+ const renderStage = renderStages[ stageIndex ];
1442
+ const bundle = renderStage.bundles[ i ];
1443
+ const isLastStage = stageIndex === renderStages.length - 1;
1444
+
1445
+ for ( let j = 0; j < layerDescriptor.colorAttachments.length; j ++ ) {
1446
+
1447
+ const attachment = layerDescriptor.colorAttachments[ j ];
1448
+ attachment.loadOp = stageIndex === 0 ? colorLoadOps[ j ] : GPULoadOp.Load;
1449
+ attachment.storeOp = isLastStage ? colorStoreOps[ j ] : GPUStoreOp.Store;
1450
+
1451
+ }
1452
+
1453
+ if ( renderContext.depth ) {
1454
+
1455
+ layerDescriptor.depthStencilAttachment.depthLoadOp = stageIndex === 0 ? depthLoadOp : GPULoadOp.Load;
1456
+ layerDescriptor.depthStencilAttachment.depthStoreOp = isLastStage ? depthStoreOp : GPUStoreOp.Store;
1457
+
1458
+ }
1203
1459
 
1204
- for ( let i = 0; i < renderContextData.layerDescriptors.length; i ++ ) {
1460
+ if ( renderContext.stencil ) {
1205
1461
 
1206
- if ( i < bundles.length ) {
1462
+ layerDescriptor.depthStencilAttachment.stencilLoadOp = stageIndex === 0 ? stencilLoadOp : GPULoadOp.Load;
1463
+ layerDescriptor.depthStencilAttachment.stencilStoreOp = isLastStage ? stencilStoreOp : GPUStoreOp.Store;
1464
+
1465
+ }
1207
1466
 
1208
- const layerDescriptor = renderContextData.layerDescriptors[ i ];
1209
1467
  const renderPass = encoder.beginRenderPass( layerDescriptor );
1210
1468
 
1211
1469
  if ( renderContext.viewport ) {
@@ -1222,10 +1480,39 @@ class WebGPUBackend extends Backend {
1222
1480
 
1223
1481
  }
1224
1482
 
1225
- renderPass.executeBundles( [ bundles[ i ] ] );
1483
+ renderPass.executeBundles( [ bundle ] );
1226
1484
 
1227
1485
  renderPass.end();
1228
1486
 
1487
+ if ( renderStage.framebufferCopy !== undefined ) {
1488
+
1489
+ const { texture, sourceGPU, destinationGPU, rectangle, generateMipmaps } = renderStage.framebufferCopy;
1490
+
1491
+ this._copyFramebufferToTexture( encoder, texture, sourceGPU, destinationGPU, rectangle, i, generateMipmaps );
1492
+
1493
+ }
1494
+
1495
+ }
1496
+
1497
+ for ( let j = 0; j < layerDescriptor.colorAttachments.length; j ++ ) {
1498
+
1499
+ layerDescriptor.colorAttachments[ j ].loadOp = colorLoadOps[ j ];
1500
+ layerDescriptor.colorAttachments[ j ].storeOp = colorStoreOps[ j ];
1501
+
1502
+ }
1503
+
1504
+ if ( renderContext.depth ) {
1505
+
1506
+ layerDescriptor.depthStencilAttachment.depthLoadOp = depthLoadOp;
1507
+ layerDescriptor.depthStencilAttachment.depthStoreOp = depthStoreOp;
1508
+
1509
+ }
1510
+
1511
+ if ( renderContext.stencil ) {
1512
+
1513
+ layerDescriptor.depthStencilAttachment.stencilLoadOp = stencilLoadOp;
1514
+ layerDescriptor.depthStencilAttachment.stencilStoreOp = stencilStoreOp;
1515
+
1229
1516
  }
1230
1517
 
1231
1518
  }
@@ -1349,9 +1636,11 @@ class WebGPUBackend extends Backend {
1349
1636
 
1350
1637
  for ( let i = 0; i < currentOcclusionQueryObjects.length; i ++ ) {
1351
1638
 
1352
- if ( results[ i ] === BigInt( 0 ) ) {
1639
+ const object = currentOcclusionQueryObjects[ i ];
1353
1640
 
1354
- occluded.add( currentOcclusionQueryObjects[ i ] );
1641
+ if ( object !== undefined && results[ i ] === BigInt( 0 ) ) {
1642
+
1643
+ occluded.add( object );
1355
1644
 
1356
1645
  }
1357
1646
 
@@ -1728,8 +2017,9 @@ class WebGPUBackend extends Backend {
1728
2017
  * @param {{vertexCount: number, firstVertex: number, instanceCount: number, firstInstance: number}} drawParams - The draw parameters.
1729
2018
  * @param {GPURenderPassEncoder|GPURenderBundleEncoder} passEncoderGPU - The GPU pass encoder used for recording draw commands.
1730
2019
  * @param {Object} currentSets - Tracking object for currently set pipeline, attributes, bind groups, and index state.
2020
+ * @param {number} [cameraIndexSlot=-1] - Index of the binding slot holding the camera index bind group.
1731
2021
  */
1732
- _draw( renderObject, info, renderContextData, pipelineGPU, bindings, vertexBuffers, drawParams, passEncoderGPU, currentSets ) {
2022
+ _draw( renderObject, info, renderContextData, pipelineGPU, bindings, vertexBuffers, drawParams, passEncoderGPU, currentSets, cameraIndexSlot = - 1 ) {
1733
2023
 
1734
2024
  const { object, material, context } = renderObject;
1735
2025
 
@@ -1751,14 +2041,19 @@ class WebGPUBackend extends Backend {
1751
2041
 
1752
2042
  for ( let i = 0, l = bindings.length; i < l; i ++ ) {
1753
2043
 
1754
- const bindGroup = bindings[ i ];
2044
+ // the camera index slot is bound per sub-camera in draw()
2045
+
2046
+ if ( i === cameraIndexSlot ) continue;
1755
2047
 
1756
- if ( currentBindingGroups[ i ] !== bindGroup.id ) {
2048
+ // compare native bind groups
2049
+
2050
+ const bindGroup = bindings[ i ];
2051
+ const bindGroupGPU = this.get( bindGroup ).group;
1757
2052
 
1758
- const bindingsData = this.get( bindGroup );
2053
+ if ( currentBindingGroups[ i ] !== bindGroupGPU ) {
1759
2054
 
1760
- passEncoderGPU.setBindGroup( i, bindingsData.group );
1761
- currentBindingGroups[ i ] = bindGroup.id;
2055
+ passEncoderGPU.setBindGroup( i, bindGroupGPU );
2056
+ currentBindingGroups[ i ] = bindGroupGPU;
1762
2057
 
1763
2058
  }
1764
2059
 
@@ -1806,20 +2101,36 @@ class WebGPUBackend extends Backend {
1806
2101
 
1807
2102
  }
1808
2103
 
1809
- if ( object.isBatchedMesh === true ) {
2104
+ // blend constant
1810
2105
 
1811
- const starts = object._multiDrawStarts;
1812
- const counts = object._multiDrawCounts;
1813
- const drawCount = object._multiDrawCount;
2106
+ if ( material.blending === CustomBlending && passEncoderGPU.setBlendConstant !== undefined ) {
1814
2107
 
1815
- let bytesPerElement = ( hasIndex === true ) ? index.array.BYTES_PER_ELEMENT : 1;
2108
+ const blendColor = material.blendColor;
2109
+ const blendAlpha = material.blendAlpha;
1816
2110
 
1817
- if ( material.wireframe ) {
2111
+ if ( blendColor.equals( renderContextData.currentBlendColor ) === false || blendAlpha !== renderContextData.currentBlendAlpha ) {
1818
2112
 
1819
- bytesPerElement = object.geometry.attributes.position.count > 65535 ? 4 : 2;
2113
+ _blendConstant.r = blendColor.r;
2114
+ _blendConstant.g = blendColor.g;
2115
+ _blendConstant.b = blendColor.b;
2116
+ _blendConstant.a = blendAlpha;
2117
+
2118
+ passEncoderGPU.setBlendConstant( _blendConstant );
2119
+
2120
+ renderContextData.currentBlendColor.copy( blendColor );
2121
+ renderContextData.currentBlendAlpha = blendAlpha;
1820
2122
 
1821
2123
  }
1822
2124
 
2125
+ }
2126
+
2127
+ if ( object.isBatchedMesh === true ) {
2128
+
2129
+ const starts = object._multiDrawStarts;
2130
+ const counts = object._multiDrawCounts;
2131
+ const drawCount = object._multiDrawCount;
2132
+ const bytesPerElement = object._multiDrawBytesPerElement;
2133
+
1823
2134
  for ( let i = 0; i < drawCount; i ++ ) {
1824
2135
 
1825
2136
  if ( hasIndex === true ) {
@@ -1949,7 +2260,9 @@ class WebGPUBackend extends Backend {
1949
2260
 
1950
2261
  }
1951
2262
 
1952
- const pixelRatio = this.renderer.getPixelRatio();
2263
+ const renderTarget = context.renderTarget;
2264
+ const pixelRatio = ( renderTarget === null || renderTarget.isPostProcessingRenderTarget === true ) ? this.renderer.getPixelRatio() : 1;
2265
+ const indexPos = cameraIndex ? bindings.indexOf( cameraIndex ) : - 1;
1953
2266
 
1954
2267
  for ( let i = 0, len = cameras.length; i < len; i ++ ) {
1955
2268
 
@@ -1987,15 +2300,20 @@ class WebGPUBackend extends Backend {
1987
2300
  }
1988
2301
 
1989
2302
  // Set camera index binding for this layer
1990
- if ( cameraIndex && cameraData.indexesGPU ) {
2303
+ if ( indexPos !== - 1 && cameraData.indexesGPU ) {
2304
+
2305
+ const cameraIndexGPU = cameraData.indexesGPU[ i ];
1991
2306
 
1992
- const indexPos = bindings.indexOf( cameraIndex );
1993
- pass.setBindGroup( indexPos, cameraData.indexesGPU[ i ] );
1994
- sets.bindingGroups[ indexPos ] = cameraIndex.id;
2307
+ if ( sets.bindingGroups[ indexPos ] !== cameraIndexGPU ) {
2308
+
2309
+ pass.setBindGroup( indexPos, cameraIndexGPU );
2310
+ sets.bindingGroups[ indexPos ] = cameraIndexGPU;
2311
+
2312
+ }
1995
2313
 
1996
2314
  }
1997
2315
 
1998
- this._draw( renderObject, info, renderContextData, pipelineGPU, bindings, vertexBuffers, drawParams, pass, sets );
2316
+ this._draw( renderObject, info, renderContextData, pipelineGPU, bindings, vertexBuffers, drawParams, pass, sets, indexPos );
1999
2317
 
2000
2318
  }
2001
2319
 
@@ -2007,7 +2325,16 @@ class WebGPUBackend extends Backend {
2007
2325
  if ( renderContextData.currentPass ) {
2008
2326
 
2009
2327
  // Handle occlusion queries
2010
- if ( renderContextData.occlusionQuerySet !== undefined ) {
2328
+
2329
+ if ( renderContextData.currentPass instanceof GPURenderBundleEncoder ) {
2330
+
2331
+ if ( object.occlusionTest === true ) {
2332
+
2333
+ warnOnce( 'WebGPUBackend: Occlusion queries can not be recorded into render bundles.' );
2334
+
2335
+ }
2336
+
2337
+ } else if ( renderContextData.occlusionQuerySet !== undefined ) {
2011
2338
 
2012
2339
  const lastObject = renderContextData.lastOcclusionObject;
2013
2340
  if ( lastObject !== object ) {
@@ -2073,6 +2400,7 @@ class WebGPUBackend extends Backend {
2073
2400
  data.stencilWrite !== material.stencilWrite || data.stencilFunc !== material.stencilFunc ||
2074
2401
  data.stencilFail !== material.stencilFail || data.stencilZFail !== material.stencilZFail || data.stencilZPass !== material.stencilZPass ||
2075
2402
  data.stencilFuncMask !== material.stencilFuncMask || data.stencilWriteMask !== material.stencilWriteMask ||
2403
+ data.polygonOffset !== material.polygonOffset || data.polygonOffsetFactor !== material.polygonOffsetFactor || data.polygonOffsetUnits !== material.polygonOffsetUnits ||
2076
2404
  data.side !== material.side || data.alphaToCoverage !== material.alphaToCoverage ||
2077
2405
  data.sampleCount !== sampleCount || data.colorSpace !== colorSpace ||
2078
2406
  data.colorFormat !== colorFormat || data.depthStencilFormat !== depthStencilFormat ||
@@ -2090,6 +2418,7 @@ class WebGPUBackend extends Backend {
2090
2418
  data.stencilWrite = material.stencilWrite; data.stencilFunc = material.stencilFunc;
2091
2419
  data.stencilFail = material.stencilFail; data.stencilZFail = material.stencilZFail; data.stencilZPass = material.stencilZPass;
2092
2420
  data.stencilFuncMask = material.stencilFuncMask; data.stencilWriteMask = material.stencilWriteMask;
2421
+ data.polygonOffset = material.polygonOffset; data.polygonOffsetFactor = material.polygonOffsetFactor; data.polygonOffsetUnits = material.polygonOffsetUnits;
2093
2422
  data.side = material.side; data.alphaToCoverage = material.alphaToCoverage;
2094
2423
  data.sampleCount = sampleCount;
2095
2424
  data.colorSpace = colorSpace;
@@ -2134,7 +2463,8 @@ class WebGPUBackend extends Backend {
2134
2463
  material.stencilWrite, material.stencilFunc,
2135
2464
  material.stencilFail, material.stencilZFail, material.stencilZPass,
2136
2465
  material.stencilFuncMask, material.stencilWriteMask,
2137
- material.side,
2466
+ material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits,
2467
+ material.side, material.alphaToCoverage,
2138
2468
  frontFaceCW,
2139
2469
  utils.getSampleCountRenderContext( renderContext ),
2140
2470
  utils.getCurrentColorSpace( renderContext ), utils.getCurrentColorFormat( renderContext ), utils.getCurrentDepthStencilFormat( renderContext ),
@@ -2239,7 +2569,7 @@ class WebGPUBackend extends Backend {
2239
2569
  * @param {number} y - The y coordinate of the copy origin.
2240
2570
  * @param {number} width - The width of the copy.
2241
2571
  * @param {number} height - The height of the copy.
2242
- * @param {number} faceIndex - The face index.
2572
+ * @param {number} faceIndex - The cube face, depth slice or array layer index.
2243
2573
  * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished.
2244
2574
  */
2245
2575
  async copyTextureToBuffer( texture, x, y, width, height, faceIndex ) {
@@ -2367,10 +2697,11 @@ class WebGPUBackend extends Backend {
2367
2697
  *
2368
2698
  * @param {ComputePipeline} computePipeline - The compute pipeline.
2369
2699
  * @param {Array<BindGroup>} bindings - The bindings.
2700
+ * @param {?Array<Promise>} [promises=null] - Optional compilation promises.
2370
2701
  */
2371
- createComputePipeline( computePipeline, bindings ) {
2702
+ createComputePipeline( computePipeline, bindings, promises = null ) {
2372
2703
 
2373
- this.pipelineUtils.createComputePipeline( computePipeline, bindings );
2704
+ this.pipelineUtils.createComputePipeline( computePipeline, bindings, promises );
2374
2705
 
2375
2706
  }
2376
2707
 
@@ -2410,6 +2741,8 @@ class WebGPUBackend extends Backend {
2410
2741
 
2411
2742
  renderContextData.currentSets = renderContextData._currentSets;
2412
2743
  renderContextData.currentPass = renderContextData._currentPass;
2744
+ renderContextData._currentPass = null;
2745
+ renderContextData._currentSets = null;
2413
2746
 
2414
2747
  }
2415
2748
 
@@ -2500,12 +2833,12 @@ class WebGPUBackend extends Backend {
2500
2833
  *
2501
2834
  * @param {BindGroup} bindGroup - The bind group.
2502
2835
  * @param {Array<BindGroup>} bindings - Array of bind groups.
2503
- * @param {number} cacheIndex - The cache index.
2836
+ * @param {string} cacheKey - The cache key.
2504
2837
  * @param {number} version - The version.
2505
2838
  */
2506
- createBindings( bindGroup, bindings, cacheIndex, version ) {
2839
+ createBindings( bindGroup, bindings, cacheKey, version ) {
2507
2840
 
2508
- this.bindingUtils.createBindings( bindGroup, bindings, cacheIndex, version );
2841
+ this.bindingUtils.createBindings( bindGroup, bindings, cacheKey, version );
2509
2842
 
2510
2843
  }
2511
2844
 
@@ -2514,12 +2847,12 @@ class WebGPUBackend extends Backend {
2514
2847
  *
2515
2848
  * @param {BindGroup} bindGroup - The bind group.
2516
2849
  * @param {Array<BindGroup>} bindings - Array of bind groups.
2517
- * @param {number} cacheIndex - The cache index.
2850
+ * @param {string} cacheKey - The cache key.
2518
2851
  * @param {number} version - The version.
2519
2852
  */
2520
- updateBindings( bindGroup, bindings, cacheIndex, version ) {
2853
+ updateBindings( bindGroup, bindings, cacheKey, version ) {
2521
2854
 
2522
- this.bindingUtils.createBindings( bindGroup, bindings, cacheIndex, version );
2855
+ this.bindingUtils.createBindings( bindGroup, bindings, cacheKey, version );
2523
2856
 
2524
2857
  }
2525
2858
 
@@ -2798,6 +3131,29 @@ class WebGPUBackend extends Backend {
2798
3131
 
2799
3132
  }
2800
3133
 
3134
+ if ( this._isRenderCameraDepthArray( renderContext ) === true ) {
3135
+
3136
+ // Layered draws are only executed in finishRender(), so preserve this copy as a render-stage boundary.
3137
+ const bundles = this._finishArrayCameraBundleEncoders( renderContextData );
3138
+
3139
+ renderContextData.arrayCameraRenderStages.push( {
3140
+ bundles,
3141
+ framebufferCopy: {
3142
+ texture,
3143
+ sourceGPU,
3144
+ destinationGPU,
3145
+ rectangle: { x: rectangle.x, y: rectangle.y, z: rectangle.z, w: rectangle.w },
3146
+ // ViewportTextureNode restores this flag before the deferred copy executes.
3147
+ generateMipmaps: texture.generateMipmaps
3148
+ }
3149
+ } );
3150
+
3151
+ this._createArrayCameraBundleEncoders( renderContext, renderContextData );
3152
+
3153
+ return;
3154
+
3155
+ }
3156
+
2801
3157
  let encoder;
2802
3158
 
2803
3159
  if ( renderContextData.currentPass ) {
@@ -2814,33 +3170,10 @@ class WebGPUBackend extends Backend {
2814
3170
 
2815
3171
  }
2816
3172
 
2817
- _texelCopyTextureInfoSrc.texture = sourceGPU;
2818
- _texelCopyTextureInfoSrc.origin.x = rectangle.x;
2819
- _texelCopyTextureInfoSrc.origin.y = rectangle.y;
2820
-
2821
- _texelCopyTextureInfoDst.texture = destinationGPU;
2822
-
2823
- _extent3D.width = rectangle.z;
2824
- _extent3D.height = rectangle.w;
2825
-
2826
- encoder.copyTextureToTexture(
2827
- _texelCopyTextureInfoSrc,
2828
- _texelCopyTextureInfoDst,
2829
- _extent3D
2830
- );
2831
-
2832
- _texelCopyTextureInfoSrc.reset();
2833
- _texelCopyTextureInfoDst.reset();
2834
- _extent3D.reset();
2835
-
2836
3173
  // mipmaps must be genereated with the same encoder otherwise the copied texture data
2837
3174
  // might be out-of-sync, see #31768
2838
3175
 
2839
- if ( texture.generateMipmaps ) {
2840
-
2841
- this.textureUtils.generateMipmaps( texture, encoder );
2842
-
2843
- }
3176
+ this._copyFramebufferToTexture( encoder, texture, sourceGPU, destinationGPU, rectangle );
2844
3177
 
2845
3178
  if ( renderContextData.currentPass ) {
2846
3179
 
@@ -2867,7 +3200,8 @@ class WebGPUBackend extends Backend {
2867
3200
  // !WITH_GENESYS
2868
3201
 
2869
3202
  renderContextData.currentPass = encoder.beginRenderPass( descriptor );
2870
- renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null };
3203
+
3204
+ this._resetRenderContextData( renderContextData );
2871
3205
 
2872
3206
  if ( renderContext.viewport ) {
2873
3207
 
@@ -2889,6 +3223,48 @@ class WebGPUBackend extends Backend {
2889
3223
 
2890
3224
  }
2891
3225
 
3226
+ /**
3227
+ * Encodes a framebuffer copy from a specific texture-array layer.
3228
+ *
3229
+ * @param {GPUCommandEncoder} encoder - The command encoder.
3230
+ * @param {Texture} texture - The destination texture.
3231
+ * @param {GPUTexture} sourceGPU - The source GPU texture.
3232
+ * @param {GPUTexture} destinationGPU - The destination GPU texture.
3233
+ * @param {Object} rectangle - The source rectangle.
3234
+ * @param {number} [sourceLayer=0] - The source array layer.
3235
+ * @param {boolean} [generateMipmaps=texture.generateMipmaps] - Whether mipmaps should be generated.
3236
+ * @private
3237
+ */
3238
+ _copyFramebufferToTexture( encoder, texture, sourceGPU, destinationGPU, rectangle, sourceLayer = 0, generateMipmaps = texture.generateMipmaps ) {
3239
+
3240
+ _texelCopyTextureInfoSrc.texture = sourceGPU;
3241
+ _texelCopyTextureInfoSrc.origin.x = rectangle.x;
3242
+ _texelCopyTextureInfoSrc.origin.y = rectangle.y;
3243
+ _texelCopyTextureInfoSrc.origin.z = sourceLayer;
3244
+
3245
+ _texelCopyTextureInfoDst.texture = destinationGPU;
3246
+
3247
+ _extent3D.width = rectangle.z;
3248
+ _extent3D.height = rectangle.w;
3249
+
3250
+ encoder.copyTextureToTexture(
3251
+ _texelCopyTextureInfoSrc,
3252
+ _texelCopyTextureInfoDst,
3253
+ _extent3D
3254
+ );
3255
+
3256
+ _texelCopyTextureInfoSrc.reset();
3257
+ _texelCopyTextureInfoDst.reset();
3258
+ _extent3D.reset();
3259
+
3260
+ if ( generateMipmaps ) {
3261
+
3262
+ this.textureUtils.generateMipmaps( texture, encoder );
3263
+
3264
+ }
3265
+
3266
+ }
3267
+
2892
3268
  /**
2893
3269
  * Checks if the given compatibility is supported by the backend.
2894
3270
  *
@@ -2907,7 +3283,9 @@ class WebGPUBackend extends Backend {
2907
3283
 
2908
3284
  }
2909
3285
 
2910
- dispose() {
3286
+ async dispose() {
3287
+
3288
+ await super.dispose();
2911
3289
 
2912
3290
  this.bindingUtils.dispose();
2913
3291
  this.textureUtils.dispose();
@@ -2924,16 +3302,6 @@ class WebGPUBackend extends Backend {
2924
3302
 
2925
3303
  }
2926
3304
 
2927
- if ( this.timestampQueryPool ) {
2928
-
2929
- for ( const queryPool of Object.values( this.timestampQueryPool ) ) {
2930
-
2931
- if ( queryPool !== null ) queryPool.dispose();
2932
-
2933
- }
2934
-
2935
- }
2936
-
2937
3305
  if ( this.parameters.device === undefined && this.device !== null ) {
2938
3306
 
2939
3307
  this.device.destroy();