@plastic-software/three 0.178.0 → 0.179.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 (141) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +856 -196
  3. package/build/three.core.js +647 -123
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +211 -76
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +70 -21
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +1796 -557
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +1754 -557
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/jsm/Addons.js +1 -2
  14. package/examples/jsm/capabilities/WebGPU.js +1 -1
  15. package/examples/jsm/csm/CSMShadowNode.js +4 -4
  16. package/examples/jsm/environments/RoomEnvironment.js +8 -3
  17. package/examples/jsm/exporters/USDZExporter.js +676 -299
  18. package/examples/jsm/geometries/RoundedBoxGeometry.js +47 -8
  19. package/examples/jsm/interactive/HTMLMesh.js +5 -3
  20. package/examples/jsm/libs/meshopt_decoder.module.js +75 -58
  21. package/examples/jsm/lights/LightProbeGenerator.js +14 -3
  22. package/examples/jsm/loaders/EXRLoader.js +210 -22
  23. package/examples/jsm/loaders/FBXLoader.js +1 -1
  24. package/examples/jsm/loaders/MaterialXLoader.js +212 -30
  25. package/examples/jsm/loaders/TTFLoader.js +13 -1
  26. package/examples/jsm/loaders/USDLoader.js +219 -0
  27. package/examples/jsm/loaders/USDZLoader.js +4 -892
  28. package/examples/jsm/loaders/usd/USDAParser.js +741 -0
  29. package/examples/jsm/loaders/usd/USDCParser.js +17 -0
  30. package/examples/jsm/objects/LensflareMesh.js +3 -3
  31. package/examples/jsm/objects/SkyMesh.js +2 -2
  32. package/examples/jsm/physics/RapierPhysics.js +14 -5
  33. package/examples/jsm/postprocessing/GTAOPass.js +10 -9
  34. package/examples/jsm/postprocessing/OutlinePass.js +17 -17
  35. package/examples/jsm/postprocessing/SSAOPass.js +10 -9
  36. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +11 -2
  37. package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
  38. package/examples/jsm/tsl/display/BloomNode.js +8 -7
  39. package/examples/jsm/tsl/display/GaussianBlurNode.js +6 -8
  40. package/examples/jsm/tsl/display/{TRAAPassNode.js → TRAANode.js} +181 -172
  41. package/examples/jsm/tsl/lighting/TiledLightsNode.js +1 -1
  42. package/package.json +1 -1
  43. package/src/Three.Core.js +1 -0
  44. package/src/Three.TSL.js +69 -20
  45. package/src/animation/KeyframeTrack.js +1 -1
  46. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  47. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  48. package/src/cameras/Camera.js +14 -0
  49. package/src/cameras/OrthographicCamera.js +1 -1
  50. package/src/cameras/PerspectiveCamera.js +1 -1
  51. package/src/constants.js +1 -1
  52. package/{examples/jsm/misc → src/core}/Timer.js +4 -42
  53. package/src/extras/PMREMGenerator.js +11 -0
  54. package/src/helpers/CameraHelper.js +41 -11
  55. package/src/helpers/SkeletonHelper.js +35 -6
  56. package/src/lights/LightShadow.js +21 -8
  57. package/src/lights/PointLightShadow.js +1 -1
  58. package/src/loaders/FileLoader.js +25 -2
  59. package/src/loaders/ImageBitmapLoader.js +23 -0
  60. package/src/loaders/Loader.js +14 -0
  61. package/src/loaders/LoadingManager.js +23 -0
  62. package/src/materials/MeshBasicMaterial.js +1 -1
  63. package/src/materials/nodes/Line2NodeMaterial.js +0 -8
  64. package/src/materials/nodes/NodeMaterial.js +1 -1
  65. package/src/materials/nodes/PointsNodeMaterial.js +5 -0
  66. package/src/materials/nodes/manager/NodeMaterialObserver.js +87 -2
  67. package/src/math/Frustum.js +19 -8
  68. package/src/math/FrustumArray.js +10 -5
  69. package/src/math/Line3.js +129 -2
  70. package/src/math/Matrix4.js +48 -27
  71. package/src/math/Spherical.js +2 -2
  72. package/src/nodes/Nodes.js +1 -0
  73. package/src/nodes/TSL.js +1 -0
  74. package/src/nodes/accessors/Camera.js +12 -12
  75. package/src/nodes/accessors/Normal.js +11 -11
  76. package/src/nodes/accessors/ReferenceNode.js +18 -3
  77. package/src/nodes/accessors/SceneNode.js +1 -1
  78. package/src/nodes/accessors/StorageTextureNode.js +1 -1
  79. package/src/nodes/accessors/TextureNode.js +12 -0
  80. package/src/nodes/core/ArrayNode.js +12 -0
  81. package/src/nodes/core/AssignNode.js +3 -0
  82. package/src/nodes/core/ContextNode.js +20 -1
  83. package/src/nodes/core/Node.js +14 -2
  84. package/src/nodes/core/NodeBuilder.js +25 -20
  85. package/src/nodes/core/NodeUtils.js +4 -1
  86. package/src/nodes/core/StackNode.js +42 -0
  87. package/src/nodes/core/UniformNode.js +63 -5
  88. package/src/nodes/core/VarNode.js +91 -2
  89. package/src/nodes/display/PassNode.js +148 -2
  90. package/src/nodes/display/ViewportTextureNode.js +67 -7
  91. package/src/nodes/functions/PhysicalLightingModel.js +2 -2
  92. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  93. package/src/nodes/gpgpu/ComputeNode.js +67 -23
  94. package/src/nodes/gpgpu/WorkgroupInfoNode.js +28 -3
  95. package/src/nodes/lighting/ProjectorLightNode.js +19 -6
  96. package/src/nodes/lighting/ShadowFilterNode.js +1 -1
  97. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  98. package/src/nodes/materialx/lib/mx_noise.js +165 -1
  99. package/src/nodes/math/ConditionalNode.js +1 -1
  100. package/src/nodes/math/MathNode.js +78 -54
  101. package/src/nodes/math/OperatorNode.js +22 -22
  102. package/src/nodes/tsl/TSLCore.js +64 -9
  103. package/src/nodes/utils/DebugNode.js +1 -1
  104. package/src/nodes/utils/EventNode.js +83 -0
  105. package/src/nodes/utils/RTTNode.js +9 -0
  106. package/src/objects/BatchedMesh.js +4 -2
  107. package/src/renderers/WebGLRenderer.js +21 -22
  108. package/src/renderers/common/Bindings.js +19 -18
  109. package/src/renderers/common/Color4.js +2 -2
  110. package/src/renderers/common/PostProcessing.js +60 -5
  111. package/src/renderers/common/Renderer.js +18 -15
  112. package/src/renderers/common/SampledTexture.js +3 -71
  113. package/src/renderers/common/Sampler.js +79 -0
  114. package/src/renderers/common/Storage3DTexture.js +21 -0
  115. package/src/renderers/common/StorageArrayTexture.js +21 -0
  116. package/src/renderers/common/StorageTexture.js +19 -0
  117. package/src/renderers/common/Textures.js +19 -3
  118. package/src/renderers/common/XRManager.js +26 -8
  119. package/src/renderers/common/nodes/NodeSampledTexture.js +0 -12
  120. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +20 -2
  121. package/src/renderers/shaders/ShaderLib/depth.glsl.js +11 -2
  122. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  123. package/src/renderers/webgl/WebGLMaterials.js +6 -6
  124. package/src/renderers/webgl/WebGLProgram.js +22 -16
  125. package/src/renderers/webgl/WebGLPrograms.js +4 -4
  126. package/src/renderers/webgl/WebGLShadowMap.js +11 -1
  127. package/src/renderers/webgl/WebGLTextures.js +19 -7
  128. package/src/renderers/webgl-fallback/WebGLBackend.js +22 -12
  129. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +2 -2
  130. package/src/renderers/webgpu/WebGPUBackend.js +54 -15
  131. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +53 -73
  132. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +35 -31
  133. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +1 -1
  134. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +11 -64
  135. package/src/renderers/webgpu/utils/WebGPUUtils.js +2 -17
  136. package/src/renderers/webxr/WebXRDepthSensing.js +6 -10
  137. package/src/renderers/webxr/WebXRManager.js +68 -8
  138. package/src/textures/ExternalTexture.js +45 -0
  139. package/src/textures/FramebufferTexture.js +2 -2
  140. package/src/textures/Source.js +11 -1
  141. package/src/textures/VideoTexture.js +30 -2
