@plastic-software/three 0.178.0 → 0.180.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 (245) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +950 -230
  3. package/build/three.core.js +754 -138
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +197 -96
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +99 -25
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +4586 -1499
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +4544 -1499
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/jsm/Addons.js +2 -3
  14. package/examples/jsm/capabilities/WebGPU.js +1 -1
  15. package/examples/jsm/controls/ArcballControls.js +7 -7
  16. package/examples/jsm/controls/DragControls.js +6 -56
  17. package/examples/jsm/controls/FirstPersonControls.js +2 -2
  18. package/examples/jsm/controls/PointerLockControls.js +0 -8
  19. package/examples/jsm/csm/CSMShadowNode.js +4 -4
  20. package/examples/jsm/environments/RoomEnvironment.js +8 -3
  21. package/examples/jsm/exporters/GLTFExporter.js +30 -22
  22. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  23. package/examples/jsm/exporters/PLYExporter.js +1 -1
  24. package/examples/jsm/exporters/USDZExporter.js +676 -299
  25. package/examples/jsm/geometries/RoundedBoxGeometry.js +47 -8
  26. package/examples/jsm/interactive/HTMLMesh.js +5 -3
  27. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  28. package/examples/jsm/libs/meshopt_decoder.module.js +75 -58
  29. package/examples/jsm/lights/LightProbeGenerator.js +14 -3
  30. package/examples/jsm/lines/Line2.js +3 -3
  31. package/examples/jsm/lines/LineGeometry.js +1 -1
  32. package/examples/jsm/lines/LineSegments2.js +2 -2
  33. package/examples/jsm/lines/Wireframe.js +2 -2
  34. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  35. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  36. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  37. package/examples/jsm/loaders/ColladaLoader.js +1 -1
  38. package/examples/jsm/loaders/EXRLoader.js +210 -22
  39. package/examples/jsm/loaders/FBXLoader.js +1 -1
  40. package/examples/jsm/loaders/GLTFLoader.js +9 -5
  41. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  42. package/examples/jsm/loaders/HDRLoader.js +486 -0
  43. package/examples/jsm/loaders/KTX2Loader.js +112 -32
  44. package/examples/jsm/loaders/MaterialXLoader.js +212 -30
  45. package/examples/jsm/loaders/RGBELoader.js +7 -473
  46. package/examples/jsm/loaders/TTFLoader.js +13 -1
  47. package/examples/jsm/loaders/USDLoader.js +219 -0
  48. package/examples/jsm/loaders/USDZLoader.js +4 -892
  49. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  50. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  51. package/examples/jsm/loaders/usd/USDAParser.js +741 -0
  52. package/examples/jsm/loaders/usd/USDCParser.js +17 -0
  53. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  54. package/examples/jsm/math/ColorSpaces.js +19 -1
  55. package/examples/jsm/math/ConvexHull.js +2 -2
  56. package/examples/jsm/math/Lut.js +2 -2
  57. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  58. package/examples/jsm/misc/ProgressiveLightMap.js +1 -1
  59. package/examples/jsm/misc/Volume.js +1 -1
  60. package/examples/jsm/objects/LensflareMesh.js +3 -3
  61. package/examples/jsm/objects/SkyMesh.js +2 -2
  62. package/examples/jsm/physics/RapierPhysics.js +14 -5
  63. package/examples/jsm/postprocessing/GTAOPass.js +10 -9
  64. package/examples/jsm/postprocessing/OutlinePass.js +17 -17
  65. package/examples/jsm/postprocessing/SSAOPass.js +10 -9
  66. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  67. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +11 -2
  68. package/examples/jsm/transpiler/GLSLDecoder.js +23 -20
  69. package/examples/jsm/transpiler/TSLEncoder.js +2 -10
  70. package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
  71. package/examples/jsm/tsl/display/AnamorphicNode.js +27 -4
  72. package/examples/jsm/tsl/display/BloomNode.js +7 -6
  73. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
  74. package/examples/jsm/tsl/display/DepthOfFieldNode.js +439 -90
  75. package/examples/jsm/tsl/display/GTAONode.js +8 -0
  76. package/examples/jsm/tsl/display/GaussianBlurNode.js +51 -41
  77. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  78. package/examples/jsm/tsl/display/SSRNode.js +180 -65
  79. package/examples/jsm/tsl/display/{TRAAPassNode.js → TRAANode.js} +181 -172
  80. package/examples/jsm/tsl/display/boxBlur.js +64 -0
  81. package/examples/jsm/tsl/display/hashBlur.js +15 -18
  82. package/examples/jsm/tsl/lighting/TiledLightsNode.js +1 -1
  83. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  84. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  85. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  86. package/package.json +1 -1
  87. package/src/Three.Core.js +2 -0
  88. package/src/Three.TSL.js +98 -24
  89. package/src/animation/AnimationClip.js +17 -2
  90. package/src/animation/KeyframeTrack.js +1 -1
  91. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  92. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  93. package/src/cameras/Camera.js +14 -0
  94. package/src/cameras/OrthographicCamera.js +1 -1
  95. package/src/cameras/PerspectiveCamera.js +1 -1
  96. package/src/constants.js +11 -3
  97. package/src/core/BufferGeometry.js +2 -2
  98. package/{examples/jsm/misc → src/core}/Timer.js +4 -42
  99. package/src/extras/PMREMGenerator.js +11 -0
  100. package/src/extras/TextureUtils.js +2 -1
  101. package/src/extras/lib/earcut.js +1 -1
  102. package/src/helpers/CameraHelper.js +41 -11
  103. package/src/helpers/SkeletonHelper.js +35 -6
  104. package/src/lights/LightShadow.js +21 -8
  105. package/src/lights/PointLightShadow.js +1 -1
  106. package/src/lights/webgpu/ProjectorLight.js +1 -1
  107. package/src/loaders/FileLoader.js +25 -2
  108. package/src/loaders/ImageBitmapLoader.js +23 -0
  109. package/src/loaders/Loader.js +14 -0
  110. package/src/loaders/LoadingManager.js +23 -0
  111. package/src/materials/Material.js +12 -0
  112. package/src/materials/MeshBasicMaterial.js +1 -1
  113. package/src/materials/MeshDistanceMaterial.js +1 -1
  114. package/src/materials/nodes/Line2NodeMaterial.js +0 -8
  115. package/src/materials/nodes/NodeMaterial.js +1 -1
  116. package/src/materials/nodes/PointsNodeMaterial.js +86 -28
  117. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  118. package/src/materials/nodes/manager/NodeMaterialObserver.js +87 -2
  119. package/src/math/ColorManagement.js +7 -1
  120. package/src/math/Frustum.js +19 -8
  121. package/src/math/FrustumArray.js +10 -5
  122. package/src/math/Line3.js +129 -2
  123. package/src/math/Matrix4.js +48 -27
  124. package/src/math/Spherical.js +2 -2
  125. package/src/nodes/Nodes.js +4 -0
  126. package/src/nodes/TSL.js +4 -0
  127. package/src/nodes/accessors/BufferNode.js +1 -1
  128. package/src/nodes/accessors/Camera.js +142 -16
  129. package/src/nodes/accessors/ClippingNode.js +6 -5
  130. package/src/nodes/accessors/CubeTextureNode.js +2 -2
  131. package/src/nodes/accessors/InstanceNode.js +3 -1
  132. package/src/nodes/accessors/Normal.js +11 -11
  133. package/src/nodes/accessors/Object3DNode.js +1 -1
  134. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  135. package/src/nodes/accessors/ReferenceNode.js +19 -4
  136. package/src/nodes/accessors/SceneNode.js +1 -1
  137. package/src/nodes/accessors/StorageTextureNode.js +1 -1
  138. package/src/nodes/accessors/Texture3DNode.js +13 -0
  139. package/src/nodes/accessors/TextureNode.js +83 -19
  140. package/src/nodes/code/FunctionCallNode.js +19 -0
  141. package/src/nodes/code/FunctionNode.js +23 -0
  142. package/src/nodes/core/ArrayNode.js +12 -0
  143. package/src/nodes/core/AssignNode.js +6 -2
  144. package/src/nodes/core/ContextNode.js +44 -1
  145. package/src/nodes/core/Node.js +30 -22
  146. package/src/nodes/core/NodeBuilder.js +71 -32
  147. package/src/nodes/core/NodeFrame.js +1 -1
  148. package/src/nodes/core/NodeUniform.js +1 -1
  149. package/src/nodes/core/NodeUtils.js +5 -3
  150. package/src/nodes/core/StackNode.js +71 -4
  151. package/src/nodes/core/StructNode.js +5 -5
  152. package/src/nodes/core/StructTypeNode.js +1 -0
  153. package/src/nodes/core/SubBuildNode.js +2 -2
  154. package/src/nodes/core/UniformNode.js +79 -14
  155. package/src/nodes/core/VarNode.js +83 -15
  156. package/src/nodes/display/FrontFacingNode.js +4 -8
  157. package/src/nodes/display/PassNode.js +148 -2
  158. package/src/nodes/display/ScreenNode.js +42 -13
  159. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  160. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  161. package/src/nodes/display/ViewportTextureNode.js +94 -4
  162. package/src/nodes/functions/PhysicalLightingModel.js +2 -2
  163. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  164. package/src/nodes/gpgpu/ComputeNode.js +67 -23
  165. package/src/nodes/gpgpu/SubgroupFunctionNode.js +430 -0
  166. package/src/nodes/gpgpu/WorkgroupInfoNode.js +28 -3
  167. package/src/nodes/lighting/LightsNode.js +1 -1
  168. package/src/nodes/lighting/ProjectorLightNode.js +19 -6
  169. package/src/nodes/lighting/ShadowFilterNode.js +1 -1
  170. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  171. package/src/nodes/materialx/lib/mx_noise.js +165 -1
  172. package/src/nodes/math/BitcastNode.js +156 -0
  173. package/src/nodes/math/ConditionalNode.js +19 -3
  174. package/src/nodes/math/MathNode.js +72 -60
  175. package/src/nodes/math/OperatorNode.js +26 -25
  176. package/src/nodes/tsl/TSLCore.js +477 -142
  177. package/src/nodes/utils/DebugNode.js +1 -1
  178. package/src/nodes/utils/EventNode.js +83 -0
  179. package/src/nodes/utils/JoinNode.js +3 -1
  180. package/src/nodes/utils/MemberNode.js +58 -7
  181. package/src/nodes/utils/RTTNode.js +10 -1
  182. package/src/nodes/utils/ReflectorNode.js +51 -7
  183. package/src/nodes/utils/SampleNode.js +12 -2
  184. package/src/nodes/utils/SplitNode.js +11 -0
  185. package/src/nodes/utils/Timer.js +0 -47
  186. package/src/objects/BatchedMesh.js +6 -4
  187. package/src/objects/LOD.js +1 -1
  188. package/src/objects/Sprite.js +2 -2
  189. package/src/renderers/WebGLRenderer.js +21 -31
  190. package/src/renderers/common/Attributes.js +1 -1
  191. package/src/renderers/common/Backend.js +19 -1
  192. package/src/renderers/common/Bindings.js +21 -18
  193. package/src/renderers/common/ChainMap.js +1 -1
  194. package/src/renderers/common/Color4.js +2 -2
  195. package/src/renderers/common/DataMap.js +1 -1
  196. package/src/renderers/common/Pipelines.js +1 -1
  197. package/src/renderers/common/PostProcessing.js +60 -5
  198. package/src/renderers/common/RenderContext.js +2 -2
  199. package/src/renderers/common/RenderObject.js +14 -2
  200. package/src/renderers/common/Renderer.js +55 -32
  201. package/src/renderers/common/SampledTexture.js +4 -72
  202. package/src/renderers/common/Sampler.js +91 -0
  203. package/src/renderers/common/Storage3DTexture.js +21 -0
  204. package/src/renderers/common/StorageArrayTexture.js +21 -0
  205. package/src/renderers/common/StorageTexture.js +19 -0
  206. package/src/renderers/common/Textures.js +52 -14
  207. package/src/renderers/common/TimestampQueryPool.js +3 -3
  208. package/src/renderers/common/XRManager.js +51 -17
  209. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  210. package/src/renderers/common/nodes/NodeLibrary.js +5 -5
  211. package/src/renderers/common/nodes/NodeSampledTexture.js +0 -12
  212. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  213. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  214. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  215. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  216. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +21 -11
  217. package/src/renderers/shaders/ShaderLib/depth.glsl.js +11 -2
  218. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  219. package/src/renderers/webgl/WebGLMaterials.js +6 -6
  220. package/src/renderers/webgl/WebGLProgram.js +24 -18
  221. package/src/renderers/webgl/WebGLPrograms.js +4 -4
  222. package/src/renderers/webgl/WebGLShadowMap.js +11 -1
  223. package/src/renderers/webgl/WebGLTextures.js +20 -7
  224. package/src/renderers/webgl/WebGLUtils.js +3 -2
  225. package/src/renderers/webgl-fallback/WebGLBackend.js +207 -146
  226. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +112 -19
  227. package/src/renderers/webgl-fallback/utils/WebGLState.js +1 -1
  228. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -3
  229. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -10
  230. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  231. package/src/renderers/webgpu/WebGPUBackend.js +87 -44
  232. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +169 -99
  233. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +35 -31
  234. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -2
  235. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +10 -19
  236. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +120 -84
  237. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +3 -3
  238. package/src/renderers/webgpu/utils/WebGPUUtils.js +2 -17
  239. package/src/renderers/webxr/WebXRDepthSensing.js +6 -10
  240. package/src/renderers/webxr/WebXRManager.js +86 -11
  241. package/src/textures/ExternalTexture.js +56 -0
  242. package/src/textures/FramebufferTexture.js +2 -2
  243. package/src/textures/Source.js +12 -2
  244. package/src/textures/VideoTexture.js +27 -2
  245. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
