super-three 0.154.1 → 0.156.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 (172) hide show
  1. package/build/three.cjs +360 -160
  2. package/build/three.js +360 -160
  3. package/build/three.min.js +1 -1
  4. package/build/three.module.js +355 -161
  5. package/build/three.module.min.js +1 -1
  6. package/examples/jsm/controls/OrbitControls.js +155 -25
  7. package/examples/jsm/csm/CSMShader.js +35 -1
  8. package/examples/jsm/environments/RoomEnvironment.js +1 -1
  9. package/examples/jsm/exporters/USDZExporter.js +1 -0
  10. package/examples/jsm/interactive/SelectionHelper.js +7 -0
  11. package/examples/jsm/libs/tween.module.js +790 -735
  12. package/examples/jsm/libs/utif.module.js +1644 -1558
  13. package/examples/jsm/loaders/DDSLoader.js +46 -3
  14. package/examples/jsm/loaders/EXRLoader.js +4 -4
  15. package/examples/jsm/loaders/FBXLoader.js +3 -1
  16. package/examples/jsm/loaders/GLTFLoader.js +25 -10
  17. package/examples/jsm/loaders/KTX2Loader.js +128 -79
  18. package/examples/jsm/loaders/LDrawLoader.js +1 -1
  19. package/examples/jsm/loaders/LogLuvLoader.js +2 -2
  20. package/examples/jsm/loaders/MMDLoader.js +10 -7
  21. package/examples/jsm/loaders/NRRDLoader.js +3 -3
  22. package/examples/jsm/loaders/PLYLoader.js +1 -1
  23. package/examples/jsm/loaders/RGBELoader.js +48 -66
  24. package/examples/jsm/loaders/STLLoader.js +7 -0
  25. package/examples/jsm/loaders/TGALoader.js +10 -10
  26. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  27. package/examples/jsm/misc/GPUComputationRenderer.js +0 -9
  28. package/examples/jsm/misc/Volume.js +4 -6
  29. package/examples/jsm/nodes/Nodes.js +8 -6
  30. package/examples/jsm/nodes/accessors/BufferAttributeNode.js +29 -3
  31. package/examples/jsm/nodes/accessors/CubeTextureNode.js +20 -3
  32. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +15 -4
  33. package/examples/jsm/nodes/accessors/InstanceNode.js +8 -8
  34. package/examples/jsm/nodes/accessors/LineMaterialNode.js +31 -0
  35. package/examples/jsm/nodes/accessors/MaterialNode.js +73 -61
  36. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +3 -0
  37. package/examples/jsm/nodes/accessors/Object3DNode.js +2 -2
  38. package/examples/jsm/nodes/accessors/SceneNode.js +6 -0
  39. package/examples/jsm/nodes/accessors/TextureNode.js +54 -9
  40. package/examples/jsm/nodes/accessors/TextureStoreNode.js +29 -0
  41. package/examples/jsm/nodes/core/AttributeNode.js +2 -2
  42. package/examples/jsm/nodes/core/LightingModel.js +7 -9
  43. package/examples/jsm/nodes/core/Node.js +28 -3
  44. package/examples/jsm/nodes/core/NodeBuilder.js +94 -12
  45. package/examples/jsm/nodes/core/NodeUniform.js +1 -1
  46. package/examples/jsm/nodes/core/OutputStructNode.js +58 -0
  47. package/examples/jsm/nodes/core/PropertyNode.js +6 -0
  48. package/examples/jsm/nodes/core/StackNode.js +4 -4
  49. package/examples/jsm/nodes/core/StructTypeNode.js +24 -0
  50. package/examples/jsm/nodes/display/BumpMapNode.js +77 -0
  51. package/examples/jsm/nodes/display/NormalMapNode.js +2 -2
  52. package/examples/jsm/nodes/display/ViewportNode.js +19 -5
  53. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +10 -2
  54. package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +13 -0
  55. package/examples/jsm/nodes/functions/PhongLightingModel.js +53 -14
  56. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +236 -97
  57. package/examples/jsm/nodes/geometry/RangeNode.js +2 -2
  58. package/examples/jsm/nodes/gpgpu/ComputeNode.js +13 -0
  59. package/examples/jsm/nodes/lighting/AONode.js +1 -1
  60. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +58 -20
  61. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +7 -10
  62. package/examples/jsm/nodes/lighting/EnvironmentNode.js +22 -12
  63. package/examples/jsm/nodes/lighting/HemisphereLightNode.js +1 -1
  64. package/examples/jsm/nodes/lighting/LightingContextNode.js +12 -9
  65. package/examples/jsm/nodes/lighting/PointLightNode.js +7 -10
  66. package/examples/jsm/nodes/lighting/SpotLightNode.js +7 -10
  67. package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +54 -0
  68. package/examples/jsm/nodes/materials/Materials.js +2 -0
  69. package/examples/jsm/nodes/materials/MeshLambertNodeMaterial.js +34 -0
  70. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -0
  71. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
  72. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +19 -2
  73. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +2 -2
  74. package/examples/jsm/nodes/materials/NodeMaterial.js +61 -26
  75. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +2 -2
  76. package/examples/jsm/nodes/math/HashNode.js +35 -0
  77. package/examples/jsm/nodes/shadernode/ShaderNode.js +6 -2
  78. package/examples/jsm/nodes/utils/SplitNode.js +1 -1
  79. package/examples/jsm/objects/Reflector.js +1 -9
  80. package/examples/jsm/objects/Refractor.js +0 -8
  81. package/examples/jsm/offscreen/scene.js +0 -1
  82. package/examples/jsm/postprocessing/FilmPass.js +3 -5
  83. package/examples/jsm/postprocessing/MaskPass.js +4 -1
  84. package/examples/jsm/postprocessing/OutputPass.js +33 -14
  85. package/examples/jsm/postprocessing/RenderPass.js +30 -12
  86. package/examples/jsm/postprocessing/SAOPass.js +23 -98
  87. package/examples/jsm/postprocessing/SSAOPass.js +10 -30
  88. package/examples/jsm/postprocessing/UnrealBloomPass.js +21 -17
  89. package/examples/jsm/renderers/common/Backend.js +11 -8
  90. package/examples/jsm/renderers/common/Background.js +22 -20
  91. package/examples/jsm/renderers/common/Binding.js +14 -0
  92. package/examples/jsm/renderers/common/Bindings.js +7 -10
  93. package/examples/jsm/renderers/common/Geometries.js +1 -1
  94. package/examples/jsm/renderers/common/Pipelines.js +96 -47
  95. package/examples/jsm/renderers/common/RenderContext.js +1 -0
  96. package/examples/jsm/renderers/common/RenderContexts.js +41 -5
  97. package/examples/jsm/renderers/common/RenderList.js +12 -4
  98. package/examples/jsm/renderers/common/RenderObject.js +26 -6
  99. package/examples/jsm/renderers/common/RenderObjects.js +10 -7
  100. package/examples/jsm/renderers/common/Renderer.js +82 -42
  101. package/examples/jsm/renderers/common/SampledTexture.js +2 -1
  102. package/examples/jsm/renderers/common/Sampler.js +1 -1
  103. package/examples/jsm/renderers/common/StorageBuffer.js +1 -1
  104. package/examples/jsm/renderers/common/Textures.js +172 -20
  105. package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +2 -2
  106. package/examples/jsm/renderers/common/nodes/NodeSampler.js +1 -1
  107. package/examples/jsm/renderers/common/nodes/Nodes.js +58 -13
  108. package/examples/jsm/renderers/webgl/WebGLBackend.js +607 -0
  109. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +118 -17
  110. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +84 -0
  111. package/examples/jsm/renderers/webgl/utils/WebGLExtensions.js +26 -0
  112. package/examples/jsm/renderers/webgl/utils/WebGLState.js +529 -0
  113. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +199 -0
  114. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +242 -0
  115. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +340 -0
  116. package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/WebGLNodeBuilder.js +1 -1
  117. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +320 -84
  118. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +18 -2
  119. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +120 -66
  120. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -2
  121. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +55 -36
  122. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +96 -5
  123. package/examples/jsm/renderers/webgpu/utils/WebGPUConstants.js +24 -22
  124. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +117 -139
  125. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +60 -142
  126. package/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js +7 -6
  127. package/examples/jsm/shaders/FilmShader.js +11 -54
  128. package/examples/jsm/shaders/OutputShader.js +19 -2
  129. package/examples/jsm/shaders/SAOShader.js +0 -13
  130. package/examples/jsm/shaders/SSAOShader.js +33 -26
  131. package/examples/jsm/utils/BufferGeometryUtils.js +13 -4
  132. package/examples/jsm/webxr/OculusHandPointerModel.js +2 -2
  133. package/package.json +2 -2
  134. package/src/Three.js +3 -0
  135. package/src/animation/PropertyBinding.js +1 -1
  136. package/src/audio/Audio.js +6 -0
  137. package/src/cameras/CubeCamera.js +1 -4
  138. package/src/constants.js +4 -1
  139. package/src/core/BufferAttribute.js +20 -0
  140. package/src/core/Object3D.js +2 -15
  141. package/src/core/RenderTarget.js +122 -0
  142. package/src/core/UniformsGroup.js +2 -2
  143. package/src/geometries/CapsuleGeometry.js +1 -1
  144. package/src/loaders/DataTextureLoader.js +19 -2
  145. package/src/materials/Material.js +2 -2
  146. package/src/math/Vector2.js +2 -2
  147. package/src/math/Vector3.js +3 -3
  148. package/src/math/Vector4.js +4 -4
  149. package/src/objects/Line.js +1 -1
  150. package/src/objects/Mesh.js +1 -1
  151. package/src/objects/Points.js +1 -1
  152. package/src/renderers/WebGLMultipleRenderTargets.js +0 -2
  153. package/src/renderers/WebGLRenderTarget.js +3 -110
  154. package/src/renderers/WebGLRenderer.js +83 -57
  155. package/src/renderers/shaders/ShaderChunk/iridescence_fragment.glsl.js +1 -2
  156. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +11 -1
  157. package/src/renderers/shaders/ShaderLib/background.glsl.js +8 -0
  158. package/src/renderers/webgl/WebGLBackground.js +5 -14
  159. package/src/renderers/webgl/WebGLGeometries.js +5 -1
  160. package/src/renderers/webgl/WebGLMaterials.js +1 -1
  161. package/src/renderers/webgl/WebGLProgram.js +2 -0
  162. package/src/renderers/webgl/WebGLPrograms.js +19 -3
  163. package/src/renderers/webgl/WebGLTextures.js +101 -16
  164. package/src/renderers/webgl/WebGLUtils.js +27 -20
  165. package/src/textures/CompressedCubeTexture.js +19 -0
  166. package/src/textures/Texture.js +2 -2
  167. package/src/utils.js +9 -1
  168. package/examples/jsm/nodes/functions/BSDF/BRDF_BlinnPhong.js +0 -30
  169. package/examples/jsm/renderers/common/RenderTarget.js +0 -15
  170. package/examples/jsm/renderers/common/nodes/NodeRender.js +0 -302
  171. /package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/SlotNode.js +0 -0
  172. /package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/WebGLNodes.js +0 -0
