@plastic-software/three 0.178.0 → 0.180.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 (245) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +950 -230
  3. package/build/three.core.js +754 -138
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +197 -96
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +99 -25
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +4586 -1499
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +4544 -1499
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/jsm/Addons.js +2 -3
  14. package/examples/jsm/capabilities/WebGPU.js +1 -1
  15. package/examples/jsm/controls/ArcballControls.js +7 -7
  16. package/examples/jsm/controls/DragControls.js +6 -56
  17. package/examples/jsm/controls/FirstPersonControls.js +2 -2
  18. package/examples/jsm/controls/PointerLockControls.js +0 -8
  19. package/examples/jsm/csm/CSMShadowNode.js +4 -4
  20. package/examples/jsm/environments/RoomEnvironment.js +8 -3
  21. package/examples/jsm/exporters/GLTFExporter.js +30 -22
  22. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  23. package/examples/jsm/exporters/PLYExporter.js +1 -1
  24. package/examples/jsm/exporters/USDZExporter.js +676 -299
  25. package/examples/jsm/geometries/RoundedBoxGeometry.js +47 -8
  26. package/examples/jsm/interactive/HTMLMesh.js +5 -3
  27. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  28. package/examples/jsm/libs/meshopt_decoder.module.js +75 -58
  29. package/examples/jsm/lights/LightProbeGenerator.js +14 -3
  30. package/examples/jsm/lines/Line2.js +3 -3
  31. package/examples/jsm/lines/LineGeometry.js +1 -1
  32. package/examples/jsm/lines/LineSegments2.js +2 -2
  33. package/examples/jsm/lines/Wireframe.js +2 -2
  34. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  35. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  36. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  37. package/examples/jsm/loaders/ColladaLoader.js +1 -1
  38. package/examples/jsm/loaders/EXRLoader.js +210 -22
  39. package/examples/jsm/loaders/FBXLoader.js +1 -1
  40. package/examples/jsm/loaders/GLTFLoader.js +9 -5
  41. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  42. package/examples/jsm/loaders/HDRLoader.js +486 -0
  43. package/examples/jsm/loaders/KTX2Loader.js +112 -32
  44. package/examples/jsm/loaders/MaterialXLoader.js +212 -30
  45. package/examples/jsm/loaders/RGBELoader.js +7 -473
  46. package/examples/jsm/loaders/TTFLoader.js +13 -1
  47. package/examples/jsm/loaders/USDLoader.js +219 -0
  48. package/examples/jsm/loaders/USDZLoader.js +4 -892
  49. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  50. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  51. package/examples/jsm/loaders/usd/USDAParser.js +741 -0
  52. package/examples/jsm/loaders/usd/USDCParser.js +17 -0
  53. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  54. package/examples/jsm/math/ColorSpaces.js +19 -1
  55. package/examples/jsm/math/ConvexHull.js +2 -2
  56. package/examples/jsm/math/Lut.js +2 -2
  57. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  58. package/examples/jsm/misc/ProgressiveLightMap.js +1 -1
  59. package/examples/jsm/misc/Volume.js +1 -1
  60. package/examples/jsm/objects/LensflareMesh.js +3 -3
  61. package/examples/jsm/objects/SkyMesh.js +2 -2
  62. package/examples/jsm/physics/RapierPhysics.js +14 -5
  63. package/examples/jsm/postprocessing/GTAOPass.js +10 -9
  64. package/examples/jsm/postprocessing/OutlinePass.js +17 -17
  65. package/examples/jsm/postprocessing/SSAOPass.js +10 -9
  66. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  67. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +11 -2
  68. package/examples/jsm/transpiler/GLSLDecoder.js +23 -20
  69. package/examples/jsm/transpiler/TSLEncoder.js +2 -10
  70. package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
  71. package/examples/jsm/tsl/display/AnamorphicNode.js +27 -4
  72. package/examples/jsm/tsl/display/BloomNode.js +7 -6
  73. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
  74. package/examples/jsm/tsl/display/DepthOfFieldNode.js +439 -90
  75. package/examples/jsm/tsl/display/GTAONode.js +8 -0
  76. package/examples/jsm/tsl/display/GaussianBlurNode.js +51 -41
  77. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  78. package/examples/jsm/tsl/display/SSRNode.js +180 -65
  79. package/examples/jsm/tsl/display/{TRAAPassNode.js → TRAANode.js} +181 -172
  80. package/examples/jsm/tsl/display/boxBlur.js +64 -0
  81. package/examples/jsm/tsl/display/hashBlur.js +15 -18
  82. package/examples/jsm/tsl/lighting/TiledLightsNode.js +1 -1
  83. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  84. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  85. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  86. package/package.json +1 -1
  87. package/src/Three.Core.js +2 -0
  88. package/src/Three.TSL.js +98 -24
  89. package/src/animation/AnimationClip.js +17 -2
  90. package/src/animation/KeyframeTrack.js +1 -1
  91. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  92. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  93. package/src/cameras/Camera.js +14 -0
  94. package/src/cameras/OrthographicCamera.js +1 -1
  95. package/src/cameras/PerspectiveCamera.js +1 -1
  96. package/src/constants.js +11 -3
  97. package/src/core/BufferGeometry.js +2 -2
  98. package/{examples/jsm/misc → src/core}/Timer.js +4 -42
  99. package/src/extras/PMREMGenerator.js +11 -0
  100. package/src/extras/TextureUtils.js +2 -1
  101. package/src/extras/lib/earcut.js +1 -1
  102. package/src/helpers/CameraHelper.js +41 -11
  103. package/src/helpers/SkeletonHelper.js +35 -6
  104. package/src/lights/LightShadow.js +21 -8
  105. package/src/lights/PointLightShadow.js +1 -1
  106. package/src/lights/webgpu/ProjectorLight.js +1 -1
  107. package/src/loaders/FileLoader.js +25 -2
  108. package/src/loaders/ImageBitmapLoader.js +23 -0
  109. package/src/loaders/Loader.js +14 -0
  110. package/src/loaders/LoadingManager.js +23 -0
  111. package/src/materials/Material.js +12 -0
  112. package/src/materials/MeshBasicMaterial.js +1 -1
  113. package/src/materials/MeshDistanceMaterial.js +1 -1
  114. package/src/materials/nodes/Line2NodeMaterial.js +0 -8
  115. package/src/materials/nodes/NodeMaterial.js +1 -1
  116. package/src/materials/nodes/PointsNodeMaterial.js +86 -28
  117. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  118. package/src/materials/nodes/manager/NodeMaterialObserver.js +87 -2
  119. package/src/math/ColorManagement.js +7 -1
  120. package/src/math/Frustum.js +19 -8
  121. package/src/math/FrustumArray.js +10 -5
  122. package/src/math/Line3.js +129 -2
  123. package/src/math/Matrix4.js +48 -27
  124. package/src/math/Spherical.js +2 -2
  125. package/src/nodes/Nodes.js +4 -0
  126. package/src/nodes/TSL.js +4 -0
  127. package/src/nodes/accessors/BufferNode.js +1 -1
  128. package/src/nodes/accessors/Camera.js +142 -16
  129. package/src/nodes/accessors/ClippingNode.js +6 -5
  130. package/src/nodes/accessors/CubeTextureNode.js +2 -2
  131. package/src/nodes/accessors/InstanceNode.js +3 -1
  132. package/src/nodes/accessors/Normal.js +11 -11
  133. package/src/nodes/accessors/Object3DNode.js +1 -1
  134. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  135. package/src/nodes/accessors/ReferenceNode.js +19 -4
  136. package/src/nodes/accessors/SceneNode.js +1 -1
  137. package/src/nodes/accessors/StorageTextureNode.js +1 -1
  138. package/src/nodes/accessors/Texture3DNode.js +13 -0
  139. package/src/nodes/accessors/TextureNode.js +83 -19
  140. package/src/nodes/code/FunctionCallNode.js +19 -0
  141. package/src/nodes/code/FunctionNode.js +23 -0
  142. package/src/nodes/core/ArrayNode.js +12 -0
  143. package/src/nodes/core/AssignNode.js +6 -2
  144. package/src/nodes/core/ContextNode.js +44 -1
  145. package/src/nodes/core/Node.js +30 -22
  146. package/src/nodes/core/NodeBuilder.js +71 -32
  147. package/src/nodes/core/NodeFrame.js +1 -1
  148. package/src/nodes/core/NodeUniform.js +1 -1
  149. package/src/nodes/core/NodeUtils.js +5 -3
  150. package/src/nodes/core/StackNode.js +71 -4
  151. package/src/nodes/core/StructNode.js +5 -5
  152. package/src/nodes/core/StructTypeNode.js +1 -0
  153. package/src/nodes/core/SubBuildNode.js +2 -2
  154. package/src/nodes/core/UniformNode.js +79 -14
  155. package/src/nodes/core/VarNode.js +83 -15
  156. package/src/nodes/display/FrontFacingNode.js +4 -8
  157. package/src/nodes/display/PassNode.js +148 -2
  158. package/src/nodes/display/ScreenNode.js +42 -13
  159. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  160. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  161. package/src/nodes/display/ViewportTextureNode.js +94 -4
  162. package/src/nodes/functions/PhysicalLightingModel.js +2 -2
  163. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  164. package/src/nodes/gpgpu/ComputeNode.js +67 -23
  165. package/src/nodes/gpgpu/SubgroupFunctionNode.js +430 -0
  166. package/src/nodes/gpgpu/WorkgroupInfoNode.js +28 -3
  167. package/src/nodes/lighting/LightsNode.js +1 -1
  168. package/src/nodes/lighting/ProjectorLightNode.js +19 -6
  169. package/src/nodes/lighting/ShadowFilterNode.js +1 -1
  170. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  171. package/src/nodes/materialx/lib/mx_noise.js +165 -1
  172. package/src/nodes/math/BitcastNode.js +156 -0
  173. package/src/nodes/math/ConditionalNode.js +19 -3
  174. package/src/nodes/math/MathNode.js +72 -60
  175. package/src/nodes/math/OperatorNode.js +26 -25
  176. package/src/nodes/tsl/TSLCore.js +477 -142
  177. package/src/nodes/utils/DebugNode.js +1 -1
  178. package/src/nodes/utils/EventNode.js +83 -0
  179. package/src/nodes/utils/JoinNode.js +3 -1
  180. package/src/nodes/utils/MemberNode.js +58 -7
  181. package/src/nodes/utils/RTTNode.js +10 -1
  182. package/src/nodes/utils/ReflectorNode.js +51 -7
  183. package/src/nodes/utils/SampleNode.js +12 -2
  184. package/src/nodes/utils/SplitNode.js +11 -0
  185. package/src/nodes/utils/Timer.js +0 -47
  186. package/src/objects/BatchedMesh.js +6 -4
  187. package/src/objects/LOD.js +1 -1
  188. package/src/objects/Sprite.js +2 -2
  189. package/src/renderers/WebGLRenderer.js +21 -31
  190. package/src/renderers/common/Attributes.js +1 -1
  191. package/src/renderers/common/Backend.js +19 -1
  192. package/src/renderers/common/Bindings.js +21 -18
  193. package/src/renderers/common/ChainMap.js +1 -1
  194. package/src/renderers/common/Color4.js +2 -2
  195. package/src/renderers/common/DataMap.js +1 -1
  196. package/src/renderers/common/Pipelines.js +1 -1
  197. package/src/renderers/common/PostProcessing.js +60 -5
  198. package/src/renderers/common/RenderContext.js +2 -2
  199. package/src/renderers/common/RenderObject.js +14 -2
  200. package/src/renderers/common/Renderer.js +55 -32
  201. package/src/renderers/common/SampledTexture.js +4 -72
  202. package/src/renderers/common/Sampler.js +91 -0
  203. package/src/renderers/common/Storage3DTexture.js +21 -0
  204. package/src/renderers/common/StorageArrayTexture.js +21 -0
  205. package/src/renderers/common/StorageTexture.js +19 -0
  206. package/src/renderers/common/Textures.js +52 -14
  207. package/src/renderers/common/TimestampQueryPool.js +3 -3
  208. package/src/renderers/common/XRManager.js +51 -17
  209. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  210. package/src/renderers/common/nodes/NodeLibrary.js +5 -5
  211. package/src/renderers/common/nodes/NodeSampledTexture.js +0 -12
  212. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  213. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  214. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  215. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  216. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +21 -11
  217. package/src/renderers/shaders/ShaderLib/depth.glsl.js +11 -2
  218. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  219. package/src/renderers/webgl/WebGLMaterials.js +6 -6
  220. package/src/renderers/webgl/WebGLProgram.js +24 -18
  221. package/src/renderers/webgl/WebGLPrograms.js +4 -4
  222. package/src/renderers/webgl/WebGLShadowMap.js +11 -1
  223. package/src/renderers/webgl/WebGLTextures.js +20 -7
  224. package/src/renderers/webgl/WebGLUtils.js +3 -2
  225. package/src/renderers/webgl-fallback/WebGLBackend.js +207 -146
  226. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +112 -19
  227. package/src/renderers/webgl-fallback/utils/WebGLState.js +1 -1
  228. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -3
  229. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -10
  230. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  231. package/src/renderers/webgpu/WebGPUBackend.js +87 -44
  232. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +169 -99
  233. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +35 -31
  234. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -2
  235. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +10 -19
  236. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +120 -84
  237. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +3 -3
  238. package/src/renderers/webgpu/utils/WebGPUUtils.js +2 -17
  239. package/src/renderers/webxr/WebXRDepthSensing.js +6 -10
  240. package/src/renderers/webxr/WebXRManager.js +86 -11
  241. package/src/textures/ExternalTexture.js +56 -0
  242. package/src/textures/FramebufferTexture.js +2 -2
  243. package/src/textures/Source.js +12 -2
  244. package/src/textures/VideoTexture.js +27 -2
  245. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