@@ -16,7 +16,7 @@ import { NodeAccess } from '../../../nodes/core/constants.js';
16
16
  import VarNode from '../../../nodes/core/VarNode.js';
17
17
  import ExpressionNode from '../../../nodes/code/ExpressionNode.js';
18
18
 
19
- import { NoColorSpace, FloatType, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter } from '../../../constants.js';
19
+ import { FloatType, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter } from '../../../constants.js';
20
20
 
21
21
  // GPUShaderStage is not defined in browsers not supporting WebGPU
22
22
  const GPUShaderStage = ( typeof self !== 'undefined' ) ? self.GPUShaderStage : { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 };
@@ -131,22 +131,6 @@ const wgslMethods = {
131
131
  bitcast: 'bitcast<f32>'
132
132
  };
133
133
 
134
- // WebGPU issue: does not support pow() with negative base on Windows
135
-
136
- if ( typeof navigator !== 'undefined' && /Windows/g.test( navigator.userAgent ) ) {
137
-
138
- wgslPolyfill.pow_float = new CodeNode( 'fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }' );
139
- wgslPolyfill.pow_vec2 = new CodeNode( 'fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }', [ wgslPolyfill.pow_float ] );
140
- wgslPolyfill.pow_vec3 = new CodeNode( 'fn tsl_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ) ); }', [ wgslPolyfill.pow_float ] );
141
- wgslPolyfill.pow_vec4 = new CodeNode( 'fn tsl_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ), tsl_pow_float( a.w, b.w ) ); }', [ wgslPolyfill.pow_float ] );
142
-
143
- wgslMethods.pow_float = 'tsl_pow_float';
144
- wgslMethods.pow_vec2 = 'tsl_pow_vec2';
145
- wgslMethods.pow_vec3 = 'tsl_pow_vec3';
146
- wgslMethods.pow_vec4 = 'tsl_pow_vec4';
147
-
148
- }
149
-
150
134
  //
