super-three 0.160.0 → 0.161.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 (145) hide show
  1. package/LICENSE +1 -1
  2. package/build/three.cjs +380 -109
  3. package/build/three.module.js +381 -109
  4. package/build/three.module.min.js +1 -1
  5. package/examples/jsm/Addons.js +5 -1
  6. package/examples/jsm/capabilities/WebGPU.js +13 -9
  7. package/examples/jsm/controls/OrbitControls.js +102 -13
  8. package/examples/jsm/curves/NURBSUtils.js +59 -4
  9. package/examples/jsm/curves/NURBSVolume.js +62 -0
  10. package/examples/jsm/exporters/USDZExporter.js +8 -7
  11. package/examples/jsm/helpers/TextureHelper.js +3 -3
  12. package/examples/jsm/loaders/3DMLoader.js +44 -43
  13. package/examples/jsm/loaders/DDSLoader.js +1 -0
  14. package/examples/jsm/loaders/KTX2Loader.js +20 -5
  15. package/examples/jsm/loaders/LUT3dlLoader.js +78 -46
  16. package/examples/jsm/loaders/LUTCubeLoader.js +81 -67
  17. package/examples/jsm/loaders/LUTImageLoader.js +3 -2
  18. package/examples/jsm/loaders/MaterialXLoader.js +115 -16
  19. package/examples/jsm/loaders/SVGLoader.js +4 -3
  20. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  21. package/examples/jsm/materials/MeshPostProcessingMaterial.js +144 -0
  22. package/examples/jsm/misc/Timer.js +13 -4
  23. package/examples/jsm/nodes/Nodes.js +16 -5
  24. package/examples/jsm/nodes/accessors/BufferAttributeNode.js +5 -3
  25. package/examples/jsm/nodes/accessors/CameraNode.js +9 -4
  26. package/examples/jsm/nodes/accessors/CubeTextureNode.js +12 -1
  27. package/examples/jsm/nodes/accessors/StorageBufferNode.js +27 -0
  28. package/examples/jsm/nodes/accessors/TextureStoreNode.js +56 -3
  29. package/examples/jsm/nodes/accessors/VertexColorNode.js +70 -0
  30. package/examples/jsm/nodes/core/AttributeNode.js +1 -1
  31. package/examples/jsm/nodes/core/NodeBuilder.js +23 -18
  32. package/examples/jsm/nodes/core/NodeFrame.js +16 -8
  33. package/examples/jsm/nodes/core/constants.js +1 -0
  34. package/examples/jsm/nodes/display/AfterImageNode.js +148 -0
  35. package/examples/jsm/nodes/display/AnamorphicNode.js +148 -0
  36. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +3 -0
  37. package/examples/jsm/nodes/display/GaussianBlurNode.js +33 -13
  38. package/examples/jsm/nodes/display/PassNode.js +3 -2
  39. package/examples/jsm/nodes/display/ToneMappingNode.js +46 -3
  40. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +1 -4
  41. package/examples/jsm/nodes/display/ViewportNode.js +0 -2
  42. package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +4 -4
  43. package/examples/jsm/nodes/fog/FogNode.js +2 -1
  44. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  45. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +13 -5
  46. package/examples/jsm/nodes/lighting/LightingContextNode.js +1 -1
  47. package/examples/jsm/nodes/lighting/LightsNode.js +1 -1
  48. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +18 -30
  49. package/examples/jsm/nodes/materials/Materials.js +1 -0
  50. package/examples/jsm/nodes/materials/MeshSSSNodeMaterial.js +84 -0
  51. package/examples/jsm/nodes/materials/NodeMaterial.js +6 -4
  52. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +1 -7
  53. package/examples/jsm/nodes/math/MathNode.js +12 -2
  54. package/examples/jsm/nodes/math/MathUtils.js +15 -0
  55. package/examples/jsm/nodes/math/OperatorNode.js +13 -5
  56. package/examples/jsm/nodes/math/TriNoise3D.js +71 -0
  57. package/examples/jsm/nodes/shadernode/ShaderNode.js +10 -1
  58. package/examples/jsm/nodes/utils/ArrayElementNode.js +6 -0
  59. package/examples/jsm/nodes/utils/JoinNode.js +2 -2
  60. package/examples/jsm/nodes/utils/LoopNode.js +3 -3
  61. package/examples/jsm/nodes/utils/ReflectorNode.js +227 -0
  62. package/examples/jsm/nodes/utils/RotateNode.js +68 -0
  63. package/examples/jsm/nodes/utils/RotateUVNode.js +1 -9
  64. package/examples/jsm/nodes/utils/SplitNode.js +4 -4
  65. package/examples/jsm/objects/GroundedSkybox.js +50 -0
  66. package/examples/jsm/objects/QuadMesh.js +8 -2
  67. package/examples/jsm/objects/Water2.js +8 -8
  68. package/examples/jsm/postprocessing/GTAOPass.js +11 -1
  69. package/examples/jsm/renderers/common/Backend.js +14 -0
  70. package/examples/jsm/renderers/common/Bindings.js +1 -1
  71. package/examples/jsm/renderers/common/DataMap.js +1 -1
  72. package/examples/jsm/renderers/common/Info.js +25 -1
  73. package/examples/jsm/renderers/common/Pipelines.js +8 -8
  74. package/examples/jsm/renderers/common/PostProcessing.js +2 -2
  75. package/examples/jsm/renderers/common/ProgrammableStage.js +3 -1
  76. package/examples/jsm/renderers/common/RenderObject.js +2 -0
  77. package/examples/jsm/renderers/common/Renderer.js +238 -22
  78. package/examples/jsm/renderers/common/StorageBufferAttribute.js +17 -0
  79. package/examples/jsm/renderers/common/Textures.js +25 -5
  80. package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +2 -1
  81. package/examples/jsm/renderers/common/nodes/Nodes.js +4 -2
  82. package/examples/jsm/renderers/webgl/WebGLBackend.js +631 -270
  83. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +37 -30
  84. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +89 -8
  85. package/examples/jsm/renderers/webgl/utils/WebGLConstants.js +11 -0
  86. package/examples/jsm/renderers/webgl/utils/WebGLState.js +197 -0
  87. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +377 -11
  88. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +2 -2
  89. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +1 -21
  90. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +2 -2
  91. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +289 -102
  92. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +7 -2
  93. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +56 -39
  94. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +9 -1
  95. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +38 -4
  96. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +85 -12
  97. package/examples/jsm/transpiler/AST.js +1 -1
  98. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  99. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  100. package/examples/jsm/transpiler/TSLEncoder.js +1 -1
  101. package/examples/jsm/utils/BufferGeometryUtils.js +23 -27
  102. package/examples/jsm/utils/SortUtils.js +2 -0
  103. package/examples/jsm/webxr/ARButton.js +12 -2
  104. package/examples/jsm/webxr/VRButton.js +12 -2
  105. package/examples/jsm/webxr/XRButton.js +12 -2
  106. package/examples/jsm/webxr/XRControllerModelFactory.js +6 -1
  107. package/examples/jsm/webxr/XRHandMeshModel.js +3 -1
  108. package/package.json +2 -2
  109. package/src/audio/Audio.js +1 -3
  110. package/src/cameras/PerspectiveCamera.js +35 -0
  111. package/src/constants.js +1 -2
  112. package/src/core/BufferAttribute.js +2 -1
  113. package/src/core/InterleavedBuffer.js +2 -1
  114. package/src/core/InterleavedBufferAttribute.js +20 -0
  115. package/src/materials/ShaderMaterial.js +2 -1
  116. package/src/math/Triangle.js +0 -30
  117. package/src/objects/BatchedMesh.js +6 -7
  118. package/src/objects/SkinnedMesh.js +0 -8
  119. package/src/renderers/WebGLRenderer.js +6 -2
  120. package/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl.js +9 -0
  121. package/src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl.js +56 -11
  122. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +15 -7
  123. package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -2
  124. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +1 -2
  125. package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +1 -1
  126. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +1 -2
  127. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +1 -1
  128. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +1 -2
  129. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +3 -1
  130. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +1 -1
  131. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +1 -1
  132. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +1 -1
  133. package/src/renderers/shaders/ShaderLib/points.glsl.js +1 -1
  134. package/src/renderers/shaders/ShaderLib/sprite.glsl.js +1 -1
  135. package/src/renderers/webgl/WebGLAttributes.js +2 -2
  136. package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
  137. package/src/renderers/webgl/WebGLProgram.js +30 -3
  138. package/src/renderers/webgl/WebGLPrograms.js +19 -11
  139. package/src/renderers/webgl/WebGLTextures.js +90 -16
  140. package/src/renderers/webxr/WebXRDepthSensing.js +105 -0
  141. package/src/renderers/webxr/WebXRManager.js +46 -0
  142. package/src/textures/Source.js +1 -0
  143. package/build/three.js +0 -54519
  144. package/build/three.min.js +0 -7
  145. package/examples/jsm/objects/GroundProjectedSkybox.js +0 -172
