super-three 0.164.0 → 0.165.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 (124) hide show
  1. package/README.md +3 -3
  2. package/build/three.cjs +664 -217
  3. package/build/three.module.js +664 -217
  4. package/build/three.module.min.js +1 -1
  5. package/examples/jsm/controls/TransformControls.js +1 -1
  6. package/examples/jsm/environments/RoomEnvironment.js +1 -5
  7. package/examples/jsm/exporters/GLTFExporter.js +1 -1
  8. package/examples/jsm/exporters/USDZExporter.js +6 -4
  9. package/examples/jsm/helpers/ViewHelper.js +32 -67
  10. package/examples/jsm/libs/tween.module.js +75 -64
  11. package/examples/jsm/lines/LineMaterial.js +1 -15
  12. package/examples/jsm/lines/LineSegments2.js +15 -0
  13. package/examples/jsm/lines/Wireframe.js +16 -1
  14. package/examples/jsm/loaders/DRACOLoader.js +1 -1
  15. package/examples/jsm/loaders/FBXLoader.js +24 -13
  16. package/examples/jsm/loaders/GLTFLoader.js +2 -0
  17. package/examples/jsm/loaders/LDrawLoader.js +3 -2
  18. package/examples/jsm/loaders/MMDLoader.js +31 -12
  19. package/examples/jsm/modifiers/CurveModifier.js +11 -9
  20. package/examples/jsm/nodes/Nodes.js +12 -11
  21. package/examples/jsm/nodes/accessors/BitangentNode.js +7 -83
  22. package/examples/jsm/nodes/accessors/BufferNode.js +6 -0
  23. package/examples/jsm/nodes/accessors/CameraNode.js +12 -119
  24. package/examples/jsm/nodes/accessors/MaterialNode.js +2 -0
  25. package/examples/jsm/nodes/accessors/ModelNode.js +3 -0
  26. package/examples/jsm/nodes/accessors/NormalNode.js +9 -101
  27. package/examples/jsm/nodes/accessors/PositionNode.js +6 -100
  28. package/examples/jsm/nodes/accessors/ReferenceNode.js +6 -0
  29. package/examples/jsm/nodes/accessors/ReflectVectorNode.js +2 -31
  30. package/examples/jsm/nodes/accessors/{TextureStoreNode.js → StorageTextureNode.js} +19 -6
  31. package/examples/jsm/nodes/accessors/TangentNode.js +11 -97
  32. package/examples/jsm/nodes/accessors/Texture3DNode.js +100 -0
  33. package/examples/jsm/nodes/accessors/UVNode.js +2 -46
  34. package/examples/jsm/nodes/core/AttributeNode.js +15 -3
  35. package/examples/jsm/nodes/core/ContextNode.js +6 -0
  36. package/examples/jsm/nodes/core/Node.js +15 -2
  37. package/examples/jsm/nodes/core/NodeBuilder.js +20 -9
  38. package/examples/jsm/nodes/core/NodeKeywords.js +1 -1
  39. package/examples/jsm/nodes/core/OutputStructNode.js +1 -5
  40. package/examples/jsm/nodes/core/PropertyNode.js +1 -0
  41. package/examples/jsm/nodes/core/VaryingNode.js +40 -9
  42. package/examples/jsm/nodes/display/AfterImageNode.js +14 -2
  43. package/examples/jsm/nodes/display/PassNode.js +3 -1
  44. package/examples/jsm/nodes/display/ViewportNode.js +1 -1
  45. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +61 -17
  46. package/examples/jsm/nodes/functions/ToonLightingModel.js +49 -0
  47. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +2 -1
  48. package/examples/jsm/nodes/lighting/LightsNode.js +17 -0
  49. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +1 -1
  50. package/examples/jsm/nodes/materials/Materials.js +3 -0
  51. package/examples/jsm/nodes/materials/MeshMatcapNodeMaterial.js +52 -0
  52. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +21 -4
  53. package/examples/jsm/nodes/materials/MeshToonNodeMaterial.js +34 -0
  54. package/examples/jsm/nodes/materials/NodeMaterial.js +13 -5
  55. package/examples/jsm/nodes/materials/VolumeNodeMaterial.js +106 -0
  56. package/examples/jsm/nodes/math/HashNode.js +2 -2
  57. package/examples/jsm/nodes/shadernode/ShaderNode.js +55 -33
  58. package/examples/jsm/nodes/utils/ArrayElementNode.js +1 -1
  59. package/examples/jsm/nodes/utils/MatcapUVNode.js +1 -1
  60. package/examples/jsm/nodes/utils/TimerNode.js +1 -1
  61. package/examples/jsm/objects/Lensflare.js +2 -2
  62. package/examples/jsm/postprocessing/RenderPass.js +1 -1
  63. package/examples/jsm/renderers/CSS2DRenderer.js +25 -5
  64. package/examples/jsm/renderers/CSS3DRenderer.js +24 -3
  65. package/examples/jsm/renderers/common/Attributes.js +2 -0
  66. package/examples/jsm/renderers/common/Bindings.js +17 -0
  67. package/examples/jsm/renderers/common/ChainMap.js +18 -48
  68. package/examples/jsm/renderers/common/ClippingContext.js +4 -4
  69. package/examples/jsm/renderers/common/Pipelines.js +2 -2
  70. package/examples/jsm/renderers/common/RenderBundle.js +18 -0
  71. package/examples/jsm/renderers/common/RenderBundles.js +38 -0
  72. package/examples/jsm/renderers/common/RenderList.js +9 -0
  73. package/examples/jsm/renderers/common/RenderObject.js +6 -0
  74. package/examples/jsm/renderers/common/Renderer.js +139 -11
  75. package/examples/jsm/renderers/common/Uniform.js +1 -1
  76. package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +18 -4
  77. package/examples/jsm/renderers/common/nodes/NodeSampler.js +6 -0
  78. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +17 -5
  79. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +93 -6
  80. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +50 -4
  81. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +69 -11
  82. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +10 -1
  83. package/examples/jsm/renderers/webgpu/utils/WebGPUConstants.js +6 -0
  84. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +62 -19
  85. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -3
  86. package/examples/jsm/utils/BufferGeometryUtils.js +18 -16
  87. package/examples/jsm/utils/GPUStatsPanel.js +2 -0
  88. package/examples/jsm/utils/SortUtils.js +8 -5
  89. package/package.json +3 -2
  90. package/src/animation/tracks/BooleanKeyframeTrack.js +10 -1
  91. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -2
  92. package/src/animation/tracks/StringKeyframeTrack.js +10 -1
  93. package/src/constants.js +1 -1
  94. package/src/core/Object3D.js +2 -0
  95. package/src/core/Raycaster.js +6 -2
  96. package/src/loaders/FileLoader.js +4 -0
  97. package/src/loaders/LoaderUtils.js +3 -1
  98. package/src/loaders/ObjectLoader.js +1 -0
  99. package/src/objects/BatchedMesh.js +91 -1
  100. package/src/renderers/WebGLRenderer.js +288 -57
  101. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +15 -0
  102. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -1
  103. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +9 -1
  104. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +8 -22
  105. package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +1 -1
  106. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +1 -1
  107. package/src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl.js +3 -14
  108. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +10 -31
  109. package/src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl.js +3 -23
  110. package/src/renderers/webgl/WebGLBackground.js +6 -0
  111. package/src/renderers/webgl/WebGLExtensions.js +3 -1
  112. package/src/renderers/webgl/WebGLLights.js +9 -12
  113. package/src/renderers/webgl/WebGLMaterials.js +1 -5
  114. package/src/renderers/webgl/WebGLMorphtargets.js +1 -2
  115. package/src/renderers/webgl/WebGLProgram.js +2 -31
  116. package/src/renderers/webgl/WebGLPrograms.js +14 -14
  117. package/src/renderers/webgl/WebGLRenderStates.js +2 -2
  118. package/src/renderers/webgl/WebGLTextures.js +139 -70
  119. package/src/renderers/webxr/WebXRDepthSensing.js +3 -3
  120. package/src/renderers/webxr/WebXRManager.js +6 -2
  121. package/src/textures/CompressedArrayTexture.js +14 -0
  122. package/src/textures/DataArrayTexture.js +14 -0
  123. package/src/textures/DepthTexture.js +1 -3
  124. package/src/utils.js +30 -1
