super-three 0.163.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 (197) hide show
  1. package/README.md +3 -3
  2. package/build/three.cjs +1127 -452
  3. package/build/three.module.js +1127 -452
  4. package/build/three.module.min.js +2 -2
  5. package/examples/jsm/animation/CCDIKSolver.js +4 -2
  6. package/examples/jsm/controls/TransformControls.js +1 -1
  7. package/examples/jsm/environments/RoomEnvironment.js +1 -5
  8. package/examples/jsm/exporters/GLTFExporter.js +45 -1
  9. package/examples/jsm/exporters/USDZExporter.js +13 -5
  10. package/examples/jsm/helpers/ViewHelper.js +32 -67
  11. package/examples/jsm/libs/draco/README.md +2 -2
  12. package/examples/jsm/libs/tween.module.js +75 -64
  13. package/examples/jsm/lines/LineMaterial.js +1 -15
  14. package/examples/jsm/lines/LineSegments2.js +15 -0
  15. package/examples/jsm/lines/Wireframe.js +16 -1
  16. package/examples/jsm/loaders/DRACOLoader.js +1 -1
  17. package/examples/jsm/loaders/EXRLoader.js +283 -99
  18. package/examples/jsm/loaders/FBXLoader.js +24 -13
  19. package/examples/jsm/loaders/GLTFLoader.js +55 -0
  20. package/examples/jsm/loaders/KTX2Loader.js +3 -6
  21. package/examples/jsm/loaders/LDrawLoader.js +3 -2
  22. package/examples/jsm/loaders/MMDLoader.js +31 -12
  23. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  24. package/examples/jsm/loaders/lwo/IFFParser.js +8 -5
  25. package/examples/jsm/materials/MeshGouraudMaterial.js +7 -1
  26. package/examples/jsm/math/Octree.js +26 -20
  27. package/examples/jsm/modifiers/CurveModifier.js +11 -9
  28. package/examples/jsm/nodes/Nodes.js +15 -13
  29. package/examples/jsm/nodes/accessors/AccessorsUtils.js +16 -1
  30. package/examples/jsm/nodes/accessors/BitangentNode.js +7 -83
  31. package/examples/jsm/nodes/accessors/BufferNode.js +6 -0
  32. package/examples/jsm/nodes/accessors/CameraNode.js +12 -119
  33. package/examples/jsm/nodes/accessors/ClippingNode.js +3 -2
  34. package/examples/jsm/nodes/accessors/MaterialNode.js +109 -3
  35. package/examples/jsm/nodes/accessors/ModelNode.js +3 -0
  36. package/examples/jsm/nodes/accessors/NormalNode.js +9 -101
  37. package/examples/jsm/nodes/accessors/PositionNode.js +6 -100
  38. package/examples/jsm/nodes/accessors/ReferenceNode.js +6 -0
  39. package/examples/jsm/nodes/accessors/ReflectVectorNode.js +2 -31
  40. package/examples/jsm/nodes/accessors/StorageBufferNode.js +9 -0
  41. package/examples/jsm/nodes/accessors/{TextureStoreNode.js → StorageTextureNode.js} +19 -6
  42. package/examples/jsm/nodes/accessors/TangentNode.js +11 -97
  43. package/examples/jsm/nodes/accessors/Texture3DNode.js +100 -0
  44. package/examples/jsm/nodes/accessors/TextureNode.js +21 -3
  45. package/examples/jsm/nodes/accessors/TextureSizeNode.js +1 -1
  46. package/examples/jsm/nodes/accessors/UVNode.js +2 -46
  47. package/examples/jsm/nodes/code/FunctionNode.js +0 -8
  48. package/examples/jsm/nodes/core/AttributeNode.js +15 -3
  49. package/examples/jsm/nodes/core/ContextNode.js +6 -0
  50. package/examples/jsm/nodes/core/Node.js +23 -2
  51. package/examples/jsm/nodes/core/NodeBuilder.js +25 -18
  52. package/examples/jsm/nodes/core/NodeKeywords.js +1 -1
  53. package/examples/jsm/nodes/core/OutputStructNode.js +3 -6
  54. package/examples/jsm/nodes/core/PropertyNode.js +11 -0
  55. package/examples/jsm/nodes/core/VaryingNode.js +40 -9
  56. package/examples/jsm/nodes/display/AfterImageNode.js +14 -2
  57. package/examples/jsm/nodes/display/BumpMapNode.js +7 -26
  58. package/examples/jsm/nodes/display/FrontFacingNode.js +13 -0
  59. package/examples/jsm/nodes/display/PassNode.js +3 -1
  60. package/examples/jsm/nodes/display/ViewportDepthNode.js +1 -1
  61. package/examples/jsm/nodes/display/ViewportNode.js +5 -3
  62. package/examples/jsm/nodes/display/ViewportTextureNode.js +4 -1
  63. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +26 -7
  64. package/examples/jsm/nodes/functions/BSDF/D_GGX_Anisotropic.js +28 -0
  65. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -3
  66. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +29 -0
  67. package/examples/jsm/nodes/functions/PhongLightingModel.js +1 -1
  68. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +210 -12
  69. package/examples/jsm/nodes/functions/ShadowMaskModel.js +31 -0
  70. package/examples/jsm/nodes/functions/ToonLightingModel.js +49 -0
  71. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +20 -5
  72. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +2 -1
  73. package/examples/jsm/nodes/lighting/EnvironmentNode.js +11 -2
  74. package/examples/jsm/nodes/lighting/IrradianceNode.js +24 -0
  75. package/examples/jsm/nodes/lighting/LightsNode.js +28 -1
  76. package/examples/jsm/nodes/lighting/PointLightNode.js +2 -1
  77. package/examples/jsm/nodes/lighting/SpotLightNode.js +2 -1
  78. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +11 -7
  79. package/examples/jsm/nodes/materials/Materials.js +4 -0
  80. package/examples/jsm/nodes/materials/MeshMatcapNodeMaterial.js +52 -0
  81. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +0 -2
  82. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
  83. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +94 -6
  84. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +11 -4
  85. package/examples/jsm/nodes/materials/MeshToonNodeMaterial.js +34 -0
  86. package/examples/jsm/nodes/materials/NodeMaterial.js +43 -45
  87. package/examples/jsm/nodes/materials/ShadowNodeMaterial.js +34 -0
  88. package/examples/jsm/nodes/materials/VolumeNodeMaterial.js +106 -0
  89. package/examples/jsm/nodes/math/HashNode.js +2 -2
  90. package/examples/jsm/nodes/pmrem/PMREMUtils.js +1 -1
  91. package/examples/jsm/nodes/shadernode/ShaderNode.js +57 -41
  92. package/examples/jsm/nodes/utils/ArrayElementNode.js +1 -1
  93. package/examples/jsm/nodes/utils/MatcapUVNode.js +1 -1
  94. package/examples/jsm/nodes/utils/TimerNode.js +1 -1
  95. package/examples/jsm/objects/Lensflare.js +2 -2
  96. package/examples/jsm/physics/JoltPhysics.js +281 -0
  97. package/examples/jsm/postprocessing/RenderPass.js +1 -1
  98. package/examples/jsm/postprocessing/RenderTransitionPass.js +193 -0
  99. package/examples/jsm/renderers/CSS2DRenderer.js +25 -5
  100. package/examples/jsm/renderers/CSS3DRenderer.js +24 -3
  101. package/examples/jsm/renderers/common/Attributes.js +2 -0
  102. package/examples/jsm/renderers/common/Background.js +3 -3
  103. package/examples/jsm/renderers/common/Bindings.js +17 -0
  104. package/examples/jsm/renderers/common/ChainMap.js +18 -48
  105. package/examples/jsm/renderers/common/ClippingContext.js +5 -5
  106. package/examples/jsm/renderers/common/Pipelines.js +2 -2
  107. package/examples/jsm/renderers/common/RenderBundle.js +18 -0
  108. package/examples/jsm/renderers/common/RenderBundles.js +38 -0
  109. package/examples/jsm/renderers/common/RenderList.js +10 -1
  110. package/examples/jsm/renderers/common/RenderObject.js +49 -1
  111. package/examples/jsm/renderers/common/Renderer.js +268 -25
  112. package/examples/jsm/renderers/common/Textures.js +1 -1
  113. package/examples/jsm/renderers/common/Uniform.js +1 -1
  114. package/examples/jsm/renderers/common/extras/PMREMGenerator.js +13 -17
  115. package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +18 -4
  116. package/examples/jsm/renderers/common/nodes/NodeSampler.js +6 -0
  117. package/examples/jsm/renderers/common/nodes/Nodes.js +31 -47
  118. package/examples/jsm/renderers/webgl/WebGLBackend.js +7 -21
  119. package/examples/jsm/renderers/webgl/WebGLBufferRenderer.js +5 -1
  120. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +23 -5
  121. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +114 -13
  122. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +3 -21
  123. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +80 -46
  124. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +85 -12
  125. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -1
  126. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +10 -1
  127. package/examples/jsm/renderers/webgpu/utils/WebGPUConstants.js +6 -0
  128. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +62 -19
  129. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -3
  130. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  131. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  132. package/examples/jsm/utils/BufferGeometryUtils.js +18 -16
  133. package/examples/jsm/utils/GPUStatsPanel.js +2 -0
  134. package/examples/jsm/utils/SceneUtils.js +60 -1
  135. package/examples/jsm/utils/SortUtils.js +8 -5
  136. package/examples/jsm/webxr/OculusHandModel.js +3 -2
  137. package/examples/jsm/webxr/XRHandModelFactory.js +4 -2
  138. package/package.json +3 -2
  139. package/src/animation/tracks/BooleanKeyframeTrack.js +10 -1
  140. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -2
  141. package/src/animation/tracks/StringKeyframeTrack.js +10 -1
  142. package/src/constants.js +1 -1
  143. package/src/core/Object3D.js +2 -0
  144. package/src/core/Raycaster.js +6 -2
  145. package/src/core/RenderTarget.js +8 -0
  146. package/src/extras/PMREMGenerator.js +12 -11
  147. package/src/loaders/FileLoader.js +5 -1
  148. package/src/loaders/LoaderUtils.js +3 -1
  149. package/src/loaders/MaterialLoader.js +1 -0
  150. package/src/loaders/ObjectLoader.js +1 -0
  151. package/src/materials/Material.js +2 -0
  152. package/src/materials/MeshPhysicalMaterial.js +20 -0
  153. package/src/objects/BatchedMesh.js +114 -1
  154. package/src/objects/Line.js +66 -43
  155. package/src/renderers/WebGLRenderer.js +371 -109
  156. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +15 -0
  157. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -1
  158. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +9 -1
  159. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +8 -22
  160. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  161. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -0
  162. package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +1 -1
  163. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +1 -1
  164. package/src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl.js +3 -14
  165. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +10 -31
  166. package/src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl.js +3 -23
  167. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +17 -9
  168. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  169. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +47 -13
  170. package/src/renderers/shaders/ShaderChunk.js +0 -2
  171. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  172. package/src/renderers/shaders/ShaderLib.js +1 -0
  173. package/src/renderers/webgl/WebGLBackground.js +24 -3
  174. package/src/renderers/webgl/WebGLBufferRenderer.js +36 -0
  175. package/src/renderers/webgl/WebGLCapabilities.js +33 -1
  176. package/src/renderers/webgl/WebGLExtensions.js +3 -1
  177. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +36 -0
  178. package/src/renderers/webgl/WebGLLights.js +9 -12
  179. package/src/renderers/webgl/WebGLMaterials.js +7 -5
  180. package/src/renderers/webgl/WebGLMorphtargets.js +1 -2
  181. package/src/renderers/webgl/WebGLProgram.js +5 -36
  182. package/src/renderers/webgl/WebGLPrograms.js +19 -14
  183. package/src/renderers/webgl/WebGLRenderStates.js +8 -4
  184. package/src/renderers/webgl/WebGLShadowMap.js +25 -25
  185. package/src/renderers/webgl/WebGLTextures.js +206 -129
  186. package/src/renderers/webgl/WebGLUtils.js +3 -21
  187. package/src/renderers/webxr/WebXRDepthSensing.js +3 -3
  188. package/src/renderers/webxr/WebXRManager.js +8 -6
  189. package/src/textures/CompressedArrayTexture.js +14 -0
  190. package/src/textures/DataArrayTexture.js +14 -0
  191. package/src/textures/DepthTexture.js +1 -3
  192. package/src/utils.js +30 -1
  193. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +0 -318
  194. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +0 -26
  195. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +0 -792
  196. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +0 -51
  197. package/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl.js +0 -10