@@ -1,10 +1,7 @@
1
- import { NoColorSpace } from 'three';
1
+ import { NoColorSpace, FloatType } from 'three';
2
2
 
3
3
  import UniformsGroup from '../../common/UniformsGroup.js';
4
- import {
5
- FloatNodeUniform, Vector2NodeUniform, Vector3NodeUniform, Vector4NodeUniform,
6
- ColorNodeUniform, Matrix3NodeUniform, Matrix4NodeUniform
7
- } from '../../common/nodes/NodeUniform.js';
4
+
8
5
  import NodeSampler from '../../common/nodes/NodeSampler.js';
9
6
  import { NodeSampledTexture, NodeSampledCubeTexture } from '../../common/nodes/NodeSampledTexture.js';
10
7
 
@@ -12,20 +9,15 @@ import UniformBuffer from '../../common/UniformBuffer.js';
12
9
  import StorageBuffer from '../../common/StorageBuffer.js';
13
10
  import { getVectorLength, getStrideLength } from '../../common/BufferUtils.js';
14
11
 
15
- import RenderTarget from '../../common/RenderTarget.js';
16
- import CubeRenderTarget from '../../common/CubeRenderTarget.js';
17
-
18
12
  import { NodeBuilder, CodeNode, NodeMaterial } from '../../../nodes/Nodes.js';
