super-three 0.170.0 → 0.171.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 (172) hide show
  1. package/build/three.cjs +24410 -24422
  2. package/build/three.core.js +37002 -0
  3. package/build/three.core.min.js +6 -0
  4. package/build/three.module.js +10573 -47578
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +533 -0
  7. package/build/three.tsl.min.js +6 -0
  8. package/build/three.webgpu.js +2907 -37975
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +2914 -37959
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/capabilities/WebGPU.js +1 -10
  13. package/examples/jsm/controls/ArcballControls.js +25 -21
  14. package/examples/jsm/controls/OrbitControls.js +41 -9
  15. package/examples/jsm/controls/PointerLockControls.js +2 -5
  16. package/examples/jsm/csm/CSMShadowNode.js +7 -5
  17. package/examples/jsm/geometries/DecalGeometry.js +5 -1
  18. package/examples/jsm/lighting/TiledLighting.js +1 -1
  19. package/examples/jsm/lines/LineGeometry.js +25 -0
  20. package/examples/jsm/lines/LineMaterial.js +1 -7
  21. package/examples/jsm/lines/webgpu/Line2.js +2 -1
  22. package/examples/jsm/lines/webgpu/LineSegments2.js +2 -1
  23. package/examples/jsm/lines/webgpu/Wireframe.js +2 -1
  24. package/examples/jsm/loaders/KTX2Loader.js +3 -0
  25. package/examples/jsm/loaders/MMDLoader.js +2 -6
  26. package/examples/jsm/loaders/MaterialXLoader.js +2 -2
  27. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -6
  28. package/examples/jsm/misc/ProgressiveLightMapGPU.js +2 -2
  29. package/examples/jsm/objects/InstancedPoints.js +2 -4
  30. package/examples/jsm/objects/LensflareMesh.js +4 -2
  31. package/examples/jsm/objects/SkyMesh.js +5 -3
  32. package/examples/jsm/objects/Water2Mesh.js +7 -3
  33. package/examples/jsm/objects/WaterMesh.js +5 -3
  34. package/examples/jsm/transpiler/AST.js +2 -2
  35. package/examples/jsm/transpiler/GLSLDecoder.js +57 -25
  36. package/examples/jsm/transpiler/TSLEncoder.js +11 -6
  37. package/examples/jsm/tsl/display/AfterImageNode.js +3 -3
  38. package/examples/jsm/tsl/display/AnaglyphPassNode.js +2 -2
  39. package/examples/jsm/tsl/display/AnamorphicNode.js +2 -2
  40. package/examples/jsm/tsl/display/BloomNode.js +3 -3
  41. package/examples/jsm/tsl/display/DenoiseNode.js +48 -12
  42. package/examples/jsm/tsl/display/DepthOfFieldNode.js +3 -2
  43. package/examples/jsm/tsl/display/DotScreenNode.js +2 -2
  44. package/examples/jsm/tsl/display/FXAANode.js +3 -3
  45. package/examples/jsm/tsl/display/FilmNode.js +3 -2
  46. package/examples/jsm/tsl/display/GTAONode.js +62 -27
  47. package/examples/jsm/tsl/display/GaussianBlurNode.js +6 -8
  48. package/examples/jsm/tsl/display/LensflareNode.js +3 -3
  49. package/examples/jsm/tsl/display/Lut3DNode.js +3 -2
  50. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  51. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -1
  52. package/examples/jsm/tsl/display/PixelationPassNode.js +4 -4
  53. package/examples/jsm/tsl/display/RGBShiftNode.js +2 -1
  54. package/examples/jsm/tsl/display/SMAANode.js +3 -3
  55. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  56. package/examples/jsm/tsl/display/SSRNode.js +31 -8
  57. package/examples/jsm/tsl/display/SobelOperatorNode.js +3 -3
  58. package/examples/jsm/tsl/display/StereoCompositePassNode.js +4 -4
  59. package/examples/jsm/tsl/display/StereoPassNode.js +2 -2
  60. package/examples/jsm/tsl/display/TRAAPassNode.js +2 -2
  61. package/examples/jsm/tsl/display/TransitionNode.js +3 -2
  62. package/examples/jsm/tsl/lighting/TiledLightsNode.js +6 -9
  63. package/examples/jsm/utils/SceneOptimizer.js +410 -0
  64. package/examples/jsm/utils/UVsDebug.js +1 -1
  65. package/package.json +3 -3
  66. package/src/Three.Core.js +178 -0
  67. package/src/Three.TSL.js +526 -0
  68. package/src/Three.WebGPU.Nodes.js +5 -186
  69. package/src/Three.WebGPU.js +4 -186
  70. package/src/Three.js +1 -177
  71. package/src/animation/AnimationClip.js +2 -2
  72. package/src/animation/AnimationObjectGroup.js +2 -2
  73. package/src/audio/Audio.js +38 -0
  74. package/src/cameras/PerspectiveCamera.js +6 -6
  75. package/src/cameras/StereoCamera.js +2 -2
  76. package/src/constants.js +1 -1
  77. package/src/core/BufferGeometry.js +5 -3
  78. package/src/core/InterleavedBuffer.js +4 -4
  79. package/src/core/Object3D.js +2 -2
  80. package/src/extras/core/Curve.js +3 -3
  81. package/src/extras/core/Shape.js +2 -2
  82. package/src/geometries/EdgesGeometry.js +2 -2
  83. package/src/geometries/LatheGeometry.js +2 -2
  84. package/src/lights/SpotLightShadow.js +2 -2
  85. package/src/materials/LineBasicMaterial.js +2 -6
  86. package/src/materials/LineDashedMaterial.js +1 -6
  87. package/src/materials/Material.js +3 -16
  88. package/src/materials/MeshBasicMaterial.js +2 -6
  89. package/src/materials/MeshDepthMaterial.js +2 -6
  90. package/src/materials/MeshDistanceMaterial.js +2 -6
  91. package/src/materials/MeshLambertMaterial.js +2 -6
  92. package/src/materials/MeshMatcapMaterial.js +2 -6
  93. package/src/materials/MeshNormalMaterial.js +2 -6
  94. package/src/materials/MeshPhongMaterial.js +3 -7
  95. package/src/materials/MeshPhysicalMaterial.js +4 -8
  96. package/src/materials/MeshStandardMaterial.js +2 -6
  97. package/src/materials/MeshToonMaterial.js +2 -6
  98. package/src/materials/PointsMaterial.js +2 -6
  99. package/src/materials/RawShaderMaterial.js +2 -6
  100. package/src/materials/ShaderMaterial.js +2 -6
  101. package/src/materials/ShadowMaterial.js +2 -6
  102. package/src/materials/SpriteMaterial.js +2 -6
  103. package/src/materials/nodes/Line2NodeMaterial.js +32 -13
  104. package/src/materials/nodes/LineDashedNodeMaterial.js +4 -2
  105. package/src/materials/nodes/NodeMaterial.js +64 -16
  106. package/src/materials/nodes/manager/NodeMaterialObserver.js +13 -10
  107. package/src/math/ColorManagement.js +130 -122
  108. package/src/math/Line3.js +2 -2
  109. package/src/math/Quaternion.js +2 -2
  110. package/src/math/Spherical.js +3 -3
  111. package/src/math/Vector2.js +7 -7
  112. package/src/math/Vector3.js +9 -9
  113. package/src/math/Vector4.js +11 -9
  114. package/src/nodes/Nodes.js +1 -0
  115. package/src/nodes/TSL.js +3 -1
  116. package/src/nodes/accessors/Arrays.js +27 -0
  117. package/src/nodes/accessors/BuiltinNode.js +26 -0
  118. package/src/nodes/accessors/ClippingNode.js +76 -42
  119. package/src/nodes/accessors/InstanceNode.js +17 -20
  120. package/src/nodes/accessors/InstancedMeshNode.js +26 -0
  121. package/src/nodes/accessors/Lights.js +32 -0
  122. package/src/nodes/accessors/StorageBufferNode.js +29 -9
  123. package/src/nodes/accessors/StorageTextureNode.js +10 -4
  124. package/src/nodes/accessors/TextureNode.js +1 -1
  125. package/src/nodes/core/NodeBuilder.js +2 -9
  126. package/src/nodes/core/NodeUtils.js +28 -0
  127. package/src/nodes/core/constants.js +6 -0
  128. package/src/nodes/display/BlendModes.js +99 -0
  129. package/src/nodes/display/ToonOutlinePassNode.js +3 -3
  130. package/src/nodes/display/ViewportDepthNode.js +21 -6
  131. package/src/nodes/functions/material/getAlphaHashThreshold.js +13 -7
  132. package/src/nodes/functions/material/getParallaxCorrectNormal.js +1 -1
  133. package/src/nodes/lighting/AnalyticLightNode.js +12 -4
  134. package/src/nodes/lighting/PointLightNode.js +10 -1
  135. package/src/nodes/lighting/PointShadowNode.js +254 -0
  136. package/src/nodes/lighting/ShadowNode.js +176 -67
  137. package/src/nodes/lighting/SpotLightNode.js +14 -2
  138. package/src/nodes/utils/RTTNode.js +9 -1
  139. package/src/nodes/utils/StorageArrayElementNode.js +2 -2
  140. package/src/objects/BatchedMesh.js +54 -95
  141. package/src/objects/ClippingGroup.js +19 -0
  142. package/src/objects/Skeleton.js +2 -2
  143. package/src/renderers/WebGLRenderer.js +94 -23
  144. package/src/renderers/common/Animation.js +23 -11
  145. package/src/renderers/common/Background.js +1 -1
  146. package/src/renderers/common/Bindings.js +20 -4
  147. package/src/renderers/common/ClippingContext.js +77 -85
  148. package/src/renderers/common/RenderList.js +9 -6
  149. package/src/renderers/common/RenderObject.js +27 -27
  150. package/src/renderers/common/RenderObjects.js +12 -6
  151. package/src/renderers/common/Renderer.js +63 -57
  152. package/src/renderers/common/Textures.js +11 -3
  153. package/src/renderers/common/UniformsGroup.js +16 -4
  154. package/src/renderers/common/extras/PMREMGenerator.js +89 -13
  155. package/src/renderers/common/nodes/NodeLibrary.js +2 -2
  156. package/src/renderers/common/nodes/NodeStorageBuffer.js +2 -3
  157. package/src/renderers/common/nodes/NodeUniform.js +42 -0
  158. package/src/renderers/webgl/WebGLBackground.js +20 -1
  159. package/src/renderers/webgl/WebGLGeometries.js +0 -28
  160. package/src/renderers/webgl-fallback/WebGLBackend.js +13 -6
  161. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +43 -12
  162. package/src/renderers/webgl-fallback/utils/WebGLState.js +26 -1
  163. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +4 -1
  164. package/src/renderers/webgpu/WebGPUBackend.js +47 -31
  165. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +13 -26
  166. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +184 -74
  167. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -2
  168. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -7
  169. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +5 -1
  170. package/src/textures/Source.js +2 -2
  171. package/src/textures/Texture.js +2 -2
  172. package/src/nodes/display/BlendMode.js +0 -54