@@ -14,7 +14,6 @@ import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js';
14
14
  import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js';
15
15
  import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js';
16
16
  import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js';
17
- import WebGPU from '../../capabilities/WebGPU.js';
18
17
 
19
18
  //
20
19
 
@@ -45,7 +44,6 @@ class WebGPUBackend extends Backend {
45
44
 
46
45
  this.trackTimestamp = ( parameters.trackTimestamp === true );
47
46
 
48
- this.adapter = null;
49
47
  this.device = null;
50
48
  this.context = null;
51
49
  this.colorBuffer = null;
@@ -68,44 +66,55 @@ class WebGPUBackend extends Backend {
68
66
 
69
67
  const parameters = this.parameters;
70
68
 
71
- const adapterOptions = {
72
- powerPreference: parameters.powerPreference
73
- };
69
+ // create the device if it is not passed with parameters
70
+
71
+ let device;
74
72
 
75
- const adapter = await navigator.gpu.requestAdapter( adapterOptions );
73
+ if ( parameters.device === undefined ) {
76
74
 
77
- if ( adapter === null ) {
75
+ const adapterOptions = {
76
+ powerPreference: parameters.powerPreference
77
+ };
78
78
 
79
- throw new Error( 'WebGPUBackend: Unable to create WebGPU adapter.' );
79
+ const adapter = await navigator.gpu.requestAdapter( adapterOptions );
80
80
 
81
- }
81
+ if ( adapter === null ) {
82
+
83
+ throw new Error( 'WebGPUBackend: Unable to create WebGPU adapter.' );
84
+
85
+ }
82
86
 
83
- // feature support
87
+ // feature support
84
88
 
85
- const features = Object.values( GPUFeatureName );
89
+ const features = Object.values( GPUFeatureName );
86
90
 
87
- const supportedFeatures = [];
91
+ const supportedFeatures = [];
88
92
 
89
- for ( const name of features ) {
93
+ for ( const name of features ) {
90
94
 
91
- if ( adapter.features.has( name ) ) {
95
+ if ( adapter.features.has( name ) ) {
92
96
 
93
- supportedFeatures.push( name );
97
+ supportedFeatures.push( name );
98
+
99
+ }
94
100
 
95
101
  }
96
102
 
97
- }
103
+ const deviceDescriptor = {
104
+ requiredFeatures: supportedFeatures,
105
+ requiredLimits: parameters.requiredLimits
106
+ };
98
107
 
99
- const deviceDescriptor = {
100
- requiredFeatures: supportedFeatures,
101
- requiredLimits: parameters.requiredLimits
102
- };
108
+ device = await adapter.requestDevice( deviceDescriptor );
109
+
110
+ } else {
111
+
112
+ device = parameters.device;
103
113
 
104
- const device = await adapter.requestDevice( deviceDescriptor );
114
+ }
105
115
 
106
116
  const context = ( parameters.context !== undefined ) ? parameters.context : renderer.domElement.getContext( 'webgpu' );
107
117
 
108
- this.adapter = adapter;
109
118
  this.device = device;
110
119
  this.context = context;
111
120
 
@@ -444,6 +453,13 @@ class WebGPUBackend extends Backend {
444
453
  const renderContextData = this.get( renderContext );
445
454
  const occlusionQueryCount = renderContext.occlusionQueryCount;
446
455
 
456
+ if ( renderContextData.renderBundles !== undefined && renderContextData.renderBundles.length > 0 ) {
457
+
458
+ renderContextData.registerBundlesPhase = false;
459
+ renderContextData.currentPass.executeBundles( renderContextData.renderBundles );
460
+
461
+ }
462
+
447
463
  if ( occlusionQueryCount > renderContextData.occlusionQueryIndex ) {
448
464
 
449
465
  renderContextData.currentPass.endOcclusionQuery();
@@ -782,9 +798,22 @@ class WebGPUBackend extends Backend {
782
798
  const pipelineGPU = this.get( pipeline ).pipeline;
783
799
  const currentSets = contextData.currentSets;
784
800
 
785
- // pipeline
801
+ const renderObjectData = this.get( renderObject );
802
+
803
+ const { bundleEncoder, renderBundle, lastPipelineGPU } = renderObjectData;
804
+
805
+ const renderContextData = this.get( context );
786
806
 
787
- const passEncoderGPU = contextData.currentPass;
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;
815
+
816
+ // pipeline
788
817
 
789
818
  if ( currentSets.pipeline !== pipelineGPU ) {
790
819
 
@@ -871,7 +900,7 @@ class WebGPUBackend extends Backend {
871
900
 
872
901
  // draw
873
902
 
874
- const drawRange = geometry.drawRange;
903
+ const drawRange = renderObject.drawRange;
875
904
  const firstVertex = drawRange.start;
876
905
 
877
906
  const instanceCount = this.getInstanceCount( renderObject );
@@ -896,6 +925,16 @@ class WebGPUBackend extends Backend {
896
925
 
897
926
  }
898
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
+
899
938
  }
900
939
 
901
940
  // cache key
@@ -1151,6 +1190,12 @@ class WebGPUBackend extends Backend {
1151
1190
 
1152
1191
  }
1153
1192
 
1193
+ createBundleEncoder( renderContext, renderObject ) {
1194
+
1195
+ return this.pipelineUtils.createBundleEncoder( renderContext, renderObject );
1196
+
1197
+ }
1198
+
1154
1199
  // bindings
1155
1200
 
1156
1201
  createBindings( bindings ) {
@@ -1220,32 +1265,24 @@ class WebGPUBackend extends Backend {
1220
1265
 
1221
1266
  }
1222
1267
 
1223
- async hasFeatureAsync( name ) {
1224
-
1225
- const adapter = this.adapter || await WebGPU.getStaticAdapter();
1226
-
1227
- //
1268
+ hasFeature( name ) {
1228
1269
 
1229
- return adapter.features.has( name );
1270
+ return this.device.features.has( name );
1230
1271
 
1231
1272
  }
1232
1273
 
1233
- hasFeature( name ) {
1274
+ copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
1234
1275
 
1235
- if ( ! this.adapter ) {
1276
+ let dstX = 0;
1277
+ let dstY = 0;
1236
1278
 
1237
- console.warn( 'WebGPUBackend: WebGPU adapter has not been initialized yet. Please use hasFeatureAsync instead' );
1279
+ if ( dstPosition !== null ) {
1238
1280
 
1239
- return false;
1281
+ dstX = dstPosition.x;
1282
+ dstY = dstPosition.y;
1240
1283
 
1241
1284
  }
1242
-
1243
- return this.adapter.features.has( name );
1244
-
1245
- }
1246
-
1247
- copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
1248
-
1285
+
1249
1286
  const encoder = this.device.createCommandEncoder( { label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id } );
1250
1287
 
1251
1288
  const sourceGPU = this.get( srcTexture ).texture;
@@ -1260,7 +1297,7 @@ class WebGPUBackend extends Backend {
1260
1297
  {
1261
1298
  texture: destinationGPU,
1262
1299
  mipLevel: level,
1263
- origin: { x: position.x, y: position.y, z: position.z }
1300
+ origin: { x: dstX, y: dstY, z: 0 }
1264
1301
  },
1265
1302
  [
1266
1303
  srcTexture.image.width,
@@ -1272,9 +1309,6 @@ class WebGPUBackend extends Backend {
1272
1309
 
1273
1310
  }
1274
1311
 
1275
-
1276
-
1277
-
1278
1312
  copyFramebufferToTexture( texture, renderContext ) {
1279
1313
 
1280
1314
  const renderContextData = this.get( renderContext );
@@ -3,7 +3,7 @@ import { NoColorSpace, FloatType } from 'three';
3
3
  import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js';
4
4
 
5
5
  import NodeSampler from '../../common/nodes/NodeSampler.js';
6
- import { NodeSampledTexture, NodeSampledCubeTexture } from '../../common/nodes/NodeSampledTexture.js';
6
+ import { NodeSampledTexture, NodeSampledCubeTexture, NodeSampledTexture3D } from '../../common/nodes/NodeSampledTexture.js';
7
7
 
8
8
  import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js';
9
9
  import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js';
@@ -13,6 +13,8 @@ import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js';
13
13
  import { getFormat } from '../utils/WebGPUTextureUtils.js';
14
14
 
15
15
  import WGSLNodeParser from './WGSLNodeParser.js';
16
+ import { GPUStorageTextureAccess } from '../utils/WebGPUConstants.js';
17
+
16
18
 
17
19
  // GPUShaderStage is not defined in browsers not supporting WebGPU
18
20
  const GPUShaderStage = self.GPUShaderStage;
@@ -254,6 +256,21 @@ class WGSLNodeBuilder extends NodeBuilder {
254
256
 
255
257
  }
256
258
 
259
+ generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, shaderStage = this.shaderStage ) {
260
+
261
+ if ( shaderStage === 'fragment' ) {
262
+
263
+ // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy
264
+ return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
265
+
266
+ } else {
267
+
268
+ console.error( `WebGPURenderer: THREE.TextureNode.gradient() does not support ${ shaderStage } shader.` );
269
+
270
+ }
271
+
272
+ }
273
+
257
274
  generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage ) {
258
275
 
259
276
  if ( shaderStage === 'fragment' ) {
@@ -301,7 +318,7 @@ class WGSLNodeBuilder extends NodeBuilder {
301
318
  const name = node.name;
302
319
  const type = node.type;
303
320
 
304
- if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' ) {
321
+ if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D' ) {
305
322
 
306
323
  return name;
307
324
 
@@ -321,6 +338,12 @@ class WGSLNodeBuilder extends NodeBuilder {
321
338
 
322
339
  }
323
340
 
341
+ getOutputStructName() {
342
+
343
+ return 'output';
344
+
345
+ }
346
+
324
347
  _getUniformGroupCount( shaderStage ) {
325
348
 
326
349
  return Object.keys( this.uniforms[ shaderStage ] ).length;
@@ -343,6 +366,41 @@ class WGSLNodeBuilder extends NodeBuilder {
343
366
 
344
367
  }
345
368
 
369
+ getStorageAccess( node ) {
370
+
371
+ if ( node.isStorageTextureNode ) {
372
+
373
+ switch ( node.access ) {
374
+
375
+ case GPUStorageTextureAccess.ReadOnly: {
376
+
377
+ return 'read';
378
+
379
+ }
380
+
381
+ case GPUStorageTextureAccess.WriteOnly: {
382
+
383
+ return 'write';
384
+
385
+ }
386
+
387
+ default: {
388
+
389
+ return 'read_write';
390
+
391
+ }
392
+
393
+ }
394
+
395
+ } else {
396
+
397
+ // @TODO: Account for future read-only storage buffer pull request
398
+ return 'read_write';
399
+
400
+ }
401
+
402
+ }
403
+
346
404
  getUniformFromNode( node, type, shaderStage, name = null ) {
347
405
 
348
406
  const uniformNode = super.getUniformFromNode( node, type, shaderStage, name );
@@ -354,21 +412,25 @@ class WGSLNodeBuilder extends NodeBuilder {
354
412
 
355
413
  const bindings = this.bindings[ shaderStage ];
356
414
 
357
- if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' ) {
415
+ if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D' ) {
358
416
 
359
417
  let texture = null;
360
418
 
361
419
  if ( type === 'texture' || type === 'storageTexture' ) {
362
420
 
363
- texture = new NodeSampledTexture( uniformNode.name, uniformNode.node );
421
+ texture = new NodeSampledTexture( uniformNode.name, uniformNode.node, node.access ? node.access : null );
364
422
 
365
423
  } else if ( type === 'cubeTexture' ) {
366
424
 
367
- texture = new NodeSampledCubeTexture( uniformNode.name, uniformNode.node );
425
+ texture = new NodeSampledCubeTexture( uniformNode.name, uniformNode.node, node.access ? node.access : null );
426
+
427
+ } else if ( type === 'texture3D' ) {
428
+
429
+ texture = new NodeSampledTexture3D( uniformNode.name, uniformNode.node, node.access ? node.access : null );
368
430
 
369
431
  }
370
432
 
371
- texture.store = node.isStoreTextureNode === true;
433
+ texture.store = node.isStorageTextureNode === true;
372
434
  texture.setVisibility( gpuShaderStageLib[ shaderStage ] );
373
435
 
374
436
  if ( shaderStage === 'fragment' && this.isUnfilterable( node.value ) === false && texture.store === false ) {
@@ -440,7 +502,7 @@ class WGSLNodeBuilder extends NodeBuilder {
440
502
 
441
503
  isReference( type ) {
442
504
 
443
- return super.isReference( type ) || type === 'texture_2d' || type === 'texture_cube' || type === 'texture_depth_2d' || type === 'texture_storage_2d';
505
+ return super.isReference( type ) || type === 'texture_2d' || type === 'texture_cube' || type === 'texture_depth_2d' || type === 'texture_storage_2d' || type === 'texture_3d';
444
506
 
445
507
  }
446
508
 
@@ -522,7 +584,7 @@ ${ flowData.code }
522
584
 
523
585
  getFragCoord() {
524
586
 
525
- return this.getBuiltin( 'position', 'fragCoord', 'vec4<f32>' ) + '.xy';
587
+ return this.getBuiltin( 'position', 'fragCoord', 'vec4<f32>' ) + '.xyz';
526
588
 
527
589
  }
528
590
 
@@ -603,6 +665,10 @@ ${ flowData.code }
603
665
 
604
666
  }
605
667
 
668
+ const builtins = this.getBuiltins( 'output' );
669
+
670
+ if ( builtins ) snippets.push( builtins );
671
+
606
672
  return snippets.join( ',\n' );
607
673
 
608
674
  }
@@ -623,6 +689,8 @@ ${ flowData.code }
623
689
 
624
690
  snippets.push( snippet );
625
691
 
692
+ snippets.push( `\nvar<private> output : ${ name };\n\n`);
693
+
626
694
  }
627
695
 
628
696
  return snippets.join( '\n\n' );
@@ -719,11 +787,11 @@ ${ flowData.code }
719
787
 
720
788
  for ( const uniform of uniforms ) {
721
789
 
722
- if ( uniform.type === 'texture' || uniform.type === 'cubeTexture' || uniform.type === 'storageTexture' ) {
790
+ if ( uniform.type === 'texture' || uniform.type === 'cubeTexture' || uniform.type === 'storageTexture' || uniform.type === 'texture3D' ) {
723
791
 
724
792
  const texture = uniform.node.value;
725
793
 
726
- if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false && uniform.node.isStoreTextureNode !== true ) {
794
+ if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false && uniform.node.isStorageTextureNode !== true ) {
727
795
 
728
796
  if ( texture.isDepthTexture === true && texture.compareFunction !== null ) {
729
797
 
@@ -755,11 +823,16 @@ ${ flowData.code }
755
823
 
756
824
  textureType = 'texture_external';
757
825
 
758
- } else if ( uniform.node.isStoreTextureNode === true ) {
826
+ } else if ( texture.isData3DTexture === true ) {
827
+
828
+ textureType = 'texture_3d<f32>';
829
+
830
+ } else if ( uniform.node.isStorageTextureNode === true ) {
759
831
 
760
832
  const format = getFormat( texture );
833
+ const access = this.getStorageAccess( uniform.node );
761
834
 
762
- textureType = `texture_storage_2d<${ format }, write>`;
835
+ textureType = `texture_storage_2d<${ format }, ${access}>`;
763
836
 
764
837
  } else {
765
838
 
@@ -64,7 +64,6 @@ class WebGPUAttributeUtils {
64
64
 
65
65
  if ( ( bufferAttribute.isStorageBufferAttribute || bufferAttribute.isStorageInstancedBufferAttribute ) && bufferAttribute.itemSize === 3 ) {
66
66
 
67
- bufferAttribute.itemSize = 4;
68
67
  array = new array.constructor( bufferAttribute.count * 4 );
69
68
 
70
69
  for ( let i = 0; i < bufferAttribute.count; i ++ ) {
@@ -73,6 +72,10 @@ class WebGPUAttributeUtils {
73
72
 
74
73
  }
75
74
 
75
+ // Update BufferAttribute
76
+ bufferAttribute.itemSize = 4;
77
+ bufferAttribute.array = array;
78
+
76
79
  }
77
80
 
78
81
  const size = array.byteLength + ( ( 4 - ( array.byteLength % 4 ) ) % 4 ); // ensure 4 byte alignment, see #20441
@@ -62,8 +62,9 @@ class WebGPUBindingUtils {
62
62
  } else if ( binding.isSampledTexture && binding.store ) {
63
63
 
64
64
  const format = this.backend.get( binding.texture ).texture.format;
65
+ const access = binding.access;
65
66
 
66
- bindingGPU.storageTexture = { format }; // GPUStorageTextureBindingLayout
67
+ bindingGPU.storageTexture = { format, access }; // GPUStorageTextureBindingLayout
67
68
 
68
69
  } else if ( binding.isSampledTexture ) {
69
70
 
@@ -103,6 +104,10 @@ class WebGPUBindingUtils {
103
104
 
104
105
  texture.viewDimension = GPUTextureViewDimension.TwoDArray;
105
106
 
107
+ } else if ( binding.isSampledTexture3D ) {
108
+
109
+ texture.viewDimension = GPUTextureViewDimension.ThreeD;
110
+
106
111
  }
107
112
 
108
113
  bindingGPU.texture = texture;
@@ -214,6 +219,10 @@ class WebGPUBindingUtils {
214
219
 
215
220
  dimensionViewGPU = GPUTextureViewDimension.Cube;
216
221
 
222
+ } else if ( binding.isSampledTexture3D ) {
223
+
224
+ dimensionViewGPU = GPUTextureViewDimension.ThreeD;
225
+
217
226
  } else if ( binding.texture.isDataArrayTexture ) {
218
227
 
219
228
  dimensionViewGPU = GPUTextureViewDimension.TwoDArray;
@@ -269,6 +269,12 @@ export const GPUBufferBindingType = {
269
269
  ReadOnlyStorage: 'read-only-storage'
270
270
  };
271
271
 
272
+ export const GPUStorageTextureAccess = {
273
+ WriteOnly: 'write-only',
274
+ ReadOnly: 'read-only',
275
+ ReadWrite: 'read-write',
276
+ };
277
+
272
278
  export const GPUSamplerBindingType = {
273
279
  Filtering: 'filtering',
274
280
  NonFiltering: 'non-filtering',
@@ -23,6 +23,27 @@ class WebGPUPipelineUtils {
23
23
 
24
24
  }
25
25
 
26
+ _getSampleCount( renderObjectContext ) {
27
+
28
+ let sampleCount = this.backend.utils.getSampleCount( renderObjectContext );
29
+
30
+ if ( sampleCount > 1 ) {
31
+
32
+ // WebGPU only supports power-of-two sample counts and 2 is not a valid value
33
+ sampleCount = Math.pow( 2, Math.floor( Math.log2( sampleCount ) ) );
34
+
35
+ if ( sampleCount === 2 ) {
36
+
37
+ sampleCount = 4;
38
+
39
+ }
40
+
41
+ }
42
+
43
+ return sampleCount;
44
+
45
+ }
46
+
26
47
  createRenderPipeline( renderObject, promises ) {
27
48
 
28
49
  const { object, material, geometry, pipeline } = renderObject;
@@ -102,22 +123,11 @@ class WebGPUPipelineUtils {
102
123
  const primitiveState = this._getPrimitiveState( object, geometry, material );
103
124
  const depthCompare = this._getDepthCompare( material );
104
125
  const depthStencilFormat = utils.getCurrentDepthStencilFormat( renderObject.context );
105
- let sampleCount = utils.getSampleCount( renderObject.context );
106
-
107
- if ( sampleCount > 1 ) {
108
126
 
109
- // WebGPU only supports power-of-two sample counts and 2 is not a valid value
110
- sampleCount = Math.pow( 2, Math.floor( Math.log2( sampleCount ) ) );
111
-
112
- if ( sampleCount === 2 ) {
113
-
114
- sampleCount = 4;
115
-
116
- }
117
-
118
- }
127
+ const sampleCount = this._getSampleCount( renderObject.context );
119
128
 
120
129
  const pipelineDescriptor = {
130
+ label: 'renderPipeline',
121
131
  vertex: Object.assign( {}, vertexModule, { buffers: vertexBuffers } ),
122
132
  fragment: Object.assign( {}, fragmentModule, { targets } ),
123
133
  primitive: primitiveState,
@@ -162,6 +172,35 @@ class WebGPUPipelineUtils {
162
172
 
163
173
  }
164
174
 
175
+ createBundleEncoder( renderContext, renderObject ) {
176
+
177
+ const backend = this.backend;
178
+ const { utils, device } = backend;
179
+
180
+ const renderContextData = backend.get( renderContext );
181
+ const renderObjectData = backend.get( renderObject );
182
+
183
+ const depthStencilFormat = utils.getCurrentDepthStencilFormat( renderContext );
184
+ const colorFormat = utils.getCurrentColorFormat( renderContext );
185
+ const sampleCount = this._getSampleCount( renderObject.context );
186
+
187
+ const descriptor = {
188
+ label: 'renderBundleEncoder',
189
+ colorFormats: [ colorFormat ],
190
+ depthStencilFormat,
191
+ sampleCount
192
+ };
193
+
194
+ const bundleEncoder = device.createRenderBundleEncoder( descriptor );
195
+
196
+ renderObjectData.bundleEncoder = bundleEncoder;
197
+ renderContextData.currentSets = { attributes: {} };
198
+ renderContextData._renderBundleViewport = renderContext.width + '_' + renderContext.height;
199
+
200
+ return bundleEncoder;
201
+
202
+ }
203
+
165
204
  createComputePipeline( pipeline, bindings ) {
166
205
 
167
206
  const backend = this.backend;
@@ -186,17 +225,21 @@ class WebGPUPipelineUtils {
186
225
  let color, alpha;
187
226
 
188
227
  const blending = material.blending;
228
+ const blendSrc = material.blendSrc;
229
+ const blendDst = material.blendDst;
230
+ const blendEquation = material.blendEquation;
231
+
189
232
 
190
233
  if ( blending === CustomBlending ) {
191
234
 
192
- const blendSrcAlpha = material.blendSrcAlpha !== null ? material.blendSrcAlpha : GPUBlendFactor.One;
193
- const blendDstAlpha = material.blendDstAlpha !== null ? material.blendDstAlpha : GPUBlendFactor.Zero;
194
- const blendEquationAlpha = material.blendEquationAlpha !== null ? material.blendEquationAlpha : GPUBlendFactor.Add;
235
+ const blendSrcAlpha = material.blendSrcAlpha !== null ? material.blendSrcAlpha : blendSrc;
236
+ const blendDstAlpha = material.blendDstAlpha !== null ? material.blendDstAlpha : blendDst;
237
+ const blendEquationAlpha = material.blendEquationAlpha !== null ? material.blendEquationAlpha : blendEquation;
195
238
 
196
239
  color = {
197
- srcFactor: this._getBlendFactor( material.blendSrc ),
198
- dstFactor: this._getBlendFactor( material.blendDst ),
199
- operation: this._getBlendOperation( material.blendEquation )
240
+ srcFactor: this._getBlendFactor( blendSrc ),
241
+ dstFactor: this._getBlendFactor( blendDst ),
242
+ operation: this._getBlendOperation( blendEquation )
200
243
  };
201
244
 
202
245
  alpha = {