@@ -2,28 +2,19 @@
2
2
  import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js';
3
3
  //*/
4
4
 
5
+ import { WebGPUCoordinateSystem } from 'three';
6
+
5
7
  import { GPUFeatureName, GPUTextureFormat, GPULoadOp, GPUStoreOp, GPUIndexFormat, GPUTextureViewDimension } from './utils/WebGPUConstants.js';
6
8
 
7
9
  import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js';
8
10
  import Backend from '../common/Backend.js';
9
11
 
10
- import { DepthFormat, WebGPUCoordinateSystem } from 'three';
11
-
12
12
  import WebGPUUtils from './utils/WebGPUUtils.js';
13
13
  import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js';
14
14
  import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js';
15
15
  import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js';
16
16
  import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js';
17
-
18
- // statics
19
-
20
- let _staticAdapter = null;
21
-
22
- if ( navigator.gpu !== undefined ) {
23
-
24
- _staticAdapter = await navigator.gpu.requestAdapter();
25
-
26
- }
17
+ import WebGPU from '../../capabilities/WebGPU.js';
27
18
 
28
19
  //
29
20
 
@@ -36,6 +27,7 @@ class WebGPUBackend extends Backend {
36
27
  this.isWebGPUBackend = true;
37
28
 
38
29
  // some parameters require default values other than "undefined"
30
+ this.parameters.alpha = ( parameters.alpha === undefined ) ? true : parameters.alpha;
39
31
 
40
32
  this.parameters.antialias = ( parameters.antialias === true );
41
33
 
@@ -51,10 +43,13 @@ class WebGPUBackend extends Backend {
51
43
 
52
44
  this.parameters.requiredLimits = ( parameters.requiredLimits === undefined ) ? {} : parameters.requiredLimits;
53
45
 
46
+ this.trackTimestamp = ( parameters.trackTimestamp === true );
47
+
54
48
  this.adapter = null;
55
49
  this.device = null;
56
50
  this.context = null;
57
51
  this.colorBuffer = null;
52
+ this.defaultRenderPassdescriptor = null;
58
53
 
59
54
  this.utils = new WebGPUUtils( this );
60
55
  this.attributeUtils = new WebGPUAttributeUtils( this );
@@ -114,11 +109,13 @@ class WebGPUBackend extends Backend {
114
109
  this.device = device;
115
110
  this.context = context;
116
111
 
112
+ const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque';
113
+
117
114
  this.context.configure( {
118
115
  device: this.device,
119
116
  format: GPUTextureFormat.BGRA8Unorm,
120
117
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
121
- alphaMode: 'premultiplied'
118
+ alphaMode: alphaMode
122
119
  } );
123
120
 
124
121
  this.updateSize();
@@ -137,60 +134,94 @@ class WebGPUBackend extends Backend {
137
134
 
138
135
  }
139
136
 
140
- beginRender( renderContext ) {
137
+ getContext() {
141
138
 
142
- const renderContextData = this.get( renderContext );
139
+ return this.context;
143
140
 
144
- const device = this.device;
145
- const occlusionQueryCount = renderContext.occlusionQueryCount;
141
+ }
146
142
 
147
- let occlusionQuerySet;
143
+ _getDefaultRenderPassDescriptor() {
148
144
 
149
- if ( occlusionQueryCount > 0 ) {
145
+ let descriptor = this.defaultRenderPassdescriptor;
150
146
 
151
- if ( renderContextData.currentOcclusionQuerySet ) renderContextData.currentOcclusionQuerySet.destroy();
152
- if ( renderContextData.currentOcclusionQueryBuffer ) renderContextData.currentOcclusionQueryBuffer.destroy();
147
+ const antialias = this.parameters.antialias;
153
148
 
154
- // Get a reference to the array of objects with queries. The renderContextData property
155
- // can be changed by another render pass before the buffer.mapAsyc() completes.
156
- renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet;
157
- renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer;
158
- renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects;
149
+ if ( descriptor === null ) {
159
150
 
160
- //
151
+ const renderer = this.renderer;
161
152
 
162
- occlusionQuerySet = device.createQuerySet( { type: 'occlusion', count: occlusionQueryCount } );
153
+ descriptor = {
154
+ colorAttachments: [ {
155
+ view: null
156
+ } ],
157
+ depthStencilAttachment: {
158
+ view: this.textureUtils.getDepthBuffer( renderer.depth, renderer.stencil ).createView()
159
+ }
160
+ };
163
161
 
164
- renderContextData.occlusionQuerySet = occlusionQuerySet;
165
- renderContextData.occlusionQueryIndex = 0;
166
- renderContextData.occlusionQueryObjects = new Array( occlusionQueryCount );
162
+ const colorAttachment = descriptor.colorAttachments[ 0 ];
167
163
 
168
- renderContextData.lastOcclusionObject = null;
164
+ if ( antialias === true ) {
169
165
 
170
- }
166
+ colorAttachment.view = this.colorBuffer.createView();
171
167
 
172
- const descriptor = {
173
- colorAttachments: [ {
174
- view: null
175
- } ],
176
- depthStencilAttachment: {
177
- view: null
178
- },
179
- occlusionQuerySet
180
- };
168
+ } else {
169
+
170
+ colorAttachment.resolveTarget = undefined;
171
+
172
+ }
173
+
174
+ this.defaultRenderPassdescriptor = descriptor;
175
+
176
+ }
181
177
 
182
178
  const colorAttachment = descriptor.colorAttachments[ 0 ];
183
- const depthStencilAttachment = descriptor.depthStencilAttachment;
184
179
 
185
- const antialias = this.parameters.antialias;
180
+ if ( antialias === true ) {
186
181
 
187
- if ( renderContext.textures !== null ) {
182
+ colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
188
183
 
189
- const textures = renderContext.textures;
184
+ } else {
190
185
 
191
- descriptor.colorAttachments = [];
186
+ colorAttachment.view = this.context.getCurrentTexture().createView();
192
187
 
193
- const colorAttachments = descriptor.colorAttachments;
188
+ }
189
+
190
+ return descriptor;
191
+
192
+ }
193
+
194
+ _getRenderPassDescriptor( renderContext ) {
195
+
196
+ const renderTarget = renderContext.renderTarget;
197
+ const renderTargetData = this.get( renderTarget );
198
+
199
+ let descriptors = renderTargetData.descriptors;
200
+
201
+ if ( descriptors === undefined ) {
202
+
203
+ descriptors = [];
204
+
205
+ renderTargetData.descriptors = descriptors;
206
+
207
+ }
208
+
209
+ if ( renderTargetData.width !== renderTarget.width ||
210
+ renderTargetData.height !== renderTarget.height ||
211
+ renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel ||
212
+ renderTargetData.samples !== renderTarget.samples
213
+ ) {
214
+
215
+ descriptors.length = 0;
216
+
217
+ }
218
+
219
+ let descriptor = descriptors[ renderContext.activeCubeFace ];
220
+
221
+ if ( descriptor === undefined ) {
222
+
223
+ const textures = renderContext.textures;
224
+ const colorAttachments = [];
194
225
 
195
226
  for ( let i = 0; i < textures.length; i ++ ) {
196
227
 
@@ -228,32 +259,78 @@ class WebGPUBackend extends Backend {
228
259
 
229
260
  const depthTextureData = this.get( renderContext.depthTexture );
230
261
 
231
- depthStencilAttachment.view = depthTextureData.texture.createView();
262
+ const depthStencilAttachment = {
263
+ view: depthTextureData.texture.createView(),
264
+ };
232
265
 
233
- if ( renderContext.stencil && renderContext.depthTexture.format === DepthFormat ) {
266
+ descriptor = {
267
+ colorAttachments,
268
+ depthStencilAttachment
269
+ };
234
270
 
235
- renderContext.stencil = false;
271
+ descriptors[ renderContext.activeCubeFace ] = descriptor;
236
272
 
237
- }
273
+ renderTargetData.width = renderTarget.width;
274
+ renderTargetData.height = renderTarget.height;
275
+ renderTargetData.samples = renderTarget.samples;
276
+ renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel;
238
277
 
239
- } else {
278
+ }
240
279
 
241
- if ( antialias === true ) {
280
+ return descriptor;
242
281
 
243
- colorAttachment.view = this.colorBuffer.createView();
244
- colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
282
+ }
245
283
 
246
- } else {
284
+ beginRender( renderContext ) {
247
285
 
248
- colorAttachment.view = this.context.getCurrentTexture().createView();
249
- colorAttachment.resolveTarget = undefined;
286
+ const renderContextData = this.get( renderContext );
250
287
 
251
- }
288
+ const device = this.device;
289
+ const occlusionQueryCount = renderContext.occlusionQueryCount;
290
+
291
+ let occlusionQuerySet;
292
+
293
+ if ( occlusionQueryCount > 0 ) {
294
+
295
+ if ( renderContextData.currentOcclusionQuerySet ) renderContextData.currentOcclusionQuerySet.destroy();
296
+ if ( renderContextData.currentOcclusionQueryBuffer ) renderContextData.currentOcclusionQueryBuffer.destroy();
297
+
298
+ // Get a reference to the array of objects with queries. The renderContextData property
299
+ // can be changed by another render pass before the buffer.mapAsyc() completes.
300
+ renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet;
301
+ renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer;
302
+ renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects;
303
+
304
+ //
305
+
306
+ occlusionQuerySet = device.createQuerySet( { type: 'occlusion', count: occlusionQueryCount } );
307
+
308
+ renderContextData.occlusionQuerySet = occlusionQuerySet;
309
+ renderContextData.occlusionQueryIndex = 0;
310
+ renderContextData.occlusionQueryObjects = new Array( occlusionQueryCount );
311
+
312
+ renderContextData.lastOcclusionObject = null;
313
+
314
+ }
315
+
316
+ let descriptor;
252
317
 
253
- depthStencilAttachment.view = this.textureUtils.getDepthBuffer( renderContext.depth, renderContext.stencil ).createView();
318
+ if ( renderContext.textures === null ) {
319
+
320
+ descriptor = this._getDefaultRenderPassDescriptor();
321
+
322
+ } else {
323
+
324
+ descriptor = this._getRenderPassDescriptor( renderContext );
254
325
 
255
326
  }
256
327
 
328
+ this.initTimestampQuery( renderContext, descriptor );
329
+
330
+ descriptor.occlusionQuerySet = occlusionQuerySet;
331
+
332
+ const depthStencilAttachment = descriptor.depthStencilAttachment;
333
+
257
334
  if ( renderContext.textures !== null ) {
258
335
 
259
336
  const colorAttachments = descriptor.colorAttachments;
@@ -277,9 +354,10 @@ class WebGPUBackend extends Backend {
277
354
 
278
355
  }
279
356
 
280
-
281
357
  } else {
282
358
 
359
+ const colorAttachment = descriptor.colorAttachments[ 0 ];
360
+
283
361
  if ( renderContext.clearColor ) {
284
362
 
285
363
  colorAttachment.clearValue = renderContext.clearColorValue;
@@ -416,8 +494,11 @@ class WebGPUBackend extends Backend {
416
494
 
417
495
  }
418
496
 
497
+ this.prepareTimestampBuffer( renderContext, renderContextData.encoder );
498
+
419
499
  this.device.queue.submit( [ renderContextData.encoder.finish() ] );
420
500
 
501
+
421
502
  //
422
503
 
423
504
  if ( renderContext.textures !== null ) {
@@ -468,7 +549,7 @@ class WebGPUBackend extends Backend {
468
549
  const buffer = currentOcclusionQueryBuffer.getMappedRange();
469
550
  const results = new BigUint64Array( buffer );
470
551
 
471
- for ( let i = 0; i < currentOcclusionQueryObjects.length; i++ ) {
552
+ for ( let i = 0; i < currentOcclusionQueryObjects.length; i ++ ) {
472
553
 
473
554
  if ( results[ i ] !== 0n ) {
474
555
 
@@ -489,7 +570,7 @@ class WebGPUBackend extends Backend {
489
570
  updateViewport( renderContext ) {
490
571
 
491
572
  const { currentPass } = this.get( renderContext );
492
- let { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue;
573
+ const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue;
493
574
 
494
575
  currentPass.setViewport( x, renderContext.height - height - y, width, height, minDepth, maxDepth );
495
576
 
@@ -500,7 +581,7 @@ class WebGPUBackend extends Backend {
500
581
  const device = this.device;
501
582
  const renderer = this.renderer;
502
583
 
503
- const colorAttachments = [];
584
+ let colorAttachments = [];
504
585
 
505
586
  let depthStencilAttachment;
506
587
  let clearValue;
@@ -524,36 +605,23 @@ class WebGPUBackend extends Backend {
524
605
  depth = depth && supportsDepth;
525
606
  stencil = stencil && supportsStencil;
526
607
 
527
- if ( color ) {
528
-
529
- const antialias = this.parameters.antialias;
608
+ const descriptor = this._getDefaultRenderPassDescriptor();
530
609
 
531
- const colorAttachment = {};
610
+ if ( color ) {
532
611
 
533
- if ( antialias === true ) {
612
+ colorAttachments = descriptor.colorAttachments;
534
613
 
535
- colorAttachment.view = this.colorBuffer.createView();
536
- colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
537
-
538
- } else {
539
-
540
- colorAttachment.view = this.context.getCurrentTexture().createView();
541
-
542
- }
614
+ const colorAttachment = colorAttachments[ 0 ];
543
615
 
544
616
  colorAttachment.clearValue = clearValue;
545
617
  colorAttachment.loadOp = GPULoadOp.Clear;
546
618
  colorAttachment.storeOp = GPUStoreOp.Store;
547
619
 
548
- colorAttachments.push( colorAttachment );
549
-
550
620
  }
551
621
 
552
622
  if ( depth || stencil ) {
553
623
 
554
- depthStencilAttachment = {
555
- view: this.textureUtils.getDepthBuffer( renderer.depth, renderer.stencil ).createView()
556
- };
624
+ depthStencilAttachment = descriptor.depthStencilAttachment;
557
625
 
558
626
  }
559
627
 
@@ -664,8 +732,14 @@ class WebGPUBackend extends Backend {
664
732
 
665
733
  const groupGPU = this.get( computeGroup );
666
734
 
667
- groupGPU.cmdEncoderGPU = this.device.createCommandEncoder( {} );
668
- groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass();
735
+
736
+ const descriptor = {};
737
+
738
+ this.initTimestampQuery( computeGroup, descriptor );
739
+
740
+ groupGPU.cmdEncoderGPU = this.device.createCommandEncoder();
741
+
742
+ groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass( descriptor );
669
743
 
670
744
  }
671
745
 
@@ -692,6 +766,9 @@ class WebGPUBackend extends Backend {
692
766
  const groupData = this.get( computeGroup );
693
767
 
694
768
  groupData.passEncoderGPU.end();
769
+
770
+ this.prepareTimestampBuffer( computeGroup, groupData.cmdEncoderGPU );
771
+
695
772
  this.device.queue.submit( [ groupData.cmdEncoderGPU.finish() ] );
696
773
 
697
774
  }
@@ -768,7 +845,7 @@ class WebGPUBackend extends Backend {
768
845
 
769
846
  // occlusion queries - handle multiple consecutive draw calls for an object
770
847
 
771
- if ( contextData.occlusionQuerySet !== undefined ) {
848
+ if ( contextData.occlusionQuerySet !== undefined ) {
772
849
 
773
850
  const lastObject = contextData.lastOcclusionObject;
774
851
 
@@ -852,7 +929,7 @@ class WebGPUBackend extends Backend {
852
929
  data.side !== material.side || data.alphaToCoverage !== material.alphaToCoverage ||
853
930
  data.sampleCount !== sampleCount || data.colorSpace !== colorSpace ||
854
931
  data.colorFormat !== colorFormat || data.depthStencilFormat !== depthStencilFormat ||
855
- data.primitiveTopology !== primitiveTopology
932
+ data.primitiveTopology !== primitiveTopology
856
933
  ) {
857
934
 
858
935
  data.material = material; data.materialVersion = material.version;
@@ -953,6 +1030,87 @@ class WebGPUBackend extends Backend {
953
1030
 
954
1031
  }
955
1032
 
1033
+
1034
+ initTimestampQuery( renderContext, descriptor ) {
1035
+
1036
+ if ( ! this.hasFeature( GPUFeatureName.TimestampQuery ) || ! this.trackTimestamp ) return;
1037
+
1038
+ const renderContextData = this.get( renderContext );
1039
+
1040
+ if ( ! renderContextData.timeStampQuerySet ) {
1041
+
1042
+ // Create a GPUQuerySet which holds 2 timestamp query results: one for the
1043
+ // beginning and one for the end of compute pass execution.
1044
+ const timeStampQuerySet = this.device.createQuerySet( { type: 'timestamp', count: 2 } );
1045
+
1046
+ const timestampWrites = {
1047
+ querySet: timeStampQuerySet,
1048
+ beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins.
1049
+ endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends.
1050
+ };
1051
+ Object.assign( descriptor, {
1052
+ timestampWrites,
1053
+ } );
1054
+ renderContextData.timeStampQuerySet = timeStampQuerySet;
1055
+
1056
+ }
1057
+
1058
+ }
1059
+
1060
+ // timestamp utils
1061
+
1062
+ prepareTimestampBuffer( renderContext, encoder ) {
1063
+
1064
+ if ( ! this.hasFeature( GPUFeatureName.TimestampQuery ) || ! this.trackTimestamp ) return;
1065
+
1066
+ const renderContextData = this.get( renderContext );
1067
+
1068
+ const size = 2 * BigInt64Array.BYTES_PER_ELEMENT;
1069
+ const resolveBuffer = this.device.createBuffer( {
1070
+ size,
1071
+ usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
1072
+ } );
1073
+
1074
+ const resultBuffer = this.device.createBuffer( {
1075
+ size,
1076
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
1077
+ } );
1078
+
1079
+ encoder.resolveQuerySet( renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0 );
1080
+ encoder.copyBufferToBuffer( resolveBuffer, 0, resultBuffer, 0, size );
1081
+
1082
+ renderContextData.currentTimestampQueryBuffer = resultBuffer;
1083
+
1084
+ }
1085
+
1086
+ async resolveTimestampAsync( renderContext, type = 'render' ) {
1087
+
1088
+ if ( ! this.hasFeature( GPUFeatureName.TimestampQuery ) || ! this.trackTimestamp ) return;
1089
+
1090
+ const renderContextData = this.get( renderContext );
1091
+
1092
+ // handle timestamp query results
1093
+
1094
+ const { currentTimestampQueryBuffer } = renderContextData;
1095
+
1096
+ if ( currentTimestampQueryBuffer ) {
1097
+
1098
+ renderContextData.currentTimestampQueryBuffer = null;
1099
+
1100
+ await currentTimestampQueryBuffer.mapAsync( GPUMapMode.READ );
1101
+
1102
+ const times = new BigUint64Array( currentTimestampQueryBuffer.getMappedRange() );
1103
+
1104
+ const duration = Number( times[ 1 ] - times[ 0 ] ) / 1000000;
1105
+ // console.log( `Compute ${type} duration: ${Number( times[ 1 ] - times[ 0 ] ) / 1000000}ms` );
1106
+ this.renderer.info.updateTimestamp( type, duration );
1107
+
1108
+ currentTimestampQueryBuffer.unmap();
1109
+
1110
+ }
1111
+
1112
+ }
1113
+
956
1114
  // node builder
957
1115
 
958
1116
  createNodeBuilder( object, renderer, scene = null ) {
@@ -982,9 +1140,9 @@ class WebGPUBackend extends Backend {
982
1140
 
983
1141
  // pipelines
984
1142
 
985
- createRenderPipeline( renderObject ) {
1143
+ createRenderPipeline( renderObject, promises ) {
986
1144
 
987
- this.pipelineUtils.createRenderPipeline( renderObject );
1145
+ this.pipelineUtils.createRenderPipeline( renderObject, promises );
988
1146
 
989
1147
  }
990
1148
 
@@ -1051,7 +1209,8 @@ class WebGPUBackend extends Backend {
1051
1209
  updateSize() {
1052
1210
 
1053
1211
  this.colorBuffer = this.textureUtils.getColorBuffer();
1054
-
1212
+ this.defaultRenderPassdescriptor = null;
1213
+
1055
1214
  }
1056
1215
 
1057
1216
  // utils public
@@ -1062,23 +1221,27 @@ class WebGPUBackend extends Backend {
1062
1221
 
1063
1222
  }
1064
1223
 
1065
- hasFeature( name ) {
1224
+ async hasFeatureAsync( name ) {
1066
1225
 
1067
- const adapter = this.adapter || _staticAdapter;
1226
+ const adapter = this.adapter || await WebGPU.getStaticAdapter();
1068
1227
 
1069
1228
  //
1070
1229
 
1071
- const features = Object.values( GPUFeatureName );
1230
+ return adapter.features.has( name );
1072
1231
 
1073
- if ( features.includes( name ) === false ) {
1232
+ }
1074
1233
 
1075
- throw new Error( 'THREE.WebGPURenderer: Unknown WebGPU GPU feature: ' + name );
1234
+ hasFeature( name ) {
1076
1235
 
1077
- }
1236
+ if ( ! this.adapter ) {
1078
1237
 
1079
- //
1238
+ console.warn( 'WebGPUBackend: WebGPU adapter has not been initialized yet. Please use detectSupportAsync instead' );
1080
1239
 
1081
- return adapter.features.has( name );
1240
+ return false;
1241
+
1242
+ }
1243
+
1244
+ return this.adapter.features.has( name );
1082
1245
 
1083
1246
  }
1084
1247
 
@@ -1090,18 +1253,42 @@ class WebGPUBackend extends Backend {
1090
1253
 
1091
1254
  let sourceGPU = null;
1092
1255
 
1093
- if ( texture.isFramebufferTexture ) {
1256
+ if ( renderContext.renderTarget ) {
1257
+
1258
+ if ( texture.isDepthTexture ) {
1259
+
1260
+ sourceGPU = this.get( renderContext.depthTexture ).texture;
1261
+
1262
+ } else {
1263
+
1264
+ sourceGPU = this.get( renderContext.textures[ 0 ] ).texture;
1094
1265
 
1095
- sourceGPU = this.context.getCurrentTexture();
1266
+ }
1267
+
1268
+ } else {
1096
1269
 
1097
- } else if ( texture.isDepthTexture ) {
1270
+ if ( texture.isDepthTexture ) {
1098
1271
 
1099
- sourceGPU = this.textureUtils.getDepthBuffer( renderContext.depth, renderContext.stencil );
1272
+ sourceGPU = this.textureUtils.getDepthBuffer( renderContext.depth, renderContext.stencil );
1273
+
1274
+ } else {
1275
+
1276
+ sourceGPU = this.context.getCurrentTexture();
1277
+
1278
+ }
1100
1279
 
1101
1280
  }
1102
1281
 
1103
1282
  const destinationGPU = this.get( texture ).texture;
1104
1283
 
1284
+ if ( sourceGPU.format !== destinationGPU.format ) {
1285
+
1286
+ console.error( 'WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.', sourceGPU.format, destinationGPU.format );
1287
+
1288
+ return;
1289
+
1290
+ }
1291
+
1105
1292
  renderContextData.currentPass.end();
1106
1293
 
1107
1294
  encoder.copyTextureToTexture(
@@ -1,7 +1,8 @@
1
+ import WebGPU from '../../capabilities/WebGPU.js';
2
+
1
3
  import Renderer from '../common/Renderer.js';
2
4
  import WebGLBackend from '../webgl/WebGLBackend.js';
3
5
  import WebGPUBackend from './WebGPUBackend.js';
4
- import WebGPU from '../../capabilities/WebGPU.js';
5
6
  /*
6
7
  const debugHandler = {
7
8
 
@@ -22,7 +23,11 @@ class WebGPURenderer extends Renderer {
22
23
 
23
24
  let BackendClass;
24
25
 
25
- if ( WebGPU.isAvailable() ) {
26
+ if ( parameters.forceWebGL ) {
27
+
28
+ BackendClass = WebGLBackend;
29
+
30
+ } else if ( WebGPU.isAvailable() ) {
26
31
 
27
32
  BackendClass = WebGPUBackend;
28
33