@plastic-software/three 0.181.2 → 0.182.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 (253) hide show
  1. package/README.md +3 -4
  2. package/build/three.cjs +1192 -522
  3. package/build/three.core.js +345 -219
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +864 -328
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +15 -3
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +3660 -1545
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +3659 -1544
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/jsm/controls/MapControls.js +55 -1
  14. package/examples/jsm/controls/OrbitControls.js +6 -6
  15. package/examples/jsm/controls/TrackballControls.js +6 -6
  16. package/examples/jsm/csm/CSM.js +2 -1
  17. package/examples/jsm/environments/RoomEnvironment.js +2 -0
  18. package/examples/jsm/geometries/DecalGeometry.js +1 -1
  19. package/examples/jsm/helpers/LightProbeHelperGPU.js +1 -1
  20. package/examples/jsm/helpers/TextureHelperGPU.js +1 -1
  21. package/examples/jsm/inspector/Inspector.js +53 -9
  22. package/examples/jsm/inspector/RendererInspector.js +12 -2
  23. package/examples/jsm/inspector/tabs/Console.js +2 -2
  24. package/examples/jsm/inspector/tabs/Parameters.js +2 -2
  25. package/examples/jsm/inspector/tabs/Performance.js +2 -2
  26. package/examples/jsm/inspector/tabs/Viewer.js +4 -4
  27. package/examples/jsm/inspector/ui/Profiler.js +1836 -31
  28. package/examples/jsm/inspector/ui/Style.js +948 -13
  29. package/examples/jsm/inspector/ui/Tab.js +188 -1
  30. package/examples/jsm/inspector/ui/Values.js +17 -1
  31. package/examples/jsm/loaders/3DMLoader.js +5 -4
  32. package/examples/jsm/loaders/DRACOLoader.js +5 -5
  33. package/examples/jsm/loaders/FBXLoader.js +0 -2
  34. package/examples/jsm/loaders/HDRLoader.js +0 -1
  35. package/examples/jsm/loaders/KTX2Loader.js +16 -0
  36. package/examples/jsm/loaders/LDrawLoader.js +2 -3
  37. package/examples/jsm/loaders/PCDLoader.js +1 -0
  38. package/examples/jsm/loaders/SVGLoader.js +1 -1
  39. package/examples/jsm/loaders/TDSLoader.js +0 -2
  40. package/examples/jsm/loaders/TGALoader.js +0 -2
  41. package/examples/jsm/loaders/UltraHDRLoader.js +110 -137
  42. package/examples/jsm/loaders/VOXLoader.js +660 -117
  43. package/examples/jsm/loaders/VRMLLoader.js +2 -2
  44. package/examples/jsm/loaders/usd/USDCParser.js +1 -1
  45. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +1 -1
  46. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -1
  47. package/examples/jsm/materials/WoodNodeMaterial.js +11 -11
  48. package/examples/jsm/math/Octree.js +131 -1
  49. package/examples/jsm/misc/Volume.js +0 -1
  50. package/examples/jsm/misc/VolumeSlice.js +0 -1
  51. package/examples/jsm/objects/SkyMesh.js +13 -3
  52. package/examples/jsm/physics/AmmoPhysics.js +12 -7
  53. package/examples/jsm/physics/JoltPhysics.js +3 -1
  54. package/examples/jsm/physics/RapierPhysics.js +3 -1
  55. package/examples/jsm/postprocessing/OutputPass.js +9 -0
  56. package/examples/jsm/postprocessing/RenderPass.js +10 -0
  57. package/examples/jsm/postprocessing/UnrealBloomPass.js +48 -18
  58. package/examples/jsm/renderers/Projector.js +268 -30
  59. package/examples/jsm/renderers/SVGRenderer.js +191 -58
  60. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -4
  61. package/examples/jsm/transpiler/AST.js +44 -0
  62. package/examples/jsm/transpiler/GLSLDecoder.js +61 -4
  63. package/examples/jsm/transpiler/ShaderToyDecoder.js +2 -0
  64. package/examples/jsm/transpiler/TSLEncoder.js +46 -3
  65. package/examples/jsm/transpiler/TranspilerUtils.js +3 -3
  66. package/examples/jsm/transpiler/WGSLEncoder.js +27 -0
  67. package/examples/jsm/tsl/display/AnaglyphPassNode.js +2 -0
  68. package/examples/jsm/tsl/display/BloomNode.js +11 -1
  69. package/examples/jsm/tsl/display/GTAONode.js +3 -2
  70. package/examples/jsm/tsl/display/PixelationPassNode.js +2 -1
  71. package/examples/jsm/tsl/display/SSGINode.js +7 -19
  72. package/examples/jsm/tsl/display/SSRNode.js +1 -1
  73. package/examples/jsm/tsl/display/SSSNode.js +4 -2
  74. package/examples/jsm/tsl/display/StereoCompositePassNode.js +8 -1
  75. package/examples/jsm/tsl/display/TRAANode.js +265 -114
  76. package/examples/jsm/tsl/display/radialBlur.js +68 -0
  77. package/examples/jsm/utils/ShadowMapViewer.js +24 -10
  78. package/examples/jsm/utils/ShadowMapViewerGPU.js +1 -1
  79. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  80. package/package.json +14 -12
  81. package/src/Three.Core.js +1 -0
  82. package/src/Three.TSL.js +14 -2
  83. package/src/animation/AnimationUtils.js +1 -12
  84. package/src/animation/KeyframeTrack.js +1 -1
  85. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  86. package/src/animation/tracks/ColorKeyframeTrack.js +1 -1
  87. package/src/animation/tracks/NumberKeyframeTrack.js +1 -1
  88. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -1
  89. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  90. package/src/animation/tracks/VectorKeyframeTrack.js +1 -1
  91. package/src/constants.js +61 -5
  92. package/src/core/BufferGeometry.js +14 -2
  93. package/src/core/Raycaster.js +2 -2
  94. package/src/extras/PMREMGenerator.js +3 -10
  95. package/src/extras/TextureUtils.js +5 -1
  96. package/src/geometries/ExtrudeGeometry.js +2 -2
  97. package/src/geometries/PolyhedronGeometry.js +1 -1
  98. package/src/helpers/PointLightHelper.js +1 -1
  99. package/src/lights/DirectionalLight.js +13 -0
  100. package/src/lights/HemisphereLight.js +10 -0
  101. package/src/lights/Light.js +1 -11
  102. package/src/lights/LightProbe.js +0 -15
  103. package/src/lights/LightShadow.js +0 -3
  104. package/src/lights/PointLight.js +15 -0
  105. package/src/lights/PointLightShadow.js +0 -86
  106. package/src/lights/SpotLight.js +22 -1
  107. package/src/loaders/MaterialLoader.js +2 -1
  108. package/src/loaders/ObjectLoader.js +3 -1
  109. package/src/loaders/nodes/NodeLoader.js +2 -2
  110. package/src/materials/Material.js +2 -0
  111. package/src/materials/ShaderMaterial.js +20 -1
  112. package/src/materials/nodes/Line2NodeMaterial.js +2 -2
  113. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +3 -2
  114. package/src/materials/nodes/MeshStandardNodeMaterial.js +5 -4
  115. package/src/materials/nodes/NodeMaterial.js +59 -3
  116. package/src/materials/nodes/manager/NodeMaterialObserver.js +1 -1
  117. package/src/math/Matrix4.js +40 -40
  118. package/src/math/Sphere.js +1 -1
  119. package/src/math/Vector3.js +0 -2
  120. package/src/nodes/TSL.js +4 -1
  121. package/src/nodes/accessors/BatchNode.js +10 -10
  122. package/src/nodes/accessors/BufferAttributeNode.js +98 -12
  123. package/src/nodes/accessors/BufferNode.js +29 -2
  124. package/src/nodes/accessors/ClippingNode.js +4 -4
  125. package/src/nodes/accessors/CubeTextureNode.js +20 -1
  126. package/src/nodes/accessors/InstanceNode.js +69 -29
  127. package/src/nodes/accessors/MaterialNode.js +9 -1
  128. package/src/nodes/accessors/MaterialReferenceNode.js +1 -2
  129. package/src/nodes/accessors/ModelNode.js +1 -1
  130. package/src/nodes/accessors/Normal.js +2 -2
  131. package/src/nodes/accessors/ReferenceBaseNode.js +4 -4
  132. package/src/nodes/accessors/ReferenceNode.js +4 -4
  133. package/src/nodes/accessors/RendererReferenceNode.js +1 -2
  134. package/src/nodes/accessors/SkinningNode.js +15 -2
  135. package/src/nodes/accessors/StorageBufferNode.js +4 -2
  136. package/src/nodes/accessors/Tangent.js +1 -11
  137. package/src/nodes/accessors/Texture3DNode.js +26 -1
  138. package/src/nodes/accessors/UniformArrayNode.js +2 -2
  139. package/src/nodes/accessors/UserDataNode.js +1 -2
  140. package/src/nodes/accessors/VertexColorNode.js +1 -2
  141. package/src/nodes/code/FunctionNode.js +1 -2
  142. package/src/nodes/core/ArrayNode.js +20 -1
  143. package/src/nodes/core/AssignNode.js +2 -2
  144. package/src/nodes/core/AttributeNode.js +2 -2
  145. package/src/nodes/core/ContextNode.js +103 -4
  146. package/src/nodes/core/NodeBuilder.js +56 -14
  147. package/src/nodes/core/NodeFrame.js +12 -4
  148. package/src/nodes/core/NodeUtils.js +5 -5
  149. package/src/nodes/core/ParameterNode.js +1 -2
  150. package/src/nodes/core/PropertyNode.js +19 -3
  151. package/src/nodes/core/StackNode.js +56 -8
  152. package/src/nodes/core/StructNode.js +1 -2
  153. package/src/nodes/core/StructTypeNode.js +11 -17
  154. package/src/nodes/core/UniformNode.js +19 -4
  155. package/src/nodes/core/VarNode.js +46 -21
  156. package/src/nodes/display/NormalMapNode.js +37 -2
  157. package/src/nodes/display/PassNode.js +77 -7
  158. package/src/nodes/display/ScreenNode.js +1 -0
  159. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +3 -3
  160. package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
  161. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  162. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +1 -1
  163. package/src/nodes/functions/PhysicalLightingModel.js +102 -43
  164. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -2
  165. package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
  166. package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -3
  167. package/src/nodes/lighting/AnalyticLightNode.js +53 -0
  168. package/src/nodes/lighting/LightsNode.js +2 -2
  169. package/src/nodes/lighting/PointShadowNode.js +141 -140
  170. package/src/nodes/lighting/ShadowFilterNode.js +53 -37
  171. package/src/nodes/lighting/ShadowNode.js +53 -19
  172. package/src/nodes/math/BitcountNode.js +433 -0
  173. package/src/nodes/math/PackFloatNode.js +98 -0
  174. package/src/nodes/math/UnpackFloatNode.js +96 -0
  175. package/src/nodes/pmrem/PMREMNode.js +1 -1
  176. package/src/nodes/tsl/TSLCore.js +4 -4
  177. package/src/nodes/utils/ArrayElementNode.js +13 -0
  178. package/src/nodes/utils/EventNode.js +1 -2
  179. package/src/nodes/utils/Packing.js +13 -1
  180. package/src/nodes/utils/PostProcessingUtils.js +33 -1
  181. package/src/nodes/utils/ReflectorNode.js +1 -1
  182. package/src/nodes/utils/SampleNode.js +1 -1
  183. package/src/nodes/utils/UVUtils.js +26 -0
  184. package/src/objects/BatchedMesh.js +5 -2
  185. package/src/objects/Line.js +1 -1
  186. package/src/objects/Mesh.js +1 -1
  187. package/src/objects/Points.js +1 -1
  188. package/src/objects/Skeleton.js +9 -0
  189. package/src/renderers/WebGLRenderer.js +145 -33
  190. package/src/renderers/common/Backend.js +8 -0
  191. package/src/renderers/common/Background.js +19 -9
  192. package/src/renderers/common/Binding.js +11 -0
  193. package/src/renderers/common/Bindings.js +7 -7
  194. package/src/renderers/common/Buffer.js +40 -0
  195. package/src/renderers/common/ChainMap.js +30 -6
  196. package/src/renderers/common/Geometries.js +12 -0
  197. package/src/renderers/common/RenderContexts.js +8 -1
  198. package/src/renderers/common/RenderObject.js +14 -1
  199. package/src/renderers/common/Renderer.js +53 -35
  200. package/src/renderers/common/Textures.js +1 -1
  201. package/src/renderers/common/UniformsGroup.js +1 -0
  202. package/src/renderers/common/XRManager.js +1 -0
  203. package/src/renderers/common/extras/PMREMGenerator.js +2 -8
  204. package/src/renderers/common/nodes/NodeUniformBuffer.js +52 -0
  205. package/src/renderers/shaders/DFGLUTData.js +19 -34
  206. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +5 -2
  207. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
  208. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +90 -51
  209. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +194 -186
  210. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  211. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  212. package/src/renderers/shaders/ShaderChunk.js +3 -3
  213. package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -0
  214. package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +1 -2
  215. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +0 -1
  216. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
  217. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +0 -1
  218. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
  219. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
  220. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +0 -1
  221. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
  222. package/src/renderers/shaders/ShaderLib.js +3 -3
  223. package/src/renderers/webgl/WebGLCapabilities.js +3 -4
  224. package/src/renderers/webgl/WebGLLights.js +18 -1
  225. package/src/renderers/webgl/WebGLOutput.js +267 -0
  226. package/src/renderers/webgl/WebGLProgram.js +43 -107
  227. package/src/renderers/webgl/WebGLPrograms.js +35 -45
  228. package/src/renderers/webgl/WebGLShadowMap.js +188 -25
  229. package/src/renderers/webgl/WebGLState.js +20 -20
  230. package/src/renderers/webgl/WebGLTextures.js +89 -28
  231. package/src/renderers/webgl/WebGLUniforms.js +40 -3
  232. package/src/renderers/webgl/WebGLUtils.js +6 -2
  233. package/src/renderers/webgl-fallback/WebGLBackend.js +79 -13
  234. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +59 -7
  235. package/src/renderers/webgl-fallback/utils/WebGLState.js +18 -3
  236. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +5 -3
  237. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -9
  238. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +6 -2
  239. package/src/renderers/webgpu/WebGPUBackend.js +61 -4
  240. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  241. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +65 -23
  242. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -17
  243. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +354 -186
  244. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -0
  245. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +20 -7
  246. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +40 -17
  247. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +7 -7
  248. package/src/renderers/webgpu/utils/WebGPUUtils.js +7 -5
  249. package/src/textures/CubeDepthTexture.js +76 -0
  250. package/src/textures/Source.js +1 -1
  251. package/src/textures/Texture.js +1 -1
  252. package/src/utils.js +13 -1
  253. package/src/nodes/functions/BSDF/DFGApprox.js +0 -71