@@ -1,6 +1,6 @@
1
1
  import { WebGLCoordinateSystem } from '../../constants.js';
2
2
  import TempNode from '../core/TempNode.js';
3
- import { addMethodChaining, Fn, int, nodeProxy } from '../tsl/TSLCore.js';
3
+ import { addMethodChaining, Fn, int, nodeProxyIntent } from '../tsl/TSLCore.js';
4
4
 
5
5
  const _vectorOperators = {
6
6
  '==': 'equal',
@@ -419,7 +419,7 @@ export default OperatorNode;
419
419
  * @param {...Node} params - Additional input parameters.
420
420
  * @returns {OperatorNode}
421
421
  */
422
- export const add = /*@__PURE__*/ nodeProxy( OperatorNode, '+' ).setParameterLength( 2, Infinity ).setName( 'add' );
422
+ export const add = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '+' ).setParameterLength( 2, Infinity ).setName( 'add' );
423
423
 
424
424
  /**
425
425
  * Returns the subtraction of two or more value.
@@ -431,7 +431,7 @@ export const add = /*@__PURE__*/ nodeProxy( OperatorNode, '+' ).setParameterLeng
431
431
  * @param {...Node} params - Additional input parameters.
432
432
  * @returns {OperatorNode}
433
433
  */
434
- export const sub = /*@__PURE__*/ nodeProxy( OperatorNode, '-' ).setParameterLength( 2, Infinity ).setName( 'sub' );
434
+ export const sub = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '-' ).setParameterLength( 2, Infinity ).setName( 'sub' );
435
435
 
436
436
  /**
437
437
  * Returns the multiplication of two or more value.
@@ -443,7 +443,7 @@ export const sub = /*@__PURE__*/ nodeProxy( OperatorNode, '-' ).setParameterLeng
443
443
  * @param {...Node} params - Additional input parameters.