19
13
 
20
14
  import WGSLNodeParser from './WGSLNodeParser.js';
21
15
 
22
- /*
23
16
  const gpuShaderStageLib = {
24
17
  'vertex': GPUShaderStage.VERTEX,
25
18
  'fragment': GPUShaderStage.FRAGMENT,
26
19
  'compute': GPUShaderStage.COMPUTE
27
20
  };
28
- */
29
21
 
30
22
  const supports = {
31
23
  instance: true
@@ -139,7 +131,7 @@ class WGSLNodeBuilder extends NodeBuilder {
139
131
 
140
132
  }
141
133
 
142
- getSampler( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
134
+ _getSampler( texture, textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
143
135
 
144
136
  if ( shaderStage === 'fragment' ) {
145
137
 
@@ -147,17 +139,13 @@ class WGSLNodeBuilder extends NodeBuilder {
147
139
 
148
140
  } else {
149
141
 
150
- this._include( 'repeatWrapping' );
151
-
152
- const dimension = `textureDimensions( ${textureProperty}, 0 )`;
153
-
154
- return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), 0 )`;
142
+ return this.getTextureLoad( texture, textureProperty, uvSnippet );
155
143
 
156
144
  }
157
145
 
158
146
  }
159
147
 
160
- getVideoSampler( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
148
+ _getVideoSampler( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
161
149
 
162
150
  if ( shaderStage === 'fragment' ) {
163
151
 
@@ -171,21 +159,33 @@ class WGSLNodeBuilder extends NodeBuilder {
171
159
 
172
160
  }
173
161
 
174
- getSamplerLevel( textureProperty, uvSnippet, biasSnippet, shaderStage = this.shaderStage ) {
162
+ _getSamplerLevel( texture, textureProperty, uvSnippet, biasSnippet, shaderStage = this.shaderStage ) {
175
163
 
176
- if ( shaderStage === 'fragment' ) {
164
+ if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false ) {
177
165
 
178
166
  return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${biasSnippet} )`;
179
167
 
180
168
  } else {
181
169
 
182
- this._include( 'repeatWrapping' );
170
+ return this.getTextureLoad( texture, textureProperty, uvSnippet, biasSnippet );
183
171
 
184
- const dimension = `textureDimensions( ${textureProperty}, 0 )`;
172
+ }
185
173
 
186
- return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${biasSnippet} ) )`;
174
+ }
187
175
 
188
- }
176
+ getTextureLoad( texture, textureProperty, uvSnippet, biasSnippet = '0' ) {
177
+
178
+ this._include( 'repeatWrapping' );
179
+
180
+ const dimension = `textureDimensions( ${textureProperty}, 0 )`;
181
+
182
+ return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${biasSnippet} ) )`;
183
+
184
+ }
185
+
186
+ isUnfilterable( texture ) {
187
+
188
+ return texture.isDataTexture === true && texture.type === FloatType;
189
189
 
190
190
  }