@@ -1,11 +1,43 @@
1
1
  import {
2
2
  GPUTextureAspect, GPUTextureViewDimension, GPUTextureSampleType, GPUBufferBindingType, GPUStorageTextureAccess,
3
- GPUSamplerBindingType
3
+ GPUSamplerBindingType, GPUShaderStage
4
4
  } from './WebGPUConstants.js';
5
5
 
6
6
  import { FloatType, IntType, UnsignedIntType } from '../../../constants.js';
7
7
  import { NodeAccess } from '../../../nodes/core/constants.js';
8
- import { error } from '../../../utils.js';
8
+ import { isTypedArray, error } from '../../../utils.js';
9
+
10
+ /**
11
+ * Class representing a WebGPU bind group layout.
12
+ *
13
+ * @private
14
+ */
15
+ class BindGroupLayout {
16
+
17
+ /**
18
+ * Constructs a new layout.
19
+ *
20
+ * @param {GPUBindGroupLayout} layoutGPU - A GPU Bind Group Layout.
21
+ */
22
+ constructor( layoutGPU ) {
23
+
24
+ /**
25
+ * The current GPUBindGroupLayout.
26
+ *
27
+ * @type {GPUBindGroupLayout}
28
+ */
29
+ this.layoutGPU = layoutGPU;
30
+
31
+ /**
32
+ * The number of bind groups that use this layout.
33
+ *
34
+ * @type {number}
35
+ */
36
+ this.usedTimes = 0;
37
+
38
+ }
39
+
40
+ }
9
41
 