@@ -13,9 +13,10 @@ import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js';
13
13
  import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js';
14
14
  import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js';
15
15
 
16
- import { WebGPUCoordinateSystem } from '../../constants.js';
16
+ import { WebGPUCoordinateSystem, TimestampQuery } from '../../constants.js';
17
17
  import WebGPUTimestampQueryPool from './utils/WebGPUTimestampQueryPool.js';
18
18
  import { warnOnce } from '../../utils.js';
19
+ import { ColorManagement } from '../../math/ColorManagement.js';
19
20
 
20
21
  /**
21
22
  * A backend implementation targeting WebGPU.
@@ -238,15 +239,20 @@ class WebGPUBackend extends Backend {
238
239
 
239
240
  const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque';
240
241
 
241
- this.trackTimestamp = this.trackTimestamp && this.hasFeature( GPUFeatureName.TimestampQuery );
242
+ const toneMappingMode = ColorManagement.getToneMappingMode( this.renderer.outputColorSpace );
242
243
 
243
244
  this.context.configure( {
244
245
  device: this.device,
245
246
  format: this.utils.getPreferredCanvasFormat(),
246
247
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
247
- alphaMode: alphaMode
248
+ alphaMode: alphaMode,
249
+ toneMapping: {
250
+ mode: toneMappingMode
251
+ }
248
252
  } );
249
253
 
254
+ this.trackTimestamp = this.trackTimestamp && this.hasFeature( GPUFeatureName.TimestampQuery );
255
+
250
256
  this.updateSize();
251
257
 
252
258
  }
@@ -384,9 +390,6 @@ class WebGPUBackend extends Backend {
384
390
  if ( descriptors === undefined ||
385
391
  renderTargetData.width !== renderTarget.width ||
386
392
  renderTargetData.height !== renderTarget.height ||
387
- renderTargetData.dimensions !== renderTarget.dimensions ||
388
- renderTargetData.activeMipmapLevel !== renderContext.activeMipmapLevel ||
389
- renderTargetData.activeCubeFace !== renderContext.activeCubeFace ||
390
393
  renderTargetData.samples !== renderTarget.samples
391
394
  ) {
392
395
 
@@ -394,21 +397,6 @@ class WebGPUBackend extends Backend {
394
397
 
395
398
  renderTargetData.descriptors = descriptors;
396
399
 
397
- // dispose
398
-
399
- const onDispose = () => {
400
-
401
- renderTarget.removeEventListener( 'dispose', onDispose );
402
- this.delete( renderTarget );
403
-
404
- };
405
-
406
- if ( renderTarget.hasEventListener( 'dispose', onDispose ) === false ) {
407
-
408
- renderTarget.addEventListener( 'dispose', onDispose );
409
-
410
- }
411
-
412
400
  }
413
401
 
414
402
  const cacheKey = renderContext.getCacheKey();
@@ -528,7 +516,6 @@ class WebGPUBackend extends Backend {
528
516
  renderTargetData.samples = renderTarget.samples;
529
517
  renderTargetData.activeMipmapLevel = renderContext.activeMipmapLevel;
530
518
  renderTargetData.activeCubeFace = renderContext.activeCubeFace;
531
- renderTargetData.dimensions = renderTarget.dimensions;
532
519
 
533
520
  }
534
521
 
@@ -581,6 +568,12 @@ class WebGPUBackend extends Backend {
581
568
 
582
569
  const renderContextData = this.get( renderContext );
583
570
 
571
+ //
572
+
573
+ renderContextData.frameCalls = this.renderer.info.render.frameCalls;
574
+
575
+ //
576
+
584
577
  const device = this.device;
585
578
  const occlusionQueryCount = renderContext.occlusionQueryCount;
586
579
 
@@ -621,7 +614,7 @@ class WebGPUBackend extends Backend {
621
614
 
622
615
  }
623
616
 
624
- this.initTimestampQuery( renderContext, descriptor );
617
+ this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ), descriptor );
625
618
 
626
619
  descriptor.occlusionQuerySet = occlusionQuerySet;
627
620
 
@@ -1236,7 +1229,7 @@ class WebGPUBackend extends Backend {
1236
1229
 
1237
1230
  }
1238
1231
 
1239
- if ( supportsDepth && depthStencilAttachment && depthStencilAttachment.depthLoadOp === undefined ) {
1232
+ if ( supportsDepth && depthStencilAttachment ) {
1240
1233
 
1241
1234
  if ( depth ) {
1242
1235
 
@@ -1255,7 +1248,7 @@ class WebGPUBackend extends Backend {
1255
1248
 
1256
1249
  //
1257
1250
 
1258
- if ( supportsStencil && depthStencilAttachment && depthStencilAttachment.stencilLoadOp === undefined ) {
1251
+ if ( supportsStencil && depthStencilAttachment ) {
1259
1252
 
1260
1253
  if ( stencil ) {
1261
1254
 
@@ -1298,12 +1291,17 @@ class WebGPUBackend extends Backend {
1298
1291
 
1299
1292
  const groupGPU = this.get( computeGroup );
1300
1293
 
1294
+ //
1295
+
1296
+ groupGPU.frameCalls = this.renderer.info.compute.frameCalls;
1297
+
1298
+ //
1301
1299
 
1302
1300
  const descriptor = {
1303
1301
  label: 'computeGroup_' + computeGroup.id
1304
1302
  };
1305
1303
 
1306
- this.initTimestampQuery( computeGroup, descriptor );
1304
+ this.initTimestampQuery( TimestampQuery.COMPUTE, this.getTimestampUID( computeGroup ), descriptor );
1307
1305
 
1308
1306
  groupGPU.cmdEncoderGPU = this.device.createCommandEncoder( { label: 'computeGroup_' + computeGroup.id } );
1309
1307
 
@@ -1318,9 +1316,11 @@ class WebGPUBackend extends Backend {
1318
1316
  * @param {Node} computeNode - The compute node.
1319
1317
  * @param {Array<BindGroup>} bindings - The bindings.
1320
1318
  * @param {ComputePipeline} pipeline - The compute pipeline.
1319
+ * @param {?(Array<number>|number)} [dispatchSizeOrCount=null] - Array with [ x, y, z ] values for dispatch or a single number for the count.
1321
1320
  */