191
191
 
@@ -195,11 +195,15 @@ class WGSLNodeBuilder extends NodeBuilder {
195
195
 
196
196
  if ( texture.isVideoTexture === true ) {
197
197
 
198
- snippet = this.getVideoSampler( textureProperty, uvSnippet, shaderStage );
198
+ snippet = this._getVideoSampler( textureProperty, uvSnippet, shaderStage );
199
+
200
+ } else if ( this.isUnfilterable( texture ) ) {
201
+
202
+ snippet = this.getTextureLoad( texture, textureProperty, uvSnippet );
199
203
 
200
204
  } else {
201
205
 
202
- snippet = this.getSampler( textureProperty, uvSnippet, shaderStage );
206
+ snippet = this._getSampler( texture, textureProperty, uvSnippet, shaderStage );
203
207
 
204
208
  }
205
209
 
@@ -207,17 +211,31 @@ class WGSLNodeBuilder extends NodeBuilder {
207
211
 
208
212
  }
209
213
 
214
+ getTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, shaderStage = this.shaderStage ) {
215
+
216
+ if ( shaderStage === 'fragment' ) {
217
+
218
+ return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`;
219
+
220
+ } else {
221
+
222
+ console.error( `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${ shaderStage } shader.` );
223
+
224
+ }
225
+
226
+ }
227
+
210
228
  getTextureLevel( texture, textureProperty, uvSnippet, biasSnippet, shaderStage = this.shaderStage ) {
211
229
 
212
230
  let snippet = null;
213
231
 
214
232
  if ( texture.isVideoTexture === true ) {
215
233
 
216
- snippet = this.getVideoSampler( textureProperty, uvSnippet, shaderStage );
234
+ snippet = this._getVideoSampler( textureProperty, uvSnippet, shaderStage );
217
235
 
218
236
  } else {
219
237
 
220
- snippet = this.getSamplerLevel( textureProperty, uvSnippet, biasSnippet, shaderStage );
238
+ snippet = this._getSamplerLevel( texture, textureProperty, uvSnippet, biasSnippet, shaderStage );
221
239
 
222
240
  }
223
241
 
@@ -273,8 +291,6 @@ class WGSLNodeBuilder extends NodeBuilder {
273
291
 
274
292
  if ( type === 'texture' || type === 'cubeTexture' ) {
275
293
 
276
- const sampler = new NodeSampler( `${uniformNode.name}_sampler`, uniformNode.node );
277
-
278
294
  let texture = null;
279
295
 
280
296
  if ( type === 'texture' ) {
@@ -287,11 +303,17 @@ class WGSLNodeBuilder extends NodeBuilder {
287
303
 
288
304
  }
289
305
 
306
+ texture.store = node.isStoreTextureNode === true;
307
+ texture.setVisibility( gpuShaderStageLib[ shaderStage ] );
308
+
290
309
  // add first textures in sequence and group for last
291
310
  const lastBinding = bindings[ bindings.length - 1 ];
292
311
  const index = lastBinding && lastBinding.isUniformsGroup ? bindings.length - 1 : bindings.length;
293
312
 
294
- if ( shaderStage === 'fragment' ) {
313
+ if ( shaderStage === 'fragment' && this.isUnfilterable( node.value ) === false && texture.store === false ) {
314
+
315
+ const sampler = new NodeSampler( `${uniformNode.name}_sampler`, uniformNode.node );
316
+ sampler.setVisibility( gpuShaderStageLib[ shaderStage ] );
295
317
 
296
318
  bindings.splice( index, 0, sampler, texture );
297
319
 
@@ -309,7 +331,7 @@ class WGSLNodeBuilder extends NodeBuilder {
309
331
 
310
332
  const bufferClass = type === 'storageBuffer' ? StorageBuffer : UniformBuffer;
311
333
  const buffer = new bufferClass( 'NodeBuffer_' + node.id, node.value );
312
- //buffer.setVisibility( gpuShaderStageLib[ shaderStage ] );
334
+ buffer.setVisibility( gpuShaderStageLib[ shaderStage ] );
313
335
 
314
336
  // add first textures in sequence and group for last
315
337
  const lastBinding = bindings[ bindings.length - 1 ];
@@ -326,7 +348,7 @@ class WGSLNodeBuilder extends NodeBuilder {
326
348
  if ( uniformsGroup === undefined ) {
327
349
 
328
350
  uniformsGroup = new UniformsGroup( 'nodeUniforms' );
329
- //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] );
351
+ uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] );
330
352
 
331
353
  this.uniformsGroup[ shaderStage ] = uniformsGroup;
332
354
 
@@ -340,7 +362,7 @@ class WGSLNodeBuilder extends NodeBuilder {
340
362
 
341
363
  for ( const uniformNode of node.nodes ) {
342
364
 
343
- const uniformNodeGPU = this._getNodeUniform( uniformNode, type );
365
+ const uniformNodeGPU = this.getNodeUniform( uniformNode, type );
344
366
 
345
367
  // fit bounds to buffer
346
368
  uniformNodeGPU.boundary = getVectorLength( uniformNodeGPU.itemSize );
@@ -354,7 +376,7 @@ class WGSLNodeBuilder extends NodeBuilder {
354
376
 
355
377
  } else {
356
378
 
357
- uniformGPU = this._getNodeUniform( uniformNode, type );
379
+ uniformGPU = this.getNodeUniform( uniformNode, type );
358
380
 
359
381
  uniformsGroup.addUniform( uniformGPU );
360
382
 
@@ -378,7 +400,7 @@ class WGSLNodeBuilder extends NodeBuilder {
378
400
 
379
401
  isReference( type ) {
380
402
 
381
- return super.isReference( type ) || type === 'texture_2d' || type === 'texture_cube';
403
+ return super.isReference( type ) || type === 'texture_2d' || type === 'texture_cube' || type === 'texture_storage_2d';
382
404
 
383
405
  }
384
406
 
@@ -478,6 +500,44 @@ class WGSLNodeBuilder extends NodeBuilder {
478
500
 
479
501
  }
480
502
 
503
+ getStructMembers( struct ) {
504
+
505
+ const snippets = [];
506
+ const members = struct.getMemberTypes();
507
+
508
+ for ( let i = 0; i < members.length; i ++ ) {
509
+
510
+ const member = members[ i ];
511
+ snippets.push( `\t@location( ${i} ) m${i} : ${ member }<f32>` );
512
+
513
+ }
514
+
515
+ return snippets.join( ',\n' );
516
+
517
+ }
518
+
519
+ getStructs( shaderStage ) {
520
+
521
+ const snippets = [];
522
+ const structs = this.structs[ shaderStage ];
523
+
524
+ for ( let index = 0, length = structs.length; index < length; index ++ ) {
525
+
526
+ const struct = structs[ index ];
527
+ const name = struct.name;
528
+
529
+ let snippet = `\struct ${ name } {\n`;
530
+ snippet += this.getStructMembers( struct );
531
+ snippet += '\n}';
532
+
533
+ snippets.push( snippet );
534
+
535
+ }
536
+
537
+ return snippets.join( '\n\n' );
538
+
539
+ }
540
+
481
541
  getVar( type, name ) {
482
542
 
483
543
  return `var ${ name } : ${ this.getType( type ) }`;
@@ -526,6 +586,7 @@ class WGSLNodeBuilder extends NodeBuilder {
526
586
 
527
587
  attributesSnippet += ' @interpolate( flat )';
528
588
 
589
+
529
590
  }
530
591
 
531
592
  snippets.push( `${ attributesSnippet } ${ varying.name } : ${ this.getType( varying.type ) }` );
@@ -566,13 +627,21 @@ class WGSLNodeBuilder extends NodeBuilder {
566
627
 
567
628
  if ( uniform.type === 'texture' || uniform.type === 'cubeTexture' ) {
568
629
 
569
- if ( shaderStage === 'fragment' ) {
630
+ const texture = uniform.node.value;
631
+
632
+ if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false && uniform.node.isStoreTextureNode !== true ) {
570
633
 
571
- bindingSnippets.push( `@binding( ${index ++} ) @group( 0 ) var ${uniform.name}_sampler : sampler;` );
634
+ if ( texture.isDepthTexture === true && texture.compareFunction !== null ) {
572
635
 
573
- }
636
+ bindingSnippets.push( `@binding( ${index ++} ) @group( 0 ) var ${uniform.name}_sampler : sampler_comparison;` );
574
637
 
575
- const texture = uniform.node.value;
638
+ } else {
639
+
640
+ bindingSnippets.push( `@binding( ${index ++} ) @group( 0 ) var ${uniform.name}_sampler : sampler;` );
641
+
642
+ }
643
+
644
+ }
576
645
 
577
646
  let textureType;
578
647
 
@@ -588,6 +657,11 @@ class WGSLNodeBuilder extends NodeBuilder {
588
657
 
589
658
  textureType = 'texture_external';
590
659
 
660
+ } else if ( uniform.node.isStoreTextureNode === true ) {
661
+
662
+ // @TODO: Add support for other formats
663
+ textureType = 'texture_storage_2d<rgba8unorm, write>';
664
+
591
665
  } else {
592
666
 
593
667
  textureType = 'texture_2d<f32>';
@@ -688,13 +762,16 @@ class WGSLNodeBuilder extends NodeBuilder {
688
762
 
689
763
  }
690
764
 
765
+ const outputNode = mainNode.outputNode;
691
766
  const stageData = shadersData[ shaderStage ];
692
767
 
693
768
  stageData.uniforms = this.getUniforms( shaderStage );
694
769
  stageData.attributes = this.getAttributes( shaderStage );
695
770
  stageData.varyings = this.getVaryings( shaderStage );
771
+ stageData.structs = this.getStructs( shaderStage );
696
772
  stageData.vars = this.getVars( shaderStage );
697
773
  stageData.codes = this.getCodes( shaderStage );
774
+ stageData.returnType = ( outputNode !== undefined && outputNode.isOutputStructNode === true ) ? outputNode.nodeType : '@location( 0 ) vec4<f32>';
698
775
  stageData.flow = flow;
699
776
 
700
777
  }
@@ -712,18 +789,6 @@ class WGSLNodeBuilder extends NodeBuilder {
712
789
 
713
790
  }
714
791
 
715
- getRenderTarget( width, height, options ) {
716
-
717
- return new RenderTarget( width, height, options );
718
-
719
- }
720
-
721
- getCubeRenderTarget( size, options ) {
722
-
723
- return new CubeRenderTarget( size, options );
724
-
725
- }
726
-
727
792
  getMethod( method ) {
728
793
 
729
794
  if ( wgslPolyfill[ method ] !== undefined ) {
@@ -754,20 +819,6 @@ class WGSLNodeBuilder extends NodeBuilder {
754
819
 
755
820
  }
756
821
 
757
- _getNodeUniform( uniformNode, type ) {
758
-
759
- if ( type === 'float' ) return new FloatNodeUniform( uniformNode );
760
- if ( type === 'vec2' ) return new Vector2NodeUniform( uniformNode );
761
- if ( type === 'vec3' ) return new Vector3NodeUniform( uniformNode );
762
- if ( type === 'vec4' ) return new Vector4NodeUniform( uniformNode );
763
- if ( type === 'color' ) return new ColorNodeUniform( uniformNode );
764
- if ( type === 'mat3' ) return new Matrix3NodeUniform( uniformNode );
765
- if ( type === 'mat4' ) return new Matrix4NodeUniform( uniformNode );
766
-
767
- throw new Error( `Uniform "${type}" not declared.` );
768
-
769
- }
770
-
771
822
  _getWGSLVertexCode( shaderData ) {
772
823
 
773
824
  return `${ this.getSignature() }
@@ -807,11 +858,14 @@ fn main( ${shaderData.attributes} ) -> NodeVaryingsStruct {
807
858
  // uniforms
808
859
  ${shaderData.uniforms}
809
860
 
861
+ // structs
862
+ ${shaderData.structs}
863
+
810
864
  // codes
811
865
  ${shaderData.codes}
812
866
 
813
867
  @fragment
814
- fn main( ${shaderData.varyings} ) -> @location( 0 ) vec4<f32> {
868
+ fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} {
815
869
 
816
870
  // vars
817
871
  ${shaderData.vars}
@@ -2,7 +2,7 @@ import NodeFunction from '../../../nodes/core/NodeFunction.js';
2
2
  import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js';
3
3
 
4
4
  const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+)?/i;
5
- const propertiesRegexp = /[a-z_0-9]+/ig;
5
+ const propertiesRegexp = /[a-z_0-9]+|<(.*?)>+/ig;
6
6
 
7
7
  const wgslTypeLib = {
8
8
  f32: 'float'
@@ -46,7 +46,7 @@ const parse = ( source ) => {
46
46
 
47
47
  // precision
48
48
 
49
- if ( i < propsMatches.length && /^[fui]\d{2}$/.test( propsMatches[ i ][ 0 ] ) === true )
49
+ if ( i < propsMatches.length && propsMatches[ i ][ 0 ].startsWith( '<' ) === true )
50
50
  i ++;
51
51
 
52
52
  // add input
@@ -34,23 +34,31 @@ class WebGPUAttributeUtils {
34
34
  const bufferAttribute = this._getBufferAttribute( attribute );
35
35
 
36
36
  const backend = this.backend;
37
- const device = backend.device;
37
+ const bufferData = backend.get( bufferAttribute );
38
38
 
39
- const array = bufferAttribute.array;
40
- const size = array.byteLength + ( ( 4 - ( array.byteLength % 4 ) ) % 4 ); // ensure 4 byte alignment, see #20441
39
+ let buffer = bufferData.buffer;
40
+
41
+ if ( buffer === undefined ) {
41
42
 
42
- const buffer = device.createBuffer( {
43
- label: bufferAttribute.name,
44
- size: size,
45
- usage: usage,
46
- mappedAtCreation: true
47
- } );
43
+ const device = backend.device;
48
44
 
49
- new array.constructor( buffer.getMappedRange() ).set( array );
45
+ const array = bufferAttribute.array;
46
+ const size = array.byteLength + ( ( 4 - ( array.byteLength % 4 ) ) % 4 ); // ensure 4 byte alignment, see #20441
47
+
48
+ buffer = device.createBuffer( {
49
+ label: bufferAttribute.name,
50
+ size: size,
51
+ usage: usage,
52
+ mappedAtCreation: true
53
+ } );
50
54
 
51
- buffer.unmap();
55
+ new array.constructor( buffer.getMappedRange() ).set( array );
52
56
 
53
- backend.get( attribute ).buffer = buffer;
57
+ buffer.unmap();
58
+
59
+ bufferData.buffer = buffer;
60
+
61
+ }
54
62
 
55
63
  }
56
64
 
@@ -61,7 +69,7 @@ class WebGPUAttributeUtils {
61
69
  const backend = this.backend;
62
70
  const device = backend.device;
63
71
 
64
- const buffer = backend.get( attribute ).buffer;
72
+ const buffer = backend.get( bufferAttribute ).buffer;
65
73
 
66
74
  const array = bufferAttribute.array;
67
75
  const updateRange = bufferAttribute.updateRange;
@@ -93,51 +101,64 @@ class WebGPUAttributeUtils {
93
101
 
94
102
  }
95
103
 
96
- createShaderAttributes( renderObject ) {
104
+ createShaderVertexBuffers( renderObject ) {
97
105
 
98
106
  const attributes = renderObject.getAttributes();
99
- const shaderAttributes = [];
107
+ const vertexBuffers = new Map();
100
108
 
101
109
  for ( let slot = 0; slot < attributes.length; slot ++ ) {
102
110
 
103
111
  const geometryAttribute = attributes[ slot ];
104
112
  const bytesPerElement = geometryAttribute.array.BYTES_PER_ELEMENT;
113
+ const bufferAttribute = this._getBufferAttribute( geometryAttribute );
105
114
 
106
- const format = this._getVertexFormat( geometryAttribute );
115
+ let vertexBufferLayout = vertexBuffers.get( bufferAttribute );
107
116
 
108
- let arrayStride = geometryAttribute.itemSize * bytesPerElement;
109
- let offset = 0;
110
- let stepMode = geometryAttribute.isInstancedBufferAttribute ? GPUInputStepMode.Instance : GPUInputStepMode.Vertex;
117
+ if ( vertexBufferLayout === undefined ) {
111
118
 
112
- if ( geometryAttribute.isInterleavedBufferAttribute === true ) {
119
+ let arrayStride, stepMode;
113
120
 
114
- // @TODO: It can be optimized for "vertexBuffers" on RenderPipeline
121
+ if ( geometryAttribute.isInterleavedBufferAttribute === true ) {
115
122
 
116
- arrayStride = geometryAttribute.data.stride * bytesPerElement;
117
- offset = geometryAttribute.offset * bytesPerElement;
118
- if ( geometryAttribute.data.isInstancedInterleavedBuffer ) stepMode = GPUInputStepMode.Instance;
123
+ arrayStride = geometryAttribute.data.stride * bytesPerElement;
124
+ stepMode = geometryAttribute.data.isInstancedInterleavedBuffer ? GPUInputStepMode.Instance : GPUInputStepMode.Vertex;
125
+
126
+ } else {
127
+
128
+ arrayStride = geometryAttribute.itemSize * bytesPerElement;
129
+ stepMode = geometryAttribute.isInstancedBufferAttribute ? GPUInputStepMode.Instance : GPUInputStepMode.Vertex;
130
+
131
+ }
132
+
133
+ vertexBufferLayout = {
134
+ arrayStride,
135
+ attributes: [],
136
+ stepMode
137
+ };
138
+
139
+ vertexBuffers.set( bufferAttribute, vertexBufferLayout );
119
140
 
120
141
  }
121
142
 
122
- shaderAttributes.push( {
123
- geometryAttribute,
124
- arrayStride,
125
- stepMode,
143
+ const format = this._getVertexFormat( geometryAttribute );
144
+ const offset = ( geometryAttribute.isInterleavedBufferAttribute === true ) ? geometryAttribute.offset * bytesPerElement : 0;
145
+
146
+ vertexBufferLayout.attributes.push( {
147
+ shaderLocation: slot,
126
148
  offset,
127
- format,
128
- slot
149
+ format
129
150
  } );
130
151
 
131
152
  }
132
153
 
133
- return shaderAttributes;
154
+ return Array.from( vertexBuffers.values() );
134
155
 
135
156
  }
136
157
 
137
158
  destroyAttribute( attribute ) {
138
159
 
139
160
  const backend = this.backend;
140
- const data = backend.get( attribute );
161
+ const data = backend.get( this._getBufferAttribute( attribute ) );
141
162
 
142
163
  data.buffer.destroy();
143
164
 
@@ -145,14 +166,12 @@ class WebGPUAttributeUtils {
145
166
 
146
167
  }
147
168
 
148
- async getArrayBuffer( attribute ) {
169
+ async getArrayBufferAsync( attribute ) {
149
170
 
150
171
  const backend = this.backend;
151
172
  const device = backend.device;
152
173
 
153
- const data = backend.get( attribute );
154
-
155
- //const bufferAttribute = this._getBufferAttribute( attribute );
174
+ const data = backend.get( this._getBufferAttribute( attribute ) );
156
175
 
157
176
  const bufferGPU = data.buffer;
158
177
  const size = bufferGPU.size;
@@ -1,6 +1,7 @@
1
1
  import {
2
- GPUTextureAspect, GPUTextureViewDimension
2
+ GPUTextureAspect, GPUTextureViewDimension, GPUBufferBindingType, GPUTextureSampleType
3
3
  } from './WebGPUConstants.js';
4
+ import { FloatType } from 'three';
4
5
 
5
6
  class WebGPUBindingUtils {
6
7
 
@@ -10,16 +11,106 @@ class WebGPUBindingUtils {
10
11
 
11
12
  }
12
13
 
13
- createBindings( bindings, pipeline ) {
14
+ createBindingsLayout( bindings ) {
15
+
16
+ const backend = this.backend;
17
+ const device = backend.device;
18
+
19
+ const entries = [];
20
+
21
+ let index = 0;
22
+
23
+ for ( const binding of bindings ) {
24
+
25
+ const bindingGPU = {
26
+ binding: index ++,
27
+ visibility: binding.visibility
28
+ };
29
+
30
+ if ( binding.isUniformBuffer || binding.isStorageBuffer ) {
31
+
32
+ const buffer = {}; // GPUBufferBindingLayout
33
+
34
+ if ( binding.isStorageBuffer ) {
35
+
36
+ buffer.type = GPUBufferBindingType.Storage;
37
+
38
+ }
39
+
40
+ bindingGPU.buffer = buffer;
41
+
42
+ } else if ( binding.isSampler ) {
43
+
44
+ const sampler = {}; // GPUSamplerBindingLayout
45
+
46
+ if ( binding.texture.isDepthTexture ) {
47
+
48
+ if ( binding.texture.compareFunction !== null ) {
49
+
50
+ sampler.type = 'comparison';
51
+
52
+ }
53
+
54
+ }
55
+
56
+ bindingGPU.sampler = sampler;
57
+
58
+ } else if ( binding.isSampledTexture && binding.texture.isVideoTexture ) {
59
+
60
+ bindingGPU.externalTexture = {}; // GPUExternalTextureBindingLayout
61
+
62
+ } else if ( binding.isSampledTexture && binding.store ) {
63
+
64
+ const format = this.backend.get( binding.texture ).texture.format;
65
+
66
+ bindingGPU.storageTexture = { format }; // GPUStorageTextureBindingLayout
67
+
68
+ } else if ( binding.isSampledTexture ) {
69
+
70
+ const texture = {}; // GPUTextureBindingLayout
71
+
72
+ if ( binding.texture.isDepthTexture ) {
73
+
74
+ texture.sampleType = GPUTextureSampleType.Depth;
75
+
76
+ } else if ( binding.texture.isDataTexture && binding.texture.type === FloatType ) {
77
+
78
+ // @TODO: Add support for this soon: backend.hasFeature( 'float32-filterable' )
79
+
80
+ texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
81
+
82
+ }
83
+
84
+ if ( binding.isSampledCubeTexture ) {
85
+
86
+ texture.viewDimension = GPUTextureViewDimension.Cube;
87
+
88
+ }
89
+
90
+ bindingGPU.texture = texture;
91
+
92
+ } else {
93
+
94
+ console.error( 'WebGPUBindingUtils: Unsupported binding "${ binding }".' );
95
+
96
+ }
97
+
98
+ entries.push( bindingGPU );
99
+
100
+ }
101
+
102
+ return device.createBindGroupLayout( { entries } );
103
+
104
+ }
105
+
106
+ createBindings( bindings ) {
14
107
 
15
108
  const backend = this.backend;
16
109
  const bindingsData = backend.get( bindings );
17
110
 
18
111
  // setup (static) binding layout and (dynamic) binding group
19
112
 
20
- const pipelineGPU = backend.get( pipeline ).pipeline;
21
-
22
- const bindLayoutGPU = pipelineGPU.getBindGroupLayout( 0 );
113
+ const bindLayoutGPU = this.createBindingsLayout( bindings );
23
114
  const bindGroupGPU = this.createBindGroup( bindings, bindLayoutGPU );
24
115
 
25
116
  bindingsData.layout = bindLayoutGPU;