151
135
 
152
136
  let diagnostics = '';
@@ -211,18 +195,6 @@ class WGSLNodeBuilder extends NodeBuilder {
211
195
 
212
196
  }
213
197
 
214
- /**
215
- * Checks if the given texture requires a manual conversion to the working color space.
216
- *
217
- * @param {Texture} texture - The texture to check.
218
- * @return {boolean} Whether the given texture requires a conversion to working color space or not.
219
- */
220
- needsToWorkingColorSpace( texture ) {
221
-
222
- return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace;
223
-
224
- }
225
-
226
198
  /**
227
199
  * Generates the WGSL snippet for sampled textures.
228
200
  *
@@ -231,49 +203,39 @@ class WGSLNodeBuilder extends NodeBuilder {
231
203
  * @param {string} textureProperty - The name of the texture uniform in the shader.
232
204
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
233
205
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
206
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
234
207
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
235
208
  * @return {string} The WGSL snippet.
236
209
  */
237
- _generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
210
+ _generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
238
211
 
239
212
  if ( shaderStage === 'fragment' ) {
240
213
 
241
214
  if ( depthSnippet ) {
242
215
 
243
- return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet } )`;
244
-
245
- } else {
216
+ if ( offsetSnippet ) {
246
217
 
247
- return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet } )`;
218
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ offsetSnippet } )`;
248
219
 
249
- }
220
+ }
250
221
 
251
- } else {
222
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet } )`;
252
223
 