@@ -30,6 +30,10 @@ const associativityRightToLeft = [
30
30
  ':'
31
31
  ];
32
32
 
33
+ const glslToTSL = {
34
+ inversesqrt: 'inverseSqrt'
35
+ };
36
+
33
37
  const spaceRegExp = /^((\t| )\n*)+/;
34
38
  const lineRegExp = /^\n+/;
35
39
  const commentRegExp = /^\/\*[\s\S]*?\*\//;
@@ -46,6 +50,12 @@ const operatorsRegExp = new RegExp( '^(\\' + [
46
50
  '.', ',', ';', '!', '=', '~', '*', '/', '%', '+', '-', '<', '>', '&', '^', '|', '?', ':', '#'
47
51
  ].join( '$' ).split( '' ).join( '\\' ).replace( /\\\$/g, '|' ) + ')' );
48
52
 
53
+ function getFunctionName( str ) {
54
+
55
+ return glslToTSL[ str ] || str;
56
+
57
+ }
58
+
49
59
  function getGroupDelta( str ) {
50
60
 
51
61
  if ( str === '(' || str === '[' || str === '{' ) return 1;
@@ -485,62 +495,84 @@ class GLSLDecoder {
485
495
 
486
496
  // function call
487
497
 
488
- const paramsTokens = this.parseFunctionParametersFromTokens( tokens.slice( 2, tokens.length - 1 ) );
498
+ const internalTokens = this.getTokensUntil( ')', tokens, 1 ).slice( 1, - 1 );
499
+
500
+ const paramsTokens = this.parseFunctionParametersFromTokens( internalTokens );
501
+
502
+ const functionCall = new FunctionCall( getFunctionName( firstToken.str ), paramsTokens );
503
+
504
+ const accessTokens = tokens.slice( 3 + internalTokens.length );
489
505
 
490
- return new FunctionCall( firstToken.str, paramsTokens );
506
+ if ( accessTokens.length > 0 ) {
507
+
508
+ const elements = this.parseAccessorElementsFromTokens( accessTokens );
509
+
510
+ return new AccessorElements( functionCall, elements );
511
+
512
+ }
513
+
514
+ return functionCall;
491
515
 
492
516
  } else if ( secondToken.str === '[' ) {
493
517
 
494
518
  // array accessor
495
519
 
496
- const elements = [];
520
+ const elements = this.parseAccessorElementsFromTokens( tokens.slice( 1 ) );
497
521
 
498
- let currentTokens = tokens.slice( 1 );
522
+ return new AccessorElements( new Accessor( firstToken.str ), elements );
499
523
 
500
- while ( currentTokens.length > 0 ) {
524
+ }
501
525
 
502
- const token = currentTokens[ 0 ];
526
+ }
503
527
 
504
- if ( token.str === '[' ) {
528
+ return new Accessor( firstToken.str );
505
529
 
506
- const accessorTokens = this.getTokensUntil( ']', currentTokens );
530
+ }
507
531
 
508
- const element = this.parseExpressionFromTokens( accessorTokens.slice( 1, accessorTokens.length - 1 ) );
532
+ }
509
533
 
