@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
@@ -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 = '';
@@ -219,19 +203,32 @@ class WGSLNodeBuilder extends NodeBuilder {
219
203
  * @param {string} textureProperty - The name of the texture uniform in the shader.
220
204
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
221
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.
222
207
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
223
208
  * @return {string} The WGSL snippet.
224
209
  */
225
- _generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
210
+ _generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
226
211
 
227
212
  if ( shaderStage === 'fragment' ) {
228
213
 
229
214
  if ( depthSnippet ) {
230
215
 
216
+ if ( offsetSnippet ) {
217
+
218
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ offsetSnippet } )`;
219
+
220
+ }
221
+
231
222
  return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet } )`;
232
223
 
233
224
  } else {
234
225
 
226
+ if ( offsetSnippet ) {
227
+
228
+ return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ offsetSnippet } )`;
229
+
230
+ }
231
+
235
232
  return `textureSample( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet } )`;
236
233
 
237
234
  }
@@ -253,21 +250,28 @@ class WGSLNodeBuilder extends NodeBuilder {
253
250
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
254
251
  * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
255
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.
256
254
  * @return {string} The WGSL snippet.
257
255
  */
258
- generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet ) {
256
+ generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
259
257
 
260
258
  if ( this.isUnfilterable( texture ) === false ) {
261
259
 
260
+ if ( offsetSnippet ) {
261
+
262
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
263
+
264
+ }
265
+
262
266
  return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
263
267
 
264
268
  } else if ( this.isFilteredTexture( texture ) ) {
265
269
 
266
- return this.generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet );
270
+ return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet );
267
271
 
268
272
  } else {
269
273
 
270
- return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet );
274
+ return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet );
271
275
 
272
276
  }
273
277
 
@@ -445,16 +449,23 @@ class WGSLNodeBuilder extends NodeBuilder {
445
449
  * @param {Texture} texture - The texture.
446
450
  * @param {string} textureProperty - The name of the texture uniform in the shader.
447
451
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
448
- * @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.
449
454
  * @return {string} The WGSL snippet.
450
455
  */
451
- generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet = '0u' ) {
456
+ generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet = '0u' ) {
452
457
 
453
458
  this._include( 'biquadraticTexture' );
454
459
 
455
460
  const wrapFunction = this.generateWrapFunction( texture );
456
461
  const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
457
462
 
463
+ if ( offsetSnippet ) {
464
+
465
+ uvSnippet = `${ uvSnippet } + vec2<f32>(${ offsetSnippet }) / ${ textureDimension }`;
466
+
467
+ }
468
+
458
469
  return `tsl_biquadraticTexture( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, u32( ${ levelSnippet } ) )`;
459
470
 
460
471
  }
@@ -467,18 +478,26 @@ class WGSLNodeBuilder extends NodeBuilder {
467
478
  * @param {string} textureProperty - The name of the texture uniform in the shader.
468
479
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
469
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.
470
482
  * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
471
483
  * @return {string} The WGSL snippet.
472
484
  */
473
- generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet = '0u' ) {
485
+ generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet = '0u' ) {
474
486
 
475
487
  const wrapFunction = this.generateWrapFunction( texture );
476
488
  const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
477
489
 
478
490
  const vecType = texture.isData3DTexture ? 'vec3' : 'vec2';
491
+
492
+ if ( offsetSnippet ) {
493
+
494
+ uvSnippet = `${ uvSnippet } + ${ vecType }<f32>(${ offsetSnippet }) / ${ vecType }<f32>( ${ textureDimension } )`;
495
+
496
+ }
497
+
479
498
  const coordSnippet = `${ vecType }<u32>( ${ wrapFunction }( ${ uvSnippet } ) * ${ vecType }<f32>( ${ textureDimension } ) )`;
480
499
 
481
- return this.generateTextureLoad( texture, textureProperty, coordSnippet, depthSnippet, levelSnippet );
500
+ return this.generateTextureLoad( texture, textureProperty, coordSnippet, depthSnippet, null, levelSnippet );
482
501
 
483
502
  }
484
503
 
@@ -489,13 +508,20 @@ class WGSLNodeBuilder extends NodeBuilder {
489
508
  * @param {string} textureProperty - The name of the texture uniform in the shader.
490
509
  * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
491
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.
492
512
  * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
493
513
  * @return {string} The WGSL snippet.
494
514
  */
495
- generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u' ) {
515
+ generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, offsetSnippet, levelSnippet = '0u' ) {
496
516
 
497
517
  let snippet;
498
518
 
519
+ if ( offsetSnippet ) {
520
+
521
+ uvIndexSnippet = `${ uvIndexSnippet } + ${ offsetSnippet }`;
522
+
523
+ }
524
+
499
525
  if ( depthSnippet ) {
500
526
 
501
527
  snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, u32( ${ levelSnippet } ) )`;
@@ -578,20 +604,21 @@ class WGSLNodeBuilder extends NodeBuilder {
578
604
  * @param {string} textureProperty - The name of the texture uniform in the shader.
579
605
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
580
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.
581
608
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
582
609
  * @return {string} The WGSL snippet.
583
610
  */
584
- generateTexture( texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage ) {
611
+ generateTexture( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
585
612
 
586
613
  let snippet = null;
587
614
 
588
615
  if ( this.isUnfilterable( texture ) ) {
589
616
 
590
- snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, '0', shaderStage );
617
+ snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, '0', shaderStage );
591
618
 
592
619
  } else {
593
620
 
594
- snippet = this._generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, shaderStage );
621
+ snippet = this._generateTextureSample( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, shaderStage );
595
622
 
596
623
  }
597
624
 
