@plastic-software/three 0.179.0 → 0.180.1

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 (173) hide show
  1. package/build/three.cjs +167 -107
  2. package/build/three.core.js +112 -20
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +56 -90
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +30 -5
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +2896 -1048
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +2896 -1048
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +1 -1
  13. package/examples/jsm/controls/ArcballControls.js +7 -7
  14. package/examples/jsm/controls/DragControls.js +6 -56
  15. package/examples/jsm/controls/FirstPersonControls.js +2 -2
  16. package/examples/jsm/controls/PointerLockControls.js +0 -8
  17. package/examples/jsm/exporters/GLTFExporter.js +30 -22
  18. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  19. package/examples/jsm/exporters/PLYExporter.js +1 -1
  20. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  21. package/examples/jsm/lines/Line2.js +3 -3
  22. package/examples/jsm/lines/LineGeometry.js +1 -1
  23. package/examples/jsm/lines/LineSegments2.js +2 -2
  24. package/examples/jsm/lines/Wireframe.js +2 -2
  25. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  26. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  27. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  28. package/examples/jsm/loaders/ColladaLoader.js +1 -1
  29. package/examples/jsm/loaders/EXRLoader.js +5 -5
  30. package/examples/jsm/loaders/GLTFLoader.js +9 -5
  31. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  32. package/examples/jsm/loaders/HDRLoader.js +486 -0
  33. package/examples/jsm/loaders/KTX2Loader.js +112 -32
  34. package/examples/jsm/loaders/RGBELoader.js +7 -473
  35. package/examples/jsm/loaders/TTFLoader.js +4 -4
  36. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  37. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  38. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  39. package/examples/jsm/math/ColorSpaces.js +19 -1
  40. package/examples/jsm/math/ConvexHull.js +2 -2
  41. package/examples/jsm/math/Lut.js +2 -2
  42. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  43. package/examples/jsm/misc/ProgressiveLightMap.js +1 -1
  44. package/examples/jsm/misc/Volume.js +1 -1
  45. package/examples/jsm/postprocessing/OutlinePass.js +1 -1
  46. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  47. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +1 -1
  48. package/examples/jsm/transpiler/GLSLDecoder.js +22 -19
  49. package/examples/jsm/transpiler/TSLEncoder.js +2 -10
  50. package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
  51. package/examples/jsm/tsl/display/AnamorphicNode.js +27 -4
  52. package/examples/jsm/tsl/display/BloomNode.js +3 -3
  53. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
  54. package/examples/jsm/tsl/display/DepthOfFieldNode.js +439 -90
  55. package/examples/jsm/tsl/display/GTAONode.js +8 -0
  56. package/examples/jsm/tsl/display/GaussianBlurNode.js +47 -35
  57. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  58. package/examples/jsm/tsl/display/SSRNode.js +180 -65
  59. package/examples/jsm/tsl/display/TRAANode.js +1 -1
  60. package/examples/jsm/tsl/display/boxBlur.js +64 -0
  61. package/examples/jsm/tsl/display/hashBlur.js +15 -18
  62. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  63. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  64. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  65. package/package.json +1 -1
  66. package/src/Three.Core.js +1 -0
  67. package/src/Three.TSL.js +29 -4
  68. package/src/animation/AnimationClip.js +17 -2
  69. package/src/constants.js +11 -3
  70. package/src/core/BufferGeometry.js +2 -2
  71. package/src/extras/TextureUtils.js +2 -1
  72. package/src/extras/lib/earcut.js +1 -1
  73. package/src/lights/webgpu/ProjectorLight.js +1 -1
  74. package/src/materials/Material.js +12 -0
  75. package/src/materials/MeshDistanceMaterial.js +1 -1
  76. package/src/materials/nodes/PointsNodeMaterial.js +81 -28
  77. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  78. package/src/materials/nodes/manager/NodeMaterialObserver.js +1 -1
  79. package/src/math/ColorManagement.js +7 -1
  80. package/src/nodes/Nodes.js +3 -0
  81. package/src/nodes/TSL.js +3 -0
  82. package/src/nodes/accessors/BufferNode.js +1 -1
  83. package/src/nodes/accessors/Camera.js +133 -7
  84. package/src/nodes/accessors/ClippingNode.js +6 -5
  85. package/src/nodes/accessors/CubeTextureNode.js +2 -2
  86. package/src/nodes/accessors/InstanceNode.js +3 -1
  87. package/src/nodes/accessors/Object3DNode.js +1 -1
  88. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  89. package/src/nodes/accessors/ReferenceNode.js +1 -1
  90. package/src/nodes/accessors/Texture3DNode.js +13 -0
  91. package/src/nodes/accessors/TextureNode.js +71 -19
  92. package/src/nodes/code/FunctionCallNode.js +19 -0
  93. package/src/nodes/code/FunctionNode.js +23 -0
  94. package/src/nodes/core/AssignNode.js +4 -3
  95. package/src/nodes/core/ContextNode.js +24 -0
  96. package/src/nodes/core/Node.js +16 -20
  97. package/src/nodes/core/NodeBuilder.js +48 -14
  98. package/src/nodes/core/NodeFrame.js +1 -1
  99. package/src/nodes/core/NodeUniform.js +1 -1
  100. package/src/nodes/core/NodeUtils.js +1 -2
  101. package/src/nodes/core/StackNode.js +29 -4
  102. package/src/nodes/core/StructNode.js +5 -5
  103. package/src/nodes/core/StructTypeNode.js +1 -0
  104. package/src/nodes/core/SubBuildNode.js +2 -2
  105. package/src/nodes/core/UniformNode.js +16 -9
  106. package/src/nodes/core/VarNode.js +0 -21
  107. package/src/nodes/display/FrontFacingNode.js +4 -8
  108. package/src/nodes/display/PassNode.js +1 -1
  109. package/src/nodes/display/ScreenNode.js +42 -13
  110. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  111. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  112. package/src/nodes/display/ViewportTextureNode.js +42 -12
  113. package/src/nodes/gpgpu/SubgroupFunctionNode.js +430 -0
  114. package/src/nodes/lighting/LightsNode.js +1 -1
  115. package/src/nodes/math/BitcastNode.js +156 -0
  116. package/src/nodes/math/ConditionalNode.js +18 -2
  117. package/src/nodes/math/MathNode.js +3 -15
  118. package/src/nodes/math/OperatorNode.js +4 -3
  119. package/src/nodes/tsl/TSLCore.js +432 -152
  120. package/src/nodes/utils/JoinNode.js +3 -1
  121. package/src/nodes/utils/MemberNode.js +58 -7
  122. package/src/nodes/utils/RTTNode.js +1 -1
  123. package/src/nodes/utils/ReflectorNode.js +51 -7
  124. package/src/nodes/utils/SampleNode.js +12 -2
  125. package/src/nodes/utils/SplitNode.js +11 -0
  126. package/src/nodes/utils/Timer.js +0 -47
  127. package/src/objects/BatchedMesh.js +2 -2
  128. package/src/objects/LOD.js +1 -1
  129. package/src/objects/Sprite.js +2 -2
  130. package/src/renderers/WebGLRenderer.js +1 -10
  131. package/src/renderers/common/Attributes.js +1 -1
  132. package/src/renderers/common/Backend.js +19 -1
  133. package/src/renderers/common/Bindings.js +2 -0
  134. package/src/renderers/common/ChainMap.js +1 -1
  135. package/src/renderers/common/DataMap.js +1 -1
  136. package/src/renderers/common/Pipelines.js +1 -1
  137. package/src/renderers/common/RenderContext.js +2 -2
  138. package/src/renderers/common/RenderObject.js +14 -2
  139. package/src/renderers/common/Renderer.js +39 -19
  140. package/src/renderers/common/SampledTexture.js +1 -1
  141. package/src/renderers/common/Sampler.js +25 -13
  142. package/src/renderers/common/Textures.js +34 -12
  143. package/src/renderers/common/TimestampQueryPool.js +3 -3
  144. package/src/renderers/common/XRManager.js +35 -19
  145. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  146. package/src/renderers/common/nodes/NodeLibrary.js +5 -5
  147. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  148. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  149. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  150. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  151. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +7 -15
  152. package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -1
  153. package/src/renderers/webgl/WebGLProgram.js +4 -4
  154. package/src/renderers/webgl/WebGLShadowMap.js +1 -1
  155. package/src/renderers/webgl/WebGLTextures.js +1 -0
  156. package/src/renderers/webgl/WebGLUtils.js +3 -2
  157. package/src/renderers/webgl-fallback/WebGLBackend.js +186 -135
  158. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +110 -17
  159. package/src/renderers/webgl-fallback/utils/WebGLState.js +1 -1
  160. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -3
  161. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -10
  162. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  163. package/src/renderers/webgpu/WebGPUBackend.js +35 -31
  164. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +124 -34
  165. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -2
  166. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +9 -18
  167. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +114 -25
  168. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +3 -3
  169. package/src/renderers/webxr/WebXRManager.js +39 -24
  170. package/src/textures/ExternalTexture.js +15 -4
  171. package/src/textures/Source.js +1 -1
  172. package/src/textures/VideoTexture.js +0 -3
  173. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