510
- currentTokens = currentTokens.slice( accessorTokens.length );
534
+ parseAccessorElementsFromTokens( tokens ) {
511
535
 
512
- elements.push( new DynamicElement( element ) );
536
+ const elements = [];
513
537
 
514
- } else if ( token.str === '.' ) {
538
+ let currentTokens = tokens;
515
539
 
516
- const accessorTokens = currentTokens.slice( 1, 2 );
540
+ while ( currentTokens.length > 0 ) {
517
541
 
518
- const element = this.parseExpressionFromTokens( accessorTokens );
542
+ const token = currentTokens[ 0 ];
519
543
 
520
- currentTokens = currentTokens.slice( 2 );
544
+ if ( token.str === '[' ) {
521
545
 
522
- elements.push( new StaticElement( element ) );
546
+ const accessorTokens = this.getTokensUntil( ']', currentTokens );
523
547
 
524
- } else {
548
+ const element = this.parseExpressionFromTokens( accessorTokens.slice( 1, accessorTokens.length - 1 ) );
525
549
 
526
- console.error( 'Unknown accessor expression', token );
550
+ currentTokens = currentTokens.slice( accessorTokens.length );
527
551
 
528
- break;
552
+ elements.push( new DynamicElement( element ) );
529
553
 
530
- }
554
+ } else if ( token.str === '.' ) {
531
555
 
532
- }
556
+ const accessorTokens = currentTokens.slice( 1, 2 );
533
557
 
534
- return new AccessorElements( firstToken.str, elements );
558
+ const element = this.parseExpressionFromTokens( accessorTokens );
535
559
 
536
- }
560
+ currentTokens = currentTokens.slice( 2 );
537
561
 
538
- }
562
+ elements.push( new StaticElement( element ) );
539
563
 
540
- return new Accessor( firstToken.str );
564
+ } else {
565
+
566
+ console.error( 'Unknown accessor expression', token );
567
+
568
+ break;
569
+
570
+ }
541
571
 
542
572
  }
543
573
 
574
+ return elements;
575
+
544
576
  }
545
577
 