253
- return this._generateTextureSampleLevel( texture, textureProperty, uvSnippet, '0', depthSnippet );
224
+ } else {
254
225
 
255
- }
226
+ if ( offsetSnippet ) {
256
227
 
257
- }
228
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ offsetSnippet } )`;
258
229
 
259
- /**
260
- * Generates the WGSL snippet when sampling video textures.
261
- *
262
- * @private
263
- * @param {string} textureProperty - The name of the video texture uniform in the shader.
264
- * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
265
- * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
266
- * @return {string} The WGSL snippet.
267
- */
268
- _generateVideoSample( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
230
+ }
269
231
 
270
- if ( shaderStage === 'fragment' ) {
232
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet } )`;
271
233
 
272
- return `textureSampleBaseClampToEdge( ${ textureProperty }, ${ textureProperty }_sampler, vec2<f32>( ${ uvSnippet }.x, 1.0 - ${ uvSnippet }.y ) )`;
234
+ }
273
235
 
274
236
  } else {
275
237
 
276
- console.error( `WebGPURenderer: THREE.VideoTexture does not support ${ shaderStage } shader.` );
238
+ return this.generateTextureSampleLevel( texture, textureProperty, uvSnippet, '0', depthSnippet );
277
239
 
278
240
  }
279
241
 
@@ -288,21 +250,28 @@ class WGSLNodeBuilder extends NodeBuilder {
288
250
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
289
251
  * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
290
252
  * @param {string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
253
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
291
254
  * @return {string} The WGSL snippet.
292
255
  */
293
- _generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet ) {
256
+ generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
294
257
 
295
258
  if ( this.isUnfilterable( texture ) === false ) {
296
259
 
260
+ if ( offsetSnippet ) {
261
+
262
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
263
+
264
+ }
265
+
297
266
  return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
298
267
 
299
268
  } else if ( this.isFilteredTexture( texture ) ) {
300
269
 
301
- return this.generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet );
270
+ return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet );
302
271
 
303
272
  } else {
304
273
 
305
- return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet );
274
+ return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet );
306
275
 