10
42
  /**
11
43
  * A WebGPU backend utility module for managing bindings.
@@ -34,11 +66,12 @@ class WebGPUBindingUtils {
34
66
  this.backend = backend;
35
67
 
36
68
  /**
37
- * A cache for managing bind group layouts.
69
+ * A cache that maps combinations of layout entries to existing bind group layouts.
38
70
  *
39
- * @type {WeakMap<Array<Binding>,GPUBindGroupLayout>}
71
+ * @private
72
+ * @type {Map<string, BindGroupLayout>}
40
73
  */
41
- this.bindGroupLayoutCache = new WeakMap();
74
+ this._bindGroupLayoutCache = new Map();
42
75
 
43
76
  }
44
77
 
@@ -53,185 +86,40 @@ class WebGPUBindingUtils {
53
86
  const backend = this.backend;
54
87
  const device = backend.device;
55
88
 
56
- const entries = [];
57
-
58
- let index = 0;
59
-
60
- for ( const binding of bindGroup.bindings ) {
61
-
62
- const bindingGPU = {
63
- binding: index ++,
64
- visibility: binding.visibility
65
- };
66
-
67
- if ( binding.isUniformBuffer || binding.isStorageBuffer ) {
68
-
69
- const buffer = {}; // GPUBufferBindingLayout
70
-
71
- if ( binding.isStorageBuffer ) {
72
-
73
- if ( binding.visibility & 4 ) {
74
-
75
- // compute
76
-
77
- if ( binding.access === NodeAccess.READ_WRITE || binding.access === NodeAccess.WRITE_ONLY ) {
78
-
79
- buffer.type = GPUBufferBindingType.Storage;
80
-
81
- } else {
82
-
83
- buffer.type = GPUBufferBindingType.ReadOnlyStorage;
84
-
85
- }
86
-
87
- } else {
88
-
89
- buffer.type = GPUBufferBindingType.ReadOnlyStorage;
90
-
91
- }
92
-
93
- }
94
-
95
- bindingGPU.buffer = buffer;
96
-
97
- } else if ( binding.isSampledTexture && binding.store ) {
98
-
99
- const storageTexture = {}; // GPUStorageTextureBindingLayout
100
- storageTexture.format = this.backend.get( binding.texture ).texture.format;
101
-
102
- const access = binding.access;
103
-
104
- if ( access === NodeAccess.READ_WRITE ) {
105
-
106
- storageTexture.access = GPUStorageTextureAccess.ReadWrite;
107
-
108
- } else if ( access === NodeAccess.WRITE_ONLY ) {
109
-
110
- storageTexture.access = GPUStorageTextureAccess.WriteOnly;
111
-
112
- } else {
113
-
114
- storageTexture.access = GPUStorageTextureAccess.ReadOnly;
115
-
116
- }
117
-
118
- if ( binding.texture.isArrayTexture ) {
119
-
120
- storageTexture.viewDimension = GPUTextureViewDimension.TwoDArray;
121
-
122
- } else if ( binding.texture.is3DTexture ) {
123
-
124
- storageTexture.viewDimension = GPUTextureViewDimension.ThreeD;
125
-
126
- }
127
-
128
- bindingGPU.storageTexture = storageTexture;
129
-
130
- } else if ( binding.isSampledTexture ) {
131
-
132
- const texture = {}; // GPUTextureBindingLayout
133
-
134
- const { primarySamples } = backend.utils.getTextureSampleData( binding.texture );
135
-
136
- if ( primarySamples > 1 ) {
137
-
138
- texture.multisampled = true;
139
-
140
- if ( ! binding.texture.isDepthTexture ) {
141
-
142
- texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
143
-
144
- }
145
-
146
- }
147
-
148
- if ( binding.texture.isDepthTexture ) {
149
-
150
- if ( backend.compatibilityMode && binding.texture.compareFunction === null ) {
151
-
152
- texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
153
-
154
- } else {
155
-
156
- texture.sampleType = GPUTextureSampleType.Depth;
157
-
158
- }
159
-
160
- } else if ( binding.texture.isDataTexture || binding.texture.isDataArrayTexture || binding.texture.isData3DTexture ) {
161
-
162
- const type = binding.texture.type;
163
-
164
- if ( type === IntType ) {
165
-
166
- texture.sampleType = GPUTextureSampleType.SInt;
167
-
168
- } else if ( type === UnsignedIntType ) {
169
-
170
- texture.sampleType = GPUTextureSampleType.UInt;
171
-
172
- } else if ( type === FloatType ) {
173
-
174
- if ( this.backend.hasFeature( 'float32-filterable' ) ) {
175
-
176
- texture.sampleType = GPUTextureSampleType.Float;
177
-
178
- } else {
179
-
180
- texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
181
-
182
- }
183
-
184
- }
185
-
186
- }
187
-
188
- if ( binding.isSampledCubeTexture ) {
189
-
190
- texture.viewDimension = GPUTextureViewDimension.Cube;
191
-
192
- } else if ( binding.texture.isArrayTexture || binding.texture.isDataArrayTexture || binding.texture.isCompressedArrayTexture ) {
193
-
194
- texture.viewDimension = GPUTextureViewDimension.TwoDArray;
195
-
196
- } else if ( binding.isSampledTexture3D ) {
197
-
198
- texture.viewDimension = GPUTextureViewDimension.ThreeD;
89
+ const bindingsData = backend.get( bindGroup );
199
90
 
200
- }
91
+ // check if the the bind group already has a layout
201
92
 
202
- bindingGPU.texture = texture;
93
+ if ( bindingsData.layout ) {
203
94
 
204
- } else if ( binding.isSampler ) {
95
+ return bindingsData.layout.layoutGPU;
205
96
 
206
- const sampler = {}; // GPUSamplerBindingLayout
97
+ }
207
98
 
208
- if ( binding.texture.isDepthTexture ) {
99
+ // if not, assing one
209
100
 
210
- if ( binding.texture.compareFunction !== null ) {
101
+ const entries = this._createLayoutEntries( bindGroup );
102
+ const bindGroupLayoutKey = JSON.stringify( entries );
211
103
 
212
- sampler.type = GPUSamplerBindingType.Comparison;
104
+ // try to find an existing layout in the cache
213
105
 
214
- } else if ( backend.compatibilityMode ) {
106
+ let bindGroupLayout = this._bindGroupLayoutCache.get( bindGroupLayoutKey );
215
107
 
216
- sampler.type = GPUSamplerBindingType.NonFiltering;
108
+ // if not create a new one
217
109
 
218
- }
110
+ if ( bindGroupLayout === undefined ) {
219
111
 
220
- }
112
+ bindGroupLayout = new BindGroupLayout( device.createBindGroupLayout( { entries } ) );
113
+ this._bindGroupLayoutCache.set( bindGroupLayoutKey, bindGroupLayout );
221
114
 
222
- bindingGPU.sampler = sampler;
223
-
224
- } else {
225
-
226
- error( `WebGPUBindingUtils: Unsupported binding "${ binding }".` );
227
-
228
- }
115
+ }
229
116
 
230
- entries.push( bindingGPU );
117
+ bindGroupLayout.usedTimes ++;
231
118
 
232
- }
119
+ bindingsData.layout = bindGroupLayout;
120
+ bindingsData.layoutKey = bindGroupLayoutKey;
233
121
 
234
- return device.createBindGroupLayout( { entries } );
122
+ return bindGroupLayout.layoutGPU;
235
123
 
236
124
  }