546
578
  parseFunctionParametersFromTokens( tokens ) {
@@ -1,4 +1,5 @@
1
- import * as THREE from 'three';
1
+ import { REVISION } from 'three/webgpu';
2
+ import * as TSL from 'three/tsl';
2
3
 
3
4
  import { VariableDeclaration, Accessor } from './AST.js';
4
5
 
@@ -43,7 +44,7 @@ const unaryLib = {
43
44
  '--': 'decrement' // decrementBefore
44
45
  };
45
46
 
46
- const isPrimitive = ( value ) => /^(true|false|-?\d)/.test( value );
47
+ const isPrimitive = ( value ) => /^(true|false|-?(\d|\.\d))/.test( value );
47
48
 
48
49
  class TSLEncoder {
49
50
 
@@ -68,7 +69,7 @@ class TSLEncoder {
68
69
 
69
70
  name = name.split( '.' )[ 0 ];
70
71
 
71
- if ( THREE[ name ] !== undefined && this.global.has( name ) === false && this._currentProperties[ name ] === undefined ) {
72
+ if ( TSL[ name ] !== undefined && this.global.has( name ) === false && this._currentProperties[ name ] === undefined ) {
72
73
 
73
74
  this.imports.add( name );
74
75
 
@@ -158,6 +159,10 @@ class TSLEncoder {
158
159
 
159
160
  this.addImport( opFn );
160
161
 
162
+ } else if ( opFn === '.' ) {
163
+
164
+ code = left + opFn + right;
165
+
161
166
  } else {
162
167
 
163
168
  code = left + '.' + opFn + '( ' + right + ' )';
@@ -192,7 +197,7 @@ class TSLEncoder {
192
197
 
193
198
  } else if ( node.isAccessorElements ) {
194
199
 
195
- code = node.property;
200
+ code = this.emitExpression( node.object );
196
201
 
197
202
  for ( const element of node.elements ) {
198
203
 
@@ -248,7 +253,7 @@ class TSLEncoder {
248
253
 
249
254
  } else if ( node.isUnary && node.expression.isNumber ) {
250
255
 
251
- code = node.type + ' ' + node.expression.value;
256
+ code = node.expression.type + '( ' + node.type + ' ' + node.expression.value + ' )';
252
257
 
253
258
  } else if ( node.isUnary ) {
254
259
 
@@ -690,7 +695,7 @@ ${ this.tab }} )`;
690
695
  const imports = [ ...this.imports ];
691
696
  const exports = [ ...this.global ];
692
697
 
693
- let header = '// Three.js Transpiler r' + THREE.REVISION + '\n\n';
698
+ let header = '// Three.js Transpiler r' + REVISION + '\n\n';
694
699
  let footer = '';
695
700
 
696
701
  if ( this.iife ) {
@@ -1,5 +1,5 @@
1
- import { RenderTarget, Vector2, PostProcessingUtils } from 'three';
2
- import { TempNode, nodeObject, Fn, float, vec4, NodeUpdateType, uv, texture, passTexture, uniform, sign, max, convertToTexture, QuadMesh, NodeMaterial } from 'three/tsl';
1
+ import { RenderTarget, Vector2, QuadMesh, NodeMaterial, PostProcessingUtils, TempNode, NodeUpdateType } from 'three/webgpu';
2
+ import { nodeObject, Fn, float, vec4, uv, texture, passTexture, uniform, sign, max, convertToTexture } from 'three/tsl';
3
3
 
4
4
  const _size = /*@__PURE__*/ new Vector2();
5
5
  const _quadMeshComp = /*@__PURE__*/ new QuadMesh();
@@ -16,7 +16,7 @@ class AfterImageNode extends TempNode {
16
16
 
17
17
  constructor( textureNode, damp = 0.96 ) {
18
18
 
19
- super( textureNode );
19
+ super( 'vec4' );
20
20
 
21
21
  this.textureNode = textureNode;
22
22
  this.textureNodeOld = texture();
@@ -1,5 +1,5 @@
1
- import { Matrix3 } from 'three';
2
- import { clamp, nodeObject, Fn, vec4, uv, uniform, max, NodeMaterial } from 'three/tsl';
1
+ import { Matrix3, NodeMaterial } from 'three/webgpu';
2
+ import { clamp, nodeObject, Fn, vec4, uv, uniform, max } from 'three/tsl';
3
3
  import StereoCompositePassNode from './StereoCompositePassNode.js';
4
4
 
5
5
  class AnaglyphPassNode extends StereoCompositePassNode {
@@ -1,5 +1,5 @@
1
- import { RenderTarget, Vector2, PostProcessingUtils } from 'three';
2
- import { TempNode, nodeObject, Fn, float, NodeUpdateType, uv, passTexture, uniform, convertToTexture, QuadMesh, NodeMaterial, vec2, vec3, Loop, threshold } from 'three/tsl';
1
+ import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils } from 'three/webgpu';
2
+ import { nodeObject, Fn, float, NodeUpdateType, uv, passTexture, uniform, convertToTexture, vec2, vec3, Loop, threshold } from 'three/tsl';
3
3
 
4
4
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
5
 
@@ -1,5 +1,5 @@
1
- import { HalfFloatType, RenderTarget, Vector2, Vector3, PostProcessingUtils } from 'three';
2
- import { TempNode, nodeObject, Fn, float, NodeUpdateType, uv, passTexture, uniform, QuadMesh, NodeMaterial, Loop, texture, luminance, smoothstep, mix, vec4, uniformArray, add, int } from 'three/tsl';
1
+ import { HalfFloatType, RenderTarget, Vector2, Vector3, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils, NodeUpdateType } from 'three/webgpu';
2
+ import { nodeObject, Fn, float, uv, passTexture, uniform, Loop, texture, luminance, smoothstep, mix, vec4, uniformArray, add, int } from 'three/tsl';
3
3
 
4
4
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
5
  const _size = /*@__PURE__*/ new Vector2();
@@ -19,7 +19,7 @@ class BloomNode extends TempNode {
19
19
 
20
20
  constructor( inputNode, strength = 1, radius = 0, threshold = 0 ) {
21
21
 
22
- super();
22
+ super( 'vec4' );
23
23
 
24
24
  this.inputNode = inputNode;
25
25
  this.strength = uniform( strength );
@@ -1,5 +1,6 @@
1
- import { Vector2, Vector3 } from 'three';
2
- import { getNormalFromDepth, getViewPosition, convertToTexture, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, luminance, vec2, vec3, vec4, uniformArray, int, dot, max, pow, abs, If, textureSize, sin, cos, mat2, PI } from 'three/tsl';
1
+ import { DataTexture, RepeatWrapping, Vector2, Vector3, TempNode } from 'three/webgpu';
2
+ import { texture, getNormalFromDepth, getViewPosition, convertToTexture, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, luminance, vec2, vec3, vec4, uniformArray, int, dot, max, pow, abs, If, textureSize, sin, cos, mat2, PI } from 'three/tsl';
3
+ import { SimplexNoise } from '../../math/SimplexNoise.js';
3
4
 
4
5
  class DenoiseNode extends TempNode {
5
6
 
@@ -9,26 +10,29 @@ class DenoiseNode extends TempNode {
9
10
 
10
11
  }
11
12
 
12
- constructor( textureNode, depthNode, normalNode, noiseNode, camera ) {
13
+ constructor( textureNode, depthNode, normalNode, camera ) {
13
14
 
14
- super();
15
+ super( 'vec4' );
15
16
 
16
17
  this.textureNode = textureNode;
17
18
  this.depthNode = depthNode;
18
19
  this.normalNode = normalNode;
19
- this.noiseNode = noiseNode;
20
20
 
21
- this.cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
21
+ this.noiseNode = texture( generateDefaultNoise() );
22
+
22
23
  this.lumaPhi = uniform( 5 );
23
24
  this.depthPhi = uniform( 5 );
24
25
  this.normalPhi = uniform( 5 );
25
26
  this.radius = uniform( 5 );
26
27
  this.index = uniform( 0 );
27
28
 
29
+ this.updateBeforeType = NodeUpdateType.FRAME;
30
+
31
+ // uniforms
32
+
28
33
  this._resolution = uniform( new Vector2() );
29
34
  this._sampleVectors = uniformArray( generatePdSamplePointInitializer( 16, 2, 1 ) );
30
-
31
- this.updateBeforeType = NodeUpdateType.FRAME;
35
+ this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
32
36
 
33
37
  }
34
38
 
@@ -46,7 +50,7 @@ class DenoiseNode extends TempNode {
46
50
 
47
51
  const sampleTexture = ( uv ) => this.textureNode.uv( uv );
48
52
  const sampleDepth = ( uv ) => this.depthNode.uv( uv ).x;
49
- const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.uv( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this.cameraProjectionMatrixInverse );
53
+ const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.uv( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
50
54
  const sampleNoise = ( uv ) => this.noiseNode.uv( uv );
51
55
 
52
56
  const denoiseSample = Fn( ( [ center, viewNormal, viewPosition, sampleUv ] ) => {
@@ -55,7 +59,7 @@ class DenoiseNode extends TempNode {
55
59
  const depth = sampleDepth( sampleUv ).toVar();
56
60
  const normal = sampleNormal( sampleUv ).toVar();
57
61
  const neighborColor = texel.rgb;
58
- const viewPos = getViewPosition( sampleUv, depth, this.cameraProjectionMatrixInverse ).toVar();
62
+ const viewPos = getViewPosition( sampleUv, depth, this._cameraProjectionMatrixInverse ).toVar();
59
63
 
60
64
  const normalDiff = dot( viewNormal, normal ).toVar();
61
65
  const normalSimilarity = pow( max( normalDiff, 0 ), this.normalPhi ).toVar();
@@ -84,7 +88,7 @@ class DenoiseNode extends TempNode {
84
88
 
85
89
  const center = vec3( texel.rgb ).toVar();
86
90
 
87
- const viewPosition = getViewPosition( uvNode, depth, this.cameraProjectionMatrixInverse ).toVar();
91
+ const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar();
88
92
 
89
93
  const noiseResolution = textureSize( this.noiseNode, 0 );
90
94
  let noiseUv = vec2( uvNode.x, uvNode.y.oneMinus() );
@@ -178,4 +182,36 @@ function generateDenoiseSamples( numSamples, numRings, radiusExponent ) {
178
182
 
179
183
  }
180
184
 
181
- export const denoise = ( node, depthNode, normalNode, noiseNode, camera ) => nodeObject( new DenoiseNode( convertToTexture( node ), nodeObject( depthNode ), nodeObject( normalNode ), nodeObject( noiseNode ), camera ) );
185
+ function generateDefaultNoise( size = 64 ) {
186
+
187
+ const simplex = new SimplexNoise();
188
+
189
+ const arraySize = size * size * 4;
190
+ const data = new Uint8Array( arraySize );
191
+
192
+ for ( let i = 0; i < size; i ++ ) {
193
+
194
+ for ( let j = 0; j < size; j ++ ) {
195
+
196
+ const x = i;
197
+ const y = j;
198
+
199
+ data[ ( i * size + j ) * 4 ] = ( simplex.noise( x, y ) * 0.5 + 0.5 ) * 255;
200
+ data[ ( i * size + j ) * 4 + 1 ] = ( simplex.noise( x + size, y ) * 0.5 + 0.5 ) * 255;
201
+ data[ ( i * size + j ) * 4 + 2 ] = ( simplex.noise( x, y + size ) * 0.5 + 0.5 ) * 255;
202
+ data[ ( i * size + j ) * 4 + 3 ] = ( simplex.noise( x + size, y + size ) * 0.5 + 0.5 ) * 255;
203
+
204
+ }
205
+
206
+ }
207
+
208
+ const noiseTexture = new DataTexture( data, size, size );
209
+ noiseTexture.wrapS = RepeatWrapping;
210
+ noiseTexture.wrapT = RepeatWrapping;
211
+ noiseTexture.needsUpdate = true;
212
+
213
+ return noiseTexture;
214
+
215
+ }
216
+
217
+ export const denoise = ( node, depthNode, normalNode, camera ) => nodeObject( new DenoiseNode( convertToTexture( node ), nodeObject( depthNode ), nodeObject( normalNode ), camera ) );
@@ -1,4 +1,5 @@
1
- import { convertToTexture, TempNode, nodeObject, Fn, NodeUpdateType, uv, uniform, vec2, vec4, clamp } from 'three/tsl';
1
+ import { TempNode, NodeUpdateType } from 'three/webgpu';
2
+ import { convertToTexture, nodeObject, Fn, uv, uniform, vec2, vec4, clamp } from 'three/tsl';
2
3
 
3
4
  class DepthOfFieldNode extends TempNode {
4
5
 
@@ -10,7 +11,7 @@ class DepthOfFieldNode extends TempNode {
10
11
 
11
12
  constructor( textureNode, viewZNode, focusNode, apertureNode, maxblurNode ) {
12
13
 
13
- super();
14
+ super( 'vec4' );
14
15
 
15
16
  this.textureNode = textureNode;
16
17
  this.viewZNode = viewZNode;
@@ -1,5 +1,5 @@
1
- import { Vector2 } from 'three';
2
- import { TempNode, nodeObject, Fn, uv, uniform, vec2, vec3, sin, cos, add, vec4, screenSize } from 'three/tsl';
1
+ import { Vector2, TempNode } from 'three/webgpu';
2
+ import { nodeObject, Fn, uv, uniform, vec2, vec3, sin, cos, add, vec4, screenSize } from 'three/tsl';
3
3
 
4
4
  class DotScreenNode extends TempNode {
5
5
 
@@ -1,5 +1,5 @@
1
- import { Vector2 } from 'three';
2
- import { TempNode, nodeObject, Fn, uniformArray, select, float, NodeUpdateType, uv, dot, clamp, uniform, convertToTexture, smoothstep, bool, vec2, vec3, If, Loop, max, min, Break, abs } from 'three/tsl';
1
+ import { Vector2, TempNode } from 'three/webgpu';
2
+ import { nodeObject, Fn, uniformArray, select, float, NodeUpdateType, uv, dot, clamp, uniform, convertToTexture, smoothstep, bool, vec2, vec3, If, Loop, max, min, Break, abs } from 'three/tsl';
3
3
 
4
4
  class FXAANode extends TempNode {
5
5
 
@@ -11,7 +11,7 @@ class FXAANode extends TempNode {
11
11
 
12
12
  constructor( textureNode ) {
13
13
 
14
- super();
14
+ super( 'vec4' );
15
15
 
16
16
  this.textureNode = textureNode;
17
17
 
@@ -1,4 +1,5 @@
1
- import { TempNode, rand, Fn, fract, time, uv, clamp, mix, vec4, nodeProxy } from 'three/tsl';
1
+ import { TempNode } from 'three/webgpu';
2
+ import { rand, Fn, fract, time, uv, clamp, mix, vec4, nodeProxy } from 'three/tsl';
2
3
 
3
4
  class FilmNode extends TempNode {
4
5
 
@@ -10,7 +11,7 @@ class FilmNode extends TempNode {
10
11
 
11
12
  constructor( inputNode, intensityNode = null, uvNode = null ) {
12
13
 
13
- super();
14
+ super( 'vec4' );
14
15
 
15
16
  this.inputNode = inputNode;
16
17
  this.intensityNode = intensityNode;
@@ -1,11 +1,15 @@
1
- import { DataTexture, RenderTarget, RepeatWrapping, Vector2, Vector3, PostProcessingUtils } from 'three';
2
- import { getNormalFromDepth, getScreenPosition, getViewPosition, QuadMesh, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec2, vec3, vec4, int, dot, max, pow, abs, If, textureSize, sin, cos, PI, texture, passTexture, mat3, add, normalize, mul, cross, div, mix, sqrt, sub, acos, clamp, NodeMaterial } from 'three/tsl';
1
+ import { DataTexture, RenderTarget, RepeatWrapping, Vector2, Vector3, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils } from 'three/webgpu';
2
+ import { reference, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getNormalFromDepth, getScreenPosition, getViewPosition, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec2, vec3, vec4, int, dot, max, pow, abs, If, textureSize, sin, cos, PI, texture, passTexture, mat3, add, normalize, mul, cross, div, mix, sqrt, sub, acos, clamp } from 'three/tsl';
3
3
 
4
4
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
5
  const _size = /*@__PURE__*/ new Vector2();
6
6
 
7
7
  let _rendererState;
8
8
 
9
+ /**
10
+ * References:
11
+ * https://www.activision.com/cdn/research/Practical_Real_Time_Strategies_for_Accurate_Indirect_Occlusion_NEW%20VERSION_COLOR.pdf
12
+ */
9
13
  class GTAONode extends TempNode {
10
14
 
11
15
  static get type() {
@@ -16,31 +20,44 @@ class GTAONode extends TempNode {
16
20
 
17
21
  constructor( depthNode, normalNode, camera ) {
18
22
 
19
- super();
23
+ super( 'vec4' );
20
24
 
21
25
  this.depthNode = depthNode;
22
26
  this.normalNode = normalNode;
23
27
 
28
+ this.resolutionScale = 1;
29
+
30
+ this.updateBeforeType = NodeUpdateType.FRAME;
31
+
32
+ // render targets
33
+
34
+ this._aoRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
35
+ this._aoRenderTarget.texture.name = 'GTAONode.AO';
36
+
37
+ // uniforms
38
+
24
39
  this.radius = uniform( 0.25 );
25
40
  this.resolution = uniform( new Vector2() );
26
41
  this.thickness = uniform( 1 );
27
42
  this.distanceExponent = uniform( 1 );
28
43
  this.distanceFallOff = uniform( 1 );
29
44
  this.scale = uniform( 1 );
30
- this.noiseNode = texture( generateMagicSquareNoise() );
45
+ this.samples = uniform( 16 );
31
46
 
32
- this.cameraProjectionMatrix = uniform( camera.projectionMatrix );
33
- this.cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
47
+ this._noiseNode = texture( generateMagicSquareNoise() );
48
+ this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
49
+ this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
50
+ this._cameraNear = reference( 'near', 'float', camera );
51
+ this._cameraFar = reference( 'far', 'float', camera );
34
52
 
35
- this.SAMPLES = uniform( 16 );
53
+ // materials
36
54
 
37
- this._aoRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
38
- this._aoRenderTarget.texture.name = 'GTAONode.AO';
55
+ this._material = new NodeMaterial();
56
+ this._material.name = 'GTAO';
39
57
 
40
- this._material = null;
41
- this._textureNode = passTexture( this, this._aoRenderTarget.texture );
58
+ //
42
59
 
43
- this.updateBeforeType = NodeUpdateType.FRAME;
60
+ this._textureNode = passTexture( this, this._aoRenderTarget.texture );
44
61
 
45
62
  }
46
63
 
@@ -52,6 +69,9 @@ class GTAONode extends TempNode {
52
69
 
53
70
  setSize( width, height ) {
54
71
 
72
+ width = Math.round( this.resolutionScale * width );
73
+ height = Math.round( this.resolutionScale * height );
74
+
55
75
  this.resolution.value.set( width, height );
56
76
  this._aoRenderTarget.setSize( width, height );
57
77
 
@@ -89,9 +109,24 @@ class GTAONode extends TempNode {
89
109
 
90
110
  const uvNode = uv();
91
111
 
92
- const sampleDepth = ( uv ) => this.depthNode.uv( uv ).x;
93
- const sampleNoise = ( uv ) => this.noiseNode.uv( uv );
94
- const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.uv( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this.cameraProjectionMatrixInverse );
112
+ const sampleDepth = ( uv ) => {
113
+
114
+ const depth = this.depthNode.uv( uv ).r;
115
+
116
+ if ( builder.renderer.logarithmicDepthBuffer === true ) {
117
+
118
+ const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
119
+
120
+ return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
121
+
122
+ }
123
+
124
+ return depth;
125
+
126
+ };
127
+
128
+ const sampleNoise = ( uv ) => this._noiseNode.uv( uv );
129
+ const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.uv( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
95
130
 
96
131
  const ao = Fn( () => {
97
132
 
@@ -99,12 +134,12 @@ class GTAONode extends TempNode {
99
134
 
100
135
  depth.greaterThanEqual( 1.0 ).discard();
101
136
 
102
- const viewPosition = getViewPosition( uvNode, depth, this.cameraProjectionMatrixInverse ).toVar();
137
+ const viewPosition = getViewPosition( uvNode, depth, this._cameraProjectionMatrixInverse ).toVar();
103
138
  const viewNormal = sampleNormal( uvNode ).toVar();
104
139
 
105
140
  const radiusToUse = this.radius;
106
141
 
107
- const noiseResolution = textureSize( this.noiseNode, 0 );
142
+ const noiseResolution = textureSize( this._noiseNode, 0 );
108
143
  let noiseUv = vec2( uvNode.x, uvNode.y.oneMinus() );
109
144
  noiseUv = noiseUv.mul( this.resolution.div( noiseResolution ) );
110
145
  const noiseTexel = sampleNoise( noiseUv );
@@ -113,8 +148,8 @@ class GTAONode extends TempNode {
113
148
  const bitangent = vec3( tangent.y.mul( - 1.0 ), tangent.x, 0.0 );
114
149
  const kernelMatrix = mat3( tangent, bitangent, vec3( 0.0, 0.0, 1.0 ) );
115
150
 
116
- const DIRECTIONS = this.SAMPLES.lessThan( 30 ).select( 3, 5 ).toVar();
117
- const STEPS = add( this.SAMPLES, DIRECTIONS.sub( 1 ) ).div( DIRECTIONS ).toVar();
151
+ const DIRECTIONS = this.samples.lessThan( 30 ).select( 3, 5 ).toVar();
152
+ const STEPS = add( this.samples, DIRECTIONS.sub( 1 ) ).div( DIRECTIONS ).toVar();
118
153
 
119
154
  const ao = float( 0 ).toVar();
120
155
 
@@ -138,9 +173,9 @@ class GTAONode extends TempNode {
138
173
 
139
174
  // x
140
175
 
141
- const sampleScreenPositionX = getScreenPosition( viewPosition.add( sampleViewOffset ), this.cameraProjectionMatrix ).toVar();
176
+ const sampleScreenPositionX = getScreenPosition( viewPosition.add( sampleViewOffset ), this._cameraProjectionMatrix ).toVar();
142
177
  const sampleDepthX = sampleDepth( sampleScreenPositionX ).toVar();
143
- const sampleSceneViewPositionX = getViewPosition( sampleScreenPositionX, sampleDepthX, this.cameraProjectionMatrixInverse ).toVar();
178
+ const sampleSceneViewPositionX = getViewPosition( sampleScreenPositionX, sampleDepthX, this._cameraProjectionMatrixInverse ).toVar();
144
179
  const viewDeltaX = sampleSceneViewPositionX.sub( viewPosition ).toVar();
145
180
 
146
181
  If( abs( viewDeltaX.z ).lessThan( this.thickness ), () => {
@@ -152,9 +187,9 @@ class GTAONode extends TempNode {
152
187
 
153
188
  // y
154
189
 
155
- const sampleScreenPositionY = getScreenPosition( viewPosition.sub( sampleViewOffset ), this.cameraProjectionMatrix ).toVar();
190
+ const sampleScreenPositionY = getScreenPosition( viewPosition.sub( sampleViewOffset ), this._cameraProjectionMatrix ).toVar();
156
191
  const sampleDepthY = sampleDepth( sampleScreenPositionY ).toVar();
157
- const sampleSceneViewPositionY = getViewPosition( sampleScreenPositionY, sampleDepthY, this.cameraProjectionMatrixInverse ).toVar();
192
+ const sampleSceneViewPositionY = getViewPosition( sampleScreenPositionY, sampleDepthY, this._cameraProjectionMatrixInverse ).toVar();
158
193
  const viewDeltaY = sampleSceneViewPositionY.sub( viewPosition ).toVar();
159
194
 
160
195
  If( abs( viewDeltaY.z ).lessThan( this.thickness ), () => {
@@ -183,10 +218,8 @@ class GTAONode extends TempNode {
183
218
 
184
219
  } );
185
220
 
186
- const material = this._material || ( this._material = new NodeMaterial() );
187
- material.fragmentNode = ao().context( builder.getSharedContext() );
188
- material.name = 'GTAO';
189
- material.needsUpdate = true;
221
+ this._material.fragmentNode = ao().context( builder.getSharedContext() );
222
+ this._material.needsUpdate = true;
190
223
 
191
224
  //
192
225
 
@@ -198,6 +231,8 @@ class GTAONode extends TempNode {
198
231
 
199
232
  this._aoRenderTarget.dispose();
200
233
 
234
+ this._material.dispose();
235
+
201
236
  }
202
237
 
203
238
  }
@@ -1,11 +1,10 @@
1
- import { RenderTarget, Vector2, PostProcessingUtils } from 'three';
2
- import { TempNode, nodeObject, Fn, If, float, NodeUpdateType, uv, uniform, convertToTexture, vec2, vec4, QuadMesh, passTexture, mul, NodeMaterial } from 'three/tsl';
1
+ import { RenderTarget, Vector2, NodeMaterial, PostProcessingUtils, QuadMesh, TempNode, NodeUpdateType } from 'three/webgpu';
2
+ import { nodeObject, Fn, If, float, uv, uniform, convertToTexture, vec2, vec4, passTexture, mul } from 'three/tsl';
3
3
 
4
4
  // WebGPU: The use of a single QuadMesh for both gaussian blur passes results in a single RenderObject with a SampledTexture binding that
5
5
  // alternates between source textures and triggers creation of new BindGroups and BindGroupLayouts every frame.
6
6
 
7
- const _quadMesh1 = /*@__PURE__*/ new QuadMesh();
8
- const _quadMesh2 = /*@__PURE__*/ new QuadMesh();
7
+ const _quadMesh = /*@__PURE__*/ new QuadMesh();
9
8
 
10
9
  let _rendererState;
11
10
 
@@ -108,8 +107,7 @@ class GaussianBlurNode extends TempNode {
108
107
 
109
108
  const currentTexture = textureNode.value;
110
109
 
111
- _quadMesh1.material = this._material;
112
- _quadMesh2.material = this._material;
110
+ _quadMesh.material = this._material;
113
111
 
114
112
  this.setSize( map.image.width, map.image.height );
115
113
 
@@ -124,7 +122,7 @@ class GaussianBlurNode extends TempNode {
124
122
 
125
123
  this._passDirection.value.set( 1, 0 );
126
124
 
127
- _quadMesh1.render( renderer );
125
+ _quadMesh.render( renderer );
128
126
 
129
127
  // vertical
130
128
 
@@ -133,7 +131,7 @@ class GaussianBlurNode extends TempNode {
133
131
 
134
132
  this._passDirection.value.set( 0, 1 );
135
133
 
136
- _quadMesh2.render( renderer );
134
+ _quadMesh.render( renderer );
137
135
 
138
136
  // restore
139
137
 
@@ -1,5 +1,5 @@
1
- import { RenderTarget, Vector2 } from 'three';
2
- import { convertToTexture, TempNode, nodeObject, Fn, NodeUpdateType, QuadMesh, PostProcessingUtils, NodeMaterial, passTexture, uv, vec2, vec3, vec4, max, float, sub, int, Loop, fract, pow, distance } from 'three/tsl';
1
+ import { RenderTarget, Vector2, TempNode, NodeUpdateType, QuadMesh, PostProcessingUtils, NodeMaterial } from 'three/webgpu';
2
+ import { convertToTexture, nodeObject, Fn, passTexture, uv, vec2, vec3, vec4, max, float, sub, int, Loop, fract, pow, distance } from 'three/tsl';
3
3
 
4
4
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
5
5
  const _size = /*@__PURE__*/ new Vector2();
@@ -20,7 +20,7 @@ class LensflareNode extends TempNode {
20
20
 
21
21
  constructor( textureNode, params = {} ) {
22
22
 
23
- super();
23
+ super( 'vec4' );
24
24
 
25
25
  this.textureNode = textureNode;
26
26