@@ -607,14 +634,21 @@ class WGSLNodeBuilder extends NodeBuilder {
607
634
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
608
635
  * @param {Array<string>} gradSnippet - An array holding both gradient WGSL snippets.
609
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.
610
638
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
611
639
  * @return {string} The WGSL snippet.
612
640
  */
613
- generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, shaderStage = this.shaderStage ) {
641
+ generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
614
642
 
615
643
  if ( shaderStage === 'fragment' ) {
616
644
 
617
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
+
618
652
  return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
619
653
 
620
654
  } else {
@@ -634,19 +668,32 @@ class WGSLNodeBuilder extends NodeBuilder {
634
668
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
635
669
  * @param {string} compareSnippet - A WGSL snippet that represents the reference value.
636
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.
637
672
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
638
673
  * @return {string} The WGSL snippet.
639
674
  */
640
- generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage ) {
675
+ generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
641
676
 
642
677
  if ( shaderStage === 'fragment' ) {
643
678
 
644
679
  if ( texture.isDepthTexture === true && texture.isArrayTexture === true ) {
645
680
 
681
+ if ( offsetSnippet ) {
682
+
683
+ return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet }, ${ offsetSnippet } )`;
684
+
685
+ }
686
+
646
687
  return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet } )`;
647
688
 
648
689
  }
649
690
 
691
+ if ( offsetSnippet ) {
692
+
693
+ return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ compareSnippet }, ${ offsetSnippet } )`;
694
+
695
+ }
696
+
650
697
  return `textureSampleCompare( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ compareSnippet } )`;
651
698
 
652
699
  } else {
@@ -665,22 +712,29 @@ class WGSLNodeBuilder extends NodeBuilder {
665
712
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
666
713
  * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
667
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.
668
716
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
669
717
  * @return {string} The WGSL snippet.
670
718
  */
671
- generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet ) {
719
+ generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, offsetSnippet ) {
672
720
 
673
721
  if ( this.isUnfilterable( texture ) === false ) {
674
722
 
723
+ if ( offsetSnippet ) {
724
+
725
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
726
+
727
+ }
728
+
675
729
  return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
676
730
 
677
731
  } else if ( this.isFilteredTexture( texture ) ) {
678
732
 
679
- return this.generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet );
733
+ return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet );
680
734
 
681
735
  } else {
682
736
 
683
- return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet );
737
+ return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet, levelSnippet );
684
738
 
685
739
  }
686
740
 
@@ -694,13 +748,20 @@ class WGSLNodeBuilder extends NodeBuilder {
694
748
  * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
695
749
  * @param {string} biasSnippet - A WGSL snippet that represents the bias to apply to the mip level before sampling.
696
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.
697
752
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
698
753
  * @return {string} The WGSL snippet.
699
754
  */
700
- generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, shaderStage = this.shaderStage ) {
755
+ generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {
701
756
 
702
757
  if ( shaderStage === 'fragment' ) {
703
758
 
759
+ if ( offsetSnippet ) {
760
+
761
+ return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet }, ${ offsetSnippet } )`;
762
+
763
+ }
764
+
704
765
  return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet } )`;
705
766
 
706
767
  } else {
@@ -1899,6 +1960,35 @@ ${ flowData.code }
1899
1960
 
1900
1961
  }
1901
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
+
1902
1992
  /**
1903
1993
  * Returns the WGSL type of the given node data type.
1904
1994
  *
@@ -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.
@@ -5,7 +5,7 @@ import {
5
5
  } from './WebGPUConstants.js';
6
6
 
7
7
  import {
8
- FrontSide, BackSide, DoubleSide,
8
+ BackSide, DoubleSide,
9
9
  NeverDepth, AlwaysDepth, LessDepth, LessEqualDepth, EqualDepth, GreaterEqualDepth, GreaterDepth, NotEqualDepth,
10
10
  NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending, CustomBlending,
11
11
  ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstColorFactor,
@@ -672,6 +672,8 @@ class WebGPUPipelineUtils {
672
672
  const descriptor = {};
673
673
  const utils = this.backend.utils;
674
674
 
675
+ //
676
+
675
677
  descriptor.topology = utils.getPrimitiveTopology( object, material );
676
678
 
677
679
  if ( geometry.index !== null && object.isLine === true && object.isLineSegments !== true ) {
@@ -680,28 +682,17 @@ class WebGPUPipelineUtils {
680
682
 
681
683
  }
682
684
 
683
- switch ( material.side ) {
685
+ //
684
686
 
685
- case FrontSide:
686
- descriptor.frontFace = GPUFrontFace.CCW;
687
- descriptor.cullMode = GPUCullMode.Back;
688
- break;
687
+ let flipSided = ( material.side === BackSide );
689
688
 
690
- case BackSide:
691
- descriptor.frontFace = GPUFrontFace.CCW;
692
- descriptor.cullMode = GPUCullMode.Front;
693
- break;
689
+ if ( object.isMesh && object.matrixWorld.determinant() < 0 ) flipSided = ! flipSided;
694
690
 
695
- case DoubleSide:
696
- descriptor.frontFace = GPUFrontFace.CCW;
697
- descriptor.cullMode = GPUCullMode.None;
698
- break;
691
+ descriptor.frontFace = ( flipSided === true ) ? GPUFrontFace.CW : GPUFrontFace.CCW;
699
692
 
700
- default:
701
- console.error( 'THREE.WebGPUPipelineUtils: Unknown material.side value.', material.side );
702
- break;
693
+ //
703
694
 
704
- }
695
+ descriptor.cullMode = ( material.side === DoubleSide ) ? GPUCullMode.None : GPUCullMode.Back;
705
696
 
706
697
  return descriptor;
707
698