@@ -226,6 +226,12 @@ export default class RenderObject {
226
226
 
227
227
  cacheKey += object._matricesTexture.uuid + ',';
228
228
 
229
+ if ( object._colorsTexture !== null ) {
230
+
231
+ cacheKey += object._colorsTexture.uuid + ',';
232
+
233
+ }
234
+
229
235
  }
230
236
 
231
237
  return cacheKey;
@@ -15,6 +15,7 @@ import ClippingContext from './ClippingContext.js';
15
15
  import { Scene, Frustum, Matrix4, Vector2, Vector3, Vector4, DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoColorSpace, NoToneMapping, LinearFilter, LinearSRGBColorSpace, RenderTarget, HalfFloatType, RGBAFormat } from 'three';
16
16
  import { NodeMaterial } from '../../nodes/Nodes.js';
17
17
  import QuadMesh from '../../objects/QuadMesh.js';
18
+ import RenderBundles from './RenderBundles.js';
18
19
 
19
20
  const _scene = new Scene();
20
21
  const _drawingBufferSize = new Vector2();
@@ -87,6 +88,7 @@ class Renderer {
87
88
  this._bindings = null;
88
89
  this._objects = null;
89
90
  this._pipelines = null;
91
+ this._bundles = null;
90
92
  this._renderLists = null;
91
93
  this._renderContexts = null;
92
94
  this._textures = null;
@@ -111,6 +113,7 @@ class Renderer {
111
113
 
112
114
  this._renderObjectFunction = null;
113
115
  this._currentRenderObjectFunction = null;
116
+ this._currentRenderBundle = null;
114
117
 
115
118
  this._handleObjectFunction = this._renderObjectDirect;
116
119
 
@@ -171,6 +174,7 @@ class Renderer {
171
174
  this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
172
175
  this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
173
176
  this._renderLists = new RenderLists();
177
+ this._bundles = new RenderBundles();
174
178
  this._renderContexts = new RenderContexts();
175
179
 
176
180
  //
@@ -326,6 +330,81 @@ class Renderer {
326
330
 
327
331
  }
328
332
 
333
+ _renderBundle( bundle, sceneRef, lightsNode ) {
334
+
335
+ const { object, camera, renderList } = bundle;
336
+
337
+ const renderContext = this._currentRenderContext;
338
+ const renderContextData = this.backend.get( renderContext );
339
+
340
+ //
341
+
342
+ const renderBundle = this._bundles.get( object, camera );
343
+
344
+ const renderBundleData = this.backend.get( renderBundle );
345
+ if ( renderBundleData.renderContexts === undefined ) renderBundleData.renderContexts = new Set();
346
+
347
+ //
348
+
349
+ const renderBundleNeedsUpdate = renderBundleData.renderContexts.has( renderContext ) === false || object.needsUpdate === true;
350
+
351
+ renderBundleData.renderContexts.add( renderContext );
352
+
353
+ if ( renderBundleNeedsUpdate ) {
354
+
355
+ if ( renderContextData.renderObjects === undefined || object.needsUpdate === true ) {
356
+
357
+ const nodeFrame = this._nodes.nodeFrame;
358
+
359
+ renderContextData.renderObjects = [];
360
+ renderContextData.renderBundles = [];
361
+ renderContextData.scene = sceneRef;
362
+ renderContextData.camera = camera;
363
+ renderContextData.renderId = nodeFrame.renderId;
364
+
365
+ renderContextData.registerBundlesPhase = true;
366
+
367
+ }
368
+
369
+ this._currentRenderBundle = renderBundle;
370
+
371
+ const opaqueObjects = renderList.opaque;
372
+
373
+ if ( opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
374
+
375
+ this._currentRenderBundle = null;
376
+
377
+ //
378
+
379
+ object.needsUpdate = false;
380
+
381
+ } else {
382
+
383
+ const renderContext = this._currentRenderContext;
384
+ const renderContextData = this.backend.get( renderContext );
385
+
386
+ for ( let i = 0, l = renderContextData.renderObjects.length; i < l; i ++ ) {
387
+
388
+ const renderObject = renderContextData.renderObjects[ i ];
389
+
390
+ this._nodes.updateBefore( renderObject );
391
+
392
+ //
393
+
394
+ renderObject.object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, renderObject.object.matrixWorld );
395
+ renderObject.object.normalMatrix.getNormalMatrix( renderObject.object.modelViewMatrix );
396
+
397
+ this._nodes.updateForRender( renderObject );
398
+ this._bindings.updateForRender( renderObject );
399
+
400
+ this.backend.draw( renderObject, this.info );
401
+
402
+ }
403
+
404
+ }
405
+
406
+ }
407
+
329
408
  render( scene, camera ) {
330
409
 
331
410
  if ( this._initialized === false ) {
@@ -456,7 +535,6 @@ class Renderer {
456
535
 
457
536
  if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
458
537
 
459
-
460
538
  //
461
539
 
462
540
  let viewport = this._viewport;
@@ -564,8 +642,10 @@ class Renderer {
564
642
 
565
643
  const opaqueObjects = renderList.opaque;
566
644
  const transparentObjects = renderList.transparent;
645
+ const bundles = renderList.bundles;
567
646
  const lightsNode = renderList.lightsNode;
568
647
 
648
+ if ( bundles.length > 0 ) this._renderBundles( bundles, sceneRef, lightsNode );
569
649
  if ( opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
570
650
  if ( transparentObjects.length > 0 ) this._renderObjects( transparentObjects, camera, sceneRef, lightsNode );
571
651
 
@@ -628,14 +708,6 @@ class Renderer {
628
708
 
629
709
  }
630
710
 
631
- getArrayBuffer( attribute ) { // @deprecated, r155
632
-
633
- console.warn( 'THREE.Renderer: getArrayBuffer() is deprecated. Use getArrayBufferAsync() instead.' );
634
-
635
- return this.getArrayBufferAsync( attribute );
636
-
637
- }
638
-
639
711
  async getArrayBufferAsync( attribute ) {
640
712
 
641
713
  return await this.backend.getArrayBufferAsync( attribute );
@@ -872,6 +944,16 @@ class Renderer {
872
944
 
873
945
  this.backend.clear( color, depth, stencil, renderTargetData );
874
946
 
947
+ if ( renderTarget !== null && this._renderTarget === null ) {
948
+
949
+ // If a color space transform or tone mapping is required,
950
+ // the clear operation clears the intermediate renderTarget texture, but does not update the screen canvas.
951
+
952
+ _quad.material.fragmentNode = this._nodes.getOutputNode( renderTarget.texture );
953
+ this._renderScene( _quad, _quad.camera, false );
954
+
955
+ }
956
+
875
957
  }
876
958
 
877
959
  clearColor() {
@@ -1086,12 +1168,12 @@ class Renderer {
1086
1168
 
1087
1169
  }
1088
1170
 
1089
- copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
1171
+ copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
1090
1172
 
1091
1173
  this._textures.updateTexture( srcTexture );
1092
1174
  this._textures.updateTexture( dstTexture );
1093
1175
 
1094
- this.backend.copyTextureToTexture( position, srcTexture, dstTexture, level );
1176
+ this.backend.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, level );
1095
1177
 
1096
1178
  }
1097
1179
 
@@ -1194,6 +1276,25 @@ class Renderer {
1194
1276
 
1195
1277
  }
1196
1278
 
1279
+ if ( object.static === true ) {
1280
+
1281
+ const baseRenderList = renderList;
1282
+
1283
+ // replace render list
1284
+ renderList = this._renderLists.get( object, camera );
1285
+
1286
+ renderList.begin();
1287
+
1288
+ baseRenderList.pushBundle( {
1289
+ object,
1290
+ camera,
1291
+ renderList,
1292
+ } );
1293
+
1294
+ renderList.finish();
1295
+
1296
+ }
1297
+
1197
1298
  const children = object.children;
1198
1299
 
1199
1300
  for ( let i = 0, l = children.length; i < l; i ++ ) {
@@ -1204,6 +1305,16 @@ class Renderer {
1204
1305
 
1205
1306
  }
1206
1307
 
1308
+ _renderBundles( bundles, sceneRef, lightsNode ) {
1309
+
1310
+ for ( const bundle of bundles ) {
1311
+
1312
+ this._renderBundle( bundle, sceneRef, lightsNode );
1313
+
1314
+ }
1315
+
1316
+ }
1317
+
1207
1318
  _renderObjects( renderList, camera, scene, lightsNode ) {
1208
1319
 
1209
1320
  // process renderable objects
@@ -1397,8 +1508,25 @@ class Renderer {
1397
1508
 
1398
1509
  //
1399
1510
 
1511
+ if ( this._currentRenderBundle !== null && this._currentRenderBundle.needsUpdate === true ) {
1512
+
1513
+ const renderObjectData = this.backend.get( renderObject );
1514
+
1515
+ renderObjectData.bundleEncoder = undefined;
1516
+ renderObjectData.lastPipelineGPU = undefined;
1517
+
1518
+ }
1519
+
1400
1520
  this.backend.draw( renderObject, this.info );
1401
1521
 
1522
+ if ( this._currentRenderBundle !== null ) {
1523
+
1524
+ const renderContextData = this.backend.get( this._currentRenderContext );
1525
+
1526
+ renderContextData.renderObjects.push( renderObject );
1527
+
1528
+ }
1529
+
1402
1530
  }
1403
1531
 
1404
1532
  _createObjectPipeline( object, material, scene, camera, lightsNode, passId ) {
@@ -2,7 +2,7 @@ import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three';
2
2
 
3
3
  class Uniform {
4
4
 
5
- constructor( name, value = null ) {
5
+ constructor( name, value ) {
6
6
 
7
7
  this.name = name;
8
8
  this.value = value;
@@ -2,12 +2,14 @@ import { SampledTexture } from '../SampledTexture.js';
2
2
 
3
3
  class NodeSampledTexture extends SampledTexture {
4
4
 
5
- constructor( name, textureNode ) {
5
+ constructor( name, textureNode, access = null ) {
6
6
 
7
7
  super( name, textureNode ? textureNode.value : null );
8
8
 
9
9
  this.textureNode = textureNode;
10
10
 
11
+ this.access = access;
12
+
11
13
  }
12
14
 
13
15
  get needsBindingsUpdate() {
@@ -36,9 +38,9 @@ class NodeSampledTexture extends SampledTexture {
36
38
 
37
39
  class NodeSampledCubeTexture extends NodeSampledTexture {
38
40
 
39
- constructor( name, textureNode ) {
41
+ constructor( name, textureNode, access ) {
40
42
 
41
- super( name, textureNode );
43
+ super( name, textureNode, access );
42
44
 
43
45
  this.isSampledCubeTexture = true;
44
46
 
@@ -46,4 +48,16 @@ class NodeSampledCubeTexture extends NodeSampledTexture {
46
48
 
47
49
  }
48
50
 
49
- export { NodeSampledTexture, NodeSampledCubeTexture };
51
+ class NodeSampledTexture3D extends NodeSampledTexture {
52
+
53
+ constructor( name, textureNode, access ) {
54
+
55
+ super( name, textureNode, access );
56
+
57
+ this.isSampledTexture3D = true;
58
+
59
+ }
60
+
61
+ }
62
+
63
+ export { NodeSampledTexture, NodeSampledCubeTexture, NodeSampledTexture3D };
@@ -10,6 +10,12 @@ class NodeSampler extends Sampler {
10
10
 
11
11
  }
12
12
 
13
+ update() {
14
+
15
+ this.texture = this.textureNode.value;
16
+
17
+ }
18
+
13
19
  }
14
20
 
15
21
  export default NodeSampler;
@@ -3,7 +3,7 @@ import { MathNode, GLSLNodeParser, NodeBuilder, UniformNode, vectorComponents }
3
3
  import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js';
4
4
  import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js';
5
5
 
6
- import { NodeSampledTexture, NodeSampledCubeTexture } from '../../common/nodes/NodeSampledTexture.js';
6
+ import { NodeSampledTexture, NodeSampledCubeTexture, NodeSampledTexture3D } from '../../common/nodes/NodeSampledTexture.js';
7
7
 
8
8
  import { RedFormat, RGFormat, IntType, DataTexture, RGBFormat, RGBAFormat, FloatType } from 'three';
9
9
 
@@ -27,6 +27,7 @@ const supports = {
27
27
  const defaultPrecisions = `
28
28
  precision highp float;
29
29
  precision highp int;
30
+ precision highp sampler3D;
30
31
  precision mediump sampler2DArray;
31
32
  precision lowp sampler2DShadow;
32
33
  `;
@@ -50,12 +51,16 @@ class GLSLNodeBuilder extends NodeBuilder {
50
51
 
51
52
  getPropertyName( node, shaderStage ) {
52
53
 
53
- if ( node.isOutputStructVar ) return '';
54
-
55
54
  return super.getPropertyName( node, shaderStage );
56
55
 
57
56
  }
58
57
 
58
+ getOutputStructName() {
59
+
60
+ return '';
61
+
62
+ }
63
+
59
64
  buildFunctionCode( shaderNode ) {
60
65
 
61
66
  const layout = shaderNode.layout;
@@ -276,8 +281,6 @@ ${ flowData.code }
276
281
 
277
282
  for ( const variable of vars ) {
278
283
 
279
- if ( variable.isOutputStructVar ) continue;
280
-
281
284
  snippets.push( `${ this.getVar( variable.type, variable.name ) };` );
282
285
 
283
286
  }
@@ -322,6 +325,10 @@ ${ flowData.code }
322
325
 
323
326
  snippet = `samplerCube ${ uniform.name };`;
324
327
 
328
+ } else if ( uniform.type === 'texture3D' ) {
329
+
330
+ snippet = `sampler3D ${ uniform.name };`;
331
+
325
332
  } else if ( uniform.type === 'buffer' ) {
326
333
 
327
334
  const bufferNode = uniform.node;
@@ -759,6 +766,11 @@ void main() {
759
766
 
760
767
  this.bindings[ shaderStage ].push( uniformGPU );
761
768
 
769
+ } else if ( type === 'texture3D' ) {
770
+
771
+ uniformGPU = new NodeSampledTexture3D( uniformNode.name, uniformNode.node );
772
+ this.bindings[ shaderStage ].push( uniformGPU );
773
+
762
774
  } else if ( type === 'buffer' ) {
763
775
 
764
776
  node.name = `NodeBuffer_${ node.id }`;
@@ -83,6 +83,10 @@ class WebGLTextureUtils {
83
83
 
84
84
  glTextureType = gl.TEXTURE_2D_ARRAY;
85
85
 
86
+ } else if ( texture.isData3DTexture === true ) {
87
+
88
+ glTextureType = gl.TEXTURE_3D;
89
+
86
90
  } else {
87
91
 
88
92
  glTextureType = gl.TEXTURE_2D;
@@ -113,6 +117,11 @@ class WebGLTextureUtils {
113
117
  if ( glType === gl.FLOAT ) internalFormat = gl.R32F;
114
118
  if ( glType === gl.HALF_FLOAT ) internalFormat = gl.R16F;
115
119
  if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.R8;
120
+ if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.R16;
121
+ if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.R32UI;
122
+ if ( glType === gl.BYTE ) internalFormat = gl.R8I;
123
+ if ( glType === gl.SHORT ) internalFormat = gl.R16I;
124
+ if ( glType === gl.INT ) internalFormat = gl.R32I;
116
125
 
117
126
  }
118
127
 
@@ -132,6 +141,12 @@ class WebGLTextureUtils {
132
141
  if ( glType === gl.FLOAT ) internalFormat = gl.RG32F;
133
142
  if ( glType === gl.HALF_FLOAT ) internalFormat = gl.RG16F;
134
143
  if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RG8;
144
+ if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.RG16;
145
+ if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.RG32UI;
146
+ if ( glType === gl.BYTE ) internalFormat = gl.RG8I;
147
+ if ( glType === gl.SHORT ) internalFormat = gl.RG16I;
148
+ if ( glType === gl.INT ) internalFormat = gl.RG32I;
149
+
135
150
 
136
151
  }
137
152
 
@@ -140,6 +155,12 @@ class WebGLTextureUtils {
140
155
  if ( glType === gl.FLOAT ) internalFormat = gl.RGB32F;
141
156
  if ( glType === gl.HALF_FLOAT ) internalFormat = gl.RGB16F;
142
157
  if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RGB8;
158
+ if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.RGB16;
159
+ if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.RGB32UI;
160
+ if ( glType === gl.BYTE ) internalFormat = gl.RGB8I;
161
+ if ( glType === gl.SHORT ) internalFormat = gl.RGB16I;
162
+ if ( glType === gl.INT ) internalFormat = gl.RGB32I;
163
+ if ( glType === gl.UNSIGNED_BYTE ) internalFormat = ( colorSpace === SRGBColorSpace && forceLinearTransfer === false ) ? gl.SRGB8 : gl.RGB8;
143
164
  if ( glType === gl.UNSIGNED_SHORT_5_6_5 ) internalFormat = gl.RGB565;
144
165
  if ( glType === gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = gl.RGB5_A1;
145
166
  if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = gl.RGB4;
@@ -151,6 +172,12 @@ class WebGLTextureUtils {
151
172
 
152
173
  if ( glType === gl.FLOAT ) internalFormat = gl.RGBA32F;
153
174
  if ( glType === gl.HALF_FLOAT ) internalFormat = gl.RGBA16F;
175
+ if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RGBA8;
176
+ if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.RGBA16;
177
+ if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.RGBA32UI;
178
+ if ( glType === gl.BYTE ) internalFormat = gl.RGBA8I;
179
+ if ( glType === gl.SHORT ) internalFormat = gl.RGBA16I;
180
+ if ( glType === gl.INT ) internalFormat = gl.RGBA32I;
154
181
  if ( glType === gl.UNSIGNED_BYTE ) internalFormat = ( colorSpace === SRGBColorSpace && forceLinearTransfer === false ) ? gl.SRGB8_ALPHA8 : gl.RGBA8;
155
182
  if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = gl.RGBA4;
156
183
  if ( glType === gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = gl.RGB5_A1;
@@ -286,6 +313,10 @@ class WebGLTextureUtils {
286
313
 
287
314
  gl.texStorage3D( gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, width, height, depth );
288
315
 
316
+ } else if ( texture.isData3DTexture ) {
317
+
318
+ gl.texStorage3D( gl.TEXTURE_3D, levels, glInternalFormat, width, height, depth );
319
+
289
320
  } else if ( ! texture.isVideoTexture ) {
290
321
 
291
322
  gl.texStorage2D( glTextureType, levels, glInternalFormat, width, height );
@@ -429,6 +460,12 @@ class WebGLTextureUtils {
429
460
 
430
461
  gl.texSubImage3D( gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
431
462
 
463
+ } else if ( texture.isData3DTexture ) {
464
+
465
+ const image = options.image;
466
+
467
+ gl.texSubImage3D( gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
468
+
432
469
  } else if ( texture.isVideoTexture ) {
433
470
 
434
471
  texture.update();
@@ -524,41 +561,91 @@ class WebGLTextureUtils {
524
561
 
525
562
  }
526
563
 
527
- copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
564
+ copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
528
565
 
529
566
  const { gl, backend } = this;
530
567
  const { state } = this.backend;
531
568
 
532
- const width = srcTexture.image.width;
533
- const height = srcTexture.image.height;
534
569
  const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture );
535
570
 
571
+
572
+ let width, height, minX, minY;
573
+ let dstX, dstY;
574
+ if ( srcRegion !== null ) {
575
+
576
+ width = srcRegion.max.x - srcRegion.min.x;
577
+ height = srcRegion.max.y - srcRegion.min.y;
578
+ minX = srcRegion.min.x;
579
+ minY = srcRegion.min.y;
580
+
581
+ } else {
582
+
583
+ width = srcTexture.image.width;
584
+ height = srcTexture.image.height;
585
+ minX = 0;
586
+ minY = 0;
587
+
588
+ }
589
+
590
+ if ( dstPosition !== null ) {
591
+
592
+ dstX = dstPosition.x;
593
+ dstY = dstPosition.y;
594
+
595
+ } else {
596
+
597
+ dstX = 0;
598
+ dstY = 0;
599
+
600
+ }
601
+
536
602
  state.bindTexture( glTextureType, dstTextureGPU );
537
603
 
538
604
  // As another texture upload may have changed pixelStorei
539
605
  // parameters, make sure they are correct for the dstTexture
606
+ gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
540
607
  gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
541
608
  gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
542
609
  gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
543
610
 
611
+ const currentUnpackRowLen = gl.getParameter( gl.UNPACK_ROW_LENGTH );
612
+ const currentUnpackImageHeight = gl.getParameter( gl.UNPACK_IMAGE_HEIGHT );
613
+ const currentUnpackSkipPixels = gl.getParameter( gl.UNPACK_SKIP_PIXELS );
614
+ const currentUnpackSkipRows = gl.getParameter( gl.UNPACK_SKIP_ROWS );
615
+ const currentUnpackSkipImages = gl.getParameter( gl.UNPACK_SKIP_IMAGES );
616
+
617
+ const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image;
618
+
619
+ gl.pixelStorei( gl.UNPACK_ROW_LENGTH, image.width );
620
+ gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, image.height );
621
+ gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
622
+ gl.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );
623
+
624
+
544
625
  if ( srcTexture.isDataTexture ) {
545
626
 
546
- gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
627
+ gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data );
547
628
 
548
629
  } else {
549
630
 
550
631
  if ( srcTexture.isCompressedTexture ) {
551
632
 
552
- gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
633
+ gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data );
553
634
 
554
635
  } else {
555
636
 
556
- gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image );
637
+ gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, glFormat, glType, image );
557
638
 
558
639
  }
559
640
 
560
641
  }
561
642
 
643
+ gl.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
644
+ gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
645
+ gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
646
+ gl.pixelStorei( gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
647
+ gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
648
+
562
649
  // Generate mipmaps only when copying level 0
563
650
  if ( level === 0 && dstTexture.generateMipmaps ) gl.generateMipmap( gl.TEXTURE_2D );
564
651
 
@@ -453,6 +453,13 @@ class WebGPUBackend extends Backend {
453
453
  const renderContextData = this.get( renderContext );
454
454
  const occlusionQueryCount = renderContext.occlusionQueryCount;
455
455
 
456
+ if ( renderContextData.renderBundles !== undefined && renderContextData.renderBundles.length > 0 ) {
457
+
458
+ renderContextData.registerBundlesPhase = false;
459
+ renderContextData.currentPass.executeBundles( renderContextData.renderBundles );
460
+
461
+ }
462
+
456
463
  if ( occlusionQueryCount > renderContextData.occlusionQueryIndex ) {
457
464
 
458
465
  renderContextData.currentPass.endOcclusionQuery();
@@ -791,9 +798,22 @@ class WebGPUBackend extends Backend {
791
798
  const pipelineGPU = this.get( pipeline ).pipeline;
792
799
  const currentSets = contextData.currentSets;
793
800
 
794
- // pipeline
801
+ const renderObjectData = this.get( renderObject );
802
+
803
+ const { bundleEncoder, renderBundle, lastPipelineGPU } = renderObjectData;
804
+
805
+ const renderContextData = this.get( context );
806
+
807
+ if ( renderContextData.registerBundlesPhase === true && bundleEncoder !== undefined && lastPipelineGPU === pipelineGPU ) {
808
+
809
+ renderContextData.renderBundles.push( renderBundle );
810
+ return;
811
+
812
+ }
813
+
814
+ const passEncoderGPU = this.renderer._currentRenderBundle ? this.createBundleEncoder( context, renderObject ) : contextData.currentPass;
795
815
 
796
- const passEncoderGPU = contextData.currentPass;
816
+ // pipeline
797
817
 
798
818
  if ( currentSets.pipeline !== pipelineGPU ) {
799
819
 
@@ -905,6 +925,16 @@ class WebGPUBackend extends Backend {
905
925
 
906
926
  }
907
927
 
928
+
929
+ if ( this.renderer._currentRenderBundle ) {
930
+
931
+ const renderBundle = passEncoderGPU.finish();
932
+ renderObjectData.lastPipelineGPU = pipelineGPU;
933
+ renderObjectData.renderBundle = renderBundle;
934
+ renderObjectData.bundleEncoder = passEncoderGPU;
935
+
936
+ }
937
+
908
938
  }
909
939
 
910
940
  // cache key
@@ -1160,6 +1190,12 @@ class WebGPUBackend extends Backend {
1160
1190
 
1161
1191
  }
1162
1192
 
1193
+ createBundleEncoder( renderContext, renderObject ) {
1194
+
1195
+ return this.pipelineUtils.createBundleEncoder( renderContext, renderObject );
1196
+
1197
+ }
1198
+
1163
1199
  // bindings
1164
1200
 
1165
1201
  createBindings( bindings ) {
@@ -1235,8 +1271,18 @@ class WebGPUBackend extends Backend {
1235
1271
 
1236
1272
  }
1237
1273
 
1238
- copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
1274
+ copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
1275
+
1276
+ let dstX = 0;
1277
+ let dstY = 0;
1239
1278
 
1279
+ if ( dstPosition !== null ) {
1280
+
1281
+ dstX = dstPosition.x;
1282
+ dstY = dstPosition.y;
1283
+
1284
+ }
1285
+
1240
1286
  const encoder = this.device.createCommandEncoder( { label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id } );
1241
1287
 
1242
1288
  const sourceGPU = this.get( srcTexture ).texture;
@@ -1251,7 +1297,7 @@ class WebGPUBackend extends Backend {
1251
1297
  {
1252
1298
  texture: destinationGPU,
1253
1299
  mipLevel: level,
1254
- origin: { x: position.x, y: position.y, z: position.z }
1300
+ origin: { x: dstX, y: dstY, z: 0 }
1255
1301
  },
1256
1302
  [
1257
1303
  srcTexture.image.width,