444
444
  * @returns {OperatorNode}
445
445
  */
446
- export const mul = /*@__PURE__*/ nodeProxy( OperatorNode, '*' ).setParameterLength( 2, Infinity ).setName( 'mul' );
446
+ export const mul = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '*' ).setParameterLength( 2, Infinity ).setName( 'mul' );
447
447
 
448
448
  /**
449
449
  * Returns the division of two or more value.
@@ -455,7 +455,7 @@ export const mul = /*@__PURE__*/ nodeProxy( OperatorNode, '*' ).setParameterLeng
455
455
  * @param {...Node} params - Additional input parameters.
456
456
  * @returns {OperatorNode}
457
457
  */
458
- export const div = /*@__PURE__*/ nodeProxy( OperatorNode, '/' ).setParameterLength( 2, Infinity ).setName( 'div' );
458
+ export const div = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '/' ).setParameterLength( 2, Infinity ).setName( 'div' );
459
459
 
460
460
  /**
461
461
  * Computes the remainder of dividing the first node by the second one.
@@ -466,7 +466,7 @@ export const div = /*@__PURE__*/ nodeProxy( OperatorNode, '/' ).setParameterLeng
466
466
  * @param {Node} b - The second input.
467
467
  * @returns {OperatorNode}
468
468
  */
469
- export const mod = /*@__PURE__*/ nodeProxy( OperatorNode, '%' ).setParameterLength( 2 ).setName( 'mod' );
469
+ export const mod = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '%' ).setParameterLength( 2 ).setName( 'mod' );
470
470
 
471
471
  /**
472
472
  * Checks if two nodes are equal.
@@ -477,7 +477,7 @@ export const mod = /*@__PURE__*/ nodeProxy( OperatorNode, '%' ).setParameterLeng
477
477
  * @param {Node} b - The second input.
478
478
  * @returns {OperatorNode}
479
479
  */
480
- export const equal = /*@__PURE__*/ nodeProxy( OperatorNode, '==' ).setParameterLength( 2 ).setName( 'equal' );
480
+ export const equal = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '==' ).setParameterLength( 2 ).setName( 'equal' );
481
481
 
482
482
  /**
483
483
  * Checks if two nodes are not equal.
@@ -488,7 +488,7 @@ export const equal = /*@__PURE__*/ nodeProxy( OperatorNode, '==' ).setParameterL
488
488
  * @param {Node} b - The second input.
489
489
  * @returns {OperatorNode}
490
490
  */
491
- export const notEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '!=' ).setParameterLength( 2 ).setName( 'notEqual' );
491
+ export const notEqual = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '!=' ).setParameterLength( 2 ).setName( 'notEqual' );
492
492
 
493
493
  /**
494
494
  * Checks if the first node is less than the second.
@@ -499,7 +499,7 @@ export const notEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '!=' ).setParamet
499
499
  * @param {Node} b - The second input.
500
500
  * @returns {OperatorNode}
501
501
  */
502
- export const lessThan = /*@__PURE__*/ nodeProxy( OperatorNode, '<' ).setParameterLength( 2 ).setName( 'lessThan' );
502
+ export const lessThan = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '<' ).setParameterLength( 2 ).setName( 'lessThan' );
503
503
 
504
504
  /**
505
505
  * Checks if the first node is greater than the second.
@@ -510,7 +510,7 @@ export const lessThan = /*@__PURE__*/ nodeProxy( OperatorNode, '<' ).setParamete
510
510
  * @param {Node} b - The second input.
511
511
  * @returns {OperatorNode}
512
512
  */
513
- export const greaterThan = /*@__PURE__*/ nodeProxy( OperatorNode, '>' ).setParameterLength( 2 ).setName( 'greaterThan' );
513
+ export const greaterThan = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '>' ).setParameterLength( 2 ).setName( 'greaterThan' );
514
514
 
515
515
  /**
516
516
  * Checks if the first node is less than or equal to the second.
@@ -521,7 +521,7 @@ export const greaterThan = /*@__PURE__*/ nodeProxy( OperatorNode, '>' ).setParam
521
521
  * @param {Node} b - The second input.
522
522
  * @returns {OperatorNode}
523
523
  */
524
- export const lessThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '<=' ).setParameterLength( 2 ).setName( 'lessThanEqual' );
524
+ export const lessThanEqual = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '<=' ).setParameterLength( 2 ).setName( 'lessThanEqual' );
525
525
 
526
526
  /**
527
527
  * Checks if the first node is greater than or equal to the second.
@@ -532,7 +532,7 @@ export const lessThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '<=' ).setPa
532
532
  * @param {Node} b - The second input.
533
533
  * @returns {OperatorNode}
534
534
  */
535
- export const greaterThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '>=' ).setParameterLength( 2 ).setName( 'greaterThanEqual' );
535
+ export const greaterThanEqual = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '>=' ).setParameterLength( 2 ).setName( 'greaterThanEqual' );
536
536
 
537
537
  /**
538
538
  * Performs a logical AND operation on multiple nodes.
@@ -542,7 +542,7 @@ export const greaterThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '>=' ).se
542
542
  * @param {...Node} nodes - The input nodes to be combined using AND.
543
543
  * @returns {OperatorNode}
544
544
  */