237
125
 
@@ -245,19 +133,12 @@ class WebGPUBindingUtils {
245
133
  */
246
134
  createBindings( bindGroup, bindings, cacheIndex, version = 0 ) {
247
135
 
248
- const { backend, bindGroupLayoutCache } = this;
136
+ const { backend } = this;
249
137
  const bindingsData = backend.get( bindGroup );
250
138
 
251
139
  // setup (static) binding layout and (dynamic) binding group
252
140
 
253
- let bindLayoutGPU = bindGroupLayoutCache.get( bindGroup.bindingsReference );
254
-
255
- if ( bindLayoutGPU === undefined ) {
256
-
257
- bindLayoutGPU = this.createBindingsLayout( bindGroup );
258
- bindGroupLayoutCache.set( bindGroup.bindingsReference, bindLayoutGPU );
259
-
260
- }
141
+ const bindLayoutGPU = this.createBindingsLayout( bindGroup );
261
142
 
262
143
  let bindGroupGPU;
263
144
 
@@ -292,7 +173,6 @@ class WebGPUBindingUtils {
292
173
  }
293
174
 
294
175
  bindingsData.group = bindGroupGPU;
295
- bindingsData.layout = bindLayoutGPU;
296
176
 
297
177
  }
298
178
 
@@ -306,10 +186,47 @@ class WebGPUBindingUtils {
306
186
  const backend = this.backend;
307
187
  const device = backend.device;
308
188
 
309
- const buffer = binding.buffer;
310
- const bufferGPU = backend.get( binding ).buffer;
189
+ const array = binding.buffer; // cpu
190
+ const buffer = backend.get( binding ).buffer; // gpu
191
+
192
+ const updateRanges = binding.updateRanges;
193
+
194
+ if ( updateRanges.length === 0 ) {
195
+
196
+ device.queue.writeBuffer(
197
+ buffer,
198
+ 0,
199
+ array,
200
+ 0
201
+ );
202
+
203
+ } else {
204
+
205
+ const isTyped = isTypedArray( array );
206
+ const byteOffsetFactor = isTyped ? 1 : array.BYTES_PER_ELEMENT;
207
+
208
+ for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
209
+
210
+ const range = updateRanges[ i ];
211
+
212
+ const dataOffset = range.start * byteOffsetFactor;
213
+ const size = range.count * byteOffsetFactor;
214
+
215
+ const bufferOffset = dataOffset * ( isTyped ? array.BYTES_PER_ELEMENT : 1 ); // bufferOffset is always in bytes
216
+
217
+ device.queue.writeBuffer(
218
+ buffer,
219
+ bufferOffset,
220
+ array,
221
+ dataOffset,
222
+ size
223
+ );
224
+
225
+ }
226
+
227
+ binding.clearUpdateRanges();
311
228
 
312
- device.queue.writeBuffer( bufferGPU, 0, buffer, 0 );
229
+ }
313
230
 
314
231
  }