@@ -10,7 +10,11 @@ import { DataTexture } from '../../../textures/DataTexture.js';
10
10
 
11
11
  const glslMethods = {
12
12
  textureDimensions: 'textureSize',
13
- equals: 'equal'
13
+ equals: 'equal',
14
+ bitcast_float_int: 'floatBitsToInt',
15
+ bitcast_int_float: 'intBitsToFloat',
16
+ bitcast_uint_float: 'uintBitsToFloat',
17
+ bitcast_float_uint: 'floatBitsToUint',
14
18
  };
15
19
 
16
20
  const precisionLib = {
@@ -134,6 +138,33 @@ class GLSLNodeBuilder extends NodeBuilder {
134
138
 
135
139
  }
136
140
 
141
+ /**
142
+ * Returns the bitcast method name for a given input and outputType.
143
+ *
144
+ * @param {string} type - The output type to bitcast to.
145
+ * @param {string} inputType - The input type of the.
146
+ * @return {string} The resolved WGSL bitcast invocation.
147
+ */
148
+ getBitcastMethod( type, inputType ) {
149
+
150
+ return glslMethods[ `bitcast_${ inputType }_${ type }` ];
151
+
152
+ }
153
+
154
+ /**
155
+ * Returns the native snippet for a ternary operation.
156
+ *
157
+ * @param {string} condSnippet - The condition determining which expression gets resolved.
158
+ * @param {string} ifSnippet - The expression to resolve to if the condition is true.
159
+ * @param {string} elseSnippet - The expression to resolve to if the condition is false.
160
+ * @return {string} The resolved method name.
161
+ */
162
+ getTernary( condSnippet, ifSnippet, elseSnippet ) {
163
+
164
+ return `${condSnippet} ? ${ifSnippet} : ${elseSnippet}`;
165
+
166
+ }
167
+
137
168
  /**
138
169
  * Returns the output struct name. Not relevant for GLSL.
139
170
  *
@@ -336,7 +367,7 @@ ${ flowData.code }
336
367
  const channel = '.' + vectorComponents.join( '' ).slice( 0, itemSize );
337
368
  const uvSnippet = `ivec2(${indexSnippet} % ${ propertySizeName }, ${indexSnippet} / ${ propertySizeName })`;
338
369
 
339
- const snippet = this.generateTextureLoad( null, textureName, uvSnippet, null, '0' );
370
+ const snippet = this.generateTextureLoad( null, textureName, uvSnippet, null, null, '0' );
340
371
 
341
372
  //
342
373
 
@@ -366,25 +397,52 @@ ${ flowData.code }
366
397
  /**
367
398
  * Generates the GLSL snippet that reads a single texel from a texture without sampling or filtering.
368
399
  *
369
- * @param {Texture} texture - The texture.
400
+ * @param {?Texture} texture - The texture.
370
401
  * @param {string} textureProperty - The name of the texture uniform in the shader.
371
402
  * @param {string} uvIndexSnippet - A GLSL snippet that represents texture coordinates used for sampling.
372
403
  * @param {?string} depthSnippet - A GLSL snippet that represents the 0-based texture array index to sample.
404
+ * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
373
405
  * @param {string} [levelSnippet='0u'] - A GLSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
374
406
  * @return {string} The GLSL snippet.
375
407
  */
376
- generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0' ) {
408
+ generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, offsetSnippet, levelSnippet = '0' ) {
409
+
410
+ let snippet;
377
411
 
378
412
  if ( depthSnippet ) {
379
413
 
380
- return `texelFetch( ${ textureProperty }, ivec3( ${ uvIndexSnippet }, ${ depthSnippet } ), ${ levelSnippet } )`;
414
+ if ( offsetSnippet ) {
415
+
416
+ snippet = `texelFetchOffset( ${ textureProperty }, ivec3( ${ uvIndexSnippet }, ${ depthSnippet } ), ${ levelSnippet }, ${ offsetSnippet } )`;
417
+
418
+ } else {
419
+
420
+ snippet = `texelFetch( ${ textureProperty }, ivec3( ${ uvIndexSnippet }, ${ depthSnippet } ), ${ levelSnippet } )`;
421
+
422
+ }
381
423
 
382
424
  } else {
383
425
 
384
- return `texelFetch( ${ textureProperty }, ${ uvIndexSnippet }, ${ levelSnippet } )`;
426
+ if ( offsetSnippet ) {
427
+
428
+ snippet = `texelFetchOffset( ${ textureProperty }, ${ uvIndexSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
429
+
430
+ } else {
431
+
432
+ snippet = `texelFetch( ${ textureProperty }, ${ uvIndexSnippet }, ${ levelSnippet } )`;
433
+
434
+ }
385
435
 
386
436
  }
387
437
 
438
+ if ( texture !== null && texture.isDepthTexture ) {
439
+
440
+ snippet += '.x';
441
+
442
+ }
443
+
444
+ return snippet;
445
+
388
446
  }
389
447
 
390
448
  /**
@@ -394,23 +452,24 @@ ${ flowData.code }
394
452
  * @param {string} textureProperty - The name of the texture uniform in the shader.
395
453
  * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
396
454
  * @param {?string} depthSnippet - A GLSL snippet that represents the 0-based texture array index to sample.
455
+ * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
397
456
  * @return {string} The GLSL snippet.
398
457
  */
399
- generateTexture( texture, textureProperty, uvSnippet, depthSnippet ) {
458
+ generateTexture( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet ) {
459
+
460
+ if ( depthSnippet ) uvSnippet = `vec3( ${ uvSnippet }, ${ depthSnippet } )`;
400
461
 
401
462
  if ( texture.isDepthTexture ) {
402
463
 
403
- if ( depthSnippet ) uvSnippet = `vec4( ${ uvSnippet }, ${ depthSnippet } )`;
464
+ if ( offsetSnippet ) return `textureOffset( ${ textureProperty }, ${ uvSnippet }, ${ offsetSnippet } ).x`;
404
465
 
405
466
  return `texture( ${ textureProperty }, ${ uvSnippet } ).x`;
406
467
 
407
- } else {
468
+ }
408
469
 
409
- if ( depthSnippet ) uvSnippet = `vec3( ${ uvSnippet }, ${ depthSnippet } )`;
470
+ if ( offsetSnippet ) return `textureOffset( ${ textureProperty }, ${ uvSnippet }, ${ offsetSnippet } )`;
410
471
 
411
- return `texture( ${ textureProperty }, ${ uvSnippet } )`;
412
-
413
- }
472
+ return `texture( ${ textureProperty }, ${ uvSnippet } )`;
414
473
 
415
474
  }
416
475
 
@@ -421,9 +480,16 @@ ${ flowData.code }
421
480
  * @param {string} textureProperty - The name of the texture uniform in the shader.
422
481
  * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
423
482
  * @param {string} levelSnippet - A GLSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
483
+ * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
424
484
  * @return {string} The GLSL snippet.
425
485
  */
426
- generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet ) {
486
+ generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, offsetSnippet ) {
487
+
488
+ if ( offsetSnippet ) {
489
+
490
+ return `textureLodOffset( ${ textureProperty }, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
491
+
492
+ }
427
493
 
428
494
  return `textureLod( ${ textureProperty }, ${ uvSnippet }, ${ levelSnippet } )`;
429
495
 
@@ -436,9 +502,16 @@ ${ flowData.code }
436
502
  * @param {string} textureProperty - The name of the texture uniform in the shader.
437
503
  * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
438
504
  * @param {string} biasSnippet - A GLSL snippet that represents the bias to apply to the mip level before sampling.
505
+ * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
439
506
  * @return {string} The GLSL snippet.
440
507
  */
441
- generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet ) {
508
+ generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, offsetSnippet ) {
509
+
510
+ if ( offsetSnippet ) {
511
+
512
+ return `textureOffset( ${ textureProperty }, ${ uvSnippet }, ${ offsetSnippet }, ${ biasSnippet } )`;
513
+
514
+ }
442
515
 
443
516
  return `texture( ${ textureProperty }, ${ uvSnippet }, ${ biasSnippet } )`;
444
517
 
@@ -451,9 +524,16 @@ ${ flowData.code }
451
524
  * @param {string} textureProperty - The name of the texture uniform in the shader.
452
525
  * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
453
526
  * @param {Array<string>} gradSnippet - An array holding both gradient GLSL snippets.
527
+ * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
454
528
  * @return {string} The GLSL snippet.
455
529
  */
456
- generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet ) {
530
+ generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, offsetSnippet ) {
531
+
532
+ if ( offsetSnippet ) {
533
+
534
+ return `textureGradOffset( ${ textureProperty }, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;
535
+
536
+ }
457
537
 
458
538
  return `textureGrad( ${ textureProperty }, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
459
539
 
@@ -468,19 +548,32 @@ ${ flowData.code }
468
548
  * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
469
549
  * @param {string} compareSnippet - A GLSL snippet that represents the reference value.
470
550
  * @param {?string} depthSnippet - A GLSL snippet that represents 0-based texture array index to sample.
551
+ * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
471
552
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
472
553
  * @return {string} The GLSL snippet.
473
554
  */
474
- generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage ) {
555
+ generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
475
556
 
476
557
  if ( shaderStage === 'fragment' ) {
477
558
 
478
559
  if ( depthSnippet ) {
479
560
 
561
+ if ( offsetSnippet ) {
562
+
563
+ return `textureOffset( ${ textureProperty }, vec4( ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet } ), ${ offsetSnippet } )`;
564
+
565
+ }
566
+
480
567
  return `texture( ${ textureProperty }, vec4( ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet } ) )`;
481
568
 
482
569
  }
483
570
 
571
+ if ( offsetSnippet ) {
572
+
573
+ return `textureOffset( ${ textureProperty }, vec3( ${ uvSnippet }, ${ compareSnippet } ), ${ offsetSnippet } )`;
574
+
575
+ }
576
+
484
577
  return `texture( ${ textureProperty }, vec3( ${ uvSnippet }, ${ compareSnippet } ) )`;
485
578
 
486
579
  } else {
@@ -848,7 +848,7 @@ class WebGLState {
848
848
  * Sets the vertex state by binding the given VAO and element buffer.
849
849
  *
850
850
  * @param {WebGLVertexArrayObject} vao - The VAO.
851
- * @param {WebGLBuffer} indexBuffer - The index buffer.
851
+ * @param {?WebGLBuffer} indexBuffer - The index buffer.
852
852
  * @return {boolean} Whether a vertex state has been changed or not.
853
853
  */
854
854
  setVertexState( vao, indexBuffer = null ) {
@@ -1,5 +1,6 @@
1
1
  import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, FloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, NoColorSpace, LinearTransfer, SRGBTransfer } from '../../../constants.js';
2
2
  import { ColorManagement } from '../../../math/ColorManagement.js';
3
+ import { getByteLength } from '../../../extras/TextureUtils.js';
3
4
 
4
5
  let initialized = false, wrappingToGL, filterToGL, compareToGL;
5
6
 
@@ -221,6 +222,7 @@ class WebGLTextureUtils {
221
222
  if ( glType === gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = gl.RGB5_A1;
222
223
  if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = gl.RGB4;
223
224
  if ( glType === gl.UNSIGNED_INT_5_9_9_9_REV ) internalFormat = gl.RGB9_E5;
225
+ if ( glType === gl.UNSIGNED_INT_10F_11F_11F_REV ) internalFormat = gl.R11F_G11F_B10F;
224
226
 
225
227
  }
226
228
 
@@ -551,6 +553,7 @@ class WebGLTextureUtils {
551
553
  } else if ( texture.isCubeTexture ) {
552
554
 
553
555
  const images = options.images;
556
+ const mipmaps = texture.mipmaps;
554
557
 
555
558
  for ( let i = 0; i < 6; i ++ ) {
556
559
 
@@ -558,13 +561,42 @@ class WebGLTextureUtils {
558
561
 
559
562
  gl.texSubImage2D( gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, width, height, glFormat, glType, image );
560
563
 
564
+ for ( let j = 0; j < mipmaps.length; j ++ ) {
565
+
566
+ const mipmap = mipmaps[ j ];
567
+ const image = getImage( mipmap.images[ i ] );
568
+
569
+ gl.texSubImage2D( gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, image.width, image.height, glFormat, glType, image );
570
+
571
+ }
572
+
561
573
  }
562
574
 
563
575
  } else if ( texture.isDataArrayTexture || texture.isArrayTexture ) {
564
576
 
565
577
  const image = options.image;
566
578
 
567
- gl.texSubImage3D( gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
579
+ if ( texture.layerUpdates.size > 0 ) {
580
+
581
+ const layerByteLength = getByteLength( image.width, image.height, texture.format, texture.type );
582
+
583
+ for ( const layerIndex of texture.layerUpdates ) {
584
+
585
+ const layerData = image.data.subarray(
586
+ layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT,
587
+ ( layerIndex + 1 ) * layerByteLength / image.data.BYTES_PER_ELEMENT
588
+ );
589
+ gl.texSubImage3D( gl.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData );
590
+
591
+ }
592
+
593
+ texture.clearLayerUpdates();
594
+
595
+ } else {
596
+
597
+ gl.texSubImage3D( gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
598
+
599
+ }
568
600
 
569
601
  } else if ( texture.isData3DTexture ) {
570
602
 
@@ -581,9 +613,26 @@ class WebGLTextureUtils {
581
613
 
582
614
  } else {
583
615
 
584
- const image = getImage( options.image );
616
+ const mipmaps = texture.mipmaps;
617
+
618
+ if ( mipmaps.length > 0 ) {
619
+
620
+ for ( let i = 0, il = mipmaps.length; i < il; i ++ ) {
621
+
622
+ const mipmap = mipmaps[ i ];
623
+
624
+ const image = getImage( mipmap );
625
+ gl.texSubImage2D( glTextureType, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, image );
626
+
627
+ }
628
+
629
+ } else {
630
+
631
+ const image = getImage( options.image );
632
+ gl.texSubImage2D( glTextureType, 0, 0, 0, width, height, glFormat, glType, image );
633
+
634
+ }
585
635
 
586
- gl.texSubImage2D( glTextureType, 0, 0, 0, width, height, glFormat, glType, image );
587
636
 
588
637
  }
589
638
 
@@ -51,10 +51,10 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
51
51
  /**
52
52
  * Allocates a pair of queries for a given render context.
53
53
  *
54
- * @param {Object} renderContext - The render context to allocate queries for.
54
+ * @param {string} uid - A unique identifier for the render context.
55
55
  * @returns {?number} The base offset for the allocated queries, or null if allocation failed.
56
56
  */
57
- allocateQueriesForContext( renderContext ) {
57
+ allocateQueriesForContext( uid ) {
58
58
 
59
59
  if ( ! this.trackTimestamp ) return null;
60
60
 
@@ -71,7 +71,7 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
71
71
 
72
72
  // Initialize query states
73
73
  this.queryStates.set( baseOffset, 'inactive' );
74
- this.queryOffsets.set( renderContext.id, baseOffset );
74
+ this.queryOffsets.set( uid, baseOffset );
75
75
 
76
76
  return baseOffset;
77
77
 
@@ -80,9 +80,9 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
80
80
  /**
81
81
  * Begins a timestamp query for the specified render context.
82
82
  *
83
- * @param {Object} renderContext - The render context to begin timing for.
83
+ * @param {string} uid - A unique identifier for the render context.
84
84
  */
85
- beginQuery( renderContext ) {
85
+ beginQuery( uid ) {
86
86
 
87
87
  if ( ! this.trackTimestamp || this.isDisposed ) {
88
88
 
@@ -90,7 +90,7 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
90
90
 
91
91
  }
92
92
 
93
- const baseOffset = this.queryOffsets.get( renderContext.id );
93
+ const baseOffset = this.queryOffsets.get( uid );
94
94
  if ( baseOffset == null ) {
95
95
 
96
96
  return;
@@ -135,10 +135,9 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
135
135
  /**
136
136
  * Ends the active timestamp query for the specified render context.
137
137
  *
138
- * @param {Object} renderContext - The render context to end timing for.
139
- * @param {string} renderContext.id - Unique identifier for the render context.
138
+ * @param {string} uid - A unique identifier for the render context.
140
139
  */
141
- endQuery( renderContext ) {
140
+ endQuery( uid ) {
142
141
 
143
142
  if ( ! this.trackTimestamp || this.isDisposed ) {
144
143
 
@@ -146,7 +145,7 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
146
145
 
147
146
  }
148
147
 
149
- const baseOffset = this.queryOffsets.get( renderContext.id );
148
+ const baseOffset = this.queryOffsets.get( uid );
150
149
  if ( baseOffset == null ) {
151
150
 
152
151
  return;
@@ -1,4 +1,4 @@
1
- import { RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, DepthFormat, DepthStencilFormat, RedFormat, RGBFormat, RGBAFormat, AlphaFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedInt5999Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, RGBA_BPTC_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, SRGBTransfer, NoColorSpace } from '../../../constants.js';
1
+ import { RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, DepthFormat, DepthStencilFormat, RedFormat, RGBFormat, RGBAFormat, AlphaFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedInt5999Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, RGBA_BPTC_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, SRGBTransfer, NoColorSpace, UnsignedInt101111Type } from '../../../constants.js';
2
2
  import { ColorManagement } from '../../../math/ColorManagement.js';
3
3
 
4
4
  /**
@@ -60,6 +60,7 @@ class WebGLUtils {
60
60
  if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4;
61
61
  if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1;
62
62
  if ( p === UnsignedInt5999Type ) return gl.UNSIGNED_INT_5_9_9_9_REV;
63
+ if ( p === UnsignedInt101111Type ) return gl.UNSIGNED_INT_10F_11F_11F_REV;
63
64
 
64
65
  if ( p === ByteType ) return gl.BYTE;
65
66
  if ( p === ShortType ) return gl.SHORT;
@@ -231,7 +232,7 @@ class WebGLUtils {
231
232
 
232
233
  if ( extension !== null ) {
233
234
 
234
- if ( p === RGBA_BPTC_Format ) return extension.COMPRESSED_RED_RGTC1_EXT;
235
+ if ( p === RED_RGTC1_Format ) return extension.COMPRESSED_RED_RGTC1_EXT;
235
236
  if ( p === SIGNED_RED_RGTC1_Format ) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT;
236
237
  if ( p === RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT;
237
238
  if ( p === SIGNED_RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
@@ -13,9 +13,10 @@ import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js';
13
13
  import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js';
14
14
  import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js';
15
15
 
16
- import { WebGPUCoordinateSystem } from '../../constants.js';
16
+ import { WebGPUCoordinateSystem, TimestampQuery } from '../../constants.js';
17
17
  import WebGPUTimestampQueryPool from './utils/WebGPUTimestampQueryPool.js';
18
18
  import { warnOnce } from '../../utils.js';
19
+ import { ColorManagement } from '../../math/ColorManagement.js';
19
20
 
20
21
  /**
21
22
  * A backend implementation targeting WebGPU.
@@ -238,15 +239,20 @@ class WebGPUBackend extends Backend {
238
239
 
239
240
  const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque';
240
241
 
241
- this.trackTimestamp = this.trackTimestamp && this.hasFeature( GPUFeatureName.TimestampQuery );
242
+ const toneMappingMode = ColorManagement.getToneMappingMode( this.renderer.outputColorSpace );
242
243
 
243
244
  this.context.configure( {
244
245
  device: this.device,
245
246
  format: this.utils.getPreferredCanvasFormat(),
246
247
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
247
- alphaMode: alphaMode
248
+ alphaMode: alphaMode,
249
+ toneMapping: {
250
+ mode: toneMappingMode
251
+ }
248
252
  } );
249
253
 
254
+ this.trackTimestamp = this.trackTimestamp && this.hasFeature( GPUFeatureName.TimestampQuery );
255
+
250
256
  this.updateSize();
251
257
 
252
258
  }
@@ -384,9 +390,6 @@ class WebGPUBackend extends Backend {
384
390
  if ( descriptors === undefined ||
385
391
  renderTargetData.width !== renderTarget.width ||
386
392
  renderTargetData.height !== renderTarget.height ||
387
- renderTargetData.dimensions !== renderTarget.dimensions ||
388
- renderTargetData.activeMipmapLevel !== renderContext.activeMipmapLevel ||
389
- renderTargetData.activeCubeFace !== renderContext.activeCubeFace ||
390
393
  renderTargetData.samples !== renderTarget.samples
391
394
  ) {
392
395
 
@@ -394,21 +397,6 @@ class WebGPUBackend extends Backend {
394
397
 
395
398
  renderTargetData.descriptors = descriptors;
396
399
 
397
- // dispose
398
-
399
- const onDispose = () => {
400
-
401
- renderTarget.removeEventListener( 'dispose', onDispose );
402
- this.delete( renderTarget );
403
-
404
- };
405
-
406
- if ( renderTarget.hasEventListener( 'dispose', onDispose ) === false ) {
407
-
408
- renderTarget.addEventListener( 'dispose', onDispose );
409
-
410
- }
411
-
412
400
  }
413
401
 
414
402
  const cacheKey = renderContext.getCacheKey();
@@ -528,7 +516,6 @@ class WebGPUBackend extends Backend {
528
516
  renderTargetData.samples = renderTarget.samples;
529
517
  renderTargetData.activeMipmapLevel = renderContext.activeMipmapLevel;
530
518
  renderTargetData.activeCubeFace = renderContext.activeCubeFace;
531
- renderTargetData.dimensions = renderTarget.dimensions;
532
519
 
533
520
  }
534
521
 
@@ -581,6 +568,12 @@ class WebGPUBackend extends Backend {
581
568
 
582
569
  const renderContextData = this.get( renderContext );
583
570
 
571
+ //
572
+
573
+ renderContextData.frameCalls = this.renderer.info.render.frameCalls;
574
+
575
+ //
576
+
584
577
  const device = this.device;
585
578
  const occlusionQueryCount = renderContext.occlusionQueryCount;
586
579
 
@@ -621,7 +614,7 @@ class WebGPUBackend extends Backend {
621
614
 
622
615
  }
623
616
 
624
- this.initTimestampQuery( renderContext, descriptor );
617
+ this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ), descriptor );
625
618
 
626
619
  descriptor.occlusionQuerySet = occlusionQuerySet;
627
620
 
@@ -1298,11 +1291,17 @@ class WebGPUBackend extends Backend {
1298
1291
 
1299
1292
  const groupGPU = this.get( computeGroup );
1300
1293
 
1294
+ //
1295
+
1296
+ groupGPU.frameCalls = this.renderer.info.compute.frameCalls;
1297
+
1298
+ //
1299
+
1301
1300
  const descriptor = {
1302
1301
  label: 'computeGroup_' + computeGroup.id
1303
1302
  };
1304
1303
 
1305
- this.initTimestampQuery( computeGroup, descriptor );
1304
+ this.initTimestampQuery( TimestampQuery.COMPUTE, this.getTimestampUID( computeGroup ), descriptor );
1306
1305
 
1307
1306
  groupGPU.cmdEncoderGPU = this.device.createCommandEncoder( { label: 'computeGroup_' + computeGroup.id } );
1308
1307
 
@@ -1317,7 +1316,7 @@ class WebGPUBackend extends Backend {
1317
1316
  * @param {Node} computeNode - The compute node.
1318
1317
  * @param {Array<BindGroup>} bindings - The bindings.
1319
1318
  * @param {ComputePipeline} pipeline - The compute pipeline.
1320
- * @param {Array<number>|number} [dispatchSizeOrCount=null] - Array with [ x, y, z ] values for dispatch or a single number for the count.
1319
+ * @param {?(Array<number>|number)} [dispatchSizeOrCount=null] - Array with [ x, y, z ] values for dispatch or a single number for the count.
1321
1320
  */
1322
1321
  compute( computeGroup, computeNode, bindings, pipeline, dispatchSizeOrCount = null ) {
1323
1322
 
@@ -1807,6 +1806,11 @@ class WebGPUBackend extends Backend {
1807
1806
  const utils = this.utils;
1808
1807
  const renderContext = renderObject.context;
1809
1808
 
1809
+ // meshes with negative scale have a different frontFace render pipeline
1810
+ // descriptor value so the following must be honored in the cache key
1811
+
1812
+ const frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
1813
+
1810
1814
  return [
1811
1815
  material.transparent, material.blending, material.premultipliedAlpha,
1812
1816
  material.blendSrc, material.blendDst, material.blendEquation,
@@ -1817,6 +1821,7 @@ class WebGPUBackend extends Backend {
1817
1821
  material.stencilFail, material.stencilZFail, material.stencilZPass,
1818
1822
  material.stencilFuncMask, material.stencilWriteMask,
1819
1823
  material.side,
1824
+ frontFaceCW,
1820
1825
  utils.getSampleCountRenderContext( renderContext ),
1821
1826
  utils.getCurrentColorSpace( renderContext ), utils.getCurrentColorFormat( renderContext ), utils.getCurrentDepthStencilFormat( renderContext ),
1822
1827
  utils.getPrimitiveTopology( object, material ),
@@ -1929,15 +1934,14 @@ class WebGPUBackend extends Backend {
1929
1934
  /**
1930
1935
  * Inits a time stamp query for the given render context.
1931
1936
  *
1932
- * @param {RenderContext} renderContext - The render context.
1937
+ * @param {string} type - The type of the timestamp query (e.g. 'render', 'compute').
1938
+ * @param {number} uid - Unique id for the context (e.g. render context id).
1933
1939
  * @param {Object} descriptor - The query descriptor.
1934
1940
  */
1935
- initTimestampQuery( renderContext, descriptor ) {
1941
+ initTimestampQuery( type, uid, descriptor ) {
1936
1942
 
1937
1943
  if ( ! this.trackTimestamp ) return;
1938
1944
 
1939
- const type = renderContext.isComputeNode ? 'compute' : 'render';
1940
-
1941
1945
  if ( ! this.timestampQueryPool[ type ] ) {
1942
1946
 
1943
1947
  // TODO: Variable maxQueries?
@@ -1947,7 +1951,7 @@ class WebGPUBackend extends Backend {
1947
1951
 
1948
1952
  const timestampQueryPool = this.timestampQueryPool[ type ];
1949
1953
 
1950
- const baseOffset = timestampQueryPool.allocateQueriesForContext( renderContext );
1954
+ const baseOffset = timestampQueryPool.allocateQueriesForContext( uid );
1951
1955
 
1952
1956
  descriptor.timestampWrites = {
1953
1957
  querySet: timestampQueryPool.querySet,
@@ -2224,7 +2228,7 @@ class WebGPUBackend extends Backend {
2224
2228
  }
2225
2229
 
2226
2230
  /**
2227
- * Checks if the given feature is supported by the backend.
2231
+ * Checks if the given feature is supported by the backend.
2228
2232
  *
2229
2233
  * @param {string} name - The feature's name.
2230
2234
  * @return {boolean} Whether the feature is supported or not.