545
- export const and = /*@__PURE__*/ nodeProxy( OperatorNode, '&&' ).setParameterLength( 2, Infinity ).setName( 'and' );
545
+ export const and = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '&&' ).setParameterLength( 2, Infinity ).setName( 'and' );
546
546
 
547
547
  /**
548
548
  * Performs a logical OR operation on multiple nodes.
@@ -552,7 +552,7 @@ export const and = /*@__PURE__*/ nodeProxy( OperatorNode, '&&' ).setParameterLen
552
552
  * @param {...Node} nodes - The input nodes to be combined using OR.
553
553
  * @returns {OperatorNode}
554
554
  */
555
- export const or = /*@__PURE__*/ nodeProxy( OperatorNode, '||' ).setParameterLength( 2, Infinity ).setName( 'or' );
555
+ export const or = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '||' ).setParameterLength( 2, Infinity ).setName( 'or' );
556
556
 
557
557
  /**
558
558
  * Performs logical NOT on a node.
@@ -562,7 +562,7 @@ export const or = /*@__PURE__*/ nodeProxy( OperatorNode, '||' ).setParameterLeng
562
562
  * @param {Node} value - The value.
563
563
  * @returns {OperatorNode}
564
564
  */
565
- export const not = /*@__PURE__*/ nodeProxy( OperatorNode, '!' ).setParameterLength( 1 ).setName( 'not' );
565
+ export const not = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '!' ).setParameterLength( 1 ).setName( 'not' );
566
566
 
567
567
  /**
568
568
  * Performs logical XOR on two nodes.
@@ -573,7 +573,7 @@ export const not = /*@__PURE__*/ nodeProxy( OperatorNode, '!' ).setParameterLeng
573
573
  * @param {Node} b - The second input.
574
574
  * @returns {OperatorNode}
575
575
  */
576
- export const xor = /*@__PURE__*/ nodeProxy( OperatorNode, '^^' ).setParameterLength( 2 ).setName( 'xor' );
576
+ export const xor = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '^^' ).setParameterLength( 2 ).setName( 'xor' );
577
577
 
578
578
  /**
579
579
  * Performs bitwise AND on two nodes.
@@ -584,7 +584,7 @@ export const xor = /*@__PURE__*/ nodeProxy( OperatorNode, '^^' ).setParameterLen
584
584
  * @param {Node} b - The second input.
585
585
  * @returns {OperatorNode}
586
586
  */
587
- export const bitAnd = /*@__PURE__*/ nodeProxy( OperatorNode, '&' ).setParameterLength( 2 ).setName( 'bitAnd' );
587
+ export const bitAnd = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '&' ).setParameterLength( 2 ).setName( 'bitAnd' );
588
588
 
589
589
  /**
590
590
  * Performs bitwise NOT on a node.
@@ -595,7 +595,7 @@ export const bitAnd = /*@__PURE__*/ nodeProxy( OperatorNode, '&' ).setParameterL
595
595
  * @param {Node} b - The second input.
596
596
  * @returns {OperatorNode}
597
597
  */
598
- export const bitNot = /*@__PURE__*/ nodeProxy( OperatorNode, '~' ).setParameterLength( 2 ).setName( 'bitNot' );
598
+ export const bitNot = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '~' ).setParameterLength( 2 ).setName( 'bitNot' );
599
599
 
600
600
  /**
601
601
  * Performs bitwise OR on two nodes.
@@ -606,7 +606,7 @@ export const bitNot = /*@__PURE__*/ nodeProxy( OperatorNode, '~' ).setParameterL
606
606
  * @param {Node} b - The second input.
607
607
  * @returns {OperatorNode}
608
608
  */
609
- export const bitOr = /*@__PURE__*/ nodeProxy( OperatorNode, '|' ).setParameterLength( 2 ).setName( 'bitOr' );
609
+ export const bitOr = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '|' ).setParameterLength( 2 ).setName( 'bitOr' );
610
610
 
611
611
  /**
612
612
  * Performs bitwise XOR on two nodes.
@@ -617,7 +617,7 @@ export const bitOr = /*@__PURE__*/ nodeProxy( OperatorNode, '|' ).setParameterLe
617
617
  * @param {Node} b - The second input.
618
618
  * @returns {OperatorNode}
619
619
  */
620
- export const bitXor = /*@__PURE__*/ nodeProxy( OperatorNode, '^' ).setParameterLength( 2 ).setName( 'bitXor' );
620
+ export const bitXor = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '^' ).setParameterLength( 2 ).setName( 'bitXor' );
621
621
 
622
622
  /**
623
623
  * Shifts a node to the left.
@@ -628,7 +628,7 @@ export const bitXor = /*@__PURE__*/ nodeProxy( OperatorNode, '^' ).setParameterL
628
628
  * @param {Node} b - The value to shift.
629
629
  * @returns {OperatorNode}
630
630
  */
631
- export const shiftLeft = /*@__PURE__*/ nodeProxy( OperatorNode, '<<' ).setParameterLength( 2 ).setName( 'shiftLeft' );
631
+ export const shiftLeft = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '<<' ).setParameterLength( 2 ).setName( 'shiftLeft' );
632
632
 