307
276
  }
308
277
 
@@ -434,7 +403,7 @@ class WGSLNodeBuilder extends NodeBuilder {
434
403
  }
435
404
 
436
405
  // Build parameters string based on texture type and multisampling
437
- if ( isMultisampled || texture.isVideoTexture || texture.isStorageTexture ) {
406
+ if ( isMultisampled || texture.isStorageTexture ) {
438
407
 
439
408
  textureDimensionsParams = textureProperty;
440
409
 
@@ -480,16 +449,23 @@ class WGSLNodeBuilder extends NodeBuilder {
480
449
  * @param {Texture} texture - The texture.
481
450
  * @param {string} textureProperty - The name of the texture uniform in the shader.
482
451
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
483
- * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
452
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
453
+ * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
484
454
  * @return {string} The WGSL snippet.
485
455
  */
486
- generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet = '0u' ) {
456
+ generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet = '0u' ) {
487
457
 
488
458
  this._include( 'biquadraticTexture' );
489
459
 
490
460
  const wrapFunction = this.generateWrapFunction( texture );
491
461
  const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
492
462
 
463
+ if ( offsetSnippet ) {
464
+
465
+ uvSnippet = `${ uvSnippet } + vec2<f32>(${ offsetSnippet }) / ${ textureDimension }`;
466
+
467
+ }
468
+
493
469
  return `tsl_biquadraticTexture( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, u32( ${ levelSnippet } ) )`;
494
470
 
495
471
  }
@@ -502,18 +478,26 @@ class WGSLNodeBuilder extends NodeBuilder {
502
478
  * @param {string} textureProperty - The name of the texture uniform in the shader.
503
479
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
504
480
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
481
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
505
482
  * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
506
483
  * @return {string} The WGSL snippet.
507
484
  */
508
- generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet = '0u' ) {
485
+ generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet = '0u' ) {
509
486
 
510
487
  const wrapFunction = this.generateWrapFunction( texture );
511
488
  const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
512
489
 
513
490
  const vecType = texture.isData3DTexture ? 'vec3' : 'vec2';
491
+
492
+ if ( offsetSnippet ) {
493
+
494
+ uvSnippet = `${ uvSnippet } + ${ vecType }<f32>(${ offsetSnippet }) / ${ vecType }<f32>( ${ textureDimension } )`;
495
+
496
+ }
497
+
514
498
  const coordSnippet = `${ vecType }<u32>( ${ wrapFunction }( ${ uvSnippet } ) * ${ vecType }<f32>( ${ textureDimension } ) )`;
515
499
 
516
- return this.generateTextureLoad( texture, textureProperty, coordSnippet, depthSnippet, levelSnippet );
500
+ return this.generateTextureLoad( texture, textureProperty, coordSnippet, depthSnippet, null, levelSnippet );
517
501
 
518
502
  }
519
503
 
@@ -524,18 +508,21 @@ class WGSLNodeBuilder extends NodeBuilder {
524
508
  * @param {string} textureProperty - The name of the texture uniform in the shader.
525
509
  * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
526
510
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
511
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
527
512
  * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
528
513
  * @return {string} The WGSL snippet.
529
514
  */
530
- generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u' ) {
515
+ generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, offsetSnippet, levelSnippet = '0u' ) {
531
516
 
532
517
  let snippet;
533
518
 
534
- if ( texture.isVideoTexture === true ) {
519
+ if ( offsetSnippet ) {
520
+
521
+ uvIndexSnippet = `${ uvIndexSnippet } + ${ offsetSnippet }`;
535
522
 
536
- snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet } )`;
523
+ }
537
524
 
538
- } else if ( depthSnippet ) {
525
+ if ( depthSnippet ) {
539
526
 
540
527
  snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, u32( ${ levelSnippet } ) )`;
541
528
 
@@ -617,24 +604,21 @@ class WGSLNodeBuilder extends NodeBuilder {
617
604
  * @param {string} textureProperty - The name of the texture uniform in the shader.
618
605
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
619
606
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
607
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
620
608
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
621
609
  * @return {string} The WGSL snippet.
622
610
  */
623
- generateTexture( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
611
+ generateTexture( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
624
612
 
625
613
  let snippet = null;
626
614
 
627
- if ( texture.isVideoTexture === true ) {
628
-
629
- snippet = this._generateVideoSample( textureProperty, uvSnippet, shaderStage );
630
-
631
- } else if ( this.isUnfilterable( texture ) ) {
615
+ if ( this.isUnfilterable( texture ) ) {
632
616
 
633
- snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, '0', shaderStage );
617
+ snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, '0', shaderStage );
634
618
 
635
619
  } else {
636
620
 
637
- snippet = this._generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, shaderStage );
621
+ snippet = this._generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage );
638
622
 
639
623
  }
640
624
 
@@ -650,14 +634,21 @@ class WGSLNodeBuilder extends NodeBuilder {
650
634
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
651
635
  * @param {Array<string>} gradSnippet - An array holding both gradient WGSL snippets.
652
636
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
637
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
653
638
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
654
639
  * @return {string} The WGSL snippet.
655
640
  */
656
- generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, shaderStage = this.shaderStage ) {
641
+ generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
657
642
 
658
643
  if ( shaderStage === 'fragment' ) {
659
644
 
660
645
  // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy
646
+ if ( offsetSnippet ) {
647
+
648
+ return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;
649
+
650
+ }
651
+
661
652
  return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
662
653
 
663
654
  } else {
@@ -677,19 +668,32 @@ class WGSLNodeBuilder extends NodeBuilder {
677
668
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
678
669
  * @param {string} compareSnippet - A WGSL snippet that represents the reference value.
679
670
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
671
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
680
672
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
681
673
  * @return {string} The WGSL snippet.
682
674
  */
683
- generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage ) {
675
+ generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
684
676
 
685
677
  if ( shaderStage === 'fragment' ) {
686
678
 
687
679
  if ( texture.isDepthTexture === true && texture.isArrayTexture === true ) {
688
680
 
681
+ if ( offsetSnippet ) {
682
+
683
+ return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet }, ${ offsetSnippet } )`;
684
+
685
+ }
686
+
689
687
  return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet } )`;
690
688
 
691
689
  }
692
690
 
691
+ if ( offsetSnippet ) {
692
+
693
+ return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ compareSnippet }, ${ offsetSnippet } )`;
694
+
695
+ }
696
+
693
697
  return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ compareSnippet } )`;
694
698
 
695
699
  } else {
@@ -708,25 +712,32 @@ class WGSLNodeBuilder extends NodeBuilder {
708
712
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
709
713
  * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
710
714
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
715
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
711
716
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
712
717
  * @return {string} The WGSL snippet.
713
718
  */
714
- generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage ) {
719
+ generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
715
720
 
716
- let snippet = null;
721
+ if ( this.isUnfilterable( texture ) === false ) {
722
+
723
+ if ( offsetSnippet ) {
717
724
 
718
- if ( texture.isVideoTexture === true ) {
725
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
719
726
 
720
- snippet = this._generateVideoSample( textureProperty, uvSnippet, shaderStage );
727
+ }
728
+
729
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
730
+
731
+ } else if ( this.isFilteredTexture( texture ) ) {
732
+
733
+ return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet );
721
734
 
722
735
  } else {
723
736
 
724
- snippet = this._generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );
737
+ return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet );
725
738
 
726
739
  }
727
740
 
728
- return snippet;
729
-
730
741
  }
731
742
 
732
743
  /**
@@ -737,13 +748,20 @@ class WGSLNodeBuilder extends NodeBuilder {
737
748
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
738
749
  * @param {string} biasSnippet - A WGSL snippet that represents the bias to apply to the mip level before sampling.
739
750
  * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
751
+ * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
740
752
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
741
753
  * @return {string} The WGSL snippet.
742
754
  */
743
- generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, shaderStage = this.shaderStage ) {
755
+ generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
744
756
 
745
757
  if ( shaderStage === 'fragment' ) {
746
758
 
759
+ if ( offsetSnippet ) {
760
+
761
+ return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet }, ${ offsetSnippet } )`;
762
+
763
+ }
764
+
747
765
  return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet } )`;
748
766
 
749
767
  } else {
@@ -844,9 +862,20 @@ class WGSLNodeBuilder extends NodeBuilder {
844
862
  */
845
863
  getNodeAccess( node, shaderStage ) {
846
864
 
847
- if ( shaderStage !== 'compute' )
865
+ if ( shaderStage !== 'compute' ) {
866
+
867
+ if ( node.isAtomic === true ) {
868
+
869
+ console.warn( 'WebGPURenderer: Atomic operations are only supported in compute shaders.' );
870
+
871
+ return NodeAccess.READ_WRITE;
872
+
873
+ }
874
+
848
875
  return NodeAccess.READ_ONLY;
849
876
 
877
+ }
878
+
850
879
  return node.access;
851
880
 
852
881
  }
@@ -899,7 +928,15 @@ class WGSLNodeBuilder extends NodeBuilder {
899
928
 
900
929
  if ( type === 'texture' || type === 'storageTexture' ) {
901
930
 
902
- texture = new NodeSampledTexture( uniformNode.name, uniformNode.node, group, access );
931
+ if ( node.value.is3DTexture === true ) {
932
+
933
+ texture = new NodeSampledTexture3D( uniformNode.name, uniformNode.node, group, access );
934
+
935
+ } else {
936
+
937
+ texture = new NodeSampledTexture( uniformNode.name, uniformNode.node, group, access );
938
+
939
+ }
903
940
 
904
941
  } else if ( type === 'cubeTexture' ) {
905
942
 
@@ -1721,10 +1758,6 @@ ${ flowData.code }
1721
1758
 
1722
1759
  textureType = 'texture_3d<f32>';
1723
1760
 
1724
- } else if ( texture.isVideoTexture === true ) {
1725
-
1726
- textureType = 'texture_external';
1727
-
1728
1761
  } else {
1729
1762
 
1730
1763
  const componentPrefix = this.getComponentTypeFromTexture( texture ).charAt( 0 );
@@ -1890,7 +1923,11 @@ ${ flowData.code }
1890
1923
 
1891
1924
  } else {
1892
1925
 
1893
- this.computeShader = this._getWGSLComputeCode( shadersData.compute, ( this.object.workgroupSize || [ 64 ] ).join( ', ' ) );
1926
+ // Early strictly validated in computeNode
1927
+
1928
+ const workgroupSize = this.object.workgroupSize;
1929
+
1930
+ this.computeShader = this._getWGSLComputeCode( shadersData.compute, workgroupSize );
1894
1931
 
1895
1932
  }
1896
1933
 
@@ -1923,6 +1960,35 @@ ${ flowData.code }
1923
1960
 
1924
1961
  }
1925
1962
 
1963
+ /**
1964
+ * Returns the bitcast method name for a given input and outputType.
1965
+ *
1966
+ * @param {string} type - The output type to bitcast to.
1967
+ * @return {string} The resolved WGSL bitcast invocation.
1968
+ */
1969
+ getBitcastMethod( type ) {
1970
+
1971
+ const dataType = this.getType( type );
1972
+
1973
+ return `bitcast<${ dataType }>`;
1974
+
1975
+ }
1976
+
1977
+ /**
1978
+ * Returns the native snippet for a ternary operation.
1979
+ *
1980
+ * @param {string} condSnippet - The condition determining which expression gets resolved.
1981
+ * @param {string} ifSnippet - The expression to resolve to if the condition is true.
1982
+ * @param {string} elseSnippet - The expression to resolve to if the condition is false.
1983
+ * @return {string} The resolved method name.
1984
+ */
1985
+ getTernary( condSnippet, ifSnippet, elseSnippet ) {
1986
+
1987
+ return `select( ${elseSnippet}, ${ifSnippet}, ${condSnippet} )`;
1988
+
1989
+ }
1990
+
1991
+
1926
1992
  /**
1927
1993
  * Returns the WGSL type of the given node data type.
1928
1994
  *
@@ -2095,36 +2161,40 @@ fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} {
2095
2161
  */
2096
2162
  _getWGSLComputeCode( shaderData, workgroupSize ) {
2097
2163
 
2164
+ const [ workgroupSizeX, workgroupSizeY, workgroupSizeZ ] = workgroupSize;
2165
+
2098
2166
  return `${ this.getSignature() }
2099
2167
  // directives
2100
- ${shaderData.directives}
2168
+ ${ shaderData.directives }
2101
2169
 
2102
2170
  // system
2103
2171
  var<private> instanceIndex : u32;
2104
2172
 
2105
2173
  // locals
2106
- ${shaderData.scopedArrays}
2174
+ ${ shaderData.scopedArrays }
2107
2175
 
2108
2176
  // structs
2109
- ${shaderData.structs}
2177
+ ${ shaderData.structs }
2110
2178
 
2111
2179
  // uniforms
2112
- ${shaderData.uniforms}
2180
+ ${ shaderData.uniforms }
2113
2181
 
2114
2182
  // codes
2115
- ${shaderData.codes}
2183
+ ${ shaderData.codes }
2116
2184
 
2117
- @compute @workgroup_size( ${workgroupSize} )
2118
- fn main( ${shaderData.attributes} ) {
2185
+ @compute @workgroup_size( ${ workgroupSizeX }, ${ workgroupSizeY }, ${ workgroupSizeZ } )
2186
+ fn main( ${ shaderData.attributes } ) {
2119
2187
 
2120
2188
  // system
2121
- instanceIndex = globalId.x + globalId.y * numWorkgroups.x * u32(${workgroupSize}) + globalId.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize});
2189
+ instanceIndex = globalId.x
2190
+ + globalId.y * ( ${ workgroupSizeX } * numWorkgroups.x )
2191
+ + globalId.z * ( ${ workgroupSizeX } * numWorkgroups.x ) * ( ${ workgroupSizeY } * numWorkgroups.y );
2122
2192
 
2123
2193
  // vars
2124
- ${shaderData.vars}
2194
+ ${ shaderData.vars }
2125
2195
 
2126
2196
  // flow
2127
- ${shaderData.flow}
2197
+ ${ shaderData.flow }
2128
2198
 
2129
2199
  }
2130
2200
  `;
@@ -93,30 +93,6 @@ class WebGPUBindingUtils {
93
93
 
94
94
  bindingGPU.buffer = buffer;
95
95
 
96
- } else if ( binding.isSampler ) {
97
-
98
- const sampler = {}; // GPUSamplerBindingLayout
99
-
100
- if ( binding.texture.isDepthTexture ) {
101
-
102
- if ( binding.texture.compareFunction !== null ) {
103
-
104
- sampler.type = GPUSamplerBindingType.Comparison;
105
-
106
- } else if ( backend.compatibilityMode ) {
107
-
108
- sampler.type = GPUSamplerBindingType.NonFiltering;
109
-
110
- }
111
-
112
- }
113
-
114
- bindingGPU.sampler = sampler;
115
-
116
- } else if ( binding.isSampledTexture && binding.texture.isVideoTexture ) {
117
-
118
- bindingGPU.externalTexture = {}; // GPUExternalTextureBindingLayout
119
-
120
96
  } else if ( binding.isSampledTexture && binding.store ) {
121
97
 
122
98
  const storageTexture = {}; // GPUStorageTextureBindingLayout
@@ -224,6 +200,26 @@ class WebGPUBindingUtils {
224
200
 
225
201
  bindingGPU.texture = texture;
226
202
 
203
+ } else if ( binding.isSampler ) {
204
+
205
+ const sampler = {}; // GPUSamplerBindingLayout
206
+
207
+ if ( binding.texture.isDepthTexture ) {
208
+
209
+ if ( binding.texture.compareFunction !== null ) {
210
+
211
+ sampler.type = GPUSamplerBindingType.Comparison;
212
+
213
+ } else if ( backend.compatibilityMode ) {
214
+
215
+ sampler.type = GPUSamplerBindingType.NonFiltering;
216
+
217
+ }
218
+
219
+ }
220
+
221
+ bindingGPU.sampler = sampler;
222
+
227
223
  } else {
228
224
 
229
225
  console.error( `WebGPUBindingUtils: Unsupported binding "${ binding }".` );
@@ -405,12 +401,6 @@ class WebGPUBindingUtils {
405
401
 
406
402
  entriesGPU.push( { binding: bindingPoint, resource: { buffer: bindingData.buffer } } );
407
403
 
408
- } else if ( binding.isSampler ) {
409
-
410
- const textureGPU = backend.get( binding.texture );
411
-
412
- entriesGPU.push( { binding: bindingPoint, resource: textureGPU.sampler } );
413
-
414
404
  } else if ( binding.isSampledTexture ) {
415
405
 
416
406
  const textureData = backend.get( binding.texture );
@@ -424,7 +414,15 @@ class WebGPUBindingUtils {
424
414
  } else {
425
415
 
426
416
  const mipLevelCount = binding.store ? 1 : textureData.texture.mipLevelCount;
427
- const propertyName = `view-${ textureData.texture.width }-${ textureData.texture.height }-${ mipLevelCount }`;
417
+ let propertyName = `view-${ textureData.texture.width }-${ textureData.texture.height }`;
418
+
419
+ if ( textureData.texture.depthOrArrayLayers > 1 ) {
420
+
421
+ propertyName += `-${ textureData.texture.depthOrArrayLayers }`;
422
+
423
+ }
424
+
425
+ propertyName += `-${ mipLevelCount }`;
428
426
 
429
427
  resourceGPU = textureData[ propertyName ];
430
428
 
@@ -460,6 +458,12 @@ class WebGPUBindingUtils {
460
458
 
461
459
  entriesGPU.push( { binding: bindingPoint, resource: resourceGPU } );
462
460
 
461
+ } else if ( binding.isSampler ) {
462
+
463
+ const textureGPU = backend.get( binding.texture );
464
+
465
+ entriesGPU.push( { binding: bindingPoint, resource: textureGPU.sampler } );
466
+
463
467
  }
464
468
 
465
469
  bindingPoint ++;
@@ -113,7 +113,7 @@ export const GPUTextureFormat = {
113
113
  // Packed 32-bit formats
114
114
  RGB9E5UFloat: 'rgb9e5ufloat',
115
115
  RGB10A2Unorm: 'rgb10a2unorm',
116
- RG11B10UFloat: 'rgb10a2unorm',
116
+ RG11B10UFloat: 'rg11b10ufloat',
117
117
 
118
118
  // 64-bit formats
119
119
 
@@ -158,7 +158,7 @@ export const GPUTextureFormat = {
158
158
  BC6HRGBUFloat: 'bc6h-rgb-ufloat',
159
159
  BC6HRGBFloat: 'bc6h-rgb-float',
160
160
  BC7RGBAUnorm: 'bc7-rgba-unorm',
161
- BC7RGBAUnormSRGB: 'bc7-rgba-srgb',
161
+ BC7RGBAUnormSRGB: 'bc7-rgba-unorm-srgb',
162
162
 
163
163
  // ETC2 compressed formats usable if 'texture-compression-etc2' is both
164
164
  // supported by the device/user agent and enabled in requestDevice.