super-three 0.161.0 → 0.162.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 (131) hide show
  1. package/build/three.cjs +490 -393
  2. package/build/three.module.js +490 -391
  3. package/build/three.module.min.js +1 -1
  4. package/examples/jsm/controls/DragControls.js +91 -30
  5. package/examples/jsm/controls/OrbitControls.js +32 -6
  6. package/examples/jsm/controls/TransformControls.js +6 -6
  7. package/examples/jsm/exporters/GLTFExporter.js +11 -1
  8. package/examples/jsm/interactive/InteractiveGroup.js +15 -25
  9. package/examples/jsm/libs/rhino3dm/rhino3dm.js +1 -8723
  10. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +1 -8734
  11. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  12. package/examples/jsm/libs/tween.module.js +32 -14
  13. package/examples/jsm/loaders/3DMLoader.js +13 -21
  14. package/examples/jsm/loaders/VOXLoader.js +9 -2
  15. package/examples/jsm/loaders/VRMLLoader.js +6 -2
  16. package/examples/jsm/misc/ProgressiveLightMap.js +1 -0
  17. package/examples/jsm/nodes/Nodes.js +9 -7
  18. package/examples/jsm/nodes/accessors/AccessorsUtils.js +10 -0
  19. package/examples/jsm/nodes/accessors/ClippingNode.js +144 -0
  20. package/examples/jsm/nodes/accessors/MaterialNode.js +2 -2
  21. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +2 -12
  22. package/examples/jsm/nodes/accessors/MorphNode.js +8 -8
  23. package/examples/jsm/nodes/accessors/ReferenceNode.js +87 -29
  24. package/examples/jsm/nodes/accessors/SkinningNode.js +31 -10
  25. package/examples/jsm/nodes/accessors/StorageBufferNode.js +18 -0
  26. package/examples/jsm/nodes/accessors/TangentNode.js +8 -2
  27. package/examples/jsm/nodes/accessors/TextureNode.js +1 -1
  28. package/examples/jsm/nodes/accessors/UniformsNode.js +140 -0
  29. package/examples/jsm/nodes/code/CodeNode.js +6 -0
  30. package/examples/jsm/nodes/core/AssignNode.js +68 -12
  31. package/examples/jsm/nodes/core/Node.js +14 -4
  32. package/examples/jsm/nodes/core/NodeBuilder.js +3 -9
  33. package/examples/jsm/nodes/core/NodeFrame.js +2 -2
  34. package/examples/jsm/nodes/core/TempNode.js +1 -1
  35. package/examples/jsm/nodes/display/BlendModeNode.js +30 -1
  36. package/examples/jsm/nodes/display/NormalMapNode.js +3 -5
  37. package/examples/jsm/nodes/materials/NodeMaterial.js +37 -6
  38. package/examples/jsm/nodes/math/CondNode.js +42 -7
  39. package/examples/jsm/nodes/math/MathNode.js +20 -0
  40. package/examples/jsm/nodes/utils/ArrayElementNode.js +0 -6
  41. package/examples/jsm/nodes/utils/LoopNode.js +2 -0
  42. package/examples/jsm/nodes/utils/StorageArrayElementNode.js +91 -0
  43. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  44. package/examples/jsm/renderers/common/Background.js +2 -2
  45. package/examples/jsm/renderers/common/ClippingContext.js +165 -0
  46. package/examples/jsm/renderers/common/RenderContext.js +2 -0
  47. package/examples/jsm/renderers/common/RenderContexts.js +2 -13
  48. package/examples/jsm/renderers/common/RenderObject.js +44 -1
  49. package/examples/jsm/renderers/common/RenderObjects.js +3 -1
  50. package/examples/jsm/renderers/common/Renderer.js +94 -37
  51. package/examples/jsm/renderers/common/StorageBufferAttribute.js +2 -2
  52. package/examples/jsm/renderers/common/StorageInstancedBufferAttribute.js +17 -0
  53. package/examples/jsm/renderers/common/Textures.js +3 -13
  54. package/examples/jsm/renderers/common/UniformsGroup.js +6 -4
  55. package/examples/jsm/renderers/common/nodes/NodeStorageBuffer.js +23 -0
  56. package/examples/jsm/renderers/common/nodes/NodeUniformBuffer.js +23 -0
  57. package/examples/jsm/renderers/common/nodes/Nodes.js +1 -0
  58. package/examples/jsm/renderers/webgl/WebGLBackend.js +26 -6
  59. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +135 -10
  60. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +7 -1
  61. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +47 -0
  62. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +1 -0
  63. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +13 -12
  64. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +15 -40
  65. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +7 -1
  66. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +2 -2
  67. package/examples/jsm/shaders/OutputShader.js +4 -0
  68. package/examples/jsm/utils/SkeletonUtils.js +14 -3
  69. package/examples/jsm/webxr/VRButton.js +13 -5
  70. package/examples/jsm/webxr/XRButton.js +0 -1
  71. package/examples/jsm/webxr/XRControllerModelFactory.js +8 -0
  72. package/package.json +4 -3
  73. package/src/Three.Legacy.js +20 -0
  74. package/src/Three.js +0 -1
  75. package/src/constants.js +2 -5
  76. package/src/core/BufferAttribute.js +0 -11
  77. package/src/core/BufferGeometry.js +23 -29
  78. package/src/core/Object3D.js +11 -0
  79. package/src/core/Raycaster.js +18 -4
  80. package/src/core/RenderTarget.js +44 -21
  81. package/src/extras/PMREMGenerator.js +2 -0
  82. package/src/extras/curves/EllipseCurve.js +2 -2
  83. package/src/helpers/SpotLightHelper.js +18 -1
  84. package/src/loaders/DataTextureLoader.js +0 -4
  85. package/src/loaders/MaterialLoader.js +1 -0
  86. package/src/loaders/ObjectLoader.js +2 -1
  87. package/src/materials/Material.js +2 -1
  88. package/src/materials/MeshBasicMaterial.js +3 -0
  89. package/src/materials/MeshLambertMaterial.js +3 -0
  90. package/src/materials/MeshPhongMaterial.js +3 -0
  91. package/src/materials/MeshStandardMaterial.js +3 -0
  92. package/src/math/Quaternion.js +13 -12
  93. package/src/math/Vector3.js +7 -7
  94. package/src/objects/InstancedMesh.js +53 -0
  95. package/src/objects/Mesh.js +0 -1
  96. package/src/renderers/WebGLCubeRenderTarget.js +1 -10
  97. package/src/renderers/WebGLRenderer.js +15 -22
  98. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -0
  99. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  100. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  101. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +1 -1
  102. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +14 -0
  103. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +11 -2
  104. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +23 -0
  105. package/src/renderers/shaders/ShaderChunk.js +2 -0
  106. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +3 -2
  107. package/src/renderers/shaders/ShaderLib/depth.glsl.js +2 -0
  108. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +2 -0
  109. package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +1 -0
  110. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +1 -0
  111. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +1 -0
  112. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +1 -0
  113. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -0
  114. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +1 -0
  115. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +1 -0
  116. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +1 -0
  117. package/src/renderers/shaders/ShaderLib/points.glsl.js +1 -0
  118. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -0
  119. package/src/renderers/shaders/ShaderLib.js +2 -1
  120. package/src/renderers/shaders/UniformsLib.js +1 -0
  121. package/src/renderers/webgl/WebGLBackground.js +18 -0
  122. package/src/renderers/webgl/WebGLMaterials.js +24 -1
  123. package/src/renderers/webgl/WebGLMorphtargets.js +15 -8
  124. package/src/renderers/webgl/WebGLProgram.js +12 -1
  125. package/src/renderers/webgl/WebGLPrograms.js +19 -16
  126. package/src/renderers/webgl/WebGLState.js +11 -21
  127. package/src/renderers/webgl/WebGLTextures.js +80 -50
  128. package/src/scenes/Scene.js +8 -0
  129. package/src/textures/Texture.js +1 -29
  130. package/examples/jsm/nodes/core/ArrayUniformNode.js +0 -26
  131. package/src/renderers/WebGLMultipleRenderTargets.js +0 -82