633
633
  /**
634
634
  * Shifts a node to the right.
@@ -639,7 +639,7 @@ export const shiftLeft = /*@__PURE__*/ nodeProxy( OperatorNode, '<<' ).setParame
639
639
  * @param {Node} b - The value to shift.
640
640
  * @returns {OperatorNode}
641
641
  */
642
- export const shiftRight = /*@__PURE__*/ nodeProxy( OperatorNode, '>>' ).setParameterLength( 2 ).setName( 'shiftRight' );
642
+ export const shiftRight = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '>>' ).setParameterLength( 2 ).setName( 'shiftRight' );
643
643
 
644
644
  /**
645
645
  * Increments a node by 1.
@@ -61,6 +61,10 @@ const shaderNodeHandler = {
61
61
 
62
62
  return node.isStackNode ? ( ...params ) => nodeObj.add( nodeElement( ...params ) ) : ( ...params ) => nodeElement( nodeObj, ...params );
63
63
 
64
+ } else if ( prop === 'toVarIntent' ) {
65
+
66
+ return () => nodeObj;
67
+
64
68
  } else if ( prop === 'self' ) {
65
69
 
66
70
  return node;
@@ -211,7 +215,28 @@ const ShaderNodeArray = function ( array, altType = null ) {
211
215
 
212
216
  const ShaderNodeProxy = function ( NodeClass, scope = null, factor = null, settings = null ) {
213
217
 
214
- const assignNode = ( node ) => nodeObject( settings !== null ? Object.assign( node, settings ) : node );
218
+ function assignNode( node ) {
219
+
220
+ if ( settings !== null ) {
221
+
222
+ node = nodeObject( Object.assign( node, settings ) );
223
+
224
+ if ( settings.intent === true ) {
225
+
226
+ node = node.toVarIntent();
227
+
228
+ }
229
+
230
+ } else {
231
+
232
+ node = nodeObject( node );
233
+
234
+ }
235
+
236
+ return node;
237
+
238
+
239
+ }
215
240
 
216
241
  let fn, name = scope, minParams, maxParams;
217
242
 
@@ -371,8 +396,36 @@ class ShaderCallNodeInternal extends Node {
371
396
 
372
397
  } else {
373
398
 
399
+ let inputs = inputNodes;
400
+
401
+ if ( Array.isArray( inputs ) ) {
402
+
403
+ // If inputs is an array, we need to convert it to a Proxy
404
+ // so we can call TSL functions using the syntax `Fn( ( { r, g, b } ) => { ... } )`
405
+ // and call through `fn( 0, 1, 0 )` or `fn( { r: 0, g: 1, b: 0 } )`
406
+
407
+ let index = 0;
408
+
409
+ inputs = new Proxy( inputs, {
410
+ get: ( target, property, receiver ) => {
411
+
412
+ if ( target[ property ] === undefined ) {
413
+
414
+ return target[ index ++ ];
415
+
416
+ } else {
417
+
418
+ return Reflect.get( target, property, receiver );
419
+
420
+ }
421
+
422
+ }
423
+ } );
424
+
425
+ }
426
+
374
427
  const jsFunc = shaderNode.jsFunc;
375
- const outputNode = inputNodes !== null || jsFunc.length > 1 ? jsFunc( inputNodes || [], builder ) : jsFunc( builder );
428
+ const outputNode = inputs !== null || jsFunc.length > 1 ? jsFunc( inputs || [], builder ) : jsFunc( builder );
376
429
 
377
430
  result = nodeObject( outputNode );
378
431
 
@@ -566,20 +619,20 @@ const ConvertType = function ( type, cacheMap = null ) {
566
619
 
567
620
  if ( params.length === 1 && cacheMap !== null && cacheMap.has( params[ 0 ] ) ) {
568
621
 
569
- return nodeObject( cacheMap.get( params[ 0 ] ) );
622
+ return nodeObjectIntent( cacheMap.get( params[ 0 ] ) );
570
623
 
571
624
  }
572
625
 
573
626
  if ( params.length === 1 ) {
574
627
 
575
628
  const node = getConstNode( params[ 0 ], type );
576
- if ( node.nodeType === type ) return nodeObject( node );
577
- return nodeObject( new ConvertNode( node, type ) );
629
+ if ( node.nodeType === type ) return nodeObjectIntent( node );
630
+ return nodeObjectIntent( new ConvertNode( node, type ) );
578
631
 
579
632
  }
580
633
 
581
634
  const nodes = params.map( param => getConstNode( param ) );
582
- return nodeObject( new JoinNode( nodes, type ) );
635
+ return nodeObjectIntent( new JoinNode( nodes, type ) );
583
636
 
584
637
  };
585
638
 
@@ -602,10 +655,12 @@ export function ShaderNode( jsFunc, nodeType ) {
602
655
  }
603
656
 
604
657
  export const nodeObject = ( val, altType = null ) => /* new */ ShaderNodeObject( val, altType );
658
+ export const nodeObjectIntent = ( val, altType = null ) => /* new */ nodeObject( val, altType ).toVarIntent();
605
659
  export const nodeObjects = ( val, altType = null ) => new ShaderNodeObjects( val, altType );
606
660
  export const nodeArray = ( val, altType = null ) => new ShaderNodeArray( val, altType );