1322
- compute( computeGroup, computeNode, bindings, pipeline ) {
1321
+ compute( computeGroup, computeNode, bindings, pipeline, dispatchSizeOrCount = null ) {
1323
1322
 
1323
+ const computeNodeData = this.get( computeNode );
1324
1324
  const { passEncoderGPU } = this.get( computeGroup );
1325
1325
 
1326
1326
  // pipeline
@@ -1340,29 +1340,67 @@ class WebGPUBackend extends Backend {
1340
1340
 
1341
1341
  }
1342
1342
 
1343
- const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension;
1343
+ let dispatchSize;
1344
1344
 
1345
- const computeNodeData = this.get( computeNode );
1345
+ if ( dispatchSizeOrCount === null ) {
1346
+
1347
+ dispatchSizeOrCount = computeNode.count;
1346
1348
 
1347
- if ( computeNodeData.dispatchSize === undefined ) computeNodeData.dispatchSize = { x: 0, y: 1, z: 1 };
1349
+ }
1350
+
1351
+ if ( typeof dispatchSizeOrCount === 'number' ) {
1352
+
1353
+ // If a single number is given, we calculate the dispatch size based on the workgroup size
1354
+
1355
+ const count = dispatchSizeOrCount;
1356
+
1357
+ if ( computeNodeData.dispatchSize === undefined || computeNodeData.count !== count ) {
1358
+
1359
+ // cache dispatch size to avoid recalculating it every time
1360
+
1361
+ computeNodeData.dispatchSize = [ 0, 1, 1 ];
1362
+ computeNodeData.count = count;
1363
+
1364
+ const workgroupSize = computeNode.workgroupSize;
1365
+
1366
+ let size = workgroupSize[ 0 ];
1367
+
1368
+ for ( let i = 1; i < workgroupSize.length; i ++ )
1369
+ size *= workgroupSize[ i ];
1370
+
1371
+ const dispatchCount = Math.ceil( count / size );
1372
+
1373
+ //
1374
+
1375
+ const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension;
1348
1376
 
1349
- const { dispatchSize } = computeNodeData;
1377
+ dispatchSize = [ dispatchCount, 1, 1 ];
1350
1378
 
1351
- if ( computeNode.dispatchCount > maxComputeWorkgroupsPerDimension ) {
1379
+ if ( dispatchCount > maxComputeWorkgroupsPerDimension ) {
1352
1380
 
1353
- dispatchSize.x = Math.min( computeNode.dispatchCount, maxComputeWorkgroupsPerDimension );
1354
- dispatchSize.y = Math.ceil( computeNode.dispatchCount / maxComputeWorkgroupsPerDimension );
1381
+ dispatchSize[ 0 ] = Math.min( dispatchCount, maxComputeWorkgroupsPerDimension );
1382
+ dispatchSize[ 1 ] = Math.ceil( dispatchCount / maxComputeWorkgroupsPerDimension );
1383
+
1384
+ }
1385
+
1386
+ computeNodeData.dispatchSize = dispatchSize;
1387
+
1388
+ }
1389
+
1390
+ dispatchSize = computeNodeData.dispatchSize;
1355
1391
 
1356
1392
  } else {
1357
1393
 
1358
- dispatchSize.x = computeNode.dispatchCount;
1394
+ dispatchSize = dispatchSizeOrCount;
1359
1395
 
1360
1396
  }
1361
1397
 
1398
+ //
1399
+
1362
1400
  passEncoderGPU.dispatchWorkgroups(
1363
- dispatchSize.x,
1364
- dispatchSize.y,
1365
- dispatchSize.z
1401
+ dispatchSize[ 0 ],
1402
+ dispatchSize[ 1 ] || 1,
1403
+ dispatchSize[ 2 ] || 1
1366
1404
  );
1367
1405
 
1368
1406
  }
@@ -1768,6 +1806,11 @@ class WebGPUBackend extends Backend {
1768
1806
  const utils = this.utils;
1769
1807
  const renderContext = renderObject.context;
1770
1808
 
1809
+ // meshes with negative scale have a different frontFace render pipeline
1810
+ // descriptor value so the following must be honored in the cache key
1811
+
1812
+ const frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
1813
+
1771
1814
  return [
1772
1815
  material.transparent, material.blending, material.premultipliedAlpha,
1773
1816
  material.blendSrc, material.blendDst, material.blendEquation,
@@ -1778,6 +1821,7 @@ class WebGPUBackend extends Backend {
1778
1821
  material.stencilFail, material.stencilZFail, material.stencilZPass,
1779
1822
  material.stencilFuncMask, material.stencilWriteMask,
1780
1823
  material.side,
1824
+ frontFaceCW,
1781
1825
  utils.getSampleCountRenderContext( renderContext ),
1782
1826
  utils.getCurrentColorSpace( renderContext ), utils.getCurrentColorFormat( renderContext ), utils.getCurrentDepthStencilFormat( renderContext ),
1783
1827
  utils.getPrimitiveTopology( object, material ),
@@ -1890,15 +1934,14 @@ class WebGPUBackend extends Backend {
1890
1934
  /**
1891
1935
  * Inits a time stamp query for the given render context.
1892
1936
  *
1893
- * @param {RenderContext} renderContext - The render context.
1937
+ * @param {string} type - The type of the timestamp query (e.g. 'render', 'compute').
1938
+ * @param {number} uid - Unique id for the context (e.g. render context id).
1894
1939
  * @param {Object} descriptor - The query descriptor.
1895
1940
  */
1896
- initTimestampQuery( renderContext, descriptor ) {
1941
+ initTimestampQuery( type, uid, descriptor ) {
1897
1942
 
1898
1943
  if ( ! this.trackTimestamp ) return;
1899
1944
 
1900
- const type = renderContext.isComputeNode ? 'compute' : 'render';
1901
-
1902
1945
  if ( ! this.timestampQueryPool[ type ] ) {
1903
1946
 
1904
1947
  // TODO: Variable maxQueries?
@@ -1908,7 +1951,7 @@ class WebGPUBackend extends Backend {
1908
1951
 
1909
1952
  const timestampQueryPool = this.timestampQueryPool[ type ];
1910
1953
 
1911
- const baseOffset = timestampQueryPool.allocateQueriesForContext( renderContext );
1954
+ const baseOffset = timestampQueryPool.allocateQueriesForContext( uid );
1912
1955
 
1913
1956
  descriptor.timestampWrites = {
1914
1957
  querySet: timestampQueryPool.querySet,
@@ -2185,7 +2228,7 @@ class WebGPUBackend extends Backend {
2185
2228
  }
2186
2229
 
2187
2230
  /**
2188
- * Checks if the given feature is supported by the backend.
2231
+ * Checks if the given feature is supported by the backend.
2189
2232
  *
2190
2233
  * @param {string} name - The feature's name.
2191
2234
  * @return {boolean} Whether the feature is supported or not.