@@ -1,3 +1,5 @@
1
+ import ClippingContext from "./ClippingContext.js";
2
+
1
3
  let id = 0;
2
4
 
3
5
  export default class RenderObject {
@@ -24,6 +26,10 @@ export default class RenderObject {
24
26
  this.pipeline = null;
25
27
  this.vertexBuffers = null;
26
28
 
29
+ this.updateClipping( renderContext.clippingContext );
30
+
31
+ this.clippingContextVersion = this.clippingContext.version;
32
+
27
33
  this.initialNodesCacheKey = this.getNodesCacheKey();
28
34
  this.initialCacheKey = this.getCacheKey();
29
35
 
@@ -44,6 +50,41 @@ export default class RenderObject {
44
50
 
45
51
  }
46
52
 
53
+ updateClipping( parent ) {
54
+
55
+ const material = this.material;
56
+
57
+ let clippingContext = this.clippingContext;
58
+
59
+ if ( Array.isArray( material.clippingPlanes ) ) {
60
+
61
+ if ( clippingContext === parent || ! clippingContext ) {
62
+
63
+ clippingContext = new ClippingContext();
64
+ this.clippingContext = clippingContext;
65
+
66
+ }
67
+
68
+ clippingContext.update( parent, material );
69
+
70
+ } else if ( this.clippingContext !== parent ) {
71
+
72
+ this.clippingContext = parent;
73
+
74
+ }
75
+
76
+ }
77
+
78
+ clippingNeedsUpdate () {
79
+
80
+ if ( this.clippingContext.version === this.clippingContextVersion ) return false;
81
+
82
+ this.clippingContextVersion = this.clippingContext.version;
83
+
84
+ return true;
85
+
86
+ }
87
+
47
88
  getNodeBuilderState() {
48
89
 
49
90
  return this._nodeBuilderState || ( this._nodeBuilderState = this._nodes.getForRender( this ) );
@@ -131,9 +172,11 @@ export default class RenderObject {
131
172
 
132
173
  }
133
174
 
175
+ cacheKey += this.clippingContextVersion + ',';
176
+
134
177
  if ( object.skeleton ) {
135
178
 
136
- cacheKey += object.skeleton.uuid + ',';
179
+ cacheKey += object.skeleton.bones.length + ',';
137
180
 
138
181
  }
139
182
 
@@ -31,7 +31,9 @@ class RenderObjects {
31
31
 
32
32
  } else {
33
33
 
34
- if ( renderObject.version !== material.version || renderObject.needsUpdate ) {
34
+ renderObject.updateClipping( renderContext.clippingContext );
35
+
36
+ if ( renderObject.version !== material.version || renderObject.needsUpdate || renderObject.clippingNeedsUpdate() ) {
35
37
 
36
38
  if ( renderObject.initialCacheKey !== renderObject.getCacheKey() ) {
37
39
 
@@ -11,6 +11,7 @@ import Textures from './Textures.js';
11
11
  import Background from './Background.js';
12
12
  import Nodes from './nodes/Nodes.js';
13
13
  import Color4 from './Color4.js';
14
+ import ClippingContext from './ClippingContext.js';
14
15
  import { Scene, Frustum, Matrix4, Vector2, Vector3, Vector4, DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoToneMapping } from 'three';
15
16
 
16
17
  const _scene = new Scene();
@@ -58,6 +59,8 @@ class Renderer {
58
59
  this.depth = true;
59
60
  this.stencil = true;
60
61
 
62
+ this.clippingPlanes = [];
63
+
61
64
  this.info = new Info();
62
65
 
63
66
  // internals
@@ -223,6 +226,9 @@ class Renderer {
223
226
  renderContext.depth = this.depth;
224
227
  renderContext.stencil = this.stencil;
225
228
 
229
+ if ( ! renderContext.clippingContext ) renderContext.clippingContext = new ClippingContext();
230
+ renderContext.clippingContext.updateGlobal( this, camera );
231
+
226
232
  //
227
233
 
228
234
  sceneRef.onBeforeRender( this, scene, camera, renderTarget );
@@ -306,6 +312,27 @@ class Renderer {
306
312
 
307
313
  if ( this._initialized === false ) await this.init();
308
314
 
315
+ const renderContext = this._renderContext( scene, camera );
316
+
317
+ await this.backend.resolveTimestampAsync( renderContext, 'render' );
318
+
319
+ }
320
+
321
+ render( scene, camera ) {
322
+
323
+ if ( this._initialized === false ) {
324
+
325
+ console.error( 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.' );
326
+ return;
327
+
328
+ }
329
+
330
+ this._renderContext( scene, camera );
331
+
332
+ }
333
+
334
+ _renderContext( scene, camera ) {
335
+
309
336
  // preserve render tree
310
337
 
311
338
  const nodeFrame = this._nodes.nodeFrame;
@@ -386,6 +413,9 @@ class Renderer {
386
413
  renderContext.scissorValue.width >>= activeMipmapLevel;
387
414
  renderContext.scissorValue.height >>= activeMipmapLevel;
388
415
 
416
+ if ( ! renderContext.clippingContext ) renderContext.clippingContext = new ClippingContext();
417
+ renderContext.clippingContext.updateGlobal( this, camera );
418
+
389
419
  //
390
420
 
391
421
  sceneRef.onBeforeRender( this, scene, camera, renderTarget );
@@ -477,8 +507,9 @@ class Renderer {
477
507
 
478
508
  sceneRef.onAfterRender( this, scene, camera, renderTarget );
479
509
 
510
+ //
480
511
 
481
- await this.backend.resolveTimestampAsync( renderContext, 'render' );
512
+ return renderContext;
482
513
 
483
514
  }
484
515
 
@@ -728,9 +759,7 @@ class Renderer {
728
759
 
729
760
  }
730
761
 
731
- async clearAsync( color = true, depth = true, stencil = true ) {
732
-
733
- if ( this._initialized === false ) await this.init();
762
+ clear( color = true, depth = true, stencil = true ) {
734
763
 
735
764
  let renderTargetData = null;
736
765
  const renderTarget = this._renderTarget;
@@ -747,6 +776,32 @@ class Renderer {
747
776
 
748
777
  }
749
778
 
779
+ clearColor() {
780
+
781
+ return this.clear( true, false, false );
782
+
783
+ }
784
+
785
+ clearDepth() {
786
+
787
+ return this.clear( false, true, false );
788
+
789
+ }
790
+
791
+ clearStencil() {
792
+
793
+ return this.clear( false, false, true );
794
+
795
+ }
796
+
797
+ async clearAsync( color = true, depth = true, stencil = true ) {
798
+
799
+ if ( this._initialized === false ) await this.init();
800
+
801
+ this.clear( color, depth, stencil );
802
+
803
+ }
804
+
750
805
  clearColorAsync() {
751
806
 
752
807
  return this.clearAsync( true, false, false );
@@ -1107,10 +1162,42 @@ class Renderer {
1107
1162
 
1108
1163
  }
1109
1164
 
1110
- if ( overrideMaterial.isShadowNodeMaterial && ( material.shadowNode && material.shadowNode.isNode ) ) {
1165
+ if ( overrideMaterial.isShadowNodeMaterial ) {
1111
1166
 
1112
- overrideFragmentNode = overrideMaterial.fragmentNode;
1113
- overrideMaterial.fragmentNode = material.shadowNode;
1167
+ overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide;
1168
+
1169
+ if ( material.shadowNode && material.shadowNode.isNode ) {
1170
+
1171
+ overrideFragmentNode = overrideMaterial.fragmentNode;
1172
+ overrideMaterial.fragmentNode = material.shadowNode;
1173
+
1174
+ }
1175
+
1176
+ if ( this.localClippingEnabled ) {
1177
+
1178
+ if ( material.clipShadows ) {
1179
+
1180
+ if ( overrideMaterial.clippingPlanes !== material.clippingPlanes ) {
1181
+
1182
+ overrideMaterial.clippingPlanes = material.clippingPlanes;
1183
+ overrideMaterial.needsUpdate = true;
1184
+
1185
+ }
1186
+
1187
+ if ( overrideMaterial.clipIntersection !== material.clipIntersection ) {
1188
+
1189
+ overrideMaterial.clipIntersection = material.clipIntersection;
1190
+
1191
+ }
1192
+
1193
+ } else if ( Array.isArray( overrideMaterial.clippingPlanes ) ) {
1194
+
1195
+ overrideMaterial.clippingPlanes = null;
1196
+ overrideMaterial.needsUpdate = true;
1197
+
1198
+ }
1199
+
1200
+ }
1114
1201
 
1115
1202
  }
1116
1203
 
@@ -1212,36 +1299,6 @@ class Renderer {
1212
1299
 
1213
1300
  }
1214
1301
 
1215
- get render() {
1216
-
1217
- return this.renderAsync;
1218
-
1219
- }
1220
-
1221
- get clear() {
1222
-
1223
- return this.clearAsync;
1224
-
1225
- }
1226
-
1227
- get clearColor() {
1228
-
1229
- return this.clearColorAsync;
1230
-
1231
- }
1232
-
1233
- get clearDepth() {
1234
-
1235
- return this.clearDepthAsync;
1236
-
1237
- }
1238
-
1239
- get clearStencil() {
1240
-
1241
- return this.clearStencilAsync;
1242
-
1243
- }
1244
-
1245
1302
  }
1246
1303
 
1247
1304
  export default Renderer;
@@ -1,6 +1,6 @@
1
- import { InstancedBufferAttribute } from 'three';
1
+ import { BufferAttribute } from 'three';
2
2
 
3
- class StorageBufferAttribute extends InstancedBufferAttribute {
3
+ class StorageBufferAttribute extends BufferAttribute {
4
4
 
5
5
  constructor( array, itemSize, typeClass = Float32Array ) {
6
6
 
@@ -0,0 +1,17 @@
1
+ import { InstancedBufferAttribute } from 'three';
2
+
3
+ class StorageInstancedBufferAttribute extends InstancedBufferAttribute {
4
+
5
+ constructor( array, itemSize, typeClass = Float32Array ) {
6
+
7
+ if ( ArrayBuffer.isView( array ) === false ) array = new typeClass( array * itemSize );
8
+
9
+ super( array, itemSize );
10
+
11
+ this.isStorageInstancedBufferAttribute = true;
12
+
13
+ }
14
+
15
+ }
16
+
17
+ export default StorageInstancedBufferAttribute;
@@ -23,19 +23,8 @@ class Textures extends DataMap {
23
23
  const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
24
24
  const depthTextureMips = renderTargetData.depthTextureMips || ( renderTargetData.depthTextureMips = {} );
25
25
 
26
- let texture, textures;
27
-
28
- if ( renderTarget.isWebGLMultipleRenderTargets ) {
29
-
30
- textures = renderTarget.texture;
31
- texture = renderTarget.texture[ 0 ];
32
-
33
- } else {
34
-
35
- textures = [ renderTarget.texture ];
36
- texture = renderTarget.texture;
37
-
38
- }
26
+ const texture = renderTarget.texture;
27
+ const textures = renderTarget.textures;
39
28
 
40
29
  const size = this.getSize( texture );
41
30
 
@@ -73,6 +62,7 @@ class Textures extends DataMap {
73
62
  renderTargetData.depthTexture = depthTexture;
74
63
  renderTargetData.depth = renderTarget.depthBuffer;
75
64
  renderTargetData.stencil = renderTarget.stencilBuffer;
65
+ renderTargetData.renderTarget = renderTarget;
76
66
 
77
67
  if ( renderTargetData.sampleCount !== sampleCount ) {
78
68
 
@@ -63,6 +63,8 @@ class UniformsGroup extends UniformBuffer {
63
63
 
64
64
  const uniform = this.uniforms[ i ];
65
65
 
66
+ const { boundary, itemSize } = uniform;
67
+
66
68
  // offset within a single chunk in bytes
67
69
 
68
70
  const chunkOffset = offset % GPU_CHUNK_BYTES;
@@ -70,23 +72,23 @@ class UniformsGroup extends UniformBuffer {
70
72
 
71
73
  // conformance tests
72
74
 
73
- if ( chunkOffset !== 0 && ( remainingSizeInChunk - uniform.boundary ) < 0 ) {
75
+ if ( chunkOffset !== 0 && ( remainingSizeInChunk - boundary ) < 0 ) {
74
76
 
75
77
  // check for chunk overflow
76
78
 
77
79
  offset += ( GPU_CHUNK_BYTES - chunkOffset );
78
80
 
79
- } else if ( chunkOffset % uniform.boundary !== 0 ) {
81
+ } else if ( chunkOffset % boundary !== 0 ) {
80
82
 
81
83
  // check for correct alignment
82
84
 
83
- offset += ( chunkOffset % uniform.boundary );
85
+ offset += ( chunkOffset % boundary );
84
86
 
85
87
  }
86
88
 
87
89
  uniform.offset = ( offset / this.bytesPerElement );
88
90
 
89
- offset += ( uniform.itemSize * this.bytesPerElement );
91
+ offset += ( itemSize * this.bytesPerElement );
90
92
 
91
93
  }
92
94
 
@@ -0,0 +1,23 @@
1
+ import StorageBuffer from '../StorageBuffer.js';
2
+
3
+ let _id = 0;
4
+
5
+ class NodeStorageBuffer extends StorageBuffer {
6
+
7
+ constructor( nodeUniform ) {
8
+
9
+ super( 'StorageBuffer_' + _id ++, nodeUniform ? nodeUniform.value : null );
10
+
11
+ this.nodeUniform = nodeUniform;
12
+
13
+ }
14
+
15
+ get buffer() {
16
+
17
+ return this.nodeUniform.value;
18
+
19
+ }
20
+
21
+ }
22
+
23
+ export default NodeStorageBuffer;
@@ -0,0 +1,23 @@
1
+ import UniformBuffer from '../UniformBuffer.js';
2
+
3
+ let _id = 0;
4
+
5
+ class NodeUniformBuffer extends UniformBuffer {
6
+
7
+ constructor( nodeUniform ) {
8
+
9
+ super( 'UniformBuffer_' + _id ++, nodeUniform ? nodeUniform.value : null );
10
+
11
+ this.nodeUniform = nodeUniform;
12
+
13
+ }
14
+
15
+ get buffer() {
16
+
17
+ return this.nodeUniform.value;
18
+
19
+ }
20
+
21
+ }
22
+
23
+ export default NodeUniformBuffer;
@@ -114,6 +114,7 @@ class Nodes extends DataMap {
114
114
  nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
115
115
  nodeBuilder.fogNode = this.getFogNode( renderObject.scene );
116
116
  nodeBuilder.toneMappingNode = this.getToneMappingNode();
117
+ nodeBuilder.clippingContext = renderObject.clippingContext;
117
118
  nodeBuilder.build();
118
119
 
119
120
  nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
@@ -84,7 +84,7 @@ class WebGLBackend extends Backend {
84
84
 
85
85
  this._setFramebuffer( renderContext );
86
86
 
87
- this.clear( renderContext.clearColor, renderContext.clearDepth, renderContext.clearStencil, renderContext );
87
+ this.clear( renderContext.clearColor, renderContext.clearDepth, renderContext.clearStencil, renderContext, false );
88
88
 
89
89
  //
90
90
  if ( renderContext.viewport ) {
@@ -313,7 +313,7 @@ class WebGLBackend extends Backend {
313
313
 
314
314
  }
315
315
 
316
- clear( color, depth, stencil, descriptor = null ) {
316
+ clear( color, depth, stencil, descriptor = null, setFrameBuffer = true ) {
317
317
 
318
318
  const { gl } = this;
319
319
 
@@ -336,7 +336,7 @@ class WebGLBackend extends Backend {
336
336
 
337
337
  if ( clear !== 0 ) {
338
338
 
339
- const clearColor = descriptor.clearColorValue;
339
+ const clearColor = descriptor.clearColorValue || this.getClearColor();
340
340
 
341
341
  if ( depth ) this.state.setDepthMask( true );
342
342
 
@@ -347,6 +347,8 @@ class WebGLBackend extends Backend {
347
347
 
348
348
  } else {
349
349
 
350
+ if ( setFrameBuffer ) this._setFramebuffer( descriptor );
351
+
350
352
  if ( color ) {
351
353
 
352
354
  for ( let i = 0; i < descriptor.textures.length; i ++ ) {
@@ -422,15 +424,33 @@ class WebGLBackend extends Backend {
422
424
  gl.bindTransformFeedback( gl.TRANSFORM_FEEDBACK, transformFeedbackGPU );
423
425
  gl.beginTransformFeedback( gl.POINTS );
424
426
 
425
- gl.drawArraysInstanced( gl.POINTS, 0, 1, computeNode.count );
427
+ if ( attributes[ 0 ].isStorageInstancedBufferAttribute ) {
428
+
429
+ gl.drawArraysInstanced( gl.POINTS, 0, 1, computeNode.count );
430
+
431
+ } else {
432
+
433
+ gl.drawArrays( gl.POINTS, 0, computeNode.count );
434
+
435
+ }
426
436
 
427
437
  gl.endTransformFeedback();
428
438
  gl.bindTransformFeedback( gl.TRANSFORM_FEEDBACK, null );
429
439
 
430
440
  // switch active buffers
441
+
431
442
  for ( let i = 0; i < transformBuffers.length; i ++ ) {
432
443
 
433
- transformBuffers[ i ].switchBuffers();
444
+ const dualAttributeData = transformBuffers[ i ];
445
+
446
+ if ( dualAttributeData.pbo ) {
447
+
448
+ this.textureUtils.copyBufferToTexture( dualAttributeData.transformBuffer, dualAttributeData.pbo );
449
+
450
+ }
451
+
452
+ dualAttributeData.switchBuffers();
453
+
434
454
 
435
455
  }
436
456
 
@@ -1222,7 +1242,7 @@ class WebGLBackend extends Backend {
1222
1242
  gl.bindBuffer( gl.ARRAY_BUFFER, attributeData.bufferGPU );
1223
1243
  gl.enableVertexAttribArray( i );
1224
1244
 
1225
- if ( attribute.isStorageBufferAttribute ) staticVao = false;
1245
+ if ( attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute ) staticVao = false;
1226
1246
 
1227
1247
  let stride, offset;
1228
1248
 
@@ -1,15 +1,16 @@
1
- import { MathNode, GLSLNodeParser, NodeBuilder } from '../../../nodes/Nodes.js';
1
+ import { MathNode, GLSLNodeParser, NodeBuilder, UniformNode, vectorComponents } from '../../../nodes/Nodes.js';
2
2
 
3
- import UniformBuffer from '../../common/UniformBuffer.js';
3
+ import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js';
4
4
  import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js';
5
5
 
6
6
  import { NodeSampledTexture, NodeSampledCubeTexture } from '../../common/nodes/NodeSampledTexture.js';
7
7
 
8
- import { IntType } from 'three';
8
+ import { RedFormat, RGFormat, IntType, DataTexture, RGBAFormat, FloatType } from 'three';
9
9
 
10
10
  const glslMethods = {
11
11
  [ MathNode.ATAN2 ]: 'atan',
12
- textureDimensions: 'textureSize'
12
+ textureDimensions: 'textureSize',
13
+ equals: 'equal'
13
14
  };
14
15
 
15
16
  const precisionLib = {
@@ -19,7 +20,8 @@ const precisionLib = {
19
20
  };
20
21
 
21
22
  const supports = {
22
- instance: true
23
+ instance: true,
24
+ swizzleAssign: true
23
25
  };
24
26
 
25
27
  const defaultPrecisions = `
@@ -84,6 +86,130 @@ ${ flowData.code }
84
86
 
85
87
  }
86
88
 
89
+ setupPBO( storageBufferNode ) {
90
+
91
+ const attribute = storageBufferNode.value;
92
+
93
+ if ( attribute.pbo === undefined ) {
94
+
95
+ const originalArray = attribute.array;
96
+ const numElements = attribute.count * attribute.itemSize;
97
+
98
+ const { itemSize } = attribute;
99
+ let format = RedFormat;
100
+
101
+ if ( itemSize === 2 ) {
102
+
103
+ format = RGFormat;
104
+
105
+ } else if ( itemSize === 3 ) {
106
+
107
+ format = 6407; // patch since legacy doesn't use RGBFormat for rendering but here it's needed for packing optimization
108
+
109
+ } else if ( itemSize === 4 ) {
110
+
111
+ format = RGBAFormat;
112
+
113
+ }
114
+
115
+ const width = Math.pow( 2, Math.ceil( Math.log2( Math.sqrt( numElements / itemSize ) ) ) );
116
+ let height = Math.ceil( ( numElements / itemSize ) / width );
117
+ if ( width * height * itemSize < numElements ) height ++; // Ensure enough space
118
+
119
+ const newSize = width * height * itemSize;
120
+
121
+ const newArray = new Float32Array( newSize );
122
+
123
+ newArray.set( originalArray, 0 );
124
+
125
+ attribute.array = newArray;
126
+
127
+ const pboTexture = new DataTexture( attribute.array, width, height, format, FloatType );
128
+ pboTexture.needsUpdate = true;
129
+ pboTexture.isPBOTexture = true;
130
+
131
+ const pbo = new UniformNode( pboTexture );
132
+ pbo.setPrecision( 'high' );
133
+
134
+ attribute.pboNode = pbo;
135
+ attribute.pbo = pbo.value;
136
+
137
+ this.getUniformFromNode( attribute.pboNode, 'texture', this.shaderStage, this.context.label );
138
+
139
+ }
140
+
141
+ }
142
+
143
+ generatePBO( storageArrayElementNode ) {
144
+
145
+ const { node, indexNode } = storageArrayElementNode;
146
+ const attribute = node.value;
147
+
148
+ if ( this.renderer.backend.has( attribute ) ) {
149
+
150
+ const attributeData = this.renderer.backend.get( attribute );
151
+ attributeData.pbo = attribute.pbo;
152
+
153
+ }
154
+
155
+
156
+ const nodeUniform = this.getUniformFromNode( attribute.pboNode, 'texture', this.shaderStage, this.context.label );
157
+ const textureName = this.getPropertyName( nodeUniform );
158
+
159
+ indexNode.increaseUsage( this ); // force cache generate to be used as index in x,y
160
+ const indexSnippet = indexNode.build( this, 'uint' );
161
+
162
+ const elementNodeData = this.getDataFromNode( storageArrayElementNode );
163
+
164
+ let propertyName = elementNodeData.propertyName;
165
+
166
+ if ( propertyName === undefined ) {
167
+
168
+ // property element
169
+
170
+ const nodeVar = this.getVarFromNode( storageArrayElementNode );
171
+
172
+ propertyName = this.getPropertyName( nodeVar );
173
+
174
+ // property size
175
+
176
+ const bufferNodeData = this.getDataFromNode( node );
177
+
178
+ let propertySizeName = bufferNodeData.propertySizeName;
179
+
180
+ if ( propertySizeName === undefined ) {
181
+
182
+ propertySizeName = propertyName + 'Size';
183
+
184
+ this.getVarFromNode( node, propertySizeName, 'uint' );
185
+
186
+ this.addLineFlowCode( `${ propertySizeName } = uint( textureSize( ${ textureName }, 0 ).x )` );
187
+
188
+ bufferNodeData.propertySizeName = propertySizeName;
189
+
190
+ }
191
+
192
+ //
193
+
194
+ const { itemSize } = attribute;
195
+
196
+ const channel = '.' + vectorComponents.join( '' ).slice( 0, itemSize );
197
+ const uvSnippet = `ivec2(${indexSnippet} % ${ propertySizeName }, ${indexSnippet} / ${ propertySizeName })`;
198
+
199
+ const snippet = this.generateTextureLoad( null, textureName, uvSnippet, null, '0' );
200
+
201
+ //
202
+
203
+ this.addLineFlowCode( `${ propertyName } = ${ snippet + channel }` );
204
+
205
+ elementNodeData.propertyName = propertyName;
206
+
207
+ }
208
+
209
+ return propertyName;
210
+
211
+ }
212
+
87
213
  generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0' ) {
88
214
 
89
215
  if ( depthSnippet ) {
@@ -416,7 +542,6 @@ ${ flowData.code }
416
542
 
417
543
  }
418
544
 
419
-
420
545
  isFlipY() {
421
546
 
422
547
  return true;
@@ -630,11 +755,11 @@ void main() {
630
755
 
631
756
  } else if ( type === 'buffer' ) {
632
757
 
633
- node.name = `NodeBuffer_${node.id}`;
634
-
635
- const buffer = new UniformBuffer( node.name, node.value );
758
+ node.name = `NodeBuffer_${ node.id }`;
759
+ uniformNode.name = `buffer${ node.id }`;
636
760
 
637
- uniformNode.name = `buffer${node.id}`;
761
+ const buffer = new NodeUniformBuffer( node );
762
+ buffer.name = node.name;
638
763
 
639
764
  this.bindings[ shaderStage ].push( buffer );
640
765