607
- export const nodeProxy = ( ...params ) => new ShaderNodeProxy( ...params );
608
- export const nodeImmutable = ( ...params ) => new ShaderNodeImmutable( ...params );
661
+ export const nodeProxy = ( NodeClass, scope = null, factor = null, settings = null ) => new ShaderNodeProxy( NodeClass, scope, factor, settings );
662
+ export const nodeImmutable = ( NodeClass, ...params ) => new ShaderNodeImmutable( NodeClass, ...params );
663
+ export const nodeProxyIntent = ( NodeClass, scope = null, factor = null, settings = {} ) => new ShaderNodeProxy( NodeClass, scope, factor, { intent: true, ...settings } );
609
664
 
610
665
  let fnId = 0;
611
666
 
@@ -661,7 +716,7 @@ export const Fn = ( jsFunc, layout = null ) => {
661
716
 
662
717
  if ( nodeType === 'void' ) fnCall.toStack();
663
718
 
664
- return fnCall;
719
+ return fnCall.toVarIntent();
665
720
 
666
721
  };
667
722
 
@@ -77,6 +77,6 @@ export default DebugNode;
77
77
  * @param {?Function} [callback=null] - Optional callback function to handle the debug output.
78
78
  * @returns {DebugNode}
79
79
  */
80
- export const debug = ( node, callback = null ) => nodeObject( new DebugNode( nodeObject( node ), callback ) );
80
+ export const debug = ( node, callback = null ) => nodeObject( new DebugNode( nodeObject( node ), callback ) ).toStack();
81
81
 
82
82
  addMethodChaining( 'debug', debug );
