super-three 0.172.0 → 0.173.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/LICENSE +1 -1
  2. package/build/three.cjs +439 -380
  3. package/build/three.core.js +413 -41
  4. package/build/three.core.min.js +2 -2
  5. package/build/three.module.js +28 -344
  6. package/build/three.module.min.js +2 -2
  7. package/build/three.tsl.js +11 -3
  8. package/build/three.tsl.min.js +2 -2
  9. package/build/three.webgpu.js +7550 -1798
  10. package/build/three.webgpu.min.js +2 -2
  11. package/build/three.webgpu.nodes.js +7551 -1798
  12. package/build/three.webgpu.nodes.min.js +2 -2
  13. package/examples/jsm/animation/CCDIKSolver.js +6 -5
  14. package/examples/jsm/capabilities/WebGPU.js +1 -1
  15. package/examples/jsm/controls/ArcballControls.js +23 -21
  16. package/examples/jsm/exporters/GLTFExporter.js +26 -25
  17. package/examples/jsm/geometries/TextGeometry.js +1 -12
  18. package/examples/jsm/interactive/InteractiveGroup.js +108 -51
  19. package/examples/jsm/libs/demuxer_mp4.js +109 -0
  20. package/examples/jsm/loaders/GCodeLoader.js +3 -1
  21. package/examples/jsm/loaders/GLTFLoader.js +0 -2
  22. package/examples/jsm/loaders/TDSLoader.js +0 -1
  23. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  24. package/examples/jsm/misc/GPUComputationRenderer.js +6 -7
  25. package/examples/jsm/misc/ProgressiveLightMap.js +4 -3
  26. package/examples/jsm/misc/ProgressiveLightMapGPU.js +4 -3
  27. package/examples/jsm/misc/Volume.js +7 -5
  28. package/examples/jsm/misc/VolumeSlice.js +5 -3
  29. package/examples/jsm/objects/WaterMesh.js +25 -20
  30. package/examples/jsm/physics/JoltPhysics.js +7 -7
  31. package/examples/jsm/physics/RapierPhysics.js +4 -4
  32. package/examples/jsm/postprocessing/EffectComposer.js +23 -2
  33. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  34. package/examples/jsm/postprocessing/Pass.js +6 -1
  35. package/examples/jsm/shaders/OutputShader.js +5 -1
  36. package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
  37. package/examples/jsm/transpiler/TSLEncoder.js +2 -0
  38. package/package.json +1 -1
  39. package/src/Three.Core.js +2 -0
  40. package/src/Three.TSL.js +9 -1
  41. package/src/cameras/ArrayCamera.js +1 -0
  42. package/src/constants.js +6 -1
  43. package/src/core/BufferAttribute.js +4 -0
  44. package/src/core/EventDispatcher.js +8 -6
  45. package/src/extras/ImageUtils.js +1 -11
  46. package/src/loaders/nodes/NodeObjectLoader.js +1 -1
  47. package/src/materials/nodes/MeshBasicNodeMaterial.js +1 -1
  48. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +1 -1
  49. package/src/materials/nodes/NodeMaterial.js +5 -5
  50. package/src/materials/nodes/NodeMaterials.js +0 -1
  51. package/src/materials/nodes/PointsNodeMaterial.js +109 -7
  52. package/src/materials/nodes/SpriteNodeMaterial.js +1 -1
  53. package/src/materials/nodes/VolumeNodeMaterial.js +3 -3
  54. package/src/materials/nodes/manager/NodeMaterialObserver.js +8 -0
  55. package/src/nodes/Nodes.js +4 -0
  56. package/src/nodes/TSL.js +4 -0
  57. package/src/nodes/accessors/Arrays.js +30 -8
  58. package/src/nodes/accessors/BatchNode.js +3 -3
  59. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  60. package/src/nodes/accessors/Camera.js +64 -3
  61. package/src/nodes/accessors/InstanceNode.js +1 -1
  62. package/src/nodes/accessors/MaterialNode.js +9 -9
  63. package/src/nodes/accessors/ModelViewProjectionNode.js +1 -1
  64. package/src/nodes/accessors/Normal.js +6 -2
  65. package/src/nodes/accessors/Object3DNode.js +0 -1
  66. package/src/nodes/accessors/Position.js +6 -6
  67. package/src/nodes/accessors/ReferenceBaseNode.js +2 -4
  68. package/src/nodes/accessors/ReferenceNode.js +2 -3
  69. package/src/nodes/accessors/StorageBufferNode.js +42 -5
  70. package/src/nodes/accessors/Tangent.js +2 -2
  71. package/src/nodes/accessors/Texture3DNode.js +1 -1
  72. package/src/nodes/accessors/TextureNode.js +12 -5
  73. package/src/nodes/accessors/UniformArrayNode.js +9 -3
  74. package/src/nodes/accessors/VelocityNode.js +0 -2
  75. package/src/nodes/code/ScriptableNode.js +3 -3
  76. package/src/nodes/core/ArrayNode.js +125 -0
  77. package/src/nodes/core/ConstNode.js +8 -0
  78. package/src/nodes/core/Node.js +14 -1
  79. package/src/nodes/core/NodeBuilder.js +229 -19
  80. package/src/nodes/core/NodeUtils.js +11 -1
  81. package/src/nodes/core/NodeVar.js +17 -1
  82. package/src/nodes/core/OutputStructNode.js +19 -9
  83. package/src/nodes/core/StackNode.js +20 -1
  84. package/src/nodes/core/StructNode.js +121 -0
  85. package/src/nodes/core/StructType.js +13 -0
  86. package/src/nodes/core/StructTypeNode.js +82 -21
  87. package/src/nodes/core/TempNode.js +1 -1
  88. package/src/nodes/core/VarNode.js +94 -7
  89. package/src/nodes/core/VaryingNode.js +19 -3
  90. package/src/nodes/display/BlendModes.js +88 -1
  91. package/src/nodes/display/BumpMapNode.js +6 -6
  92. package/src/nodes/display/NormalMapNode.js +6 -6
  93. package/src/nodes/display/PassNode.js +3 -1
  94. package/src/nodes/display/ScreenNode.js +9 -0
  95. package/src/nodes/fog/Fog.js +17 -0
  96. package/src/nodes/gpgpu/AtomicFunctionNode.js +20 -4
  97. package/src/nodes/gpgpu/ComputeBuiltinNode.js +8 -0
  98. package/src/nodes/gpgpu/WorkgroupInfoNode.js +1 -1
  99. package/src/nodes/lighting/ShadowNode.js +1 -1
  100. package/src/nodes/math/ConditionalNode.js +8 -1
  101. package/src/nodes/math/MathNode.js +14 -1
  102. package/src/nodes/math/OperatorNode.js +96 -18
  103. package/src/nodes/pmrem/PMREMUtils.js +1 -1
  104. package/src/nodes/shapes/Shapes.js +33 -0
  105. package/src/nodes/tsl/TSLBase.js +1 -0
  106. package/src/nodes/tsl/TSLCore.js +22 -2
  107. package/src/nodes/utils/ArrayElementNode.js +1 -1
  108. package/src/nodes/utils/LoopNode.js +8 -1
  109. package/src/nodes/utils/MemberNode.js +68 -0
  110. package/src/nodes/utils/StorageArrayElementNode.js +14 -0
  111. package/src/nodes/utils/Timer.js +21 -0
  112. package/src/objects/BatchedMesh.js +1 -1
  113. package/src/objects/Line.js +6 -6
  114. package/src/renderers/WebGLRenderer.js +7 -0
  115. package/src/renderers/common/Animation.js +23 -1
  116. package/src/renderers/common/Backend.js +58 -15
  117. package/src/renderers/common/Background.js +14 -0
  118. package/src/renderers/common/Binding.js +1 -1
  119. package/src/renderers/common/BufferUtils.js +1 -1
  120. package/src/renderers/common/BundleGroup.js +1 -1
  121. package/src/renderers/common/ChainMap.js +9 -7
  122. package/src/renderers/common/ClippingContext.js +1 -1
  123. package/src/renderers/common/Color4.js +7 -3
  124. package/src/renderers/common/Geometries.js +2 -23
  125. package/src/renderers/common/Info.js +1 -45
  126. package/src/renderers/common/Lighting.js +8 -6
  127. package/src/renderers/common/Pipelines.js +3 -3
  128. package/src/renderers/common/PostProcessing.js +24 -8
  129. package/src/renderers/common/QuadMesh.js +1 -1
  130. package/src/renderers/common/RenderBundles.js +9 -3
  131. package/src/renderers/common/RenderContext.js +37 -3
  132. package/src/renderers/common/RenderContexts.js +30 -17
  133. package/src/renderers/common/RenderList.js +2 -2
  134. package/src/renderers/common/RenderLists.js +9 -3
  135. package/src/renderers/common/RenderObject.js +76 -17
  136. package/src/renderers/common/RenderObjects.js +9 -7
  137. package/src/renderers/common/Renderer.js +86 -67
  138. package/src/renderers/common/SampledTexture.js +0 -1
  139. package/src/renderers/common/StorageBufferAttribute.js +1 -1
  140. package/src/renderers/common/StorageInstancedBufferAttribute.js +1 -1
  141. package/src/renderers/common/StorageTexture.js +1 -1
  142. package/src/renderers/common/Textures.js +14 -7
  143. package/src/renderers/common/TimestampQueryPool.js +39 -0
  144. package/src/renderers/common/Uniform.js +37 -1
  145. package/src/renderers/common/UniformsGroup.js +2 -0
  146. package/src/renderers/common/XRManager.js +1193 -0
  147. package/src/renderers/common/XRRenderTarget.js +74 -0
  148. package/src/renderers/common/extras/PMREMGenerator.js +53 -8
  149. package/src/renderers/common/nodes/NodeBuilderState.js +4 -4
  150. package/src/renderers/common/nodes/NodeLibrary.js +5 -5
  151. package/src/renderers/common/nodes/NodeSampledTexture.js +0 -1
  152. package/src/renderers/common/nodes/NodeUniform.js +54 -2
  153. package/src/renderers/common/nodes/Nodes.js +25 -18
  154. package/src/renderers/webgl/WebGLBackground.js +4 -0
  155. package/src/renderers/webgl-fallback/WebGLBackend.js +295 -110
  156. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +347 -17
  157. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +57 -0
  158. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +28 -0
  159. package/src/renderers/webgl-fallback/utils/WebGLExtensions.js +45 -0
  160. package/src/renderers/webgl-fallback/utils/WebGLState.js +323 -11
  161. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +167 -21
  162. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +359 -0
  163. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +43 -0
  164. package/src/renderers/webgpu/WebGPUBackend.js +132 -149
  165. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +6 -4
  166. package/src/renderers/webgpu/WebGPURenderer.js +5 -4
  167. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +615 -41
  168. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +85 -6
  169. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +85 -0
  170. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +102 -3
  171. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +98 -1
  172. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +257 -9
  173. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +274 -0
  174. package/src/renderers/webgpu/utils/WebGPUUtils.js +86 -4
  175. package/src/renderers/webxr/WebXRManager.js +13 -2
  176. package/src/textures/VideoFrameTexture.js +35 -0
  177. package/examples/jsm/geometries/InstancedPointsGeometry.js +0 -176
  178. package/examples/jsm/objects/InstancedPoints.js +0 -19
  179. package/src/materials/nodes/InstancedPointsNodeMaterial.js +0 -209
  180. package/src/nodes/accessors/InstancedPointsMaterialNode.js +0 -37