315
232
 
@@ -317,10 +234,10 @@ class WebGPUBindingUtils {
317
234
  * Creates a GPU bind group for the camera index.
318
235
  *
319
236
  * @param {Uint32Array} data - The index data.
320
- * @param {GPUBindGroupLayout} layout - The GPU bind group layout.
237
+ * @param {GPUBindGroupLayout} layoutGPU - The GPU bind group layout.
321
238
  * @return {GPUBindGroup} The GPU bind group.
322
239
  */
323
- createBindGroupIndex( data, layout ) {
240
+ createBindGroupIndex( data, layoutGPU ) {
324
241
 
325
242
  const backend = this.backend;
326
243
  const device = backend.device;
@@ -340,7 +257,7 @@ class WebGPUBindingUtils {
340
257
 
341
258
  return device.createBindGroup( {
342
259
  label: 'bindGroupCameraIndex_' + index,
343
- layout,
260
+ layout: layoutGPU,
344
261
  entries
345
262
  } );
346
263
 
@@ -373,8 +290,29 @@ class WebGPUBindingUtils {
373
290
 
374
291
  const usage = GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST;
375
292
 
293
+ const visibilities = [];
294
+ if ( binding.visibility & GPUShaderStage.VERTEX ) {
295
+
296
+ visibilities.push( 'vertex' );
297
+
298
+ }
299
+
300
+ if ( binding.visibility & GPUShaderStage.FRAGMENT ) {
301
+
302
+ visibilities.push( 'fragment' );
303
+
304
+ }
305
+
306
+ if ( binding.visibility & GPUShaderStage.COMPUTE ) {
307
+
308
+ visibilities.push( 'compute' );
309
+
310
+ }
311
+
312
+ const bufferVisibility = `(${visibilities.join( ',' )})`;
313
+
376
314
  const bufferGPU = device.createBuffer( {
377
- label: 'bindingBuffer_' + binding.name,
315
+ label: `bindingBuffer${binding.id}_${binding.name}_${bufferVisibility}`,
378
316
  size: byteLength,
379
317
  usage: usage
380
318
  } );
@@ -480,6 +418,236 @@ class WebGPUBindingUtils {
480
418
 
481
419
  }
482
420
 
421
+ /**
422
+ * Creates a GPU bind group layout entries for the given bind group.
423
+ *
424
+ * @private
425
+ * @param {BindGroup} bindGroup - The bind group.
426
+ * @return {Array<GPUBindGroupLayoutEntry>} The GPU bind group layout entries.
427
+ */
428
+ _createLayoutEntries( bindGroup ) {
429
+
430
+ const entries = [];
431
+ let index = 0;
432
+
433
+ for ( const binding of bindGroup.bindings ) {
434
+
435
+ const backend = this.backend;
436
+
437
+ const bindingGPU = {
438
+ binding: index,
439
+ visibility: binding.visibility
440
+ };
441
+
442
+ if ( binding.isUniformBuffer || binding.isStorageBuffer ) {
443
+
444
+ const buffer = {}; // GPUBufferBindingLayout
445
+
446
+ if ( binding.isStorageBuffer ) {
447
+
448
+ if ( binding.visibility & GPUShaderStage.COMPUTE ) {
449
+
450
+ // compute
451
+
452
+ if ( binding.access === NodeAccess.READ_WRITE || binding.access === NodeAccess.WRITE_ONLY ) {
453
+
454
+ buffer.type = GPUBufferBindingType.Storage;
455
+
456
+ } else {
457
+
458
+ buffer.type = GPUBufferBindingType.ReadOnlyStorage;
459
+
460
+ }
461
+
462
+ } else {
463
+
464
+ buffer.type = GPUBufferBindingType.ReadOnlyStorage;
465
+
466
+ }
467
+
468
+ }
469
+
470
+ bindingGPU.buffer = buffer;
471
+
472
+ } else if ( binding.isSampledTexture && binding.store ) {
473
+
474
+ const storageTexture = {}; // GPUStorageTextureBindingLayout
475
+ storageTexture.format = this.backend.get( binding.texture ).texture.format;
476
+
477
+ const access = binding.access;
478
+
479
+ if ( access === NodeAccess.READ_WRITE ) {
480
+
481
+ storageTexture.access = GPUStorageTextureAccess.ReadWrite;
482
+
483
+ } else if ( access === NodeAccess.WRITE_ONLY ) {
484
+
485
+ storageTexture.access = GPUStorageTextureAccess.WriteOnly;
486
+
487
+ } else {
488
+
489
+ storageTexture.access = GPUStorageTextureAccess.ReadOnly;
490
+
491
+ }
492
+
493
+ if ( binding.texture.isArrayTexture ) {
494
+
495
+ storageTexture.viewDimension = GPUTextureViewDimension.TwoDArray;
496
+
497
+ } else if ( binding.texture.is3DTexture ) {
498
+
499
+ storageTexture.viewDimension = GPUTextureViewDimension.ThreeD;
500
+
501
+ }
502
+
503
+ bindingGPU.storageTexture = storageTexture;
504
+
505
+ } else if ( binding.isSampledTexture ) {
506
+
507
+ const texture = {}; // GPUTextureBindingLayout
508
+
509
+ const { primarySamples } = backend.utils.getTextureSampleData( binding.texture );
510
+
511
+ if ( primarySamples > 1 ) {
512
+
513
+ texture.multisampled = true;
514
+
515
+ if ( ! binding.texture.isDepthTexture ) {
516
+
517
+ texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
518
+
519
+ }
520
+
521
+ }
522
+
523
+ if ( binding.texture.isDepthTexture ) {
524
+
525
+ if ( backend.compatibilityMode && binding.texture.compareFunction === null ) {
526
+
527
+ texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
528
+
529
+ } else {
530
+
531
+ texture.sampleType = GPUTextureSampleType.Depth;
532
+
533
+ }
534
+
535
+ } else if ( binding.texture.isDataTexture || binding.texture.isDataArrayTexture || binding.texture.isData3DTexture ) {
536
+
537
+ const type = binding.texture.type;
538
+
539
+ if ( type === IntType ) {
540
+
541
+ texture.sampleType = GPUTextureSampleType.SInt;
542
+
543
+ } else if ( type === UnsignedIntType ) {
544
+
545
+ texture.sampleType = GPUTextureSampleType.UInt;
546
+
547
+ } else if ( type === FloatType ) {
548
+
549
+ if ( this.backend.hasFeature( 'float32-filterable' ) ) {
550
+
551
+ texture.sampleType = GPUTextureSampleType.Float;
552
+
553
+ } else {
554
+
555
+ texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
556
+
557
+ }
558
+
559
+ }
560
+
561
+ }
562
+
563
+ if ( binding.isSampledCubeTexture ) {
564
+
565
+ texture.viewDimension = GPUTextureViewDimension.Cube;
566
+
567
+ } else if ( binding.texture.isArrayTexture || binding.texture.isDataArrayTexture || binding.texture.isCompressedArrayTexture ) {
568
+
569
+ texture.viewDimension = GPUTextureViewDimension.TwoDArray;
570
+
571
+ } else if ( binding.isSampledTexture3D ) {
572
+
573
+ texture.viewDimension = GPUTextureViewDimension.ThreeD;
574
+
575
+ }
576
+
577
+ bindingGPU.texture = texture;
578
+
579
+ } else if ( binding.isSampler ) {
580
+
581
+ const sampler = {}; // GPUSamplerBindingLayout
582
+
583
+ if ( binding.texture.isDepthTexture ) {
584
+
585
+ if ( binding.texture.compareFunction !== null ) {
586
+
587
+ sampler.type = GPUSamplerBindingType.Comparison;
588
+
589
+ } else if ( backend.compatibilityMode ) {
590
+
591
+ sampler.type = GPUSamplerBindingType.NonFiltering;
592
+
593
+ }
594
+
595
+ }
596
+
597
+ bindingGPU.sampler = sampler;
598
+
599
+ } else {
600
+
601
+ error( `WebGPUBindingUtils: Unsupported binding "${ binding }".` );
602
+
603
+ }
604
+
605
+ entries.push( bindingGPU );
606
+ index ++;
607
+
608
+ }
609
+
610
+ return entries;
611
+
612
+ }
613
+
614
+ /**
615
+ * Delete the data associated with a bind group.
616
+ *
617
+ * @param {BindGroup} bindGroup - The bind group.
618
+ */
619
+ deleteBindGroupData( bindGroup ) {
620
+
621
+ const { backend } = this;
622
+
623
+ const bindingsData = backend.get( bindGroup );
624
+
625
+ if ( bindingsData.layout ) {
626
+
627
+ bindingsData.layout.usedTimes --;
628
+
629
+ if ( bindingsData.layout.usedTimes === 0 ) {
630
+
631
+ this._bindGroupLayoutCache.delete( bindingsData.layoutKey );
632
+
633
+ }
634
+
635
+ bindingsData.layout = undefined;
636
+ bindingsData.layoutKey = undefined;
637
+
638
+ }
639
+
640
+ }
641
+
642
+ /**
643
+ * Frees internal resources.
644
+ */
645
+ dispose() {
646
+
647
+ this._bindGroupLayoutCache.clear();
648
+
649
+ }
650
+
483
651
  }
484
652
 
485
653
  export default WebGPUBindingUtils;
@@ -6,6 +6,8 @@ export const GPUPrimitiveTopology = {
6
6
  TriangleStrip: 'triangle-strip',
7
7
  };
8
8
 
9
+ export const GPUShaderStage = ( typeof self !== 'undefined' ) ? self.GPUShaderStage : { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 };
10
+
9
11
  export const GPUCompareFunction = {
10
12
  Never: 'never',
11
13
  Less: 'less',
@@ -106,8 +106,9 @@ class WebGPUPipelineUtils {
106
106
  for ( const bindGroup of renderObject.getBindings() ) {
107
107
 
108
108
  const bindingsData = backend.get( bindGroup );
109
+ const { layoutGPU } = bindingsData.layout;
109
110
 
110
- bindGroupLayouts.push( bindingsData.layout );
111
+ bindGroupLayouts.push( layoutGPU );
111
112
 
112
113
  }
113
114
 
@@ -152,11 +153,22 @@ class WebGPUPipelineUtils {
152
153
 
153
154
  const colorFormat = utils.getTextureFormatGPU( textures[ i ] );
154
155
 
155
- targets.push( {
156
- format: colorFormat,
157
- blend: blending,
158
- writeMask: colorWriteMask
159
- } );
156
+ if ( i === 0 ) {
157
+
158
+ targets.push( {
159
+ format: colorFormat,
160
+ blend: blending,
161
+ writeMask: colorWriteMask
162
+ } );
163
+
164
+ } else {
165
+
166
+ targets.push( {
167
+ format: colorFormat,
168
+ writeMask: colorWriteMask
169
+ } );
170
+
171
+ }
160
172
 
161
173
  }
162
174
 
@@ -330,8 +342,9 @@ class WebGPUPipelineUtils {
330
342
  for ( const bindingsGroup of bindings ) {
331
343
 
332
344
  const bindingsData = backend.get( bindingsGroup );
345
+ const { layoutGPU } = bindingsData.layout;
333
346
 
334
- bindGroupLayouts.push( bindingsData.layout );
347
+ bindGroupLayouts.push( layoutGPU );
335
348
 
336
349
  }
337
350