@@ -0,0 +1,83 @@
1
+ import Node from '../core/Node.js';
2
+ import { NodeUpdateType } from '../core/constants.js';
3
+ import { nodeObject } from '../tsl/TSLCore.js';
4
+
5
+ /**
6
+ * EventNode is a node that executes a callback during specific update phases.
7
+ *
8
+ * @augments Node
9
+ */
10
+ class EventNode extends Node {
11
+
12
+ static get type() {
13
+
14
+ return 'EventNode';
15
+
16
+ }
17
+
18
+ /**
19
+ * Creates an EventNode.
20
+ *
21
+ * @param {string} eventType - The type of event
22
+ * @param {Function} callback - The callback to execute on update.
23
+ */
24
+ constructor( eventType, callback ) {
25
+
26
+ super( 'void' );
27
+
28
+ this.eventType = eventType;
29
+ this.callback = callback;
30
+
31
+ if ( eventType === EventNode.OBJECT ) {
32
+
33
+ this.updateType = NodeUpdateType.OBJECT;
34
+
35
+ } else if ( eventType === EventNode.MATERIAL ) {
36
+
37
+ this.updateType = NodeUpdateType.RENDER;
38
+
39
+ }
40
+
41
+ }
42
+
43
+ update( frame ) {
44
+
45
+ this.callback( frame );
46
+
47
+ }
48
+
49
+ }
50
+
51
+ EventNode.OBJECT = 'object';
52
+ EventNode.MATERIAL = 'material';
53
+
54
+ export default EventNode;
55
+
56
+ /**
57
+ * Helper to create an EventNode and add it to the stack.
58
+ *
59
+ * @param {string} type - The event type.
60
+ * @param {Function} callback - The callback function.
61
+ * @returns {EventNode}
62
+ */
63
+ const createEvent = ( type, callback ) => nodeObject( new EventNode( type, callback ) ).toStack();
64
+
65
+ /**
66
+ * Creates an event that triggers a function every time an object (Mesh|Sprite) is rendered.
67
+ *
68
+ * The event will be bound to the declared TSL function `Fn()`; it must be declared within a `Fn()` or the JS function call must be inherited from one.
69
+ *
70
+ * @param {Function} callback - The callback function.
71
+ * @returns {EventNode}
72
+ */
73
+ export const OnObjectUpdate = ( callback ) => createEvent( EventNode.OBJECT, callback );
74
+
75
+ /**
76
+ * Creates an event that triggers a function when the first object that uses the material is rendered.
77
+ *
78
+ * The event will be bound to the declared TSL function `Fn()`; it must be declared within a `Fn()` or the JS function call must be inherited from one.
79
+ *
80
+ * @param {Function} callback - The callback function.
81
+ * @returns {EventNode}
82
+ */
83
+ export const OnMaterialUpdate = ( callback ) => createEvent( EventNode.MATERIAL, callback );
@@ -41,6 +41,15 @@ class RTTNode extends TextureNode {
41
41
 
42
42
  super( renderTarget.texture, uv() );
43
43
 
44
+ /**
45
+ * This flag can be used for type testing.
46
+ *
47
+ * @type {boolean}
48
+ * @readonly
49
+ * @default true
50
+ */
51
+ this.isRTTNode = true;
52
+
44
53
  /**
45
54
  * The node to render a texture with.
46
55
  *
@@ -1251,7 +1251,7 @@ class BatchedMesh extends Mesh {
1251
1251
  const availableInstanceIds = this._availableInstanceIds;
1252
1252
  const instanceInfo = this._instanceInfo;
1253
1253
  availableInstanceIds.sort( ascIdSort );
1254
- while ( availableInstanceIds[ availableInstanceIds.length - 1 ] === instanceInfo.length ) {
1254
+ while ( availableInstanceIds[ availableInstanceIds.length - 1 ] === instanceInfo.length - 1 ) {
1255
1255
 
1256
1256
  instanceInfo.pop();
1257
1257
  availableInstanceIds.pop();
@@ -1529,9 +1529,11 @@ class BatchedMesh extends Mesh {
1529
1529
  _matrix
1530
1530
  .multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse )
1531
1531
  .multiply( this.matrixWorld );
1532
+
1532
1533
  _frustum.setFromProjectionMatrix(
1533
1534
  _matrix,
1534
- renderer.coordinateSystem
1535
+ camera.coordinateSystem,
1536
+ camera.reversedDepth
1535
1537
  );
1536
1538
 
1537
1539
  }
@@ -52,7 +52,7 @@ import { WebGLUtils } from './webgl/WebGLUtils.js';
52
52
  import { WebXRManager } from './webxr/WebXRManager.js';
53
53
  import { WebGLMaterials } from './webgl/WebGLMaterials.js';
54
54
  import { WebGLUniformsGroups } from './webgl/WebGLUniformsGroups.js';
55
- import { createCanvasElement, probeAsync, toNormalizedProjectionMatrix, toReversedProjectionMatrix, warnOnce } from '../utils.js';
55
+ import { createCanvasElement, probeAsync, warnOnce } from '../utils.js';
56
56
  import { ColorManagement } from '../math/ColorManagement.js';
57
57
 
58
58
  /**
@@ -80,7 +80,7 @@ class WebGLRenderer {
80
80
  preserveDrawingBuffer = false,
81
81
  powerPreference = 'default',
82
82
  failIfMajorPerformanceCaveat = false,
83
- reverseDepthBuffer = false,
83
+ reversedDepthBuffer = false,
84
84
  } = parameters;
85
85
 
86
86
  /**
@@ -313,7 +313,6 @@ class WebGLRenderer {
313
313
 
314
314
  // camera matrices cache
315
315
 
316
- const _currentProjectionMatrix = new Matrix4();
317
316
  const _projScreenMatrix = new Matrix4();
318
317
 
319
318
  const _vector3 = new Vector3();
@@ -409,7 +408,7 @@ class WebGLRenderer {
409
408
 
410
409
  state = new WebGLState( _gl, extensions );
411
410
 
412
- if ( capabilities.reverseDepthBuffer && reverseDepthBuffer ) {
411
+ if ( capabilities.reversedDepthBuffer && reversedDepthBuffer ) {
413
412
 
414
413
  state.buffers.depth.setReversed( true );
415
414
 
@@ -1557,7 +1556,7 @@ class WebGLRenderer {
1557
1556
  renderStateStack.push( currentRenderState );
1558
1557
 
1559
1558
  _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
1560
- _frustum.setFromProjectionMatrix( _projScreenMatrix );
1559
+ _frustum.setFromProjectionMatrix( _projScreenMatrix, WebGLCoordinateSystem, camera.reversedDepth );
1561
1560
 
1562
1561
  _localClippingEnabled = this.localClippingEnabled;
1563
1562
  _clippingEnabled = clipping.init( this.clippingPlanes, _localClippingEnabled );
@@ -2388,23 +2387,17 @@ class WebGLRenderer {
2388
2387
 
2389
2388
  // common camera uniforms
2390
2389
 
2391
- const reverseDepthBuffer = state.buffers.depth.getReversed();
2390
+ const reversedDepthBuffer = state.buffers.depth.getReversed();
2392
2391
 
2393
- if ( reverseDepthBuffer ) {
2392
+ if ( reversedDepthBuffer && camera.reversedDepth !== true ) {
2394
2393
 
2395
- _currentProjectionMatrix.copy( camera.projectionMatrix );
2396
-
2397
- toNormalizedProjectionMatrix( _currentProjectionMatrix );
2398
- toReversedProjectionMatrix( _currentProjectionMatrix );
2399
-
2400
- p_uniforms.setValue( _gl, 'projectionMatrix', _currentProjectionMatrix );
2401
-
2402
- } else {
2403
-
2404
- p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
2394
+ camera._reversedDepth = true;
2395
+ camera.updateProjectionMatrix();
2405
2396
 
2406
2397
  }
2407
2398
 
2399
+ p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
2400
+
2408
2401
  p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
2409
2402
 
2410
2403
  const uCamPos = p_uniforms.map.cameraPosition;
@@ -2834,9 +2827,15 @@ class WebGLRenderer {
2834
2827
 
2835
2828
  } else if ( isRenderTarget3D ) {
2836
2829
 
2837
- const textureProperties = properties.get( renderTarget.texture );
2838
2830
  const layer = activeCubeFace;
2839
- _gl.framebufferTextureLayer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel, layer );
2831
+
2832
+ for ( let i = 0; i < renderTarget.textures.length; i ++ ) {
2833
+
2834
+ const textureProperties = properties.get( renderTarget.textures[ i ] );
2835
+
2836
+ _gl.framebufferTextureLayer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, textureProperties.__webglTexture, activeMipmapLevel, layer );
2837
+
2838
+ }
2840
2839
 
2841
2840
  } else if ( renderTarget !== null && activeMipmapLevel !== 0 ) {
2842
2841
 
@@ -2988,7 +2987,7 @@ class WebGLRenderer {
2988
2987
  _gl.bindBuffer( _gl.PIXEL_PACK_BUFFER, glBuffer );
2989
2988
  _gl.bufferData( _gl.PIXEL_PACK_BUFFER, buffer.byteLength, _gl.STREAM_READ );
2990
2989
 
2991
- // when using MRT, select the corect color buffer for the subsequent read command
2990
+ // when using MRT, select the correct color buffer for the subsequent read command
2992
2991
 
2993
2992
  if ( renderTarget.textures.length > 1 ) _gl.readBuffer( _gl.COLOR_ATTACHMENT0 + textureIndex );
2994
2993
 
@@ -3453,7 +3452,7 @@ class WebGLRenderer {
3453
3452
  * @property {boolean} [depth=true] Whether the drawing buffer has a depth buffer of at least 16 bits.
3454
3453
  * @property {boolean} [logarithmicDepthBuffer=false] Whether to use a logarithmic depth buffer. It may be necessary to use this if dealing with huge differences in scale in a single scene.
3455
3454
  * Note that this setting uses `gl_FragDepth` if available which disables the Early Fragment Test optimization and can cause a decrease in performance.
3456
- * @property {boolean} [reverseDepthBuffer=false] Whether to use a reverse depth buffer. Requires the `EXT_clip_control` extension.
3455
+ * @property {boolean} [reversedDepthBuffer=false] Whether to use a reverse depth buffer. Requires the `EXT_clip_control` extension.
3457
3456
  * This is a more faster and accurate version than logarithmic depth buffer.
3458
3457
  **/
3459
3458
 
@@ -3474,7 +3473,7 @@ class WebGLRenderer {
3474
3473
  * @property {number} maxVertexTextures - The number of textures that can be used in a vertex shader.
3475
3474
  * @property {number} maxVertexUniforms - The maximum number of uniforms that can be used in a vertex shader.
3476
3475
  * @property {string} precision - The shader precision currently being used by the renderer.
3477
- * @property {boolean} reverseDepthBuffer - `true` if `reverseDepthBuffer` was set to `true` in the constructor
3476
+ * @property {boolean} reversedDepthBuffer - `true` if `reversedDepthBuffer` was set to `true` in the constructor
3478
3477
  * and the rendering context supports `EXT_clip_control`.
3479
3478
  * @property {boolean} vertexTextures - `true` if vertex textures can be used.
3480
3479
  **/
@@ -244,24 +244,31 @@ class Bindings extends DataMap {
244
244
 
245
245
  }
246
246
 
247
- } else if ( binding.isSampler ) {
248
-
249
- binding.update();
250
-
251
247
  } else if ( binding.isSampledTexture ) {
252
248
 
253
- const texturesTextureData = this.textures.get( binding.texture );
254
-
255
- if ( binding.needsBindingsUpdate( texturesTextureData.generation ) ) needsBindingsUpdate = true;
256
-
257
249
  const updated = binding.update();
258
250
 
251
+ // get the texture data after the update, to sync the texture reference from node
252
+
259
253
  const texture = binding.texture;
254
+ const texturesTextureData = this.textures.get( texture );
260
255
 
261
256
  if ( updated ) {
262
257
 
258
+ // version: update the texture data or create a new one
259
+
263
260
  this.textures.updateTexture( texture );
264
261
 
262
+ // generation: update the bindings if a new texture has been created
263
+
264
+ if ( binding.generation !== texturesTextureData.generation ) {
265
+
266
+ binding.generation = texturesTextureData.generation;
267
+
268
+ needsBindingsUpdate = true;
269
+
270
+ }
271
+
265
272
  }
266
273
 
267
274
  const textureData = backend.get( texture );
@@ -277,16 +284,6 @@ class Bindings extends DataMap {
277
284
 
278
285
  }
279
286
 
280
- if ( backend.isWebGPUBackend === true && textureData.texture === undefined && textureData.externalTexture === undefined ) {
281
-
282
- // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend
283
- console.error( 'Bindings._update: binding should be available:', binding, updated, texture, binding.textureNode.value, needsBindingsUpdate );
284
-
285
- this.textures.updateTexture( texture );
286
- needsBindingsUpdate = true;
287
-
288
- }
289
-
290
287
  if ( texture.isStorageTexture === true ) {
291
288
 
292
289
  const textureData = this.get( texture );
@@ -305,6 +302,10 @@ class Bindings extends DataMap {
305
302
 
306
303
  }
307
304
 
305
+ } else if ( binding.isSampler ) {
306
+
307
+ binding.update();
308
+
308
309
  }
309
310
 
310
311
  }
@@ -34,8 +34,8 @@ class Color4 extends Color {
34
34
  * string argument to this method.
35
35
  *
36
36
  * @param {number|string|Color} r - The red value.
37
- * @param {number} g - The green value.
38
- * @param {number} b - The blue value.
37
+ * @param {number} [g] - The green value.
38
+ * @param {number} [b] - The blue value.
39
39
  * @param {number} [a=1] - The alpha value.
40
40
  * @return {Color4} A reference to this object.
41
41
  */