@@ -1,16 +1,52 @@
1
1
  import { RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RedFormat, RGBFormat, RGBAFormat, AlphaFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedInt5999Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, RGBA_BPTC_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, SRGBColorSpace, NoColorSpace } from '../../../constants.js';
2
2
 
3
+ /**
4
+ * A WebGL 2 backend utility module with common helpers.
5
+ *
6
+ * @private
7
+ */
3
8
  class WebGLUtils {
4
9
 
10
+ /**
11
+ * Constructs a new utility object.
12
+ *
13
+ * @param {WebGLBackend} backend - The WebGL 2 backend.
14
+ */
5
15
  constructor( backend ) {
6
16
 
17
+ /**
18
+ * A reference to the WebGL 2 backend.
19
+ *
20
+ * @type {WebGLBackend}
21
+ */
7
22
  this.backend = backend;
8
23
 
24
+ /**
25
+ * A reference to the rendering context.
26
+ *
27
+ * @type {WebGL2RenderingContext}
28
+ */
9
29
  this.gl = this.backend.gl;
30
+
31
+ /**
32
+ * A reference to a backend module holding extension-related
33
+ * utility functions.
34
+ *
35
+ * @type {WebGLExtensions}
36
+ */
10
37
  this.extensions = backend.extensions;
11
38
 
12
39
  }
13
40
 
41
+ /**
42
+ * Converts the given three.js constant into a WebGL constant.
43
+ * The method currently supports the conversion of texture formats
44
+ * and types.
45
+ *
46
+ * @param {Number} p - The three.js constant.
47
+ * @param {String} [colorSpace=NoColorSpace] - The color space.
48
+ * @return {Number} The corresponding WebGL constant.
49
+ */
14
50
  convert( p, colorSpace = NoColorSpace ) {
15
51
 
16
52
  const { gl, extensions } = this;
@@ -221,6 +257,13 @@ class WebGLUtils {
221
257
 
222
258
  }
223
259
 
260
+ /**
261
+ * This method can be used to synchronize the CPU with the GPU by waiting until
262
+ * ongoing GPU commands have been completed.
263
+ *
264
+ * @private
265
+ * @return {Promise} A promise that resolves when all ongoing GPU commands have been completed.
266
+ */
224
267
  _clientWaitAsync() {
225
268
 
226
269
  const { gl } = this;
@@ -14,7 +14,7 @@ import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js';
14
14
  import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js';
15
15
 
16
16
  import { WebGPUCoordinateSystem } from '../../constants.js';
17
-
17
+ import WebGPUTimestampQueryPool from './utils/WebGPUTimestampQueryPool.js';
18
18
 
19
19
  /**
20
20
  * A backend implementation targeting WebGPU.
@@ -34,11 +34,12 @@ class WebGPUBackend extends Backend {
34
34
  * @param {Boolean} [parameters.stencil=false] - Whether the default framebuffer should have a stencil buffer or not.
35
35
  * @param {Boolean} [parameters.antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not.
36
36
  * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default.
37
- * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses it WebGL 2 backend no matter if WebGPU is supported or not.
37
+ * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not.
38
38
  * @param {Boolean} [parameters.trackTimestamp=false] - Whether to track timestamps with a Timestamp Query API or not.
39
- * @param {String?} [parameters.powerPreference=null] - The power preference.
40
- * @param {String?} [parameters.requiredLimits={}] - Specifies the limits that are required by the device request.
41
- * The request will fail if the adapter cannot provide these limits.
39
+ * @param {String} [parameters.powerPreference=undefined] - The power preference.
40
+ * @param {Object} [parameters.requiredLimits=undefined] - Specifies the limits that are required by the device request. The request will fail if the adapter cannot provide these limits.
41
+ * @param {GPUDevice} [parameters.device=undefined] - If there is an existing GPU device on app level, it can be passed to the renderer as a parameter.
42
+ * @param {Number} [parameters.outputType=undefined] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead.
42
43
  */
43
44
  constructor( parameters = {} ) {
44
45
 
@@ -254,8 +255,8 @@ class WebGPUBackend extends Backend {
254
255
  }
255
256
 
256
257
  /**
257
- * Transfers buffer data from a storage buffer attribute
258
- * from the GPU to the CPU in context of compute shaders.
258
+ * This method performs a readback operation by moving buffer data from
259
+ * a storage buffer attribute from the GPU to the CPU.
259
260
  *
260
261
  * @async
261
262
  * @param {StorageBufferAttribute} attribute - The storage buffer attribute.
@@ -282,7 +283,7 @@ class WebGPUBackend extends Backend {
282
283
  * Returns the default render pass descriptor.
283
284
  *
284
285
  * In WebGPU, the default framebuffer must be configured
285
- * like custom fraemebuffers so the backend needs a render
286
+ * like custom framebuffers so the backend needs a render
286
287
  * pass descriptor even when rendering directly to screen.
287
288
  *
288
289
  * @private
@@ -716,8 +717,6 @@ class WebGPUBackend extends Backend {
716
717
 
717
718
  }
718
719
 
719
- this.prepareTimestampBuffer( renderContext, renderContextData.encoder );
720
-
721
720
  this.device.queue.submit( [ renderContextData.encoder.finish() ] );
722
721
 
723
722
 
@@ -765,6 +764,7 @@ class WebGPUBackend extends Backend {
765
764
  *
766
765
  * @async
767
766
  * @param {RenderContext} renderContext - The render context.
767
+ * @return {Promise} A Promise that resolves when the occlusion query results have been processed.
768
768
  */
769
769
  async resolveOccludedAsync( renderContext ) {
770
770
 
@@ -788,7 +788,7 @@ class WebGPUBackend extends Backend {
788
788
 
789
789
  for ( let i = 0; i < currentOcclusionQueryObjects.length; i ++ ) {
790
790
 
791
- if ( results[ i ] !== BigInt( 0 ) ) {
791
+ if ( results[ i ] === BigInt( 0 ) ) {
792
792
 
793
793
  occluded.add( currentOcclusionQueryObjects[ i ] );
794
794
 
@@ -891,7 +891,7 @@ class WebGPUBackend extends Backend {
891
891
 
892
892
  if ( color ) {
893
893
 
894
- const descriptor = this._getRenderPassDescriptor( renderTargetContext, { loadOp: GPULoadOp.Clear } );
894
+ const descriptor = this._getRenderPassDescriptor( renderTargetContext, { loadOp: GPULoadOp.Clear, clearValue } );
895
895
 
896
896
  colorAttachments = descriptor.colorAttachments;
897
897
 
@@ -949,7 +949,7 @@ class WebGPUBackend extends Backend {
949
949
 
950
950
  //
951
951
 
952
- const encoder = device.createCommandEncoder( {} );
952
+ const encoder = device.createCommandEncoder( { label: 'clear' } );
953
953
  const currentPass = encoder.beginRenderPass( {
954
954
  colorAttachments,
955
955
  depthStencilAttachment
@@ -974,11 +974,13 @@ class WebGPUBackend extends Backend {
974
974
  const groupGPU = this.get( computeGroup );
975
975
 
976
976
 
977
- const descriptor = {};
977
+ const descriptor = {
978
+ label: 'computeGroup_' + computeGroup.id
979
+ };
978
980
 
979
981
  this.initTimestampQuery( computeGroup, descriptor );
980
982
 
981
- groupGPU.cmdEncoderGPU = this.device.createCommandEncoder();
983
+ groupGPU.cmdEncoderGPU = this.device.createCommandEncoder( { label: 'computeGroup_' + computeGroup.id } );
982
984
 
983
985
  groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass( descriptor );
984
986
 
@@ -1051,8 +1053,6 @@ class WebGPUBackend extends Backend {
1051
1053
 
1052
1054
  groupData.passEncoderGPU.end();
1053
1055
 
1054
- this.prepareTimestampBuffer( computeGroup, groupData.cmdEncoderGPU );
1055
-
1056
1056
  this.device.queue.submit( [ groupData.cmdEncoderGPU.finish() ] );
1057
1057
 
1058
1058
  }
@@ -1191,69 +1191,133 @@ class WebGPUBackend extends Backend {
1191
1191
 
1192
1192
  // draw
1193
1193
 
1194
- if ( object.isBatchedMesh === true ) {
1194
+ const draw = () => {
1195
+
1196
+ if ( object.isBatchedMesh === true ) {
1197
+
1198
+ const starts = object._multiDrawStarts;
1199
+ const counts = object._multiDrawCounts;
1200
+ const drawCount = object._multiDrawCount;
1201
+ const drawInstances = object._multiDrawInstances;
1202
+
1203
+ for ( let i = 0; i < drawCount; i ++ ) {
1204
+
1205
+ const count = drawInstances ? drawInstances[ i ] : 1;
1206
+ const firstInstance = count > 1 ? 0 : i;
1207
+
1208
+ if ( hasIndex === true ) {
1209
+
1210
+ passEncoderGPU.drawIndexed( counts[ i ], count, starts[ i ] / index.array.BYTES_PER_ELEMENT, 0, firstInstance );
1211
+
1212
+ } else {
1213
+
1214
+ passEncoderGPU.draw( counts[ i ], count, starts[ i ], firstInstance );
1215
+
1216
+ }
1217
+
1218
+ }
1219
+
1220
+ } else if ( hasIndex === true ) {
1221
+
1222
+ const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams;
1223
+
1224
+ const indirect = renderObject.getIndirect();
1225
+
1226
+ if ( indirect !== null ) {
1227
+
1228
+ const buffer = this.get( indirect ).buffer;
1229
+
1230
+ passEncoderGPU.drawIndexedIndirect( buffer, 0 );
1231
+
1232
+ } else {
1233
+
1234
+ passEncoderGPU.drawIndexed( indexCount, instanceCount, firstIndex, 0, 0 );
1235
+
1236
+ }
1237
+
1238
+ info.update( object, indexCount, instanceCount );
1239
+
1240
+ } else {
1195
1241
 
1196
- const starts = object._multiDrawStarts;
1197
- const counts = object._multiDrawCounts;
1198
- const drawCount = object._multiDrawCount;
1199
- const drawInstances = object._multiDrawInstances;
1242
+ const { vertexCount, instanceCount, firstVertex } = drawParams;
1200
1243
 
1201
- for ( let i = 0; i < drawCount; i ++ ) {
1244
+ const indirect = renderObject.getIndirect();
1202
1245
 
1203
- const count = drawInstances ? drawInstances[ i ] : 1;
1204
- const firstInstance = count > 1 ? 0 : i;
1246
+ if ( indirect !== null ) {
1205
1247
 
1206
- if ( hasIndex === true ) {
1248
+ const buffer = this.get( indirect ).buffer;
1207
1249
 
1208
- passEncoderGPU.drawIndexed( counts[ i ], count, starts[ i ] / index.array.BYTES_PER_ELEMENT, 0, firstInstance );
1250
+ passEncoderGPU.drawIndirect( buffer, 0 );
1209
1251
 
1210
1252
  } else {
1211
1253
 
1212
- passEncoderGPU.draw( counts[ i ], count, starts[ i ], firstInstance );
1254
+ passEncoderGPU.draw( vertexCount, instanceCount, firstVertex, 0 );
1213
1255
 
1214
1256
  }
1215
1257
 
1258
+ info.update( object, vertexCount, instanceCount );
1259
+
1216
1260
  }
1217
1261
 
1218
- } else if ( hasIndex === true ) {
1262
+ };
1219
1263
 
1220
- const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams;
1264
+ if ( renderObject.camera.isArrayCamera && renderObject.camera.cameras.length > 0 ) {
1221
1265
 
1222
- const indirect = renderObject.getIndirect();
1266
+ const cameraData = this.get( renderObject.camera );
1267
+ const cameras = renderObject.camera.cameras;
1268
+ const cameraIndex = renderObject.getBindingGroup( 'cameraIndex' );
1223
1269
 
1224
- if ( indirect !== null ) {
1270
+ if ( cameraData.indexesGPU === undefined || cameraData.indexesGPU.length !== cameras.length ) {
1225
1271
 
1226
- const buffer = this.get( indirect ).buffer;
1272
+ const bindingsData = this.get( cameraIndex );
1273
+ const indexesGPU = [];
1227
1274
 
1228
- passEncoderGPU.drawIndexedIndirect( buffer, 0 );
1275
+ const data = new Uint32Array( [ 0, 0, 0, 0 ] );
1229
1276
 
1230
- } else {
1277
+ for ( let i = 0, len = cameras.length; i < len; i ++ ) {
1278
+
1279
+ data[ 0 ] = i;
1280
+
1281
+ const bindGroupIndex = this.bindingUtils.createBindGroupIndex( data, bindingsData.layout );
1282
+
1283
+ indexesGPU.push( bindGroupIndex );
1231
1284
 
1232
- passEncoderGPU.drawIndexed( indexCount, instanceCount, firstIndex, 0, 0 );
1285
+ }
1286
+
1287
+ cameraData.indexesGPU = indexesGPU; // TODO: Create a global library for this
1233
1288
 
1234
1289
  }
1235
1290
 
1236
- info.update( object, indexCount, instanceCount );
1291
+ const pixelRatio = this.renderer.getPixelRatio();
1237
1292
 
1238
- } else {
1293
+ for ( let i = 0, len = cameras.length; i < len; i ++ ) {
1239
1294
 
1240
- const { vertexCount, instanceCount, firstVertex } = drawParams;
1295
+ const subCamera = cameras[ i ];
1241
1296
 
1242
- const indirect = renderObject.getIndirect();
1297
+ if ( object.layers.test( subCamera.layers ) ) {
1243
1298
 
1244
- if ( indirect !== null ) {
1299
+ const vp = subCamera.viewport;
1245
1300
 
1246
- const buffer = this.get( indirect ).buffer;
1301
+ passEncoderGPU.setViewport(
1302
+ Math.floor( vp.x * pixelRatio ),
1303
+ Math.floor( vp.y * pixelRatio ),
1304
+ Math.floor( vp.width * pixelRatio ),
1305
+ Math.floor( vp.height * pixelRatio ),
1306
+ context.viewportValue.minDepth,
1307
+ context.viewportValue.maxDepth
1308
+ );
1247
1309
 
1248
- passEncoderGPU.drawIndirect( buffer, 0 );
1310
+ passEncoderGPU.setBindGroup( cameraIndex.index, cameraData.indexesGPU[ i ] );
1249
1311
 
1250
- } else {
1312
+ draw();
1251
1313
 
1252
- passEncoderGPU.draw( vertexCount, instanceCount, firstVertex, 0 );
1314
+ }
1253
1315
 
1254
1316
  }
1255
1317
 
1256
- info.update( object, vertexCount, instanceCount );
1318
+ } else {
1319
+
1320
+ draw();
1257
1321
 
1258
1322
  }
1259
1323
 
@@ -1358,7 +1422,7 @@ class WebGPUBackend extends Backend {
1358
1422
  // textures
1359
1423
 
1360
1424
  /**
1361
- * Creates a sampler for the given texture.
1425
+ * Creates a GPU sampler for the given texture.
1362
1426
  *
1363
1427
  * @param {Texture} texture - The texture to create the sampler for.
1364
1428
  */
@@ -1369,7 +1433,7 @@ class WebGPUBackend extends Backend {
1369
1433
  }
1370
1434
 
1371
1435
  /**
1372
- * Destroys the sampler for the given texture.
1436
+ * Destroys the GPU sampler for the given texture.
1373
1437
  *
1374
1438
  * @param {Texture} texture - The texture to destroy the sampler for.
1375
1439
  */
@@ -1416,7 +1480,7 @@ class WebGPUBackend extends Backend {
1416
1480
  }
1417
1481
 
1418
1482
  /**
1419
- * Generates mipmaps for the given texture
1483
+ * Generates mipmaps for the given texture.
1420
1484
  *
1421
1485
  * @param {Texture} texture - The texture.
1422
1486
  */
@@ -1440,15 +1504,16 @@ class WebGPUBackend extends Backend {
1440
1504
  /**
1441
1505
  * Returns texture data as a typed array.
1442
1506
  *
1507
+ * @async
1443
1508
  * @param {Texture} texture - The texture to copy.
1444
1509
  * @param {Number} x - The x coordinate of the copy origin.
1445
1510
  * @param {Number} y - The y coordinate of the copy origin.
1446
1511
  * @param {Number} width - The width of the copy.
1447
1512
  * @param {Number} height - The height of the copy.
1448
1513
  * @param {Number} faceIndex - The face index.
1449
- * @return {TypedArray} The texture data as a typed array.
1514
+ * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished.
1450
1515
  */
1451
- copyTextureToBuffer( texture, x, y, width, height, faceIndex ) {
1516
+ async copyTextureToBuffer( texture, x, y, width, height, faceIndex ) {
1452
1517
 
1453
1518
  return this.textureUtils.copyTextureToBuffer( texture, x, y, width, height, faceIndex );
1454
1519
 
@@ -1464,109 +1529,27 @@ class WebGPUBackend extends Backend {
1464
1529
 
1465
1530
  if ( ! this.trackTimestamp ) return;
1466
1531
 
1467
- const renderContextData = this.get( renderContext );
1468
-
1469
- if ( ! renderContextData.timeStampQuerySet ) {
1470
-
1532
+ const type = renderContext.isComputeNode ? 'compute' : 'render';
1471
1533
 
1472
- const type = renderContext.isComputeNode ? 'compute' : 'render';
1473
- const timeStampQuerySet = this.device.createQuerySet( { type: 'timestamp', count: 2, label: `timestamp_${type}_${renderContext.id}` } );
1534
+ if ( ! this.timestampQueryPool[ type ] ) {
1474
1535
 
1475
- const timestampWrites = {
1476
- querySet: timeStampQuerySet,
1477
- beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins.
1478
- endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends.
1479
- };
1480
-
1481
- Object.assign( descriptor, { timestampWrites } );
1482
-
1483
- renderContextData.timeStampQuerySet = timeStampQuerySet;
1484
-
1485
- }
1486
-
1487
- }
1488
-
1489
- /**
1490
- * Prepares the timestamp buffer.
1491
- *
1492
- * @param {RenderContext} renderContext - The render context.
1493
- * @param {GPUCommandEncoder} encoder - The command encoder.
1494
- */
1495
- prepareTimestampBuffer( renderContext, encoder ) {
1496
-
1497
- if ( ! this.trackTimestamp ) return;
1498
-
1499
- const renderContextData = this.get( renderContext );
1500
-
1501
-
1502
- const size = 2 * BigInt64Array.BYTES_PER_ELEMENT;
1503
-
1504
- if ( renderContextData.currentTimestampQueryBuffers === undefined ) {
1505
-
1506
- renderContextData.currentTimestampQueryBuffers = {
1507
- resolveBuffer: this.device.createBuffer( {
1508
- label: 'timestamp resolve buffer',
1509
- size: size,
1510
- usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
1511
- } ),
1512
- resultBuffer: this.device.createBuffer( {
1513
- label: 'timestamp result buffer',
1514
- size: size,
1515
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
1516
- } )
1517
- };
1536
+ // TODO: Variable maxQueries?
1537
+ this.timestampQueryPool[ type ] = new WebGPUTimestampQueryPool( this.device, type, 2048 );
1518
1538
 
1519
1539
  }
1520
1540
 
1521
- const { resolveBuffer, resultBuffer } = renderContextData.currentTimestampQueryBuffers;
1522
-
1541
+ const timestampQueryPool = this.timestampQueryPool[ type ];
1523
1542
 
1524
- encoder.resolveQuerySet( renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0 );
1543
+ const baseOffset = timestampQueryPool.allocateQueriesForContext( renderContext );
1525
1544
 
1526
- if ( resultBuffer.mapState === 'unmapped' ) {
1527
-
1528
- encoder.copyBufferToBuffer( resolveBuffer, 0, resultBuffer, 0, size );
1529
-
1530
- }
1545
+ descriptor.timestampWrites = {
1546
+ querySet: timestampQueryPool.querySet,
1547
+ beginningOfPassWriteIndex: baseOffset,
1548
+ endOfPassWriteIndex: baseOffset + 1,
1549
+ };
1531
1550
 
1532
1551
  }
1533
1552
 
1534
- /**
1535
- * Resolves the time stamp for the given render context and type.
1536
- *
1537
- * @async
1538
- * @param {RenderContext} renderContext - The render context.
1539
- * @param {String} type - The render context.
1540
- * @return {Promise} A Promise that resolves when the time stamp has been computed.
1541
- */
1542
- async resolveTimestampAsync( renderContext, type = 'render' ) {
1543
-
1544
- if ( ! this.trackTimestamp ) return;
1545
-
1546
- const renderContextData = this.get( renderContext );
1547
-
1548
- if ( renderContextData.currentTimestampQueryBuffers === undefined ) return;
1549
-
1550
- const { resultBuffer } = renderContextData.currentTimestampQueryBuffers;
1551
-
1552
- if ( resultBuffer.mapState === 'unmapped' ) {
1553
-
1554
- resultBuffer.mapAsync( GPUMapMode.READ ).then( () => {
1555
-
1556
- const times = new BigUint64Array( resultBuffer.getMappedRange() );
1557
- const duration = Number( times[ 1 ] - times[ 0 ] ) / 1000000;
1558
-
1559
-
1560
- this.renderer.info.updateTimestamp( type, duration );
1561
-
1562
- resultBuffer.unmap();
1563
-
1564
-
1565
- } );
1566
-
1567
- }
1568
-
1569
- }
1570
1553
 
1571
1554
  // node builder
1572
1555
 
@@ -1746,7 +1729,7 @@ class WebGPUBackend extends Backend {
1746
1729
  }
1747
1730
 
1748
1731
  /**
1749
- * Creates the buffer of a shader attribute.
1732
+ * Creates the GPU buffer of a shader attribute.
1750
1733
  *
1751
1734
  * @param {BufferAttribute} attribute - The buffer attribute.
1752
1735
  */
@@ -1757,7 +1740,7 @@ class WebGPUBackend extends Backend {
1757
1740
  }
1758
1741
 
1759
1742
  /**
1760
- * Creates the buffer of a storage attribute.
1743
+ * Creates the GPU buffer of a storage attribute.
1761
1744
  *
1762
1745
  * @param {BufferAttribute} attribute - The buffer attribute.
1763
1746
  */
@@ -1768,7 +1751,7 @@ class WebGPUBackend extends Backend {
1768
1751
  }
1769
1752
 
1770
1753
  /**
1771
- * Creates the buffer of an indirect storage attribute.
1754
+ * Creates the GPU buffer of an indirect storage attribute.
1772
1755
  *
1773
1756
  * @param {BufferAttribute} attribute - The buffer attribute.
1774
1757
  */
@@ -1779,7 +1762,7 @@ class WebGPUBackend extends Backend {
1779
1762
  }
1780
1763
 
1781
1764
  /**
1782
- * Updates the buffer of a shader attribute.
1765
+ * Updates the GPU buffer of a shader attribute.
1783
1766
  *
1784
1767
  * @param {BufferAttribute} attribute - The buffer attribute to update.
1785
1768
  */
@@ -1790,7 +1773,7 @@ class WebGPUBackend extends Backend {
1790
1773
  }
1791
1774
 
1792
1775
  /**
1793
- * Destroys the buffer of a shader attribute.
1776
+ * Destroys the GPU buffer of a shader attribute.
1794
1777
  *
1795
1778
  * @param {BufferAttribute} attribute - The buffer attribute to destroy.
1796
1779
  */
@@ -7,6 +7,7 @@ import BasicNodeLibrary from './nodes/BasicNodeLibrary.js';
7
7
  * This alternative version of {@link WebGPURenderer} only supports node materials.
8
8
  * So classes like `MeshBasicMaterial` are not compatible.
9
9
  *
10
+ * @private
10
11
  * @augments module:Renderer~Renderer
11
12
  */
12
13
  class WebGPURenderer extends Renderer {
@@ -20,10 +21,11 @@ class WebGPURenderer extends Renderer {
20
21
  * @param {Boolean} [parameters.depth=true] - Whether the default framebuffer should have a depth buffer or not.
21
22
  * @param {Boolean} [parameters.stencil=false] - Whether the default framebuffer should have a stencil buffer or not.
22
23
  * @param {Boolean} [parameters.antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not.
23
- * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0
24
- * to overwrite the default.
25
- * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses it
26
- * WebGL 2 backend no matter if WebGPU is supported or not.
24
+ * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default.
25
+ * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses it WebGL 2 backend no matter if WebGPU is supported or not.
26
+ * @param {Number} [parameters.outputType=undefined] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead.
27
+ * @param {Number} [parameters.colorBufferType=HalfFloatType] - Defines the type of color buffers. The default `HalfFloatType` is recommend for best
28
+ * quality. To save memory and bandwidth, `UnsignedByteType` might be used. This will reduce rendering quality though.
27
29
  */
28
30
  constructor( parameters = {} ) {
29
31
 
@@ -35,10 +35,11 @@ class WebGPURenderer extends Renderer {
35
35
  * @param {Boolean} [parameters.depth=true] - Whether the default framebuffer should have a depth buffer or not.
36
36
  * @param {Boolean} [parameters.stencil=false] - Whether the default framebuffer should have a stencil buffer or not.
37
37
  * @param {Boolean} [parameters.antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not.
38
- * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0
39
- * to overwrite the default.
40
- * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses it
41
- * WebGL 2 backend no matter if WebGPU is supported or not.
38
+ * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default.
39
+ * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not.
40
+ * @param {Number} [parameters.outputType=undefined] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead.
41
+ * @param {Number} [parameters.colorBufferType=HalfFloatType] - Defines the type of color buffers. The default `HalfFloatType` is recommend for best
42
+ * quality. To save memory and bandwidth, `UnsignedByteType` might be used. This will reduce rendering quality though.
42
43
  */
43
44
  constructor( parameters = {} ) {
44
45