@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
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  import { Color, Vector2, Vector3, Vector4, Matrix2, Matrix3, Matrix4, EventDispatcher, MathUtils, WebGLCoordinateSystem, WebGPUCoordinateSystem, ColorManagement, SRGBTransfer, NoToneMapping, StaticDrawUsage, InterleavedBuffer, InterleavedBufferAttribute, DynamicDrawUsage, NoColorSpace, Texture, UnsignedIntType, IntType, NearestFilter, Sphere, BackSide, DoubleSide, Euler, CubeTexture, CubeReflectionMapping, CubeRefractionMapping, TangentSpaceNormalMap, ObjectSpaceNormalMap, InstancedInterleavedBuffer, InstancedBufferAttribute, DataArrayTexture, FloatType, FramebufferTexture, LinearMipmapLinearFilter, DepthTexture, Material, NormalBlending, LineBasicMaterial, LineDashedMaterial, NoBlending, MeshNormalMaterial, SRGBColorSpace, WebGLCubeRenderTarget, BoxGeometry, Mesh, Scene, LinearFilter, CubeCamera, EquirectangularReflectionMapping, EquirectangularRefractionMapping, AddOperation, MixOperation, MultiplyOperation, MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, OrthographicCamera, PerspectiveCamera, RenderTarget, LinearSRGBColorSpace, RGBAFormat, HalfFloatType, CubeUVReflectionMapping, BufferGeometry, BufferAttribute, MeshStandardMaterial, MeshPhysicalMaterial, MeshToonMaterial, MeshMatcapMaterial, SpriteMaterial, PointsMaterial, ShadowMaterial, Uint32BufferAttribute, Uint16BufferAttribute, arrayNeedsUint32, Camera, DepthStencilFormat, DepthFormat, UnsignedInt248Type, UnsignedByteType, Plane, Object3D, LinearMipMapLinearFilter, Float32BufferAttribute, UVMapping, VSMShadowMap, LessCompare, RGFormat, BasicShadowMap, SphereGeometry, LinearMipmapNearestFilter, NearestMipmapLinearFilter, Float16BufferAttribute, REVISION, ArrayCamera, PlaneGeometry, FrontSide, CustomBlending, AddEquation, ZeroFactor, CylinderGeometry, Quaternion, WebXRController, RAD2DEG, PCFShadowMap, FrustumArray, Frustum, DataTexture, RedIntegerFormat, RedFormat, ShortType, ByteType, UnsignedShortType, RGIntegerFormat, RGBIntegerFormat, RGBFormat, RGBAIntegerFormat, warnOnce, createCanvasElement, ReverseSubtractEquation, SubtractEquation, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, DstAlphaFactor, DstColorFactor, SrcAlphaSaturateFactor, SrcAlphaFactor, SrcColorFactor, OneFactor, CullFaceNone, CullFaceBack, CullFaceFront, MultiplyBlending, SubtractiveBlending, AdditiveBlending, NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessEqualDepth, LessDepth, AlwaysDepth, NeverDepth, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt5999Type, AlphaFormat, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, NearestMipmapNearestFilter, NotEqualCompare, GreaterCompare, GreaterEqualCompare, EqualCompare, LessEqualCompare, AlwaysCompare, NeverCompare, LinearTransfer, NotEqualStencilFunc, GreaterStencilFunc, GreaterEqualStencilFunc, EqualStencilFunc, LessEqualStencilFunc, LessStencilFunc, AlwaysStencilFunc, NeverStencilFunc, DecrementWrapStencilOp, IncrementWrapStencilOp, DecrementStencilOp, IncrementStencilOp, InvertStencilOp, ReplaceStencilOp, ZeroStencilOp, KeepStencilOp, MaxEquation, MinEquation, SpotLight, PointLight, DirectionalLight, RectAreaLight, AmbientLight, HemisphereLight, LightProbe, LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping, Group, Loader, FileLoader, MaterialLoader, ObjectLoader } from './three.core.js';
7
- export { AdditiveAnimationBlendMode, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BasicDepthPacking, BatchedMesh, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxHelper, BufferGeometryLoader, Cache, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CircleGeometry, Clock, ColorKeyframeTrack, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, ConstantAlphaFactor, ConstantColorFactor, Controls, CubeTextureLoader, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceFrontBack, Curve, CurvePath, CustomToneMapping, Cylindrical, CylindricalMapping, Data3DTexture, DataTextureLoader, DataUtils, DefaultLoadingManager, DetachedBindMode, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry, DynamicCopyUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, ExtrudeGeometry, Fog, FogExp2, GLBufferAttribute, GLSL1, GLSL3, GridHelper, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, InstancedBufferGeometry, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InterpolationSamplingMode, InterpolationSamplingType, KeyframeTrack, LOD, LatheGeometry, Layers, Light, Line, Line3, LineCurve, LineCurve3, LineLoop, LineSegments, LinearInterpolant, LinearMipMapNearestFilter, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, MOUSE, MeshDepthMaterial, MeshDistanceMaterial, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NormalAnimationBlendMode, NumberKeyframeTrack, OctahedronGeometry, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, PCFSoftShadowMap, Path, PlaneHelper, PointLightHelper, Points, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, QuaternionKeyframeTrack, QuaternionLinearInterpolant, RGBADepthPacking, RGBDepthPacking, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGDepthPacking, RawShaderMaterial, Ray, Raycaster, RenderTarget3D, RingGeometry, ShaderMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, Skeleton, SkeletonHelper, SkinnedMesh, Source, Spherical, SphericalHarmonics3, SplineCurve, SpotLightHelper, Sprite, StaticCopyUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, TOUCH, TetrahedronGeometry, TextureLoader, TextureUtils, TimestampQuery, TorusGeometry, TorusKnotGeometry, TriPlanarMapping, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, VectorKeyframeTrack, VideoFrameTexture, VideoTexture, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLRenderTarget, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroSlopeEnding } from './three.core.js';
7
+ export { AdditiveAnimationBlendMode, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BasicDepthPacking, BatchedMesh, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxHelper, BufferGeometryLoader, Cache, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CircleGeometry, Clock, ColorKeyframeTrack, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, ConstantAlphaFactor, ConstantColorFactor, Controls, CubeTextureLoader, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceFrontBack, Curve, CurvePath, CustomToneMapping, Cylindrical, CylindricalMapping, Data3DTexture, DataTextureLoader, DataUtils, DefaultLoadingManager, DetachedBindMode, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry, DynamicCopyUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, ExtrudeGeometry, Fog, FogExp2, GLBufferAttribute, GLSL1, GLSL3, GridHelper, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, InstancedBufferGeometry, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InterpolationSamplingMode, InterpolationSamplingType, KeyframeTrack, LOD, LatheGeometry, Layers, Light, Line, Line3, LineCurve, LineCurve3, LineLoop, LineSegments, LinearInterpolant, LinearMipMapNearestFilter, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, MOUSE, MeshDepthMaterial, MeshDistanceMaterial, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NormalAnimationBlendMode, NumberKeyframeTrack, OctahedronGeometry, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, PCFSoftShadowMap, Path, PlaneHelper, PointLightHelper, Points, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, QuaternionKeyframeTrack, QuaternionLinearInterpolant, RGBADepthPacking, RGBDepthPacking, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGDepthPacking, RawShaderMaterial, Ray, Raycaster, RenderTarget3D, RingGeometry, ShaderMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, Skeleton, SkeletonHelper, SkinnedMesh, Source, Spherical, SphericalHarmonics3, SplineCurve, SpotLightHelper, Sprite, StaticCopyUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, TOUCH, TetrahedronGeometry, TextureLoader, TextureUtils, Timer, TimestampQuery, TorusGeometry, TorusKnotGeometry, TriPlanarMapping, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, VectorKeyframeTrack, VideoFrameTexture, VideoTexture, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLRenderTarget, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroSlopeEnding } from './three.core.js';
8
8
 
9
9
  const refreshUniforms = [
10
10
  'alphaMap',
@@ -63,6 +63,16 @@ const refreshUniforms = [
63
63
  'transmissionMap'
64
64
  ];
65
65
 
66
+
67
+ /**
68
+ * A WeakMap to cache lights data for node materials.
69
+ * Cache lights data by render ID to avoid unnecessary recalculations.
70
+ *
71
+ * @private
72
+ * @type {WeakMap<LightsNode,Object>}
73
+ */
74
+ const _lightsCache = new WeakMap();
75
+
66
76
  /**
67
77
  * This class is used by {@link WebGPURenderer} as management component.
68
78
  * It's primary purpose is to determine whether render objects require a
@@ -204,6 +214,8 @@ class NodeMaterialObserver {
204
214
 
205
215
  }
206
216
 
217
+ data.lights = this.getLightsData( renderObject.lightsNode.getLights() );
218
+
207
219
  this.renderObjects.set( renderObject, data );
208
220
 
209
221
  }
@@ -307,9 +319,10 @@ class NodeMaterialObserver {
307
319
  * Returns `true` if the given render object has not changed its state.
308
320
  *
309
321
  * @param {RenderObject} renderObject - The render object.
322
+ * @param {Array<Light>} lightsData - The current material lights.
310
323
  * @return {boolean} Whether the given render object has changed its state or not.
311
324
  */
312
- equals( renderObject ) {
325
+ equals( renderObject, lightsData ) {
313
326
 
314
327
  const { object, material, geometry } = renderObject;
315
328
 
@@ -470,6 +483,22 @@ class NodeMaterialObserver {
470
483
 
471
484
  }
472
485
 
486
+ // lights
487
+
488
+ if ( renderObjectData.lights ) {
489
+
490
+ for ( let i = 0; i < lightsData.length; i ++ ) {
491
+
492
+ if ( renderObjectData.lights[ i ].map !== lightsData[ i ].map ) {
493
+
494
+ return false;
495
+
496
+ }
497
+
498
+ }
499
+
500
+ }
501
+
473
502
  // center
474
503
 
475
504
  if ( renderObjectData.center ) {
@@ -496,6 +525,61 @@ class NodeMaterialObserver {
496
525
 
497
526
  }
498
527
 
528
+ /**
529
+ * Returns the lights data for the given material lights.
530
+ *
531
+ * @param {Array<Light>} materialLights - The material lights.
532
+ * @return {Array<Object>} The lights data for the given material lights.
533
+ */
534
+ getLightsData( materialLights ) {
535
+
536
+ const lights = [];
537
+
538
+ for ( const light of materialLights ) {
539
+
540
+ if ( light.isSpotLight === true && light.map !== null ) {
541
+
542
+ // only add lights that have a map
543
+
544
+ lights.push( { map: light.map.version } );
545
+
546
+ }
547
+
548
+ }
549
+
550
+ return lights;
551
+
552
+ }
553
+
554
+ /**
555
+ * Returns the lights for the given lights node and render ID.
556
+ *
557
+ * @param {LightsNode} lightsNode - The lights node.
558
+ * @param {number} renderId - The render ID.
559
+ * @return {Array} The lights for the given lights node and render ID.
560
+ */
561
+ getLights( lightsNode, renderId ) {
562
+
563
+ if ( _lightsCache.has( lightsNode ) ) {
564
+
565
+ const cached = _lightsCache.get( lightsNode );
566
+
567
+ if ( cached.renderId === renderId ) {
568
+
569
+ return cached.lightsData;
570
+
571
+ }
572
+
573
+ }
574
+
575
+ const lightsData = this.getLightsData( lightsNode.getLights() );
576
+
577
+ _lightsCache.set( lightsNode, { renderId, lightsData } );
578
+
579
+ return lightsData;
580
+
581
+ }
582
+
499
583
  /**
500
584
  * Checks if the given render object requires a refresh.
501
585
  *
@@ -524,7 +608,8 @@ class NodeMaterialObserver {
524
608
  if ( isStatic || isBundle )
525
609
  return false;
526
610
 
527
- const notEqual = this.equals( renderObject ) !== true;
611
+ const lightsData = this.getLights( renderObject.lightsNode, renderId );
612
+ const notEqual = this.equals( renderObject, lightsData ) !== true;
528
613
 
529
614
  return notEqual;
530
615
 
@@ -664,10 +749,13 @@ function* getNodeChildren( node, toJSON = false ) {
664
749
 
665
750
  yield { property, childNode: object };
666
751
 
667
- } else if ( typeof object === 'object' ) {
752
+ } else if ( object && Object.getPrototypeOf( object ) === Object.prototype ) {
668
753
 
669
754
  for ( const subProperty in object ) {
670
755
 
756
+ // Ignore private properties.
757
+ if ( subProperty.startsWith( '_' ) === true ) continue;
758
+
671
759
  const child = object[ subProperty ];
672
760
 
673
761
  if ( child && ( child.isNode === true || toJSON && typeof child.toJSON === 'function' ) ) {
@@ -1566,10 +1654,22 @@ class Node extends EventDispatcher {
1566
1654
 
1567
1655
  }
1568
1656
 
1657
+ /**
1658
+ * Returns the number of elements in the node array.
1659
+ *
1660
+ * @param {NodeBuilder} builder - The current node builder.
1661
+ * @return {?number} The number of elements in the node array.
1662
+ */
1663
+ getArrayCount( /*builder*/ ) {
1664
+
1665
+ return null;
1666
+
1667
+ }
1668
+
1569
1669
  /**
1570
1670
  * Represents the setup stage which is the first step of the build process, see {@link Node#build} method.
1571
- * This method is often overwritten in derived modules to prepare the node which is used as the output/result.
1572
- * The output node must be returned in the `return` statement.
1671
+ * This method is often overwritten in derived modules to prepare the node which is used as a node's output/result.
1672
+ * If an output node is prepared, then it must be returned in the `return` statement of the derived module's setup function.
1573
1673
  *
1574
1674
  * @param {NodeBuilder} builder - The current node builder.
1575
1675
  * @return {?Node} The output node.
@@ -3082,6 +3182,10 @@ const shaderNodeHandler = {
3082
3182
 
3083
3183
  return node.isStackNode ? ( ...params ) => nodeObj.add( nodeElement( ...params ) ) : ( ...params ) => nodeElement( nodeObj, ...params );
3084
3184
 
3185
+ } else if ( prop === 'toVarIntent' ) {
3186
+
3187
+ return () => nodeObj;
3188
+
3085
3189
  } else if ( prop === 'self' ) {
3086
3190
 
3087
3191
  return node;
@@ -3232,7 +3336,28 @@ const ShaderNodeArray = function ( array, altType = null ) {
3232
3336
 
3233
3337
  const ShaderNodeProxy = function ( NodeClass, scope = null, factor = null, settings = null ) {
3234
3338
 
3235
- const assignNode = ( node ) => nodeObject( settings !== null ? Object.assign( node, settings ) : node );
3339
+ function assignNode( node ) {
3340
+
3341
+ if ( settings !== null ) {
3342
+
3343
+ node = nodeObject( Object.assign( node, settings ) );
3344
+
3345
+ if ( settings.intent === true ) {
3346
+
3347
+ node = node.toVarIntent();
3348
+
3349
+ }
3350
+
3351
+ } else {
3352
+
3353
+ node = nodeObject( node );
3354
+
3355
+ }
3356
+
3357
+ return node;
3358
+
3359
+
3360
+ }
3236
3361
 
3237
3362
  let fn, name = scope, minParams, maxParams;
3238
3363
 
@@ -3392,8 +3517,36 @@ class ShaderCallNodeInternal extends Node {
3392
3517
 
3393
3518
  } else {
3394
3519
 
3520
+ let inputs = inputNodes;
3521
+
3522
+ if ( Array.isArray( inputs ) ) {
3523
+
3524
+ // If inputs is an array, we need to convert it to a Proxy
3525
+ // so we can call TSL functions using the syntax `Fn( ( { r, g, b } ) => { ... } )`
3526
+ // and call through `fn( 0, 1, 0 )` or `fn( { r: 0, g: 1, b: 0 } )`
3527
+
3528
+ let index = 0;
3529
+
3530
+ inputs = new Proxy( inputs, {
3531
+ get: ( target, property, receiver ) => {
3532
+
3533
+ if ( target[ property ] === undefined ) {
3534
+
3535
+ return target[ index ++ ];
3536
+
3537
+ } else {
3538
+
3539
+ return Reflect.get( target, property, receiver );
3540
+
3541
+ }
3542
+
3543
+ }
3544
+ } );
3545
+
3546
+ }
3547
+
3395
3548
  const jsFunc = shaderNode.jsFunc;
3396
- const outputNode = inputNodes !== null || jsFunc.length > 1 ? jsFunc( inputNodes || [], builder ) : jsFunc( builder );
3549
+ const outputNode = inputs !== null || jsFunc.length > 1 ? jsFunc( inputs || [], builder ) : jsFunc( builder );
3397
3550
 
3398
3551
  result = nodeObject( outputNode );
3399
3552
 
@@ -3587,20 +3740,20 @@ const ConvertType = function ( type, cacheMap = null ) {
3587
3740
 
3588
3741
  if ( params.length === 1 && cacheMap !== null && cacheMap.has( params[ 0 ] ) ) {
3589
3742
 
3590
- return nodeObject( cacheMap.get( params[ 0 ] ) );
3743
+ return nodeObjectIntent( cacheMap.get( params[ 0 ] ) );
3591
3744
 
3592
3745
  }
3593
3746
 
3594
3747
  if ( params.length === 1 ) {
3595
3748
 
3596
3749
  const node = getConstNode( params[ 0 ], type );
3597
- if ( node.nodeType === type ) return nodeObject( node );
3598
- return nodeObject( new ConvertNode( node, type ) );
3750
+ if ( node.nodeType === type ) return nodeObjectIntent( node );
3751
+ return nodeObjectIntent( new ConvertNode( node, type ) );
3599
3752
 
3600
3753
  }
3601
3754
 
3602
3755
  const nodes = params.map( param => getConstNode( param ) );
3603
- return nodeObject( new JoinNode( nodes, type ) );
3756
+ return nodeObjectIntent( new JoinNode( nodes, type ) );
3604
3757
 
3605
3758
  };
3606
3759
 
@@ -3623,10 +3776,12 @@ function ShaderNode( jsFunc, nodeType ) {
3623
3776
  }
3624
3777
 
3625
3778
  const nodeObject = ( val, altType = null ) => /* new */ ShaderNodeObject( val, altType );
3779
+ const nodeObjectIntent = ( val, altType = null ) => /* new */ nodeObject( val, altType ).toVarIntent();
3626
3780
  const nodeObjects = ( val, altType = null ) => new ShaderNodeObjects( val, altType );
3627
3781
  const nodeArray = ( val, altType = null ) => new ShaderNodeArray( val, altType );
3628
- const nodeProxy = ( ...params ) => new ShaderNodeProxy( ...params );
3629
- const nodeImmutable = ( ...params ) => new ShaderNodeImmutable( ...params );
3782
+ const nodeProxy = ( NodeClass, scope = null, factor = null, settings = null ) => new ShaderNodeProxy( NodeClass, scope, factor, settings );
3783
+ const nodeImmutable = ( NodeClass, ...params ) => new ShaderNodeImmutable( NodeClass, ...params );
3784
+ const nodeProxyIntent = ( NodeClass, scope = null, factor = null, settings = {} ) => new ShaderNodeProxy( NodeClass, scope, factor, { intent: true, ...settings } );
3630
3785
 
3631
3786
  let fnId = 0;
3632
3787
 
@@ -3682,7 +3837,7 @@ const Fn = ( jsFunc, layout = null ) => {
3682
3837
 
3683
3838
  if ( nodeType === 'void' ) fnCall.toStack();
3684
3839
 
3685
- return fnCall;
3840
+ return fnCall.toVarIntent();
3686
3841
 
3687
3842
  };
3688
3843
 
@@ -4417,7 +4572,7 @@ class UniformNode extends InputNode {
4417
4572
  * @param {string} name - The name of the uniform.
4418
4573
  * @return {UniformNode} A reference to this node.
4419
4574
  */
4420
- label( name ) {
4575
+ setName( name ) {
4421
4576
 
4422
4577
  this.name = name;
4423
4578
 
@@ -4425,6 +4580,21 @@ class UniformNode extends InputNode {
4425
4580
 
4426
4581
  }
4427
4582
 
4583
+ /**
4584
+ * Sets the {@link UniformNode#name} property.
4585
+ *
4586
+ * @deprecated
4587
+ * @param {string} name - The name of the uniform.
4588
+ * @return {UniformNode} A reference to this node.
4589
+ */
4590
+ label( name ) {
4591
+
4592
+ console.warn( 'THREE.TSL: "label()" has been deprecated. Use "setName()" instead.' ); // @deprecated r179
4593
+
4594
+ return this.setName( name );
4595
+
4596
+ }
4597
+
4428
4598
  /**
4429
4599
  * Sets the {@link UniformNode#groupNode} property.
4430
4600
  *
@@ -4483,6 +4653,20 @@ class UniformNode extends InputNode {
4483
4653
 
4484
4654
  }
4485
4655
 
4656
+ getInputType( builder ) {
4657
+
4658
+ let type = super.getInputType( builder );
4659
+
4660
+ if ( type === 'bool' ) {
4661
+
4662
+ type = 'uint';
4663
+
4664
+ }
4665
+
4666
+ return type;
4667
+
4668
+ }
4669
+
4486
4670
  generate( builder, output ) {
4487
4671
 
4488
4672
  const type = this.getNodeType( builder );
@@ -4501,12 +4685,41 @@ class UniformNode extends InputNode {
4501
4685
 
4502
4686
  const sharedNodeType = sharedNode.getInputType( builder );
4503
4687
 
4504
- const nodeUniform = builder.getUniformFromNode( sharedNode, sharedNodeType, builder.shaderStage, this.name || builder.context.label );
4505
- const propertyName = builder.getPropertyName( nodeUniform );
4688
+ const nodeUniform = builder.getUniformFromNode( sharedNode, sharedNodeType, builder.shaderStage, this.name || builder.context.nodeName );
4689
+ const uniformName = builder.getPropertyName( nodeUniform );
4690
+
4691
+ if ( builder.context.nodeName !== undefined ) delete builder.context.nodeName;
4692
+
4693
+ //
4694
+
4695
+ let snippet = uniformName;
4696
+
4697
+ if ( type === 'bool' ) {
4698
+
4699
+ // cache to variable
4700
+
4701
+ const nodeData = builder.getDataFromNode( this );
4702
+
4703
+ let propertyName = nodeData.propertyName;
4704
+
4705
+ if ( propertyName === undefined ) {
4706
+
4707
+ const nodeVar = builder.getVarFromNode( this, null, 'bool' );
4708
+ propertyName = builder.getPropertyName( nodeVar );
4709
+
4710
+ nodeData.propertyName = propertyName;
4506
4711
 
4507
- if ( builder.context.label !== undefined ) delete builder.context.label;
4712
+ snippet = builder.format( uniformName, sharedNodeType, type );
4713
+
4714
+ builder.addLineFlowCode( `${ propertyName } = ${ snippet }`, this );
4508
4715
 
4509
- return builder.format( propertyName, type, output );
4716
+ }
4717
+
4718
+ snippet = propertyName;
4719
+
4720
+ }
4721
+
4722
+ return builder.format( snippet, type, output );
4510
4723
 
4511
4724
  }
4512
4725
 
@@ -4589,6 +4802,18 @@ class ArrayNode extends TempNode {
4589
4802
 
4590
4803
  }
4591
4804
 
4805
+ /**
4806
+ * Returns the number of elements in the node array.
4807
+ *
4808
+ * @param {NodeBuilder} builder - The current node builder.
4809
+ * @return {number} The number of elements in the node array.
4810
+ */
4811
+ getArrayCount( /*builder*/ ) {
4812
+
4813
+ return this.count;
4814
+
4815
+ }
4816
+
4592
4817
  /**
4593
4818
  * Returns the node's type.
4594
4819
  *
@@ -4765,6 +4990,9 @@ class AssignNode extends TempNode {
4765
4990
 
4766
4991
  const { targetNode, sourceNode } = this;
4767
4992
 
4993
+ const targetProperties = builder.getNodeProperties( targetNode );
4994
+ targetProperties.assign = true;
4995
+
4768
4996
  const properties = builder.getNodeProperties( this );
4769
4997
  properties.sourceNode = sourceNode;
4770
4998
  properties.targetNode = targetNode.context( { assign: true } );
@@ -5437,7 +5665,7 @@ class OperatorNode extends TempNode {
5437
5665
  * @param {...Node} params - Additional input parameters.
5438
5666
  * @returns {OperatorNode}
5439
5667
  */
5440
- const add = /*@__PURE__*/ nodeProxy( OperatorNode, '+' ).setParameterLength( 2, Infinity ).setName( 'add' );
5668
+ const add = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '+' ).setParameterLength( 2, Infinity ).setName( 'add' );
5441
5669
 
5442
5670
  /**
5443
5671
  * Returns the subtraction of two or more value.
@@ -5449,7 +5677,7 @@ const add = /*@__PURE__*/ nodeProxy( OperatorNode, '+' ).setParameterLength( 2,
5449
5677
  * @param {...Node} params - Additional input parameters.
5450
5678
  * @returns {OperatorNode}
5451
5679
  */
5452
- const sub = /*@__PURE__*/ nodeProxy( OperatorNode, '-' ).setParameterLength( 2, Infinity ).setName( 'sub' );
5680
+ const sub = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '-' ).setParameterLength( 2, Infinity ).setName( 'sub' );
5453
5681
 
5454
5682
  /**
5455
5683
  * Returns the multiplication of two or more value.
@@ -5461,7 +5689,7 @@ const sub = /*@__PURE__*/ nodeProxy( OperatorNode, '-' ).setParameterLength( 2,
5461
5689
  * @param {...Node} params - Additional input parameters.
5462
5690
  * @returns {OperatorNode}
5463
5691
  */
5464
- const mul = /*@__PURE__*/ nodeProxy( OperatorNode, '*' ).setParameterLength( 2, Infinity ).setName( 'mul' );
5692
+ const mul = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '*' ).setParameterLength( 2, Infinity ).setName( 'mul' );
5465
5693
 
5466
5694
  /**
5467
5695
  * Returns the division of two or more value.
@@ -5473,7 +5701,7 @@ const mul = /*@__PURE__*/ nodeProxy( OperatorNode, '*' ).setParameterLength( 2,
5473
5701
  * @param {...Node} params - Additional input parameters.
5474
5702
  * @returns {OperatorNode}
5475
5703
  */
5476
- const div = /*@__PURE__*/ nodeProxy( OperatorNode, '/' ).setParameterLength( 2, Infinity ).setName( 'div' );
5704
+ const div = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '/' ).setParameterLength( 2, Infinity ).setName( 'div' );
5477
5705
 
5478
5706
  /**
5479
5707
  * Computes the remainder of dividing the first node by the second one.
@@ -5484,7 +5712,7 @@ const div = /*@__PURE__*/ nodeProxy( OperatorNode, '/' ).setParameterLength( 2,
5484
5712
  * @param {Node} b - The second input.
5485
5713
  * @returns {OperatorNode}
5486
5714
  */
5487
- const mod = /*@__PURE__*/ nodeProxy( OperatorNode, '%' ).setParameterLength( 2 ).setName( 'mod' );
5715
+ const mod = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '%' ).setParameterLength( 2 ).setName( 'mod' );
5488
5716
 
5489
5717
  /**
5490
5718
  * Checks if two nodes are equal.
@@ -5495,7 +5723,7 @@ const mod = /*@__PURE__*/ nodeProxy( OperatorNode, '%' ).setParameterLength( 2 )
5495
5723
  * @param {Node} b - The second input.
5496
5724
  * @returns {OperatorNode}
5497
5725
  */
5498
- const equal = /*@__PURE__*/ nodeProxy( OperatorNode, '==' ).setParameterLength( 2 ).setName( 'equal' );
5726
+ const equal = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '==' ).setParameterLength( 2 ).setName( 'equal' );
5499
5727
 
5500
5728
  /**
5501
5729
  * Checks if two nodes are not equal.
@@ -5506,7 +5734,7 @@ const equal = /*@__PURE__*/ nodeProxy( OperatorNode, '==' ).setParameterLength(
5506
5734
  * @param {Node} b - The second input.
5507
5735
  * @returns {OperatorNode}
5508
5736
  */
5509
- const notEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '!=' ).setParameterLength( 2 ).setName( 'notEqual' );
5737
+ const notEqual = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '!=' ).setParameterLength( 2 ).setName( 'notEqual' );
5510
5738
 
5511
5739
  /**
5512
5740
  * Checks if the first node is less than the second.
@@ -5517,7 +5745,7 @@ const notEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '!=' ).setParameterLengt
5517
5745
  * @param {Node} b - The second input.
5518
5746
  * @returns {OperatorNode}
5519
5747
  */
5520
- const lessThan = /*@__PURE__*/ nodeProxy( OperatorNode, '<' ).setParameterLength( 2 ).setName( 'lessThan' );
5748
+ const lessThan = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '<' ).setParameterLength( 2 ).setName( 'lessThan' );
5521
5749
 
5522
5750
  /**
5523
5751
  * Checks if the first node is greater than the second.
@@ -5528,7 +5756,7 @@ const lessThan = /*@__PURE__*/ nodeProxy( OperatorNode, '<' ).setParameterLength
5528
5756
  * @param {Node} b - The second input.
5529
5757
  * @returns {OperatorNode}
5530
5758
  */
5531
- const greaterThan = /*@__PURE__*/ nodeProxy( OperatorNode, '>' ).setParameterLength( 2 ).setName( 'greaterThan' );
5759
+ const greaterThan = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '>' ).setParameterLength( 2 ).setName( 'greaterThan' );
5532
5760
 
5533
5761
  /**
5534
5762
  * Checks if the first node is less than or equal to the second.
@@ -5539,7 +5767,7 @@ const greaterThan = /*@__PURE__*/ nodeProxy( OperatorNode, '>' ).setParameterLen
5539
5767
  * @param {Node} b - The second input.
5540
5768
  * @returns {OperatorNode}
5541
5769
  */
5542
- const lessThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '<=' ).setParameterLength( 2 ).setName( 'lessThanEqual' );
5770
+ const lessThanEqual = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '<=' ).setParameterLength( 2 ).setName( 'lessThanEqual' );
5543
5771
 
5544
5772
  /**
5545
5773
  * Checks if the first node is greater than or equal to the second.
@@ -5550,7 +5778,7 @@ const lessThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '<=' ).setParameter
5550
5778
  * @param {Node} b - The second input.
5551
5779
  * @returns {OperatorNode}
5552
5780
  */
5553
- const greaterThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '>=' ).setParameterLength( 2 ).setName( 'greaterThanEqual' );
5781
+ const greaterThanEqual = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '>=' ).setParameterLength( 2 ).setName( 'greaterThanEqual' );
5554
5782
 
5555
5783
  /**
5556
5784
  * Performs a logical AND operation on multiple nodes.
@@ -5560,7 +5788,7 @@ const greaterThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '>=' ).setParame
5560
5788
  * @param {...Node} nodes - The input nodes to be combined using AND.
5561
5789
  * @returns {OperatorNode}
5562
5790
  */
5563
- const and = /*@__PURE__*/ nodeProxy( OperatorNode, '&&' ).setParameterLength( 2, Infinity ).setName( 'and' );
5791
+ const and = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '&&' ).setParameterLength( 2, Infinity ).setName( 'and' );
5564
5792
 
5565
5793
  /**
5566
5794
  * Performs a logical OR operation on multiple nodes.
@@ -5570,7 +5798,7 @@ const and = /*@__PURE__*/ nodeProxy( OperatorNode, '&&' ).setParameterLength( 2,
5570
5798
  * @param {...Node} nodes - The input nodes to be combined using OR.
5571
5799
  * @returns {OperatorNode}
5572
5800
  */
5573
- const or = /*@__PURE__*/ nodeProxy( OperatorNode, '||' ).setParameterLength( 2, Infinity ).setName( 'or' );
5801
+ const or = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '||' ).setParameterLength( 2, Infinity ).setName( 'or' );
5574
5802
 
5575
5803
  /**
5576
5804
  * Performs logical NOT on a node.
@@ -5580,7 +5808,7 @@ const or = /*@__PURE__*/ nodeProxy( OperatorNode, '||' ).setParameterLength( 2,
5580
5808
  * @param {Node} value - The value.
5581
5809
  * @returns {OperatorNode}
5582
5810
  */
5583
- const not = /*@__PURE__*/ nodeProxy( OperatorNode, '!' ).setParameterLength( 1 ).setName( 'not' );
5811
+ const not = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '!' ).setParameterLength( 1 ).setName( 'not' );
5584
5812
 
5585
5813
  /**
5586
5814
  * Performs logical XOR on two nodes.
@@ -5591,7 +5819,7 @@ const not = /*@__PURE__*/ nodeProxy( OperatorNode, '!' ).setParameterLength( 1 )
5591
5819
  * @param {Node} b - The second input.
5592
5820
  * @returns {OperatorNode}
5593
5821
  */
5594
- const xor = /*@__PURE__*/ nodeProxy( OperatorNode, '^^' ).setParameterLength( 2 ).setName( 'xor' );
5822
+ const xor = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '^^' ).setParameterLength( 2 ).setName( 'xor' );
5595
5823
 
5596
5824
  /**
5597
5825
  * Performs bitwise AND on two nodes.
@@ -5602,7 +5830,7 @@ const xor = /*@__PURE__*/ nodeProxy( OperatorNode, '^^' ).setParameterLength( 2
5602
5830
  * @param {Node} b - The second input.
5603
5831
  * @returns {OperatorNode}
5604
5832
  */
5605
- const bitAnd = /*@__PURE__*/ nodeProxy( OperatorNode, '&' ).setParameterLength( 2 ).setName( 'bitAnd' );
5833
+ const bitAnd = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '&' ).setParameterLength( 2 ).setName( 'bitAnd' );
5606
5834
 
5607
5835
  /**
5608
5836
  * Performs bitwise NOT on a node.
@@ -5613,7 +5841,7 @@ const bitAnd = /*@__PURE__*/ nodeProxy( OperatorNode, '&' ).setParameterLength(
5613
5841
  * @param {Node} b - The second input.
5614
5842
  * @returns {OperatorNode}
5615
5843
  */
5616
- const bitNot = /*@__PURE__*/ nodeProxy( OperatorNode, '~' ).setParameterLength( 2 ).setName( 'bitNot' );
5844
+ const bitNot = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '~' ).setParameterLength( 2 ).setName( 'bitNot' );
5617
5845
 
5618
5846
  /**
5619
5847
  * Performs bitwise OR on two nodes.
@@ -5624,7 +5852,7 @@ const bitNot = /*@__PURE__*/ nodeProxy( OperatorNode, '~' ).setParameterLength(
5624
5852
  * @param {Node} b - The second input.
5625
5853
  * @returns {OperatorNode}
5626
5854
  */
5627
- const bitOr = /*@__PURE__*/ nodeProxy( OperatorNode, '|' ).setParameterLength( 2 ).setName( 'bitOr' );
5855
+ const bitOr = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '|' ).setParameterLength( 2 ).setName( 'bitOr' );
5628
5856
 
5629
5857
  /**
5630
5858
  * Performs bitwise XOR on two nodes.
@@ -5635,7 +5863,7 @@ const bitOr = /*@__PURE__*/ nodeProxy( OperatorNode, '|' ).setParameterLength( 2
5635
5863
  * @param {Node} b - The second input.
5636
5864
  * @returns {OperatorNode}
5637
5865
  */
5638
- const bitXor = /*@__PURE__*/ nodeProxy( OperatorNode, '^' ).setParameterLength( 2 ).setName( 'bitXor' );
5866
+ const bitXor = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '^' ).setParameterLength( 2 ).setName( 'bitXor' );
5639
5867
 
5640
5868
  /**
5641
5869
  * Shifts a node to the left.
@@ -5646,7 +5874,7 @@ const bitXor = /*@__PURE__*/ nodeProxy( OperatorNode, '^' ).setParameterLength(
5646
5874
  * @param {Node} b - The value to shift.
5647
5875
  * @returns {OperatorNode}
5648
5876
  */
5649
- const shiftLeft = /*@__PURE__*/ nodeProxy( OperatorNode, '<<' ).setParameterLength( 2 ).setName( 'shiftLeft' );
5877
+ const shiftLeft = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '<<' ).setParameterLength( 2 ).setName( 'shiftLeft' );
5650
5878
 
5651
5879
  /**
5652
5880
  * Shifts a node to the right.
@@ -5657,7 +5885,7 @@ const shiftLeft = /*@__PURE__*/ nodeProxy( OperatorNode, '<<' ).setParameterLeng
5657
5885
  * @param {Node} b - The value to shift.
5658
5886
  * @returns {OperatorNode}
5659
5887
  */
5660
- const shiftRight = /*@__PURE__*/ nodeProxy( OperatorNode, '>>' ).setParameterLength( 2 ).setName( 'shiftRight' );
5888
+ const shiftRight = /*@__PURE__*/ nodeProxyIntent( OperatorNode, '>>' ).setParameterLength( 2 ).setName( 'shiftRight' );
5661
5889
 
5662
5890
  /**
5663
5891
  * Increments a node by 1.
@@ -6124,6 +6352,8 @@ MathNode.RECIPROCAL = 'reciprocal';
6124
6352
  MathNode.TRUNC = 'trunc';
6125
6353
  MathNode.FWIDTH = 'fwidth';
6126
6354
  MathNode.TRANSPOSE = 'transpose';
6355
+ MathNode.DETERMINANT = 'determinant';
6356
+ MathNode.INVERSE = 'inverse';
6127
6357
 
6128
6358
  // 2 inputs
6129
6359
 
@@ -6190,7 +6420,7 @@ const PI2 = /*@__PURE__*/ float( Math.PI * 2 );
6190
6420
  * @param {Node | number} x - The parameter.
6191
6421
  * @returns {Node<bool>}
6192
6422
  */
6193
- const all = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ALL ).setParameterLength( 1 );
6423
+ const all = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ALL ).setParameterLength( 1 );
6194
6424
 
6195
6425
  /**
6196
6426
  * Returns `true` if any components of `x` are `true`.
@@ -6200,7 +6430,7 @@ const all = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ALL ).setParameterLength
6200
6430
  * @param {Node | number} x - The parameter.
6201
6431
  * @returns {Node<bool>}
6202
6432
  */
6203
- const any = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ANY ).setParameterLength( 1 );
6433
+ const any = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ANY ).setParameterLength( 1 );
6204
6434
 
6205
6435
  /**
6206
6436
  * Converts a quantity in degrees to radians.
@@ -6210,7 +6440,7 @@ const any = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ANY ).setParameterLength
6210
6440
  * @param {Node | number} x - The input in degrees.
6211
6441
  * @returns {Node}
6212
6442
  */
6213
- const radians = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RADIANS ).setParameterLength( 1 );
6443
+ const radians = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.RADIANS ).setParameterLength( 1 );
6214
6444
 
6215
6445
  /**
6216
6446
  * Convert a quantity in radians to degrees.
@@ -6220,7 +6450,7 @@ const radians = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RADIANS ).setParamet
6220
6450
  * @param {Node | number} x - The input in radians.
6221
6451
  * @returns {Node}
6222
6452
  */
6223
- const degrees = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DEGREES ).setParameterLength( 1 );
6453
+ const degrees = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.DEGREES ).setParameterLength( 1 );
6224
6454
 
6225
6455
  /**
6226
6456
  * Returns the natural exponentiation of the parameter.
@@ -6230,7 +6460,7 @@ const degrees = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DEGREES ).setParamet
6230
6460
  * @param {Node | number} x - The parameter.
6231
6461
  * @returns {Node}
6232
6462
  */
6233
- const exp = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP ).setParameterLength( 1 );
6463
+ const exp = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.EXP ).setParameterLength( 1 );
6234
6464
 
6235
6465
  /**
6236
6466
  * Returns 2 raised to the power of the parameter.
@@ -6240,7 +6470,7 @@ const exp = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP ).setParameterLength
6240
6470
  * @param {Node | number} x - The parameter.
6241
6471
  * @returns {Node}
6242
6472
  */
6243
- const exp2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP2 ).setParameterLength( 1 );
6473
+ const exp2 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.EXP2 ).setParameterLength( 1 );
6244
6474
 
6245
6475
  /**
6246
6476
  * Returns the natural logarithm of the parameter.
@@ -6250,7 +6480,7 @@ const exp2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP2 ).setParameterLeng
6250
6480
  * @param {Node | number} x - The parameter.
6251
6481
  * @returns {Node}
6252
6482
  */
6253
- const log = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG ).setParameterLength( 1 );
6483
+ const log = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.LOG ).setParameterLength( 1 );
6254
6484
 
6255
6485
  /**
6256
6486
  * Returns the base 2 logarithm of the parameter.
@@ -6260,7 +6490,7 @@ const log = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG ).setParameterLength
6260
6490
  * @param {Node | number} x - The parameter.
6261
6491
  * @returns {Node}
6262
6492
  */
6263
- const log2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG2 ).setParameterLength( 1 );
6493
+ const log2 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.LOG2 ).setParameterLength( 1 );
6264
6494
 
6265
6495
  /**
6266
6496
  * Returns the square root of the parameter.
@@ -6270,7 +6500,7 @@ const log2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG2 ).setParameterLeng
6270
6500
  * @param {Node | number} x - The parameter.
6271
6501
  * @returns {Node}
6272
6502
  */
6273
- const sqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SQRT ).setParameterLength( 1 );
6503
+ const sqrt = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.SQRT ).setParameterLength( 1 );
6274
6504
 
6275
6505
  /**
6276
6506
  * Returns the inverse of the square root of the parameter.
@@ -6280,7 +6510,7 @@ const sqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SQRT ).setParameterLeng
6280
6510
  * @param {Node | number} x - The parameter.
6281
6511
  * @returns {Node}
6282
6512
  */
6283
- const inverseSqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.INVERSE_SQRT ).setParameterLength( 1 );
6513
+ const inverseSqrt = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.INVERSE_SQRT ).setParameterLength( 1 );
6284
6514
 
6285
6515
  /**
6286
6516
  * Finds the nearest integer less than or equal to the parameter.
@@ -6290,7 +6520,7 @@ const inverseSqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.INVERSE_SQRT ).s
6290
6520
  * @param {Node | number} x - The parameter.
6291
6521
  * @returns {Node}
6292
6522
  */
6293
- const floor = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FLOOR ).setParameterLength( 1 );
6523
+ const floor = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.FLOOR ).setParameterLength( 1 );
6294
6524
 
6295
6525
  /**
6296
6526
  * Finds the nearest integer that is greater than or equal to the parameter.
@@ -6300,7 +6530,7 @@ const floor = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FLOOR ).setParameterLe
6300
6530
  * @param {Node | number} x - The parameter.
6301
6531
  * @returns {Node}
6302
6532
  */
6303
- const ceil = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CEIL ).setParameterLength( 1 );
6533
+ const ceil = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.CEIL ).setParameterLength( 1 );
6304
6534
 
6305
6535
  /**
6306
6536
  * Calculates the unit vector in the same direction as the original vector.
@@ -6310,7 +6540,7 @@ const ceil = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CEIL ).setParameterLeng
6310
6540
  * @param {Node} x - The input vector.
6311
6541
  * @returns {Node}
6312
6542
  */
6313
- const normalize = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NORMALIZE ).setParameterLength( 1 );
6543
+ const normalize = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.NORMALIZE ).setParameterLength( 1 );
6314
6544
 
6315
6545
  /**
6316
6546
  * Computes the fractional part of the parameter.
@@ -6320,7 +6550,7 @@ const normalize = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NORMALIZE ).setPar
6320
6550
  * @param {Node | number} x - The parameter.
6321
6551
  * @returns {Node}
6322
6552
  */
6323
- const fract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FRACT ).setParameterLength( 1 );
6553
+ const fract = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.FRACT ).setParameterLength( 1 );
6324
6554
 
6325
6555
  /**
6326
6556
  * Returns the sine of the parameter.
@@ -6330,7 +6560,7 @@ const fract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FRACT ).setParameterLe
6330
6560
  * @param {Node | number} x - The parameter.
6331
6561
  * @returns {Node}
6332
6562
  */
6333
- const sin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIN ).setParameterLength( 1 );
6563
+ const sin = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.SIN ).setParameterLength( 1 );
6334
6564
 
6335
6565
  /**
6336
6566
  * Returns the cosine of the parameter.
@@ -6340,7 +6570,7 @@ const sin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIN ).setParameterLength
6340
6570
  * @param {Node | number} x - The parameter.
6341
6571
  * @returns {Node}
6342
6572
  */
6343
- const cos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.COS ).setParameterLength( 1 );
6573
+ const cos = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.COS ).setParameterLength( 1 );
6344
6574
 
6345
6575
  /**
6346
6576
  * Returns the tangent of the parameter.
@@ -6350,7 +6580,7 @@ const cos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.COS ).setParameterLength
6350
6580
  * @param {Node | number} x - The parameter.
6351
6581
  * @returns {Node}
6352
6582
  */
6353
- const tan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TAN ).setParameterLength( 1 );
6583
+ const tan = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.TAN ).setParameterLength( 1 );
6354
6584
 
6355
6585
  /**
6356
6586
  * Returns the arcsine of the parameter.
@@ -6360,7 +6590,7 @@ const tan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TAN ).setParameterLength
6360
6590
  * @param {Node | number} x - The parameter.
6361
6591
  * @returns {Node}
6362
6592
  */
6363
- const asin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ASIN ).setParameterLength( 1 );
6593
+ const asin = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ASIN ).setParameterLength( 1 );
6364
6594
 
6365
6595
  /**
6366
6596
  * Returns the arccosine of the parameter.
@@ -6370,7 +6600,7 @@ const asin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ASIN ).setParameterLeng
6370
6600
  * @param {Node | number} x - The parameter.
6371
6601
  * @returns {Node}
6372
6602
  */
6373
- const acos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ACOS ).setParameterLength( 1 );
6603
+ const acos = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ACOS ).setParameterLength( 1 );
6374
6604
 
6375
6605
  /**
6376
6606
  * Returns the arc-tangent of the parameter.
@@ -6382,7 +6612,7 @@ const acos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ACOS ).setParameterLeng
6382
6612
  * @param {?(Node | number)} x - The x parameter.
6383
6613
  * @returns {Node}
6384
6614
  */
6385
- const atan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ATAN ).setParameterLength( 1, 2 );
6615
+ const atan = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ATAN ).setParameterLength( 1, 2 );
6386
6616
 
6387
6617
  /**
6388
6618
  * Returns the absolute value of the parameter.
@@ -6392,7 +6622,7 @@ const atan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ATAN ).setParameterLeng
6392
6622
  * @param {Node | number} x - The parameter.
6393
6623
  * @returns {Node}
6394
6624
  */
6395
- const abs = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ABS ).setParameterLength( 1 );
6625
+ const abs = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ABS ).setParameterLength( 1 );
6396
6626
 
6397
6627
  /**
6398
6628
  * Extracts the sign of the parameter.
@@ -6402,7 +6632,7 @@ const abs = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ABS ).setParameterLength
6402
6632
  * @param {Node | number} x - The parameter.
6403
6633
  * @returns {Node}
6404
6634
  */
6405
- const sign = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIGN ).setParameterLength( 1 );
6635
+ const sign = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.SIGN ).setParameterLength( 1 );
6406
6636
 
6407
6637
  /**
6408
6638
  * Calculates the length of a vector.
@@ -6412,7 +6642,7 @@ const sign = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIGN ).setParameterLeng
6412
6642
  * @param {Node} x - The parameter.
6413
6643
  * @returns {Node<float>}
6414
6644
  */
6415
- const length = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LENGTH ).setParameterLength( 1 );
6645
+ const length = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.LENGTH ).setParameterLength( 1 );
6416
6646
 
6417
6647
  /**
6418
6648
  * Negates the value of the parameter (-x).
@@ -6422,7 +6652,7 @@ const length = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LENGTH ).setParameter
6422
6652
  * @param {Node | number} x - The parameter.
6423
6653
  * @returns {Node}
6424
6654
  */
6425
- const negate = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NEGATE ).setParameterLength( 1 );
6655
+ const negate = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.NEGATE ).setParameterLength( 1 );
6426
6656
 
6427
6657
  /**
6428
6658
  * Return `1` minus the parameter.
@@ -6432,7 +6662,7 @@ const negate = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NEGATE ).setParameter
6432
6662
  * @param {Node | number} x - The parameter.
6433
6663
  * @returns {Node}
6434
6664
  */
6435
- const oneMinus = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ONE_MINUS ).setParameterLength( 1 );
6665
+ const oneMinus = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ONE_MINUS ).setParameterLength( 1 );
6436
6666
 
6437
6667
  /**
6438
6668
  * Returns the partial derivative of the parameter with respect to x.
@@ -6442,7 +6672,7 @@ const oneMinus = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ONE_MINUS ).setPara
6442
6672
  * @param {Node | number} x - The parameter.
6443
6673
  * @returns {Node}
6444
6674
  */
6445
- const dFdx = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDX ).setParameterLength( 1 );
6675
+ const dFdx = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.DFDX ).setParameterLength( 1 );
6446
6676
 
6447
6677
  /**
6448
6678
  * Returns the partial derivative of the parameter with respect to y.
@@ -6452,7 +6682,7 @@ const dFdx = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDX ).setParameterLeng
6452
6682
  * @param {Node | number} x - The parameter.
6453
6683
  * @returns {Node}
6454
6684
  */
6455
- const dFdy = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDY ).setParameterLength( 1 );
6685
+ const dFdy = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.DFDY ).setParameterLength( 1 );
6456
6686
 
6457
6687
  /**
6458
6688
  * Rounds the parameter to the nearest integer.
@@ -6462,7 +6692,7 @@ const dFdy = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDY ).setParameterLeng
6462
6692
  * @param {Node | number} x - The parameter.
6463
6693
  * @returns {Node}
6464
6694
  */
6465
- const round = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ROUND ).setParameterLength( 1 );
6695
+ const round = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.ROUND ).setParameterLength( 1 );
6466
6696
 
6467
6697
  /**
6468
6698
  * Returns the reciprocal of the parameter `(1/x)`.
@@ -6472,7 +6702,7 @@ const round = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ROUND ).setParameterLe
6472
6702
  * @param {Node | number} x - The parameter.
6473
6703
  * @returns {Node}
6474
6704
  */
6475
- const reciprocal = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RECIPROCAL ).setParameterLength( 1 );
6705
+ const reciprocal = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.RECIPROCAL ).setParameterLength( 1 );
6476
6706
 
6477
6707
  /**
6478
6708
  * Truncates the parameter, removing the fractional part.
@@ -6482,7 +6712,7 @@ const reciprocal = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RECIPROCAL ).setP
6482
6712
  * @param {Node | number} x - The parameter.
6483
6713
  * @returns {Node}
6484
6714
  */
6485
- const trunc = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRUNC ).setParameterLength( 1 );
6715
+ const trunc = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.TRUNC ).setParameterLength( 1 );
6486
6716
 
6487
6717
  /**
6488
6718
  * Returns the sum of the absolute derivatives in x and y.
@@ -6492,7 +6722,7 @@ const trunc = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRUNC ).setParameterLe
6492
6722
  * @param {Node | number} x - The parameter.
6493
6723
  * @returns {Node}
6494
6724
  */
6495
- const fwidth = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FWIDTH ).setParameterLength( 1 );
6725
+ const fwidth = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.FWIDTH ).setParameterLength( 1 );
6496
6726
 
6497
6727
  /**
6498
6728
  * Returns the transpose of a matrix.
@@ -6502,7 +6732,27 @@ const fwidth = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FWIDTH ).setParameter
6502
6732
  * @param {Node<mat2|mat3|mat4>} x - The parameter.
6503
6733
  * @returns {Node}
6504
6734
  */
6505
- const transpose = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRANSPOSE ).setParameterLength( 1 );
6735
+ const transpose = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.TRANSPOSE ).setParameterLength( 1 );
6736
+
6737
+ /**
6738
+ * Returns the determinant of a matrix.
6739
+ *
6740
+ * @tsl
6741
+ * @function
6742
+ * @param {Node<mat2|mat3|mat4>} x - The parameter.
6743
+ * @returns {Node<float>}
6744
+ */
6745
+ const determinant = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.DETERMINANT ).setParameterLength( 1 );
6746
+
6747
+ /**
6748
+ * Returns the inverse of a matrix.
6749
+ *
6750
+ * @tsl
6751
+ * @function
6752
+ * @param {Node<mat2|mat3|mat4>} x - The parameter.
6753
+ * @returns {Node<mat2|mat3|mat4>}
6754
+ */
6755
+ const inverse = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.INVERSE ).setParameterLength( 1 );
6506
6756
 
6507
6757
  // 2 inputs
6508
6758
 
@@ -6515,7 +6765,7 @@ const transpose = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRANSPOSE ).setPar
6515
6765
  * @param {string} y - The new type.
6516
6766
  * @returns {Node}
6517
6767
  */
6518
- const bitcast = /*@__PURE__*/ nodeProxy( MathNode, MathNode.BITCAST ).setParameterLength( 2 );
6768
+ const bitcast = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.BITCAST ).setParameterLength( 2 );
6519
6769
 
6520
6770
  /**
6521
6771
  * Returns `true` if `x` equals `y`.
@@ -6542,7 +6792,7 @@ const equals = ( x, y ) => { // @deprecated, r172
6542
6792
  * @param {...(Node | number)} values - The values to compare.
6543
6793
  * @returns {Node}
6544
6794
  */
6545
- const min$1 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MIN ).setParameterLength( 2, Infinity );
6795
+ const min$1 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.MIN ).setParameterLength( 2, Infinity );
6546
6796
 
6547
6797
  /**
6548
6798
  * Returns the greatest of the given values.
@@ -6552,7 +6802,7 @@ const min$1 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MIN ).setParameterLeng
6552
6802
  * @param {...(Node | number)} values - The values to compare.
6553
6803
  * @returns {Node}
6554
6804
  */
6555
- const max$1 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MAX ).setParameterLength( 2, Infinity );
6805
+ const max$1 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.MAX ).setParameterLength( 2, Infinity );
6556
6806
 
6557
6807
  /**
6558
6808
  * Generate a step function by comparing two values.
@@ -6563,7 +6813,7 @@ const max$1 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MAX ).setParameterLeng
6563
6813
  * @param {Node | number} y - The x parameter.
6564
6814
  * @returns {Node}
6565
6815
  */
6566
- const step = /*@__PURE__*/ nodeProxy( MathNode, MathNode.STEP ).setParameterLength( 2 );
6816
+ const step = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.STEP ).setParameterLength( 2 );
6567
6817
 
6568
6818
  /**
6569
6819
  * Calculates the reflection direction for an incident vector.
@@ -6574,7 +6824,7 @@ const step = /*@__PURE__*/ nodeProxy( MathNode, MathNode.STEP ).setParameterLeng
6574
6824
  * @param {Node<vec2|vec3|vec4>} N - The normal vector.
6575
6825
  * @returns {Node<vec2|vec3|vec4>}
6576
6826
  */
6577
- const reflect = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFLECT ).setParameterLength( 2 );
6827
+ const reflect = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.REFLECT ).setParameterLength( 2 );
6578
6828
 
6579
6829
  /**
6580
6830
  * Calculates the distance between two points.
@@ -6585,7 +6835,7 @@ const reflect = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFLECT ).setParamet
6585
6835
  * @param {Node<vec2|vec3|vec4>} y - The second point.
6586
6836
  * @returns {Node<float>}
6587
6837
  */
6588
- const distance = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DISTANCE ).setParameterLength( 2 );
6838
+ const distance = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.DISTANCE ).setParameterLength( 2 );
6589
6839
 
6590
6840
  /**
6591
6841
  * Calculates the absolute difference between two values.
@@ -6596,7 +6846,7 @@ const distance = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DISTANCE ).setParam
6596
6846
  * @param {Node | number} y - The second parameter.
6597
6847
  * @returns {Node}
6598
6848
  */
6599
- const difference = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DIFFERENCE ).setParameterLength( 2 );
6849
+ const difference = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.DIFFERENCE ).setParameterLength( 2 );
6600
6850
 
6601
6851
  /**
6602
6852
  * Calculates the dot product of two vectors.
@@ -6607,18 +6857,18 @@ const difference = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DIFFERENCE ).setP
6607
6857
  * @param {Node<vec2|vec3|vec4>} y - The second vector.
6608
6858
  * @returns {Node<float>}
6609
6859
  */
6610
- const dot = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DOT ).setParameterLength( 2 );
6860
+ const dot = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.DOT ).setParameterLength( 2 );
6611
6861
 
6612
6862
  /**
6613
6863
  * Calculates the cross product of two vectors.
6614
6864
  *
6615
6865
  * @tsl
6616
6866
  * @function
6617
- * @param {Node<vec2|vec3|vec4>} x - The first vector.
6618
- * @param {Node<vec2|vec3|vec4>} y - The second vector.
6619
- * @returns {Node<vec2|vec3|vec4>}
6867
+ * @param {Node<vec2|vec3>} x - The first vector.
6868
+ * @param {Node<vec2|vec3>} y - The second vector.
6869
+ * @returns {Node<float|vec3>}
6620
6870
  */
6621
- const cross = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CROSS ).setParameterLength( 2 );
6871
+ const cross = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.CROSS ).setParameterLength( 2 );
6622
6872
 
6623
6873
  /**
6624
6874
  * Return the value of the first parameter raised to the power of the second one.
@@ -6629,7 +6879,7 @@ const cross = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CROSS ).setParameterLe
6629
6879
  * @param {Node | number} y - The second parameter.
6630
6880
  * @returns {Node}
6631
6881
  */
6632
- const pow = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW ).setParameterLength( 2 );
6882
+ const pow = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW ).setParameterLength( 2 );
6633
6883
 
6634
6884
  /**
6635
6885
  * Returns the square of the parameter.
@@ -6639,7 +6889,7 @@ const pow = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW ).setParameterLength
6639
6889
  * @param {Node | number} x - The first parameter.
6640
6890
  * @returns {Node}
6641
6891
  */
6642
- const pow2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 2 ).setParameterLength( 1 );
6892
+ const pow2 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 2 ).setParameterLength( 1 );
6643
6893
 
6644
6894
  /**
6645
6895
  * Returns the cube of the parameter.
@@ -6649,7 +6899,7 @@ const pow2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 2 ).setParameterLe
6649
6899
  * @param {Node | number} x - The first parameter.
6650
6900
  * @returns {Node}
6651
6901
  */
6652
- const pow3 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 3 ).setParameterLength( 1 );
6902
+ const pow3 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 3 ).setParameterLength( 1 );
6653
6903
 
6654
6904
  /**
6655
6905
  * Returns the fourth power of the parameter.
@@ -6659,7 +6909,7 @@ const pow3 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 3 ).setParameterLe
6659
6909
  * @param {Node | number} x - The first parameter.
6660
6910
  * @returns {Node}
6661
6911
  */
6662
- const pow4 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 4 ).setParameterLength( 1 );
6912
+ const pow4 = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.POW, 4 ).setParameterLength( 1 );
6663
6913
 
6664
6914
  /**
6665
6915
  * Transforms the direction of a vector by a matrix and then normalizes the result.
@@ -6670,7 +6920,7 @@ const pow4 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 4 ).setParameterLe
6670
6920
  * @param {Node<mat2|mat3|mat4>} matrix - The transformation matrix.
6671
6921
  * @returns {Node}
6672
6922
  */
6673
- const transformDirection = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRANSFORM_DIRECTION ).setParameterLength( 2 );
6923
+ const transformDirection = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.TRANSFORM_DIRECTION ).setParameterLength( 2 );
6674
6924
 
6675
6925
  /**
6676
6926
  * Returns the cube root of a number.
@@ -6702,7 +6952,7 @@ const lengthSq = ( a ) => dot( a, a );
6702
6952
  * @param {Node | number} t - The interpolation value.
6703
6953
  * @returns {Node}
6704
6954
  */
6705
- const mix = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MIX ).setParameterLength( 3 );
6955
+ const mix = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.MIX ).setParameterLength( 3 );
6706
6956
 
6707
6957
  /**
6708
6958
  * Constrains a value to lie between two further values.
@@ -6736,7 +6986,7 @@ const saturate = ( value ) => clamp( value );
6736
6986
  * @param {Node<float>} eta - The ratio of indices of refraction.
6737
6987
  * @returns {Node<vec2|vec3|vec4>}
6738
6988
  */
6739
- const refract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFRACT ).setParameterLength( 3 );
6989
+ const refract = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.REFRACT ).setParameterLength( 3 );
6740
6990
 
6741
6991
  /**
6742
6992
  * Performs a Hermite interpolation between two values.
@@ -6748,7 +6998,7 @@ const refract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFRACT ).setParamet
6748
6998
  * @param {Node | number} x - The source value for interpolation.
6749
6999
  * @returns {Node}
6750
7000
  */
6751
- const smoothstep = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SMOOTHSTEP ).setParameterLength( 3 );
7001
+ const smoothstep = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.SMOOTHSTEP ).setParameterLength( 3 );
6752
7002
 
6753
7003
  /**
6754
7004
  * Returns a vector pointing in the same direction as another.
@@ -6760,7 +7010,7 @@ const smoothstep = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SMOOTHSTEP ).setP
6760
7010
  * @param {Node<vec2|vec3|vec4>} Nref - The reference vector.
6761
7011
  * @returns {Node<vec2|vec3|vec4>}
6762
7012
  */
6763
- const faceForward = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FACEFORWARD ).setParameterLength( 3 );
7013
+ const faceForward = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.FACEFORWARD ).setParameterLength( 3 );
6764
7014
 
6765
7015
  /**
6766
7016
  * Returns a random value for the given uv.
@@ -6895,6 +7145,8 @@ addMethodChaining( 'difference', difference );
6895
7145
  addMethodChaining( 'saturate', saturate );
6896
7146
  addMethodChaining( 'cbrt', cbrt );
6897
7147
  addMethodChaining( 'transpose', transpose );
7148
+ addMethodChaining( 'determinant', determinant );
7149
+ addMethodChaining( 'inverse', inverse );
6898
7150
  addMethodChaining( 'rand', rand );
6899
7151
 
6900
7152
  /**
@@ -6968,7 +7220,7 @@ class ConditionalNode extends Node {
6968
7220
 
6969
7221
  // fallback setup
6970
7222
 
6971
- this.setup( builder );
7223
+ builder.flowBuildStage( this, 'setup' );
6972
7224
 
6973
7225
  return this.getNodeType( builder );
6974
7226
 
@@ -7248,19 +7500,38 @@ class ContextNode extends Node {
7248
7500
  */
7249
7501
  const context = /*@__PURE__*/ nodeProxy( ContextNode ).setParameterLength( 1, 2 );
7250
7502
 
7503
+ /**
7504
+ * TSL function for defining a name for the context value for a given node.
7505
+ *
7506
+ * @tsl
7507
+ * @function
7508
+ * @param {Node} node - The node whose context should be modified.
7509
+ * @param {string} name - The name to set.
7510
+ * @returns {ContextNode}
7511
+ */
7512
+ const setName = ( node, name ) => context( node, { nodeName: name } );
7513
+
7251
7514
  /**
7252
7515
  * TSL function for defining a label context value for a given node.
7253
7516
  *
7254
7517
  * @tsl
7255
7518
  * @function
7519
+ * @deprecated
7256
7520
  * @param {Node} node - The node whose context should be modified.
7257
7521
  * @param {string} name - The name/label to set.
7258
7522
  * @returns {ContextNode}
7259
7523
  */
7260
- const label = ( node, name ) => context( node, { label: name } );
7524
+ function label( node, name ) {
7525
+
7526
+ console.warn( 'THREE.TSL: "label()" has been deprecated. Use "setName()" instead.' ); // @deprecated r179
7527
+
7528
+ return setName( node, name );
7529
+
7530
+ }
7261
7531
 
7262
7532
  addMethodChaining( 'context', context );
7263
7533
  addMethodChaining( 'label', label );
7534
+ addMethodChaining( 'setName', setName );
7264
7535
 
7265
7536
  /**
7266
7537
  * Class for representing shader variables as nodes. Variables are created from
@@ -7342,6 +7613,45 @@ class VarNode extends Node {
7342
7613
  */
7343
7614
  this.parents = true;
7344
7615
 
7616
+ /**
7617
+ * This flag is used to indicate that this node is used for intent.
7618
+ *
7619
+ * @type {boolean}
7620
+ * @default false
7621
+ */
7622
+ this.intent = false;
7623
+
7624
+ }
7625
+
7626
+ /**
7627
+ * Sets the intent flag for this node.
7628
+ *
7629
+ * This flag is used to indicate that this node is used for intent
7630
+ * and should not be built directly. Instead, it is used to indicate that
7631
+ * the node should be treated as a variable intent.
7632
+ *
7633
+ * It's useful for assigning variables without needing creating a new variable node.
7634
+ *
7635
+ * @param {boolean} value - The value to set for the intent flag.
7636
+ * @returns {VarNode} This node.
7637
+ */
7638
+ setIntent( value ) {
7639
+
7640
+ this.intent = value;
7641
+
7642
+ return this;
7643
+
7644
+ }
7645
+
7646
+ /**
7647
+ * Returns the intent flag of this node.
7648
+ *
7649
+ * @return {boolean} The intent flag.
7650
+ */
7651
+ getIntent() {
7652
+
7653
+ return this.intent;
7654
+
7345
7655
  }
7346
7656
 
7347
7657
  getMemberType( builder, name ) {
@@ -7362,6 +7672,31 @@ class VarNode extends Node {
7362
7672
 
7363
7673
  }
7364
7674
 
7675
+ getArrayCount( builder ) {
7676
+
7677
+ return this.node.getArrayCount( builder );
7678
+
7679
+ }
7680
+
7681
+ build( ...params ) {
7682
+
7683
+ if ( this.intent === true ) {
7684
+
7685
+ const builder = params[ 0 ];
7686
+ const properties = builder.getNodeProperties( this );
7687
+
7688
+ if ( properties.assign !== true ) {
7689
+
7690
+ return this.node.build( ...params );
7691
+
7692
+ }
7693
+
7694
+ }
7695
+
7696
+ return super.build( ...params );
7697
+
7698
+ }
7699
+
7365
7700
  generate( builder ) {
7366
7701
 
7367
7702
  const { node, name, readOnly } = this;
@@ -7399,7 +7734,7 @@ class VarNode extends Node {
7399
7734
 
7400
7735
  } else {
7401
7736
 
7402
- const count = builder.getArrayCount( node );
7737
+ const count = node.getArrayCount( builder );
7403
7738
 
7404
7739
  declarationPrefix = `const ${ builder.getVar( nodeVar.type, propertyName, count ) }`;
7405
7740
 
@@ -7448,10 +7783,35 @@ const Var = ( node, name = null ) => createVar( node, name ).toStack();
7448
7783
  */
7449
7784
  const Const = ( node, name = null ) => createVar( node, name, true ).toStack();
7450
7785
 
7786
+ //
7787
+ //
7788
+
7789
+ /**
7790
+ * TSL function for creating a var intent node.
7791
+ *
7792
+ * @tsl
7793
+ * @function
7794
+ * @param {Node} node - The node for which a variable should be created.
7795
+ * @param {?string} name - The name of the variable in the shader.
7796
+ * @returns {VarNode}
7797
+ */
7798
+ const VarIntent = ( node ) => {
7799
+
7800
+ if ( getCurrentStack() === null ) {
7801
+
7802
+ return node;
7803
+
7804
+ }
7805
+
7806
+ return createVar( node ).setIntent( true ).toStack();
7807
+
7808
+ };
7809
+
7451
7810
  // Method chaining
7452
7811
 
7453
7812
  addMethodChaining( 'toVar', Var );
7454
7813
  addMethodChaining( 'toConst', Const );
7814
+ addMethodChaining( 'toVarIntent', VarIntent );
7455
7815
 
7456
7816
  // Deprecated
7457
7817
 
@@ -8855,10 +9215,9 @@ class ComputeNode extends Node {
8855
9215
  * Constructs a new compute node.
8856
9216
  *
8857
9217
  * @param {Node} computeNode - TODO
8858
- * @param {number} count - TODO.
8859
- * @param {Array<number>} [workgroupSize=[64]] - TODO.
9218
+ * @param {Array<number>} workgroupSize - TODO.
8860
9219
  */
8861
- constructor( computeNode, count, workgroupSize = [ 64 ] ) {
9220
+ constructor( computeNode, workgroupSize ) {
8862
9221
 
8863
9222
  super( 'void' );
8864
9223
 
@@ -8878,18 +9237,12 @@ class ComputeNode extends Node {
8878
9237
  */
8879
9238
  this.computeNode = computeNode;
8880
9239
 
8881
- /**
8882
- * TODO
8883
- *
8884
- * @type {number}
8885
- */
8886
- this.count = count;
8887
9240
 
8888
9241
  /**
8889
9242
  * TODO
8890
9243
  *
8891
9244
  * @type {Array<number>}
8892
- * @default [64]
9245
+ * @default [ 64 ]
8893
9246
  */
8894
9247
  this.workgroupSize = workgroupSize;
8895
9248
 
@@ -8898,7 +9251,7 @@ class ComputeNode extends Node {
8898
9251
  *
8899
9252
  * @type {number}
8900
9253
  */
8901
- this.dispatchCount = 0;
9254
+ this.count = null;
8902
9255
 
8903
9256
  /**
8904
9257
  * TODO
@@ -8931,7 +9284,19 @@ class ComputeNode extends Node {
8931
9284
  */
8932
9285
  this.onInitFunction = null;
8933
9286
 
8934
- this.updateDispatchCount();
9287
+ }
9288
+
9289
+ setCount( count ) {
9290
+
9291
+ this.count = count;
9292
+
9293
+ return this;
9294
+
9295
+ }
9296
+
9297
+ getCount() {
9298
+
9299
+ return this.count;
8935
9300
 
8936
9301
  }
8937
9302
 
@@ -8950,7 +9315,7 @@ class ComputeNode extends Node {
8950
9315
  * @param {string} name - The name of the uniform.
8951
9316
  * @return {ComputeNode} A reference to this node.
8952
9317
  */
8953
- label( name ) {
9318
+ setName( name ) {
8954
9319
 
8955
9320
  this.name = name;
8956
9321
 
@@ -8959,18 +9324,17 @@ class ComputeNode extends Node {
8959
9324
  }
8960
9325
 
8961
9326
  /**
8962
- * TODO
9327
+ * Sets the {@link ComputeNode#name} property.
9328
+ *
9329
+ * @deprecated
9330
+ * @param {string} name - The name of the uniform.
9331
+ * @return {ComputeNode} A reference to this node.
8963
9332
  */
8964
- updateDispatchCount() {
8965
-
8966
- const { count, workgroupSize } = this;
8967
-
8968
- let size = workgroupSize[ 0 ];
9333
+ label( name ) {
8969
9334
 
8970
- for ( let i = 1; i < workgroupSize.length; i ++ )
8971
- size *= workgroupSize[ i ];
9335
+ console.warn( 'THREE.TSL: "label()" has been deprecated. Use "setName()" instead.' ); // @deprecated r179
8972
9336
 
8973
- this.dispatchCount = Math.ceil( count / size );
9337
+ return this.setName( name );
8974
9338
 
8975
9339
  }
8976
9340
 
@@ -9047,6 +9411,45 @@ class ComputeNode extends Node {
9047
9411
 
9048
9412
  }
9049
9413
 
9414
+ /**
9415
+ * TSL function for creating a compute kernel node.
9416
+ *
9417
+ * @tsl
9418
+ * @function
9419
+ * @param {Node} node - TODO
9420
+ * @param {Array<number>} [workgroupSize=[64]] - TODO.
9421
+ * @returns {AtomicFunctionNode}
9422
+ */
9423
+ const computeKernel = ( node, workgroupSize = [ 64 ] ) => {
9424
+
9425
+ if ( workgroupSize.length === 0 || workgroupSize.length > 3 ) {
9426
+
9427
+ console.error( 'THREE.TSL: compute() workgroupSize must have 1, 2, or 3 elements' );
9428
+
9429
+ }
9430
+
9431
+ for ( let i = 0; i < workgroupSize.length; i ++ ) {
9432
+
9433
+ const val = workgroupSize[ i ];
9434
+
9435
+ if ( typeof val !== 'number' || val <= 0 || ! Number.isInteger( val ) ) {
9436
+
9437
+ console.error( `THREE.TSL: compute() workgroupSize element at index [ ${ i } ] must be a positive integer` );
9438
+
9439
+ }
9440
+
9441
+ }
9442
+
9443
+ // Implicit fill-up to [ x, y, z ] with 1s, just like WGSL treats @workgroup_size when fewer dimensions are specified
9444
+
9445
+ while ( workgroupSize.length < 3 ) workgroupSize.push( 1 );
9446
+
9447
+ //
9448
+
9449
+ return nodeObject( new ComputeNode( nodeObject( node ), workgroupSize ) );
9450
+
9451
+ };
9452
+
9050
9453
  /**
9051
9454
  * TSL function for creating a compute node.
9052
9455
  *
@@ -9057,9 +9460,10 @@ class ComputeNode extends Node {
9057
9460
  * @param {Array<number>} [workgroupSize=[64]] - TODO.
9058
9461
  * @returns {AtomicFunctionNode}
9059
9462
  */
9060
- const compute = ( node, count, workgroupSize ) => nodeObject( new ComputeNode( nodeObject( node ), count, workgroupSize ) );
9463
+ const compute = ( node, count, workgroupSize ) => computeKernel( node, workgroupSize ).setCount( count );
9061
9464
 
9062
9465
  addMethodChaining( 'compute', compute );
9466
+ addMethodChaining( 'computeKernel', computeKernel );
9063
9467
 
9064
9468
  /**
9065
9469
  * This node can be used as a cache management component for another node.
@@ -9643,7 +10047,7 @@ class DebugNode extends TempNode {
9643
10047
  * @param {?Function} [callback=null] - Optional callback function to handle the debug output.
9644
10048
  * @returns {DebugNode}
9645
10049
  */
9646
- const debug = ( node, callback = null ) => nodeObject( new DebugNode( nodeObject( node ), callback ) );
10050
+ const debug = ( node, callback = null ) => nodeObject( new DebugNode( nodeObject( node ), callback ) ).toStack();
9647
10051
 
9648
10052
  addMethodChaining( 'debug', debug );
9649
10053
 
@@ -10544,6 +10948,18 @@ class TextureNode extends UniformNode {
10544
10948
 
10545
10949
  }
10546
10950
 
10951
+ /**
10952
+ * TSL function for creating a texture node that fetches/loads texels without interpolation.
10953
+ *
10954
+ * @param {Node<uvec2>} uvNode - The uv node.
10955
+ * @returns {TextureNode} A texture node representing the texture load.
10956
+ */
10957
+ load( uvNode ) {
10958
+
10959
+ return this.sample( uvNode ).setSampler( false );
10960
+
10961
+ }
10962
+
10547
10963
  /**
10548
10964
  * Samples a blurred version of the texture by defining an internal bias.
10549
10965
  *
@@ -11319,7 +11735,7 @@ const builtin = nodeProxy( BuiltinNode ).setParameterLength( 1 );
11319
11735
  * @tsl
11320
11736
  * @type {UniformNode<uint>}
11321
11737
  */
11322
- const cameraIndex = /*@__PURE__*/ uniform( 0, 'uint' ).label( 'u_cameraIndex' ).setGroup( sharedUniformGroup( 'cameraIndex' ) ).toVarying( 'v_cameraIndex' );
11738
+ const cameraIndex = /*@__PURE__*/ uniform( 0, 'uint' ).setName( 'u_cameraIndex' ).setGroup( sharedUniformGroup( 'cameraIndex' ) ).toVarying( 'v_cameraIndex' );
11323
11739
 
11324
11740
  /**
11325
11741
  * TSL object that represents the `near` value of the camera used for the current render.
@@ -11327,7 +11743,7 @@ const cameraIndex = /*@__PURE__*/ uniform( 0, 'uint' ).label( 'u_cameraIndex' ).
11327
11743
  * @tsl
11328
11744
  * @type {UniformNode<float>}
11329
11745
  */
11330
- const cameraNear = /*@__PURE__*/ uniform( 'float' ).label( 'cameraNear' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.near );
11746
+ const cameraNear = /*@__PURE__*/ uniform( 'float' ).setName( 'cameraNear' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.near );
11331
11747
 
11332
11748
  /**
11333
11749
  * TSL object that represents the `far` value of the camera used for the current render.
@@ -11335,7 +11751,7 @@ const cameraNear = /*@__PURE__*/ uniform( 'float' ).label( 'cameraNear' ).setGro
11335
11751
  * @tsl
11336
11752
  * @type {UniformNode<float>}
11337
11753
  */
11338
- const cameraFar = /*@__PURE__*/ uniform( 'float' ).label( 'cameraFar' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.far );
11754
+ const cameraFar = /*@__PURE__*/ uniform( 'float' ).setName( 'cameraFar' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.far );
11339
11755
 
11340
11756
  /**
11341
11757
  * TSL object that represents the projection matrix of the camera used for the current render.
@@ -11357,13 +11773,13 @@ const cameraProjectionMatrix = /*@__PURE__*/ ( Fn( ( { camera } ) => {
11357
11773
 
11358
11774
  }
11359
11775
 
11360
- const cameraProjectionMatrices = uniformArray( matrices ).setGroup( renderGroup ).label( 'cameraProjectionMatrices' );
11776
+ const cameraProjectionMatrices = uniformArray( matrices ).setGroup( renderGroup ).setName( 'cameraProjectionMatrices' );
11361
11777
 
11362
11778
  cameraProjectionMatrix = cameraProjectionMatrices.element( camera.isMultiViewCamera ? builtin( 'gl_ViewID_OVR' ) : cameraIndex ).toVar( 'cameraProjectionMatrix' );
11363
11779
 
11364
11780
  } else {
11365
11781
 
11366
- cameraProjectionMatrix = uniform( 'mat4' ).label( 'cameraProjectionMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.projectionMatrix );
11782
+ cameraProjectionMatrix = uniform( 'mat4' ).setName( 'cameraProjectionMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.projectionMatrix );
11367
11783
 
11368
11784
  }
11369
11785
 
@@ -11391,13 +11807,13 @@ const cameraProjectionMatrixInverse = /*@__PURE__*/ ( Fn( ( { camera } ) => {
11391
11807
 
11392
11808
  }
11393
11809
 
11394
- const cameraProjectionMatricesInverse = uniformArray( matrices ).setGroup( renderGroup ).label( 'cameraProjectionMatricesInverse' );
11810
+ const cameraProjectionMatricesInverse = uniformArray( matrices ).setGroup( renderGroup ).setName( 'cameraProjectionMatricesInverse' );
11395
11811
 
11396
11812
  cameraProjectionMatrixInverse = cameraProjectionMatricesInverse.element( camera.isMultiViewCamera ? builtin( 'gl_ViewID_OVR' ) : cameraIndex ).toVar( 'cameraProjectionMatrixInverse' );
11397
11813
 
11398
11814
  } else {
11399
11815
 
11400
- cameraProjectionMatrixInverse = uniform( 'mat4' ).label( 'cameraProjectionMatrixInverse' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.projectionMatrixInverse );
11816
+ cameraProjectionMatrixInverse = uniform( 'mat4' ).setName( 'cameraProjectionMatrixInverse' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.projectionMatrixInverse );
11401
11817
 
11402
11818
  }
11403
11819
 
@@ -11425,13 +11841,13 @@ const cameraViewMatrix = /*@__PURE__*/ ( Fn( ( { camera } ) => {
11425
11841
 
11426
11842
  }
11427
11843
 
11428
- const cameraViewMatrices = uniformArray( matrices ).setGroup( renderGroup ).label( 'cameraViewMatrices' );
11844
+ const cameraViewMatrices = uniformArray( matrices ).setGroup( renderGroup ).setName( 'cameraViewMatrices' );
11429
11845
 
11430
11846
  cameraViewMatrix = cameraViewMatrices.element( camera.isMultiViewCamera ? builtin( 'gl_ViewID_OVR' ) : cameraIndex ).toVar( 'cameraViewMatrix' );
11431
11847
 
11432
11848
  } else {
11433
11849
 
11434
- cameraViewMatrix = uniform( 'mat4' ).label( 'cameraViewMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.matrixWorldInverse );
11850
+ cameraViewMatrix = uniform( 'mat4' ).setName( 'cameraViewMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.matrixWorldInverse );
11435
11851
 
11436
11852
  }
11437
11853
 
@@ -11445,7 +11861,7 @@ const cameraViewMatrix = /*@__PURE__*/ ( Fn( ( { camera } ) => {
11445
11861
  * @tsl
11446
11862
  * @type {UniformNode<mat4>}
11447
11863
  */
11448
- const cameraWorldMatrix = /*@__PURE__*/ uniform( 'mat4' ).label( 'cameraWorldMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.matrixWorld );
11864
+ const cameraWorldMatrix = /*@__PURE__*/ uniform( 'mat4' ).setName( 'cameraWorldMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.matrixWorld );
11449
11865
 
11450
11866
  /**
11451
11867
  * TSL object that represents the normal matrix of the camera used for the current render.
@@ -11453,7 +11869,7 @@ const cameraWorldMatrix = /*@__PURE__*/ uniform( 'mat4' ).label( 'cameraWorldMat
11453
11869
  * @tsl
11454
11870
  * @type {UniformNode<mat3>}
11455
11871
  */
11456
- const cameraNormalMatrix = /*@__PURE__*/ uniform( 'mat3' ).label( 'cameraNormalMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.normalMatrix );
11872
+ const cameraNormalMatrix = /*@__PURE__*/ uniform( 'mat3' ).setName( 'cameraNormalMatrix' ).setGroup( renderGroup ).onRenderUpdate( ( { camera } ) => camera.normalMatrix );
11457
11873
 
11458
11874
  /**
11459
11875
  * TSL object that represents the position in world space of the camera used for the current render.
@@ -11461,7 +11877,7 @@ const cameraNormalMatrix = /*@__PURE__*/ uniform( 'mat3' ).label( 'cameraNormalM
11461
11877
  * @tsl
11462
11878
  * @type {UniformNode<vec3>}
11463
11879
  */
11464
- const cameraPosition = /*@__PURE__*/ uniform( new Vector3() ).label( 'cameraPosition' ).setGroup( renderGroup ).onRenderUpdate( ( { camera }, self ) => self.value.setFromMatrixPosition( camera.matrixWorld ) );
11880
+ const cameraPosition = /*@__PURE__*/ uniform( new Vector3() ).setName( 'cameraPosition' ).setGroup( renderGroup ).onRenderUpdate( ( { camera }, self ) => self.value.setFromMatrixPosition( camera.matrixWorld ) );
11465
11881
 
11466
11882
  const _sphere = /*@__PURE__*/ new Sphere();
11467
11883
 
@@ -12070,7 +12486,7 @@ const directionToFaceDirection = /*@__PURE__*/ Fn( ( [ direction ], { material }
12070
12486
  } );
12071
12487
 
12072
12488
  /**
12073
- * TSL object that represents the normal attribute of the current rendered object.
12489
+ * TSL object that represents the normal attribute of the current rendered object in local space.
12074
12490
  *
12075
12491
  * @tsl
12076
12492
  * @type {Node<vec3>}
@@ -12078,7 +12494,7 @@ const directionToFaceDirection = /*@__PURE__*/ Fn( ( [ direction ], { material }
12078
12494
  const normalGeometry = /*@__PURE__*/ attribute( 'normal', 'vec3' );
12079
12495
 
12080
12496
  /**
12081
- * TSL object that represents the vertex normal in local space of the current rendered object.
12497
+ * TSL object that represents the vertex normal of the current rendered object in local space.
12082
12498
  *
12083
12499
  * @tsl
12084
12500
  * @type {Node<vec3>}
@@ -12098,7 +12514,7 @@ const normalLocal = /*@__PURE__*/ ( Fn( ( builder ) => {
12098
12514
  }, 'vec3' ).once() )().toVar( 'normalLocal' );
12099
12515
 
12100
12516
  /**
12101
- * TSL object that represents the flat vertex normal in view space of the current rendered object.
12517
+ * TSL object that represents the flat vertex normal of the current rendered object in view space.
12102
12518
  *
12103
12519
  * @tsl
12104
12520
  * @type {Node<vec3>}
@@ -12106,7 +12522,7 @@ const normalLocal = /*@__PURE__*/ ( Fn( ( builder ) => {
12106
12522
  const normalFlat = /*@__PURE__*/ positionView.dFdx().cross( positionView.dFdy() ).normalize().toVar( 'normalFlat' );
12107
12523
 
12108
12524
  /**
12109
- * TSL object that represents the vertex normal in view space of the current rendered object.
12525
+ * TSL object that represents the vertex normal of the current rendered object in view space.
12110
12526
  *
12111
12527
  * @tsl
12112
12528
  * @type {Node<vec3>}
@@ -12130,7 +12546,7 @@ const normalViewGeometry = /*@__PURE__*/ ( Fn( ( builder ) => {
12130
12546
  }, 'vec3' ).once() )().toVar( 'normalViewGeometry' );
12131
12547
 
12132
12548
  /**
12133
- * TSL object that represents the vertex normal in world space of the current rendered object.
12549
+ * TSL object that represents the vertex normal of the current rendered object in world space.
12134
12550
  *
12135
12551
  * @tsl
12136
12552
  * @type {Node<vec3>}
@@ -12150,7 +12566,7 @@ const normalWorldGeometry = /*@__PURE__*/ ( Fn( ( builder ) => {
12150
12566
  }, 'vec3' ).once() )();
12151
12567
 
12152
12568
  /**
12153
- * TSL object that represents the transformed vertex normal in view space of the current rendered object.
12569
+ * TSL object that represents the vertex normal of the current rendered object in view space.
12154
12570
  *
12155
12571
  * @tsl
12156
12572
  * @type {Node<vec3>}
@@ -12182,7 +12598,7 @@ const normalView = /*@__PURE__*/ ( Fn( ( { subBuildFn, material, context } ) =>
12182
12598
  }, 'vec3' ).once( [ 'NORMAL', 'VERTEX' ] ) )().toVar( 'normalView' );
12183
12599
 
12184
12600
  /**
12185
- * TSL object that represents the transformed vertex normal in world space of the current rendered object.
12601
+ * TSL object that represents the vertex normal of the current rendered object in world space.
12186
12602
  *
12187
12603
  * @tsl
12188
12604
  * @type {Node<vec3>}
@@ -12190,7 +12606,7 @@ const normalView = /*@__PURE__*/ ( Fn( ( { subBuildFn, material, context } ) =>
12190
12606
  const normalWorld = /*@__PURE__*/ normalView.transformDirection( cameraViewMatrix ).toVar( 'normalWorld' );
12191
12607
 
12192
12608
  /**
12193
- * TSL object that represents the transformed clearcoat vertex normal in view space of the current rendered object.
12609
+ * TSL object that represents the clearcoat vertex normal of the current rendered object in view space.
12194
12610
  *
12195
12611
  * @tsl
12196
12612
  * @type {Node<vec3>}
@@ -12264,7 +12680,7 @@ const transformNormalToView = /*@__PURE__*/ Fn( ( [ normal ], builder ) => {
12264
12680
  // Deprecated
12265
12681
 
12266
12682
  /**
12267
- * TSL object that represents the transformed vertex normal in view space of the current rendered object.
12683
+ * TSL object that represents the transformed vertex normal of the current rendered object in view space.
12268
12684
  *
12269
12685
  * @tsl
12270
12686
  * @type {Node<vec3>}
@@ -12278,7 +12694,7 @@ const transformedNormalView = ( Fn( () => { // @deprecated, r177
12278
12694
  } ).once( [ 'NORMAL', 'VERTEX' ] ) )();
12279
12695
 
12280
12696
  /**
12281
- * TSL object that represents the transformed vertex normal in world space of the current rendered object.
12697
+ * TSL object that represents the transformed vertex normal of the current rendered object in world space.
12282
12698
  *
12283
12699
  * @tsl
12284
12700
  * @type {Node<vec3>}
@@ -12292,7 +12708,7 @@ const transformedNormalWorld = ( Fn( () => { // @deprecated, r177
12292
12708
  } ).once( [ 'NORMAL', 'VERTEX' ] ) )();
12293
12709
 
12294
12710
  /**
12295
- * TSL object that represents the transformed clearcoat vertex normal in view space of the current rendered object.
12711
+ * TSL object that represents the transformed clearcoat vertex normal of the current rendered object in view space.
12296
12712
  *
12297
12713
  * @tsl
12298
12714
  * @type {Node<vec3>}
@@ -12780,12 +13196,12 @@ class ReferenceNode extends Node {
12780
13196
  }
12781
13197
 
12782
13198
  /**
12783
- * Sets the label for the internal uniform.
13199
+ * Sets the name for the internal uniform.
12784
13200
  *
12785
13201
  * @param {string} name - The label to set.
12786
13202
  * @return {ReferenceNode} A reference to this node.
12787
13203
  */
12788
- label( name ) {
13204
+ setName( name ) {
12789
13205
 
12790
13206
  this.name = name;
12791
13207
 
@@ -12793,6 +13209,21 @@ class ReferenceNode extends Node {
12793
13209
 
12794
13210
  }
12795
13211
 
13212
+ /**
13213
+ * Sets the label for the internal uniform.
13214
+ *
13215
+ * @deprecated
13216
+ * @param {string} name - The label to set.
13217
+ * @return {ReferenceNode} A reference to this node.
13218
+ */
13219
+ label( name ) {
13220
+
13221
+ console.warn( 'THREE.TSL: "label()" has been deprecated. Use "setName()" instead.' ); // @deprecated r179
13222
+
13223
+ return this.setName( name );
13224
+
13225
+ }
13226
+
12796
13227
  /**
12797
13228
  * Sets the node type which automatically defines the internal
12798
13229
  * uniform type.
@@ -12831,7 +13262,7 @@ class ReferenceNode extends Node {
12831
13262
 
12832
13263
  }
12833
13264
 
12834
- if ( this.name !== null ) node.label( this.name );
13265
+ if ( this.name !== null ) node.setName( this.name );
12835
13266
 
12836
13267
  this.node = node.getSelf();
12837
13268
 
@@ -16842,10 +17273,18 @@ class ViewportTextureNode extends TextureNode {
16842
17273
  */
16843
17274
  constructor( uvNode = screenUV, levelNode = null, framebufferTexture = null ) {
16844
17275
 
17276
+ let defaultFramebuffer = null;
17277
+
16845
17278
  if ( framebufferTexture === null ) {
16846
17279
 
16847
- framebufferTexture = new FramebufferTexture();
16848
- framebufferTexture.minFilter = LinearMipmapLinearFilter;
17280
+ defaultFramebuffer = new FramebufferTexture();
17281
+ defaultFramebuffer.minFilter = LinearMipmapLinearFilter;
17282
+
17283
+ framebufferTexture = defaultFramebuffer;
17284
+
17285
+ } else {
17286
+
17287
+ defaultFramebuffer = framebufferTexture;
16849
17288
 
16850
17289
  }
16851
17290
 
@@ -16859,6 +17298,16 @@ class ViewportTextureNode extends TextureNode {
16859
17298
  */
16860
17299
  this.generateMipmaps = false;
16861
17300
 
17301
+ /**
17302
+ * The reference framebuffer texture. This is used to store the framebuffer texture
17303
+ * for the current render target. If the render target changes, a new framebuffer texture
17304
+ * is created automatically.
17305
+ *
17306
+ * @type {FramebufferTexture}
17307
+ * @default null
17308
+ */
17309
+ this.defaultFramebuffer = defaultFramebuffer;
17310
+
16862
17311
  /**
16863
17312
  * This flag can be used for type testing.
16864
17313
  *
@@ -16869,24 +17318,64 @@ class ViewportTextureNode extends TextureNode {
16869
17318
  this.isOutputTextureNode = true;
16870
17319
 
16871
17320
  /**
16872
- * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders the
16873
- * scene once per frame in its {@link ViewportTextureNode#updateBefore} method.
17321
+ * The `updateBeforeType` is set to `NodeUpdateType.RENDER` since the node renders the
17322
+ * scene once per render in its {@link ViewportTextureNode#updateBefore} method.
16874
17323
  *
16875
17324
  * @type {string}
16876
17325
  * @default 'frame'
16877
17326
  */
16878
- this.updateBeforeType = NodeUpdateType.FRAME;
17327
+ this.updateBeforeType = NodeUpdateType.RENDER;
17328
+
17329
+ /**
17330
+ * The framebuffer texture for the current renderer context.
17331
+ *
17332
+ * @type {WeakMap<RenderTarget, FramebufferTexture>}
17333
+ * @private
17334
+ */
17335
+ this._textures = new WeakMap();
17336
+
17337
+ }
17338
+
17339
+ getFrameBufferTexture( reference = null ) {
17340
+
17341
+ const defaultFramebuffer = this.referenceNode ? this.referenceNode.defaultFramebuffer : this.defaultFramebuffer;
17342
+
17343
+ if ( reference === null ) {
17344
+
17345
+ return defaultFramebuffer;
17346
+
17347
+ }
17348
+
17349
+ if ( this._textures.has( reference ) === false ) {
17350
+
17351
+ const framebufferTexture = defaultFramebuffer.clone();
17352
+
17353
+ this._textures.set( reference, framebufferTexture );
17354
+
17355
+ }
17356
+
17357
+ return this._textures.get( reference );
16879
17358
 
16880
17359
  }
16881
17360
 
16882
17361
  updateBefore( frame ) {
16883
17362
 
16884
17363
  const renderer = frame.renderer;
16885
- renderer.getDrawingBufferSize( _size$4 );
17364
+ const renderTarget = renderer.getRenderTarget();
17365
+
17366
+ if ( renderTarget === null ) {
17367
+
17368
+ renderer.getDrawingBufferSize( _size$4 );
17369
+
17370
+ } else {
17371
+
17372
+ _size$4.set( renderTarget.width, renderTarget.height );
17373
+
17374
+ }
16886
17375
 
16887
17376
  //
16888
17377
 
16889
- const framebufferTexture = this.value;
17378
+ const framebufferTexture = this.getFrameBufferTexture( renderTarget );
16890
17379
 
16891
17380
  if ( framebufferTexture.image.width !== _size$4.width || framebufferTexture.image.height !== _size$4.height ) {
16892
17381
 
@@ -16905,6 +17394,8 @@ class ViewportTextureNode extends TextureNode {
16905
17394
 
16906
17395
  framebufferTexture.generateMipmaps = currentGenerateMipmaps;
16907
17396
 
17397
+ this.value = framebufferTexture;
17398
+
16908
17399
  }
16909
17400
 
16910
17401
  clone() {
@@ -18966,7 +19457,7 @@ class NodeMaterial extends Material {
18966
19457
 
18967
19458
  output.assign( outputNode );
18968
19459
 
18969
- outputNode = vec4( fogNode );
19460
+ outputNode = vec4( fogNode.toVar() );
18970
19461
 
18971
19462
  }
18972
19463
 
@@ -19432,14 +19923,6 @@ class Line2NodeMaterial extends NodeMaterial {
19432
19923
  */
19433
19924
  this.dashOffset = 0;
19434
19925
 
19435
- /**
19436
- * The line width.
19437
- *
19438
- * @type {number}
19439
- * @default 0
19440
- */
19441
- this.lineWidth = 1;
19442
-
19443
19926
  /**
19444
19927
  * Defines the lines color.
19445
19928
  *
@@ -22105,7 +22588,7 @@ class PhysicalLightingModel extends LightingModel {
22105
22588
  * @param {Object} lightData - The light data.
22106
22589
  * @param {NodeBuilder} builder - The current node builder.
22107
22590
  */
22108
- direct( { lightDirection, lightColor, reflectedLight } ) {
22591
+ direct( { lightDirection, lightColor, reflectedLight }, /* builder */ ) {
22109
22592
 
22110
22593
  const dotNL = normalView.dot( lightDirection ).clamp();
22111
22594
  const irradiance = dotNL.mul( lightColor );
@@ -22138,7 +22621,7 @@ class PhysicalLightingModel extends LightingModel {
22138
22621
  * @param {Object} input - The input data.
22139
22622
  * @param {NodeBuilder} builder - The current node builder.
22140
22623
  */
22141
- directRectArea( { lightColor, lightPosition, halfWidth, halfHeight, reflectedLight, ltc_1, ltc_2 } ) {
22624
+ directRectArea( { lightColor, lightPosition, halfWidth, halfHeight, reflectedLight, ltc_1, ltc_2 }, /* builder */ ) {
22142
22625
 
22143
22626
  const p0 = lightPosition.add( halfWidth ).sub( halfHeight ); // counterclockwise; light shines in local neg z direction
22144
22627
  const p1 = lightPosition.sub( halfWidth ).sub( halfHeight );
@@ -25407,6 +25890,11 @@ class PointsNodeMaterial extends SpriteNodeMaterial {
25407
25890
  /**
25408
25891
  * This node property provides an additional way to set the point size.
25409
25892
  *
25893
+ * Note that WebGPU only supports point primitives with 1 pixel size. Consequently,
25894
+ * this node has no effect when the material is used with {@link Points} and a WebGPU
25895
+ * backend. If an application wants to render points with a size larger than 1 pixel,
25896
+ * the material should be used with {@link Sprite} and instancing.
25897
+ *
25410
25898
  * @type {?Node<vec2>}
25411
25899
  * @default null
25412
25900
  */
@@ -28829,24 +29317,31 @@ class Bindings extends DataMap {
28829
29317
 
28830
29318
  }
28831
29319
 
28832
- } else if ( binding.isSampler ) {
28833
-
28834
- binding.update();
28835
-
28836
29320
  } else if ( binding.isSampledTexture ) {
28837
29321
 
28838
- const texturesTextureData = this.textures.get( binding.texture );
28839
-
28840
- if ( binding.needsBindingsUpdate( texturesTextureData.generation ) ) needsBindingsUpdate = true;
28841
-
28842
29322
  const updated = binding.update();
28843
29323
 
29324
+ // get the texture data after the update, to sync the texture reference from node
29325
+
28844
29326
  const texture = binding.texture;
29327
+ const texturesTextureData = this.textures.get( texture );
28845
29328
 
28846
29329
  if ( updated ) {
28847
29330
 
29331
+ // version: update the texture data or create a new one
29332
+
28848
29333
  this.textures.updateTexture( texture );
28849
29334
 
29335
+ // generation: update the bindings if a new texture has been created
29336
+
29337
+ if ( binding.generation !== texturesTextureData.generation ) {
29338
+
29339
+ binding.generation = texturesTextureData.generation;
29340
+
29341
+ needsBindingsUpdate = true;
29342
+
29343
+ }
29344
+
28850
29345
  }
28851
29346
 
28852
29347
  const textureData = backend.get( texture );
@@ -28862,16 +29357,6 @@ class Bindings extends DataMap {
28862
29357
 
28863
29358
  }
28864
29359
 
28865
- if ( backend.isWebGPUBackend === true && textureData.texture === undefined && textureData.externalTexture === undefined ) {
28866
-
28867
- // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend
28868
- console.error( 'Bindings._update: binding should be available:', binding, updated, texture, binding.textureNode.value, needsBindingsUpdate );
28869
-
28870
- this.textures.updateTexture( texture );
28871
- needsBindingsUpdate = true;
28872
-
28873
- }
28874
-
28875
29360
  if ( texture.isStorageTexture === true ) {
28876
29361
 
28877
29362
  const textureData = this.get( texture );
@@ -28890,6 +29375,10 @@ class Bindings extends DataMap {
28890
29375
 
28891
29376
  }
28892
29377
 
29378
+ } else if ( binding.isSampler ) {
29379
+
29380
+ binding.update();
29381
+
28893
29382
  }
28894
29383
 
28895
29384
  }
@@ -30107,9 +30596,25 @@ class Textures extends DataMap {
30107
30596
 
30108
30597
  if ( image.image !== undefined ) image = image.image;
30109
30598
 
30110
- target.width = image.width || 1;
30111
- target.height = image.height || 1;
30112
- target.depth = texture.isCubeTexture ? 6 : ( image.depth || 1 );
30599
+ if ( image instanceof HTMLVideoElement ) {
30600
+
30601
+ target.width = image.videoWidth || 1;
30602
+ target.height = image.videoHeight || 1;
30603
+ target.depth = 1;
30604
+
30605
+ } else if ( image instanceof VideoFrame ) {
30606
+
30607
+ target.width = image.displayWidth || 1;
30608
+ target.height = image.displayHeight || 1;
30609
+ target.depth = 1;
30610
+
30611
+ } else {
30612
+
30613
+ target.width = image.width || 1;
30614
+ target.height = image.height || 1;
30615
+ target.depth = texture.isCubeTexture ? 6 : ( image.depth || 1 );
30616
+
30617
+ }
30113
30618
 
30114
30619
  } else {
30115
30620
 
@@ -30224,8 +30729,8 @@ class Color4 extends Color {
30224
30729
  * string argument to this method.
30225
30730
  *
30226
30731
  * @param {number|string|Color} r - The red value.
30227
- * @param {number} g - The green value.
30228
- * @param {number} b - The blue value.
30732
+ * @param {number} [g] - The green value.
30733
+ * @param {number} [b] - The blue value.
30229
30734
  * @param {number} [a=1] - The alpha value.
30230
30735
  * @return {Color4} A reference to this object.
30231
30736
  */
@@ -30566,6 +31071,36 @@ class StackNode extends Node {
30566
31071
 
30567
31072
  }
30568
31073
 
31074
+ setup( builder ) {
31075
+
31076
+ const nodeProperties = builder.getNodeProperties( this );
31077
+
31078
+ let index = 0;
31079
+
31080
+ for ( const childNode of this.getChildren() ) {
31081
+
31082
+ if ( childNode.isVarNode && childNode.intent === true ) {
31083
+
31084
+ const properties = builder.getNodeProperties( childNode );
31085
+
31086
+ if ( properties.assign !== true ) {
31087
+
31088
+ continue;
31089
+
31090
+ }
31091
+
31092
+ }
31093
+
31094
+ nodeProperties[ 'node' + index ++ ] = childNode;
31095
+
31096
+ }
31097
+
31098
+ // return a outputNode if exists or null
31099
+
31100
+ return nodeProperties.outputNode || null;
31101
+
31102
+ }
31103
+
30569
31104
  build( builder, ...params ) {
30570
31105
 
30571
31106
  const previousBuildStack = builder.currentStack;
@@ -30579,6 +31114,18 @@ class StackNode extends Node {
30579
31114
 
30580
31115
  for ( const node of this.nodes ) {
30581
31116
 
31117
+ if ( node.isVarNode && node.intent === true ) {
31118
+
31119
+ const properties = builder.getNodeProperties( node );
31120
+
31121
+ if ( properties.assign !== true ) {
31122
+
31123
+ continue;
31124
+
31125
+ }
31126
+
31127
+ }
31128
+
30582
31129
  if ( buildStage === 'setup' ) {
30583
31130
 
30584
31131
  node.build( builder );
@@ -32492,6 +33039,15 @@ class RTTNode extends TextureNode {
32492
33039
 
32493
33040
  super( renderTarget.texture, uv$1() );
32494
33041
 
33042
+ /**
33043
+ * This flag can be used for type testing.
33044
+ *
33045
+ * @type {boolean}
33046
+ * @readonly
33047
+ * @default true
33048
+ */
33049
+ this.isRTTNode = true;
33050
+
32495
33051
  /**
32496
33052
  * The node to render a texture with.
32497
33053
  *
@@ -32885,6 +33441,84 @@ class SampleNode extends Node {
32885
33441
  */
32886
33442
  const sample = ( callback ) => nodeObject( new SampleNode( callback ) );
32887
33443
 
33444
+ /**
33445
+ * EventNode is a node that executes a callback during specific update phases.
33446
+ *
33447
+ * @augments Node
33448
+ */
33449
+ class EventNode extends Node {
33450
+
33451
+ static get type() {
33452
+
33453
+ return 'EventNode';
33454
+
33455
+ }
33456
+
33457
+ /**
33458
+ * Creates an EventNode.
33459
+ *
33460
+ * @param {string} eventType - The type of event
33461
+ * @param {Function} callback - The callback to execute on update.
33462
+ */
33463
+ constructor( eventType, callback ) {
33464
+
33465
+ super( 'void' );
33466
+
33467
+ this.eventType = eventType;
33468
+ this.callback = callback;
33469
+
33470
+ if ( eventType === EventNode.OBJECT ) {
33471
+
33472
+ this.updateType = NodeUpdateType.OBJECT;
33473
+
33474
+ } else if ( eventType === EventNode.MATERIAL ) {
33475
+
33476
+ this.updateType = NodeUpdateType.RENDER;
33477
+
33478
+ }
33479
+
33480
+ }
33481
+
33482
+ update( frame ) {
33483
+
33484
+ this.callback( frame );
33485
+
33486
+ }
33487
+
33488
+ }
33489
+
33490
+ EventNode.OBJECT = 'object';
33491
+ EventNode.MATERIAL = 'material';
33492
+
33493
+ /**
33494
+ * Helper to create an EventNode and add it to the stack.
33495
+ *
33496
+ * @param {string} type - The event type.
33497
+ * @param {Function} callback - The callback function.
33498
+ * @returns {EventNode}
33499
+ */
33500
+ const createEvent = ( type, callback ) => nodeObject( new EventNode( type, callback ) ).toStack();
33501
+
33502
+ /**
33503
+ * Creates an event that triggers a function every time an object (Mesh|Sprite) is rendered.
33504
+ *
33505
+ * 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.
33506
+ *
33507
+ * @param {Function} callback - The callback function.
33508
+ * @returns {EventNode}
33509
+ */
33510
+ const OnObjectUpdate = ( callback ) => createEvent( EventNode.OBJECT, callback );
33511
+
33512
+ /**
33513
+ * Creates an event that triggers a function when the first object that uses the material is rendered.
33514
+ *
33515
+ * 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.
33516
+ *
33517
+ * @param {Function} callback - The callback function.
33518
+ * @returns {EventNode}
33519
+ */
33520
+ const OnMaterialUpdate = ( callback ) => createEvent( EventNode.MATERIAL, callback );
33521
+
32888
33522
  /**
32889
33523
  * This special type of instanced buffer attribute is intended for compute shaders.
32890
33524
  * In earlier three.js versions it was only possible to update attribute data
@@ -33158,7 +33792,7 @@ class SceneNode extends Node {
33158
33792
 
33159
33793
  } else if ( scope === SceneNode.BACKGROUND_ROTATION ) {
33160
33794
 
33161
- output = uniform( 'mat4' ).label( 'backgroundRotation' ).setGroup( renderGroup ).onRenderUpdate( () => {
33795
+ output = uniform( 'mat4' ).setName( 'backgroundRotation' ).setGroup( renderGroup ).onRenderUpdate( () => {
33162
33796
 
33163
33797
  const background = scene.background;
33164
33798
 
@@ -33405,7 +34039,7 @@ class StorageTextureNode extends TextureNode {
33405
34039
  const { uvNode, storeNode, depthNode } = properties;
33406
34040
 
33407
34041
  const textureProperty = super.generate( builder, 'property' );
33408
- const uvSnippet = uvNode.build( builder, 'uvec2' );
34042
+ const uvSnippet = uvNode.build( builder, this.value.is3DTexture === true ? 'uvec3' : 'uvec2' );
33409
34043
  const storeSnippet = storeNode.build( builder, 'vec4' );
33410
34044
  const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
33411
34045
 
@@ -33492,9 +34126,9 @@ const normal = Fn( ( { texture, uv } ) => {
33492
34126
 
33493
34127
  const step = 0.01;
33494
34128
 
33495
- const x = texture.sample( uv.add( vec3( -0.01, 0.0, 0.0 ) ) ).r.sub( texture.sample( uv.add( vec3( step, 0.0, 0.0 ) ) ).r );
33496
- const y = texture.sample( uv.add( vec3( 0.0, -0.01, 0.0 ) ) ).r.sub( texture.sample( uv.add( vec3( 0.0, step, 0.0 ) ) ).r );
33497
- const z = texture.sample( uv.add( vec3( 0.0, 0.0, -0.01 ) ) ).r.sub( texture.sample( uv.add( vec3( 0.0, 0.0, step ) ) ).r );
34129
+ const x = texture.sample( uv.add( vec3( - step, 0.0, 0.0 ) ) ).r.sub( texture.sample( uv.add( vec3( step, 0.0, 0.0 ) ) ).r );
34130
+ const y = texture.sample( uv.add( vec3( 0.0, - step, 0.0 ) ) ).r.sub( texture.sample( uv.add( vec3( 0.0, step, 0.0 ) ) ).r );
34131
+ const z = texture.sample( uv.add( vec3( 0.0, 0.0, - step ) ) ).r.sub( texture.sample( uv.add( vec3( 0.0, 0.0, step ) ) ).r );
33498
34132
 
33499
34133
  ret.assign( vec3( x, y, z ) );
33500
34134
 
@@ -34158,7 +34792,7 @@ class PassTextureNode extends TextureNode {
34158
34792
 
34159
34793
  setup( builder ) {
34160
34794
 
34161
- if ( builder.object.isQuadMesh ) this.passNode.build( builder );
34795
+ this.passNode.build( builder );
34162
34796
 
34163
34797
  return super.setup( builder );
34164
34798
 
@@ -34433,10 +35067,43 @@ class PassNode extends TempNode {
34433
35067
  */
34434
35068
  this._mrt = null;
34435
35069
 
35070
+ /**
35071
+ * Layer object for configuring the camera that is used
35072
+ * to produce the pass.
35073
+ *
35074
+ * @private
35075
+ * @type {?Layers}
35076
+ * @default null
35077
+ */
34436
35078
  this._layers = null;
34437
35079
 
35080
+ /**
35081
+ * Scales the resolution of the internal render target.
35082
+ *
35083
+ * @private
35084
+ * @type {number}
35085
+ * @default 1
35086
+ */
34438
35087
  this._resolution = 1;
34439
35088
 
35089
+ /**
35090
+ * Custom viewport definition.
35091
+ *
35092
+ * @private
35093
+ * @type {?Vector4}
35094
+ * @default null
35095
+ */
35096
+ this._viewport = null;
35097
+
35098
+ /**
35099
+ * Custom scissor definition.
35100
+ *
35101
+ * @private
35102
+ * @type {?Vector4}
35103
+ * @default null
35104
+ */
35105
+ this._scissor = null;
35106
+
34440
35107
  /**
34441
35108
  * This flag can be used for type testing.
34442
35109
  *
@@ -34484,7 +35151,6 @@ class PassNode extends TempNode {
34484
35151
  * Gets the current resolution of the pass.
34485
35152
  *
34486
35153
  * @return {number} The current resolution. A value of `1` means full resolution.
34487
- * @default 1
34488
35154
  */
34489
35155
  getResolution() {
34490
35156
 
@@ -34492,6 +35158,12 @@ class PassNode extends TempNode {
34492
35158
 
34493
35159
  }
34494
35160
 
35161
+ /**
35162
+ * Sets the layer configuration that should be used when rendering the pass.
35163
+ *
35164
+ * @param {Layers} layers - The layers object to set.
35165
+ * @return {PassNode} A reference to this pass.
35166
+ */
34495
35167
  setLayers( layers ) {
34496
35168
 
34497
35169
  this._layers = layers;
@@ -34500,6 +35172,11 @@ class PassNode extends TempNode {
34500
35172
 
34501
35173
  }
34502
35174
 
35175
+ /**
35176
+ * Gets the current layer configuration of the pass.
35177
+ *
35178
+ * @return {?Layers} .
35179
+ */
34503
35180
  getLayers() {
34504
35181
 
34505
35182
  return this._layers;
@@ -34701,6 +35378,32 @@ class PassNode extends TempNode {
34701
35378
 
34702
35379
  }
34703
35380
 
35381
+ /**
35382
+ * Precompiles the pass.
35383
+ *
35384
+ * Note that this method must be called after the pass configuartion is complete.
35385
+ * So calls like `setMRT()` and `getTextureNode()` must proceed the precompilation.
35386
+ *
35387
+ * @async
35388
+ * @param {Renderer} renderer - The renderer.
35389
+ * @return {Promise} A Promise that resolves when the compile has been finished.
35390
+ * @see {@link Renderer#compileAsync}
35391
+ */
35392
+ async compileAsync( renderer ) {
35393
+
35394
+ const currentRenderTarget = renderer.getRenderTarget();
35395
+ const currentMRT = renderer.getMRT();
35396
+
35397
+ renderer.setRenderTarget( this.renderTarget );
35398
+ renderer.setMRT( this._mrt );
35399
+
35400
+ await renderer.compileAsync( this.scene, this.camera );
35401
+
35402
+ renderer.setRenderTarget( currentRenderTarget );
35403
+ renderer.setMRT( currentMRT );
35404
+
35405
+ }
35406
+
34704
35407
  setup( { renderer } ) {
34705
35408
 
34706
35409
  this.renderTarget.samples = this.options.samples === undefined ? renderer.samples : this.options.samples;
@@ -34790,6 +35493,82 @@ class PassNode extends TempNode {
34790
35493
 
34791
35494
  this.renderTarget.setSize( effectiveWidth, effectiveHeight );
34792
35495
 
35496
+ if ( this._scissor !== null ) this.renderTarget.scissor.copy( this._scissor );
35497
+ if ( this._viewport !== null ) this.renderTarget.viewport.copy( this._viewport );
35498
+
35499
+ }
35500
+
35501
+ /**
35502
+ * This method allows to define the pass's scissor rectangle. By default, the scissor rectangle is kept
35503
+ * in sync with the pass's dimensions. To reverse the process and use auto-sizing again, call the method
35504
+ * with `null` as the single argument.
35505
+ *
35506
+ * @param {?(number | Vector4)} x - The horizontal coordinate for the lower left corner of the box in logical pixel unit.
35507
+ * Instead of passing four arguments, the method also works with a single four-dimensional vector.
35508
+ * @param {number} y - The vertical coordinate for the lower left corner of the box in logical pixel unit.
35509
+ * @param {number} width - The width of the scissor box in logical pixel unit.
35510
+ * @param {number} height - The height of the scissor box in logical pixel unit.
35511
+ */
35512
+ setScissor( x, y, width, height ) {
35513
+
35514
+ if ( x === null ) {
35515
+
35516
+ this._scissor = null;
35517
+
35518
+ } else {
35519
+
35520
+ if ( this._scissor === null ) this._scissor = new Vector4();
35521
+
35522
+ if ( x.isVector4 ) {
35523
+
35524
+ this._scissor.copy( x );
35525
+
35526
+ } else {
35527
+
35528
+ this._scissor.set( x, y, width, height );
35529
+
35530
+ }
35531
+
35532
+ this._scissor.multiplyScalar( this._pixelRatio * this._resolution ).floor();
35533
+
35534
+ }
35535
+
35536
+ }
35537
+
35538
+ /**
35539
+ * This method allows to define the pass's viewport. By default, the viewport is kept in sync
35540
+ * with the pass's dimensions. To reverse the process and use auto-sizing again, call the method
35541
+ * with `null` as the single argument.
35542
+ *
35543
+ * @param {number | Vector4} x - The horizontal coordinate for the lower left corner of the viewport origin in logical pixel unit.
35544
+ * @param {number} y - The vertical coordinate for the lower left corner of the viewport origin in logical pixel unit.
35545
+ * @param {number} width - The width of the viewport in logical pixel unit.
35546
+ * @param {number} height - The height of the viewport in logical pixel unit.
35547
+ */
35548
+ setViewport( x, y, width, height ) {
35549
+
35550
+ if ( x === null ) {
35551
+
35552
+ this._viewport = null;
35553
+
35554
+ } else {
35555
+
35556
+ if ( this._viewport === null ) this._viewport = new Vector4();
35557
+
35558
+ if ( x.isVector4 ) {
35559
+
35560
+ this._viewport.copy( x );
35561
+
35562
+ } else {
35563
+
35564
+ this._viewport.set( x, y, width, height );
35565
+
35566
+ }
35567
+
35568
+ this._viewport.multiplyScalar( this._pixelRatio * this._resolution ).floor();
35569
+
35570
+ }
35571
+
34793
35572
  }
34794
35573
 
34795
35574
  /**
@@ -37265,15 +38044,23 @@ class WorkgroupInfoNode extends Node {
37265
38044
  */
37266
38045
  this.scope = scope;
37267
38046
 
38047
+ /**
38048
+ * The name of the workgroup scoped buffer.
38049
+ *
38050
+ * @type {string}
38051
+ * @default ''
38052
+ */
38053
+ this.name = '';
38054
+
37268
38055
  }
37269
38056
 
37270
38057
  /**
37271
- * Sets the name/label of this node.
38058
+ * Sets the name of this node.
37272
38059
  *
37273
38060
  * @param {string} name - The name to set.
37274
38061
  * @return {WorkgroupInfoNode} A reference to this node.
37275
38062
  */
37276
- label( name ) {
38063
+ setName( name ) {
37277
38064
 
37278
38065
  this.name = name;
37279
38066
 
@@ -37281,6 +38068,21 @@ class WorkgroupInfoNode extends Node {
37281
38068
 
37282
38069
  }
37283
38070
 
38071
+ /**
38072
+ * Sets the name/label of this node.
38073
+ *
38074
+ * @deprecated
38075
+ * @param {string} name - The name to set.
38076
+ * @return {WorkgroupInfoNode} A reference to this node.
38077
+ */
38078
+ label( name ) {
38079
+
38080
+ console.warn( 'THREE.TSL: "label()" has been deprecated. Use "setName()" instead.' ); // @deprecated r179
38081
+
38082
+ return this.setName( name );
38083
+
38084
+ }
38085
+
37284
38086
  /**
37285
38087
  * Sets the scope of this node.
37286
38088
  *
@@ -37334,7 +38136,9 @@ class WorkgroupInfoNode extends Node {
37334
38136
 
37335
38137
  generate( builder ) {
37336
38138
 
37337
- return builder.getScopedArray( this.name || `${this.scope}Array_${this.id}`, this.scope.toLowerCase(), this.bufferType, this.bufferCount );
38139
+ const name = ( this.name !== '' ) ? this.name : `${this.scope}Array_${this.id}`;
38140
+
38141
+ return builder.getScopedArray( name, this.scope.toLowerCase(), this.bufferType, this.bufferCount );
37338
38142
 
37339
38143
  }
37340
38144
 
@@ -37463,7 +38267,7 @@ class AtomicFunctionNode extends Node {
37463
38267
  }
37464
38268
 
37465
38269
  const methodSnippet = `${ builder.getMethod( method, type ) }( ${ params.join( ', ' ) } )`;
37466
- const isVoid = parents.length === 1 && parents[ 0 ].isStackNode === true;
38270
+ const isVoid = parents ? ( parents.length === 1 && parents[ 0 ].isStackNode === true ) : false;
37467
38271
 
37468
38272
  if ( isVoid ) {
37469
38273
 
@@ -38486,7 +39290,7 @@ const shadowMaterialLib = /*@__PURE__*/ new WeakMap();
38486
39290
  */
38487
39291
  const BasicShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, depthLayer } ) => {
38488
39292
 
38489
- let basic = texture( depthTexture, shadowCoord.xy ).label( 't_basic' );
39293
+ let basic = texture( depthTexture, shadowCoord.xy ).setName( 't_basic' );
38490
39294
 
38491
39295
  if ( depthTexture.isArrayTexture ) {
38492
39296
 
@@ -41487,6 +42291,170 @@ const mx_worley_noise_vec3_1 = /*@__PURE__*/ Fn( ( [ p_immutable, jitter_immutab
41487
42291
 
41488
42292
  const mx_worley_noise_vec3$1 = /*@__PURE__*/ overloadingFn( [ mx_worley_noise_vec3_0, mx_worley_noise_vec3_1 ] );
41489
42293
 
42294
+ // Unified Noise 2D
42295
+ const mx_unifiednoise2d$1 = /*@__PURE__*/ Fn( ( [
42296
+ noiseType_immutable, texcoord_immutable, freq_immutable, offset_immutable,
42297
+ jitter_immutable, outmin_immutable, outmax_immutable, clampoutput_immutable,
42298
+ octaves_immutable, lacunarity_immutable, diminish_immutable
42299
+ ] ) => {
42300
+
42301
+ const noiseType = int( noiseType_immutable ).toVar();
42302
+ const texcoord = vec2( texcoord_immutable ).toVar();
42303
+ const freq = vec2( freq_immutable ).toVar();
42304
+ const offset = vec2( offset_immutable ).toVar();
42305
+ const jitter = float( jitter_immutable ).toVar();
42306
+ const outmin = float( outmin_immutable ).toVar();
42307
+ const outmax = float( outmax_immutable ).toVar();
42308
+ const clampoutput = bool( clampoutput_immutable ).toVar();
42309
+ const octaves = int( octaves_immutable ).toVar();
42310
+ const lacunarity = float( lacunarity_immutable ).toVar();
42311
+ const diminish = float( diminish_immutable ).toVar();
42312
+
42313
+ // Compute input position
42314
+ const p = texcoord.mul( freq ).add( offset );
42315
+
42316
+ const result = float( 0.0 ).toVar();
42317
+
42318
+ // Perlin
42319
+ If( noiseType.equal( int( 0 ) ), () => {
42320
+
42321
+ result.assign( mx_perlin_noise_vec3( p ) );
42322
+
42323
+ } );
42324
+
42325
+ // Cell
42326
+ If( noiseType.equal( int( 1 ) ), () => {
42327
+
42328
+ result.assign( mx_cell_noise_vec3( p ) );
42329
+
42330
+ } );
42331
+
42332
+ // Worley (metric=0 = euclidean)
42333
+ If( noiseType.equal( int( 2 ) ), () => {
42334
+
42335
+ result.assign( mx_worley_noise_vec3$1( p, jitter, int( 0 ) ) );
42336
+
42337
+ } );
42338
+
42339
+ // Fractal (use vec3(p, 0.0) for 2D input)
42340
+ If( noiseType.equal( int( 3 ) ), () => {
42341
+
42342
+ result.assign( mx_fractal_noise_vec3$1( vec3( p, 0.0 ), octaves, lacunarity, diminish ) );
42343
+
42344
+ } );
42345
+
42346
+ // Remap output to [outmin, outmax]
42347
+ result.assign( result.mul( outmax.sub( outmin ) ).add( outmin ) );
42348
+
42349
+ // Clamp if requested
42350
+ If( clampoutput, () => {
42351
+
42352
+ result.assign( clamp( result, outmin, outmax ) );
42353
+
42354
+ } );
42355
+
42356
+ return result;
42357
+
42358
+ } ).setLayout( {
42359
+ name: 'mx_unifiednoise2d',
42360
+ type: 'float',
42361
+ inputs: [
42362
+ { name: 'noiseType', type: 'int' },
42363
+ { name: 'texcoord', type: 'vec2' },
42364
+ { name: 'freq', type: 'vec2' },
42365
+ { name: 'offset', type: 'vec2' },
42366
+ { name: 'jitter', type: 'float' },
42367
+ { name: 'outmin', type: 'float' },
42368
+ { name: 'outmax', type: 'float' },
42369
+ { name: 'clampoutput', type: 'bool' },
42370
+ { name: 'octaves', type: 'int' },
42371
+ { name: 'lacunarity', type: 'float' },
42372
+ { name: 'diminish', type: 'float' }
42373
+ ]
42374
+ } );
42375
+
42376
+ // Unified Noise 3D
42377
+ const mx_unifiednoise3d$1 = /*@__PURE__*/ Fn( ( [
42378
+ noiseType_immutable, position_immutable, freq_immutable, offset_immutable,
42379
+ jitter_immutable, outmin_immutable, outmax_immutable, clampoutput_immutable,
42380
+ octaves_immutable, lacunarity_immutable, diminish_immutable
42381
+ ] ) => {
42382
+
42383
+ const noiseType = int( noiseType_immutable ).toVar();
42384
+ const position = vec3( position_immutable ).toVar();
42385
+ const freq = vec3( freq_immutable ).toVar();
42386
+ const offset = vec3( offset_immutable ).toVar();
42387
+ const jitter = float( jitter_immutable ).toVar();
42388
+ const outmin = float( outmin_immutable ).toVar();
42389
+ const outmax = float( outmax_immutable ).toVar();
42390
+ const clampoutput = bool( clampoutput_immutable ).toVar();
42391
+ const octaves = int( octaves_immutable ).toVar();
42392
+ const lacunarity = float( lacunarity_immutable ).toVar();
42393
+ const diminish = float( diminish_immutable ).toVar();
42394
+
42395
+ // Compute input position
42396
+ const p = position.mul( freq ).add( offset );
42397
+
42398
+ const result = float( 0.0 ).toVar();
42399
+
42400
+ // Perlin
42401
+ If( noiseType.equal( int( 0 ) ), () => {
42402
+
42403
+ result.assign( mx_perlin_noise_vec3( p ) );
42404
+
42405
+ } );
42406
+
42407
+ // Cell
42408
+ If( noiseType.equal( int( 1 ) ), () => {
42409
+
42410
+ result.assign( mx_cell_noise_vec3( p ) );
42411
+
42412
+ } );
42413
+
42414
+ // Worley (metric=0 = euclidean)
42415
+ If( noiseType.equal( int( 2 ) ), () => {
42416
+
42417
+ result.assign( mx_worley_noise_vec3$1( p, jitter, int( 0 ) ) );
42418
+
42419
+ } );
42420
+
42421
+ // Fractal
42422
+ If( noiseType.equal( int( 3 ) ), () => {
42423
+
42424
+ result.assign( mx_fractal_noise_vec3$1( p, octaves, lacunarity, diminish ) );
42425
+
42426
+ } );
42427
+
42428
+ // Remap output to [outmin, outmax]
42429
+ result.assign( result.mul( outmax.sub( outmin ) ).add( outmin ) );
42430
+
42431
+ // Clamp if requested
42432
+ If( clampoutput, () => {
42433
+
42434
+ result.assign( clamp( result, outmin, outmax ) );
42435
+
42436
+ } );
42437
+
42438
+ return result;
42439
+
42440
+ } ).setLayout( {
42441
+ name: 'mx_unifiednoise3d',
42442
+ type: 'float',
42443
+ inputs: [
42444
+ { name: 'noiseType', type: 'int' },
42445
+ { name: 'position', type: 'vec3' },
42446
+ { name: 'freq', type: 'vec3' },
42447
+ { name: 'offset', type: 'vec3' },
42448
+ { name: 'jitter', type: 'float' },
42449
+ { name: 'outmin', type: 'float' },
42450
+ { name: 'outmax', type: 'float' },
42451
+ { name: 'clampoutput', type: 'bool' },
42452
+ { name: 'octaves', type: 'int' },
42453
+ { name: 'lacunarity', type: 'float' },
42454
+ { name: 'diminish', type: 'float' }
42455
+ ]
42456
+ } );
42457
+
41490
42458
  // Three.js Transpiler
41491
42459
  // https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/genglsl/lib/mx_hsv.glsl
41492
42460
 
@@ -41648,6 +42616,19 @@ const _ramp = ( a, b, uv, p ) => mix( a, b, uv[ p ].clamp() );
41648
42616
  const mx_ramplr = ( valuel, valuer, texcoord = uv$1() ) => _ramp( valuel, valuer, texcoord, 'x' );
41649
42617
  const mx_ramptb = ( valuet, valueb, texcoord = uv$1() ) => _ramp( valuet, valueb, texcoord, 'y' );
41650
42618
 
42619
+ // Bilinear ramp: interpolate between four corners (tl, tr, bl, br) using texcoord.x and texcoord.y
42620
+ const mx_ramp4 = (
42621
+ valuetl, valuetr, valuebl, valuebr, texcoord = uv$1()
42622
+ ) => {
42623
+
42624
+ const u = texcoord.x.clamp();
42625
+ const v = texcoord.y.clamp();
42626
+ const top = mix( valuetl, valuetr, u );
42627
+ const bottom = mix( valuebl, valuebr, u );
42628
+ return mix( top, bottom, v );
42629
+
42630
+ };
42631
+
41651
42632
  const _split = ( a, b, center, uv, p ) => mix( a, b, mx_aastep( center, uv[ p ] ) );
41652
42633
  const mx_splitlr = ( valuel, valuer, center, texcoord = uv$1() ) => _split( valuel, valuer, center, texcoord, 'x' );
41653
42634
  const mx_splittb = ( valuet, valueb, center, texcoord = uv$1() ) => _split( valuet, valueb, center, texcoord, 'y' );
@@ -41677,6 +42658,9 @@ const mx_noise_vec4 = ( texcoord = uv$1(), amplitude = 1, pivot = 0 ) => {
41677
42658
 
41678
42659
  };
41679
42660
 
42661
+ const mx_unifiednoise2d = ( noiseType, texcoord = uv$1(), freq = vec2( 1, 1 ), offset = vec2( 0, 0 ), jitter = 1, outmin = 0, outmax = 1, clampoutput = false, octaves = 1, lacunarity = 2, diminish = .5 ) => mx_unifiednoise2d$1( noiseType, texcoord.convert( 'vec2|vec3' ), freq, offset, jitter, outmin, outmax, clampoutput, octaves, lacunarity, diminish );
42662
+ const mx_unifiednoise3d = ( noiseType, texcoord = uv$1(), freq = vec2( 1, 1 ), offset = vec2( 0, 0 ), jitter = 1, outmin = 0, outmax = 1, clampoutput = false, octaves = 1, lacunarity = 2, diminish = .5 ) => mx_unifiednoise3d$1( noiseType, texcoord.convert( 'vec2|vec3' ), freq, offset, jitter, outmin, outmax, clampoutput, octaves, lacunarity, diminish );
42663
+
41680
42664
  const mx_worley_noise_float = ( texcoord = uv$1(), jitter = 1 ) => mx_worley_noise_float$1( texcoord.convert( 'vec2|vec3' ), jitter, int( 1 ) );
41681
42665
  const mx_worley_noise_vec2 = ( texcoord = uv$1(), jitter = 1 ) => mx_worley_noise_vec2$1( texcoord.convert( 'vec2|vec3' ), jitter, int( 1 ) );
41682
42666
  const mx_worley_noise_vec3 = ( texcoord = uv$1(), jitter = 1 ) => mx_worley_noise_vec3$1( texcoord.convert( 'vec2|vec3' ), jitter, int( 1 ) );
@@ -41688,6 +42672,115 @@ const mx_fractal_noise_vec2 = ( position = uv$1(), octaves = 3, lacunarity = 2,
41688
42672
  const mx_fractal_noise_vec3 = ( position = uv$1(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ) => mx_fractal_noise_vec3$1( position, int( octaves ), lacunarity, diminish ).mul( amplitude );
41689
42673
  const mx_fractal_noise_vec4 = ( position = uv$1(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ) => mx_fractal_noise_vec4$1( position, int( octaves ), lacunarity, diminish ).mul( amplitude );
41690
42674
 
42675
+ // === Moved from MaterialXLoader.js ===
42676
+
42677
+ // Math ops
42678
+ const mx_add = ( in1, in2 = float( 0 ) ) => add( in1, in2 );
42679
+ const mx_subtract = ( in1, in2 = float( 0 ) ) => sub( in1, in2 );
42680
+ const mx_multiply = ( in1, in2 = float( 1 ) ) => mul( in1, in2 );
42681
+ const mx_divide = ( in1, in2 = float( 1 ) ) => div( in1, in2 );
42682
+ const mx_modulo = ( in1, in2 = float( 1 ) ) => mod( in1, in2 );
42683
+ const mx_power = ( in1, in2 = float( 1 ) ) => pow( in1, in2 );
42684
+ const mx_atan2 = ( in1 = float( 0 ), in2 = float( 1 ) ) => atan( in1, in2 );
42685
+ const mx_timer = () => time;
42686
+ const mx_frame = () => frameId;
42687
+ const mx_invert = ( in1, amount = float( 1 ) ) => sub( amount, in1 );
42688
+ const mx_ifgreater = ( value1, value2, in1, in2 ) => value1.greaterThan( value2 ).mix( in1, in2 );
42689
+ const mx_ifgreatereq = ( value1, value2, in1, in2 ) => value1.greaterThanEqual( value2 ).mix( in1, in2 );
42690
+ const mx_ifequal = ( value1, value2, in1, in2 ) => value1.equal( value2 ).mix( in1, in2 );
42691
+
42692
+ // Enhanced separate node to support multi-output referencing (outx, outy, outz, outw)
42693
+ const mx_separate = ( in1, channelOrOut = null ) => {
42694
+
42695
+ if ( typeof channelOrOut === 'string' ) {
42696
+
42697
+ const map = { x: 0, r: 0, y: 1, g: 1, z: 2, b: 2, w: 3, a: 3 };
42698
+ const c = channelOrOut.replace( /^out/, '' ).toLowerCase();
42699
+ if ( map[ c ] !== undefined ) return in1.element( map[ c ] );
42700
+
42701
+ }
42702
+
42703
+ if ( typeof channelOrOut === 'number' ) {
42704
+
42705
+ return in1.element( channelOrOut );
42706
+
42707
+ }
42708
+
42709
+ if ( typeof channelOrOut === 'string' && channelOrOut.length === 1 ) {
42710
+
42711
+ const map = { x: 0, r: 0, y: 1, g: 1, z: 2, b: 2, w: 3, a: 3 };
42712
+ if ( map[ channelOrOut ] !== undefined ) return in1.element( map[ channelOrOut ] );
42713
+
42714
+ }
42715
+
42716
+ return in1;
42717
+
42718
+ };
42719
+
42720
+ const mx_place2d = (
42721
+ texcoord, pivot = vec2( 0.5, 0.5 ), scale = vec2( 1, 1 ), rotate = float( 0 ), offset = vec2( 0, 0 )/*, operationorder = int( 0 )*/
42722
+ ) => {
42723
+
42724
+ let uv = texcoord;
42725
+ if ( pivot ) uv = uv.sub( pivot );
42726
+ if ( scale ) uv = uv.mul( scale );
42727
+ if ( rotate ) {
42728
+
42729
+ const rad = rotate.mul( Math.PI / 180.0 );
42730
+ const cosR = rad.cos();
42731
+ const sinR = rad.sin();
42732
+ uv = vec2(
42733
+ uv.x.mul( cosR ).sub( uv.y.mul( sinR ) ),
42734
+ uv.x.mul( sinR ).add( uv.y.mul( cosR ) )
42735
+ );
42736
+
42737
+ }
42738
+
42739
+ if ( pivot ) uv = uv.add( pivot );
42740
+ if ( offset ) uv = uv.add( offset );
42741
+ return uv;
42742
+
42743
+ };
42744
+
42745
+ const mx_rotate2d = ( input, amount ) => {
42746
+
42747
+ input = vec2( input );
42748
+ amount = float( amount );
42749
+
42750
+ const radians = amount.mul( Math.PI / 180.0 );
42751
+ return rotate( input, radians );
42752
+
42753
+ };
42754
+
42755
+ const mx_rotate3d = ( input, amount, axis ) => {
42756
+
42757
+ input = vec3( input );
42758
+ amount = float( amount );
42759
+ axis = vec3( axis );
42760
+
42761
+
42762
+ const radians = amount.mul( Math.PI / 180.0 );
42763
+ const nAxis = axis.normalize();
42764
+ const cosA = radians.cos();
42765
+ const sinA = radians.sin();
42766
+ const oneMinusCosA = float( 1 ).sub( cosA );
42767
+ const rot =
42768
+ input.mul( cosA )
42769
+ .add( nAxis.cross( input ).mul( sinA ) )
42770
+ .add( nAxis.mul( nAxis.dot( input ) ).mul( oneMinusCosA ) );
42771
+ return rot;
42772
+
42773
+ };
42774
+
42775
+ const mx_heighttonormal = ( input, scale/*, texcoord*/ ) => {
42776
+
42777
+ input = vec3( input );
42778
+ scale = float( scale );
42779
+
42780
+ return bumpMap( input, scale );
42781
+
42782
+ };
42783
+
41691
42784
  /**
41692
42785
  * This computes a parallax corrected normal which is used for box-projected cube mapping (BPCEM).
41693
42786
  *
@@ -41770,6 +42863,8 @@ var TSL = /*#__PURE__*/Object.freeze({
41770
42863
  NodeShaderStage: NodeShaderStage,
41771
42864
  NodeType: NodeType,
41772
42865
  NodeUpdateType: NodeUpdateType,
42866
+ OnMaterialUpdate: OnMaterialUpdate,
42867
+ OnObjectUpdate: OnObjectUpdate,
41773
42868
  PCFShadowFilter: PCFShadowFilter,
41774
42869
  PCFSoftShadowFilter: PCFSoftShadowFilter,
41775
42870
  PI: PI,
@@ -41785,6 +42880,7 @@ var TSL = /*#__PURE__*/Object.freeze({
41785
42880
  VSMShadowFilter: VSMShadowFilter,
41786
42881
  V_GGX_SmithCorrelated: V_GGX_SmithCorrelated,
41787
42882
  Var: Var,
42883
+ VarIntent: VarIntent,
41788
42884
  abs: abs,
41789
42885
  acesFilmicToneMapping: acesFilmicToneMapping,
41790
42886
  acos: acos,
@@ -41875,6 +42971,7 @@ var TSL = /*#__PURE__*/Object.freeze({
41875
42971
  colorSpaceToWorking: colorSpaceToWorking,
41876
42972
  colorToDirection: colorToDirection,
41877
42973
  compute: compute,
42974
+ computeKernel: computeKernel,
41878
42975
  computeSkinning: computeSkinning,
41879
42976
  context: context,
41880
42977
  convert: convert,
@@ -41900,6 +42997,7 @@ var TSL = /*#__PURE__*/Object.freeze({
41900
42997
  densityFogFactor: densityFogFactor,
41901
42998
  depth: depth,
41902
42999
  depthPass: depthPass,
43000
+ determinant: determinant,
41903
43001
  difference: difference,
41904
43002
  diffuseColor: diffuseColor,
41905
43003
  directPointLight: directPointLight,
@@ -41966,6 +43064,7 @@ var TSL = /*#__PURE__*/Object.freeze({
41966
43064
  instancedDynamicBufferAttribute: instancedDynamicBufferAttribute,
41967
43065
  instancedMesh: instancedMesh,
41968
43066
  int: int,
43067
+ inverse: inverse,
41969
43068
  inverseSqrt: inverseSqrt,
41970
43069
  inversesqrt: inversesqrt,
41971
43070
  invocationLocalIndex: invocationLocalIndex,
@@ -42067,24 +43166,45 @@ var TSL = /*#__PURE__*/Object.freeze({
42067
43166
  mrt: mrt,
42068
43167
  mul: mul,
42069
43168
  mx_aastep: mx_aastep,
43169
+ mx_add: mx_add,
43170
+ mx_atan2: mx_atan2,
42070
43171
  mx_cell_noise_float: mx_cell_noise_float,
42071
43172
  mx_contrast: mx_contrast,
43173
+ mx_divide: mx_divide,
42072
43174
  mx_fractal_noise_float: mx_fractal_noise_float,
42073
43175
  mx_fractal_noise_vec2: mx_fractal_noise_vec2,
42074
43176
  mx_fractal_noise_vec3: mx_fractal_noise_vec3,
42075
43177
  mx_fractal_noise_vec4: mx_fractal_noise_vec4,
43178
+ mx_frame: mx_frame,
43179
+ mx_heighttonormal: mx_heighttonormal,
42076
43180
  mx_hsvtorgb: mx_hsvtorgb,
43181
+ mx_ifequal: mx_ifequal,
43182
+ mx_ifgreater: mx_ifgreater,
43183
+ mx_ifgreatereq: mx_ifgreatereq,
43184
+ mx_invert: mx_invert,
43185
+ mx_modulo: mx_modulo,
43186
+ mx_multiply: mx_multiply,
42077
43187
  mx_noise_float: mx_noise_float,
42078
43188
  mx_noise_vec3: mx_noise_vec3,
42079
43189
  mx_noise_vec4: mx_noise_vec4,
43190
+ mx_place2d: mx_place2d,
43191
+ mx_power: mx_power,
43192
+ mx_ramp4: mx_ramp4,
42080
43193
  mx_ramplr: mx_ramplr,
42081
43194
  mx_ramptb: mx_ramptb,
42082
43195
  mx_rgbtohsv: mx_rgbtohsv,
43196
+ mx_rotate2d: mx_rotate2d,
43197
+ mx_rotate3d: mx_rotate3d,
42083
43198
  mx_safepower: mx_safepower,
43199
+ mx_separate: mx_separate,
42084
43200
  mx_splitlr: mx_splitlr,
42085
43201
  mx_splittb: mx_splittb,
42086
43202
  mx_srgb_texture_to_lin_rec709: mx_srgb_texture_to_lin_rec709,
43203
+ mx_subtract: mx_subtract,
43204
+ mx_timer: mx_timer,
42087
43205
  mx_transform_uv: mx_transform_uv,
43206
+ mx_unifiednoise2d: mx_unifiednoise2d,
43207
+ mx_unifiednoise3d: mx_unifiednoise3d,
42088
43208
  mx_worley_noise_float: mx_worley_noise_float,
42089
43209
  mx_worley_noise_vec2: mx_worley_noise_vec2,
42090
43210
  mx_worley_noise_vec3: mx_worley_noise_vec3,
@@ -42093,8 +43213,10 @@ var TSL = /*#__PURE__*/Object.freeze({
42093
43213
  nodeArray: nodeArray,
42094
43214
  nodeImmutable: nodeImmutable,
42095
43215
  nodeObject: nodeObject,
43216
+ nodeObjectIntent: nodeObjectIntent,
42096
43217
  nodeObjects: nodeObjects,
42097
43218
  nodeProxy: nodeProxy,
43219
+ nodeProxyIntent: nodeProxyIntent,
42098
43220
  normalFlat: normalFlat,
42099
43221
  normalGeometry: normalGeometry,
42100
43222
  normalLocal: normalLocal,
@@ -42192,6 +43314,7 @@ var TSL = /*#__PURE__*/Object.freeze({
42192
43314
  scriptableValue: scriptableValue,
42193
43315
  select: select,
42194
43316
  setCurrentStack: setCurrentStack,
43317
+ setName: setName,
42195
43318
  shaderStages: shaderStages,
42196
43319
  shadow: shadow,
42197
43320
  shadowPositionWorld: shadowPositionWorld,
@@ -44037,7 +45160,7 @@ class NodeBuilder {
44037
45160
  /**
44038
45161
  * A reference to the current fog node.
44039
45162
  *
44040
- * @type {?FogNode}
45163
+ * @type {?Node}
44041
45164
  * @default null
44042
45165
  */
44043
45166
  this.fogNode = null;
@@ -45586,23 +46709,6 @@ class NodeBuilder {
45586
46709
 
45587
46710
  }
45588
46711
 
45589
- /**
45590
- * Returns the array length.
45591
- *
45592
- * @param {Node} node - The node.
45593
- * @return {?number} The array length.
45594
- */
45595
- getArrayCount( node ) {
45596
-
45597
- let count = null;
45598
-
45599
- if ( node.isArrayNode ) count = node.count;
45600
- else if ( node.isVarNode && node.node.isArrayNode ) count = node.node.count;
45601
-
45602
- return count;
45603
-
45604
- }
45605
-
45606
46712
  /**
45607
46713
  * Returns an instance of {@link NodeVar} for the given variable node.
45608
46714
  *
@@ -45646,7 +46752,7 @@ class NodeBuilder {
45646
46752
 
45647
46753
  //
45648
46754
 
45649
- const count = this.getArrayCount( node );
46755
+ const count = node.getArrayCount( this );
45650
46756
 
45651
46757
  nodeVar = new NodeVar( name, type, readOnly, count );
45652
46758
 
@@ -46072,6 +47178,28 @@ class NodeBuilder {
46072
47178
 
46073
47179
  }
46074
47180
 
47181
+ /**
47182
+ * Executes the node in a specific build stage.
47183
+ *
47184
+ * @param {Node} node - The node to execute.
47185
+ * @param {string} buildStage - The build stage to execute the node in.
47186
+ * @param {Node|string|null} output - Expected output type. For example 'vec3'.
47187
+ * @return {Node|string|null} The result of the node build.
47188
+ */
47189
+ flowBuildStage( node, buildStage, output = null ) {
47190
+
47191
+ const previousBuildStage = this.getBuildStage();
47192
+
47193
+ this.setBuildStage( buildStage );
47194
+
47195
+ const result = node.build( this, output );
47196
+
47197
+ this.setBuildStage( previousBuildStage );
47198
+
47199
+ return result;
47200
+
47201
+ }
47202
+
46075
47203
  /**
46076
47204
  * Runs the node flow through all the steps of creation, 'setup', 'analyze', 'generate'.
46077
47205
  *
@@ -46582,7 +47710,7 @@ class NodeBuilder {
46582
47710
 
46583
47711
  }
46584
47712
 
46585
- // setup() -> stage 1: create possible new nodes and returns an output reference node
47713
+ // setup() -> stage 1: create possible new nodes and/or return an output reference node
46586
47714
  // analyze() -> stage 2: analyze nodes to possible optimization and validation
46587
47715
  // generate() -> stage 3: generate shader
46588
47716
 
@@ -47544,13 +48672,24 @@ class ProjectorLightNode extends SpotLightNode {
47544
48672
  */
47545
48673
  getSpotAttenuation( builder ) {
47546
48674
 
48675
+ const attenuation = float( 0 );
47547
48676
  const penumbraCos = this.penumbraCosNode;
47548
- const spotLightCoord = this.getLightCoord( builder );
47549
- const coord = spotLightCoord.xyz.div( spotLightCoord.w );
47550
48677
 
47551
- const boxDist = sdBox( coord.xy.sub( vec2( 0.5 ) ), vec2( 0.5 ) );
47552
- const angleFactor = div( -1, sub( 1.0, acos( penumbraCos ) ).sub( 1.0 ) );
47553
- const attenuation = saturate( boxDist.mul( -2 ).mul( angleFactor ) );
48678
+ // compute the fragment's position in the light's clip space
48679
+
48680
+ const spotLightCoord = lightShadowMatrix( this.light ).mul( builder.context.positionWorld || positionWorld );
48681
+
48682
+ // the sign of w determines whether the current fragment is in front or behind the light.
48683
+ // to avoid a back-projection, it's important to only compute an attenuation if w is positive
48684
+
48685
+ If( spotLightCoord.w.greaterThan( 0 ), () => {
48686
+
48687
+ const projectionUV = spotLightCoord.xyz.div( spotLightCoord.w );
48688
+ const boxDist = sdBox( projectionUV.xy.sub( vec2( 0.5 ) ), vec2( 0.5 ) );
48689
+ const angleFactor = div( -1, sub( 1.0, acos( penumbraCos ) ).sub( 1.0 ) );
48690
+ attenuation.assign( saturate( boxDist.mul( -2 ).mul( angleFactor ) ) );
48691
+
48692
+ } );
47554
48693
 
47555
48694
  return attenuation;
47556
48695
 
@@ -49659,6 +50798,15 @@ class XRManager extends EventDispatcher {
49659
50798
  */
49660
50799
  this._supportsLayers = false;
49661
50800
 
50801
+ /**
50802
+ * Whether the device supports binding gl objects.
50803
+ *
50804
+ * @private
50805
+ * @type {boolean}
50806
+ * @readonly
50807
+ */
50808
+ this._supportsGlBinding = typeof XRWebGLBinding !== 'undefined';
50809
+
49662
50810
  this._frameBufferTargets = null;
49663
50811
 
49664
50812
  /**
@@ -49845,7 +50993,7 @@ class XRManager extends EventDispatcher {
49845
50993
  * @type {boolean}
49846
50994
  * @readonly
49847
50995
  */
49848
- this._useLayers = ( typeof XRWebGLBinding !== 'undefined' && 'createProjectionLayer' in XRWebGLBinding.prototype ); // eslint-disable-line compat/compat
50996
+ this._useLayers = ( this._supportsGlBinding && 'createProjectionLayer' in XRWebGLBinding.prototype ); // eslint-disable-line compat/compat
49849
50997
 
49850
50998
  /**
49851
50999
  * Whether the usage of multiview has been requested by the application or not.
@@ -50403,9 +51551,18 @@ class XRManager extends EventDispatcher {
50403
51551
 
50404
51552
  //
50405
51553
 
51554
+ if ( this._supportsGlBinding ) {
51555
+
51556
+ const glBinding = new XRWebGLBinding( session, gl );
51557
+ this._glBinding = glBinding;
51558
+
51559
+ }
51560
+
51561
+ //
51562
+
50406
51563
  if ( this._useLayers === true ) {
50407
51564
 
50408
- // default path using XRWebGLBinding/XRProjectionLayer
51565
+ // default path using XRProjectionLayer
50409
51566
 
50410
51567
  let depthFormat = null;
50411
51568
  let depthType = null;
@@ -50433,11 +51590,9 @@ class XRManager extends EventDispatcher {
50433
51590
 
50434
51591
  }
50435
51592
 
50436
- const glBinding = new XRWebGLBinding( session, gl );
50437
- const glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );
51593
+ const glProjLayer = this._glBinding.createProjectionLayer( projectionlayerInit );
50438
51594
  const layersArray = [ glProjLayer ];
50439
51595
 
50440
- this._glBinding = glBinding;
50441
51596
  this._glProjLayer = glProjLayer;
50442
51597
 
50443
51598
  renderer.setPixelRatio( 1 );
@@ -50583,9 +51738,11 @@ class XRManager extends EventDispatcher {
50583
51738
 
50584
51739
  }
50585
51740
 
50586
- cameraL.layers.mask = camera.layers.mask | 0b010;
50587
- cameraR.layers.mask = camera.layers.mask | 0b100;
50588
- cameraXR.layers.mask = cameraL.layers.mask | cameraR.layers.mask;
51741
+ // inherit camera layers and enable eye layers (1 = left, 2 = right)
51742
+ cameraXR.layers.mask = camera.layers.mask | 0b110;
51743
+ cameraL.layers.mask = cameraXR.layers.mask & 0b011;
51744
+ cameraR.layers.mask = cameraXR.layers.mask & 0b101;
51745
+
50589
51746
 
50590
51747
  const parent = camera.parent;
50591
51748
  const cameras = cameraXR.cameras;
@@ -51124,7 +52281,7 @@ function onAnimationFrame( time, frame ) {
51124
52281
  }
51125
52282
 
51126
52283
  const _scene = /*@__PURE__*/ new Scene();
51127
- const _drawingBufferSize$1 = /*@__PURE__*/ new Vector2();
52284
+ const _drawingBufferSize = /*@__PURE__*/ new Vector2();
51128
52285
  const _screen = /*@__PURE__*/ new Vector4();
51129
52286
  const _frustum = /*@__PURE__*/ new Frustum();
51130
52287
  const _frustumArray = /*@__PURE__*/ new FrustumArray();
@@ -52302,11 +53459,11 @@ class Renderer {
52302
53459
  const { currentToneMapping, currentColorSpace } = this;
52303
53460
 
52304
53461
  const useToneMapping = currentToneMapping !== NoToneMapping;
52305
- const useColorSpace = currentColorSpace !== LinearSRGBColorSpace;
53462
+ const useColorSpace = currentColorSpace !== ColorManagement.workingColorSpace;
52306
53463
 
52307
53464
  if ( useToneMapping === false && useColorSpace === false ) return null;
52308
53465
 
52309
- const { width, height } = this.getDrawingBufferSize( _drawingBufferSize$1 );
53466
+ const { width, height } = this.getDrawingBufferSize( _drawingBufferSize );
52310
53467
  const { depth, stencil } = this;
52311
53468
 
52312
53469
  let frameBufferTarget = this._frameBufferTarget;
@@ -52318,7 +53475,7 @@ class Renderer {
52318
53475
  stencilBuffer: stencil,
52319
53476
  type: this._colorBufferType,
52320
53477
  format: RGBAFormat,
52321
- colorSpace: LinearSRGBColorSpace,
53478
+ colorSpace: ColorManagement.workingColorSpace,
52322
53479
  generateMipmaps: false,
52323
53480
  minFilter: LinearFilter,
52324
53481
  magFilter: LinearFilter,
@@ -52471,9 +53628,9 @@ class Renderer {
52471
53628
 
52472
53629
  }
52473
53630
 
52474
- this.getDrawingBufferSize( _drawingBufferSize$1 );
53631
+ this.getDrawingBufferSize( _drawingBufferSize );
52475
53632
 
52476
- _screen.set( 0, 0, _drawingBufferSize$1.width, _drawingBufferSize$1.height );
53633
+ _screen.set( 0, 0, _drawingBufferSize.width, _drawingBufferSize.height );
52477
53634
 
52478
53635
  const minDepth = ( viewport.minDepth === undefined ) ? 0 : viewport.minDepth;
52479
53636
  const maxDepth = ( viewport.maxDepth === undefined ) ? 1 : viewport.maxDepth;
@@ -52504,7 +53661,7 @@ class Renderer {
52504
53661
  if ( ! camera.isArrayCamera ) {
52505
53662
 
52506
53663
  _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
52507
- frustum.setFromProjectionMatrix( _projScreenMatrix, coordinateSystem );
53664
+ frustum.setFromProjectionMatrix( _projScreenMatrix, camera.coordinateSystem, camera.reversedDepth );
52508
53665
 
52509
53666
  }
52510
53667
 
@@ -53222,8 +54379,8 @@ class Renderer {
53222
54379
  }
53223
54380
 
53224
54381
  /**
53225
- * The current output tone mapping of the renderer. When a render target is set,
53226
- * the output tone mapping is always `NoToneMapping`.
54382
+ * The current tone mapping of the renderer. When not producing screen output,
54383
+ * the tone mapping is always `NoToneMapping`.
53227
54384
  *
53228
54385
  * @type {number}
53229
54386
  */
@@ -53234,14 +54391,14 @@ class Renderer {
53234
54391
  }
53235
54392
 
53236
54393
  /**
53237
- * The current output color space of the renderer. When a render target is set,
53238
- * the output color space is always `LinearSRGBColorSpace`.
54394
+ * The current color space of the renderer. When not producing screen output,
54395
+ * the color space is always the working color space.
53239
54396
  *
53240
54397
  * @type {string}
53241
54398
  */
53242
54399
  get currentColorSpace() {
53243
54400
 
53244
- return this.isOutputTarget ? this.outputColorSpace : LinearSRGBColorSpace;
54401
+ return this.isOutputTarget ? this.outputColorSpace : ColorManagement.workingColorSpace;
53245
54402
 
53246
54403
  }
53247
54404
 
@@ -53400,9 +54557,10 @@ class Renderer {
53400
54557
  * if the renderer has been initialized.
53401
54558
  *
53402
54559
  * @param {Node|Array<Node>} computeNodes - The compute node(s).
54560
+ * @param {Array<number>|number} [dispatchSizeOrCount=null] - Array with [ x, y, z ] values for dispatch or a single number for the count.
53403
54561
  * @return {Promise|undefined} A Promise that resolve when the compute has finished. Only returned when the renderer has not been initialized.
53404
54562
  */
53405
- compute( computeNodes ) {
54563
+ compute( computeNodes, dispatchSizeOrCount = null ) {
53406
54564
 
53407
54565
  if ( this._isDeviceLost === true ) return;
53408
54566
 
@@ -53481,7 +54639,7 @@ class Renderer {
53481
54639
  const computeBindings = bindings.getForCompute( computeNode );
53482
54640
  const computePipeline = pipelines.getForCompute( computeNode, computeBindings );
53483
54641
 
53484
- backend.compute( computeNodes, computeNode, computeBindings, computePipeline );
54642
+ backend.compute( computeNodes, computeNode, computeBindings, computePipeline, dispatchSizeOrCount );
53485
54643
 
53486
54644
  }
53487
54645
 
@@ -53498,13 +54656,14 @@ class Renderer {
53498
54656
  *
53499
54657
  * @async
53500
54658
  * @param {Node|Array<Node>} computeNodes - The compute node(s).
54659
+ * @param {Array<number>|number} [dispatchSizeOrCount=null] - Array with [ x, y, z ] values for dispatch or a single number for the count.
53501
54660
  * @return {Promise} A Promise that resolve when the compute has finished.
53502
54661
  */
53503
- async computeAsync( computeNodes ) {
54662
+ async computeAsync( computeNodes, dispatchSizeOrCount = null ) {
53504
54663
 
53505
54664
  if ( this._initialized === false ) await this.init();
53506
54665
 
53507
- this.compute( computeNodes );
54666
+ this.compute( computeNodes, dispatchSizeOrCount );
53508
54667
 
53509
54668
  }
53510
54669
 
@@ -54053,7 +55212,7 @@ class Renderer {
54053
55212
  * @param {LightsNode} lightsNode - The current lights node.
54054
55213
  * @param {?{start: number, count: number}} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
54055
55214
  * @param {ClippingContext} clippingContext - The clipping context.
54056
- * @param {?string} [passId=null] - An optional ID for identifying the pass.
55215
+ * @param {string} [passId] - An optional ID for identifying the pass.
54057
55216
  */
54058
55217
  _renderObjectDirect( object, material, scene, camera, lightsNode, group, clippingContext, passId ) {
54059
55218
 
@@ -54108,7 +55267,7 @@ class Renderer {
54108
55267
  * @param {LightsNode} lightsNode - The current lights node.
54109
55268
  * @param {?{start: number, count: number}} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
54110
55269
  * @param {ClippingContext} clippingContext - The clipping context.
54111
- * @param {?string} [passId=null] - An optional ID for identifying the pass.
55270
+ * @param {string} [passId] - An optional ID for identifying the pass.
54112
55271
  */
54113
55272
  _createObjectPipeline( object, material, scene, camera, lightsNode, group, clippingContext, passId ) {
54114
55273
 
@@ -54917,20 +56076,18 @@ class NodeUniformsGroup extends UniformsGroup {
54917
56076
 
54918
56077
  }
54919
56078
 
54920
- let _id$2 = 0;
54921
-
54922
56079
  /**
54923
- * Represents a sampled texture binding type.
56080
+ * Represents a sampler binding type.
54924
56081
  *
54925
56082
  * @private
54926
56083
  * @augments Binding
54927
56084
  */
54928
- class SampledTexture extends Binding {
56085
+ class Sampler extends Binding {
54929
56086
 
54930
56087
  /**
54931
- * Constructs a new sampled texture.
56088
+ * Constructs a new sampler.
54932
56089
  *
54933
- * @param {string} name - The sampled texture's name.
56090
+ * @param {string} name - The samplers's name.
54934
56091
  * @param {?Texture} texture - The texture this binding is referring to.
54935
56092
  */
54936
56093
  constructor( name, texture ) {
@@ -54938,14 +56095,18 @@ class SampledTexture extends Binding {
54938
56095
  super( name );
54939
56096
 
54940
56097
  /**
54941
- * This identifier.
54942
- *
54943
- * @type {number}
56098
+ * This function is called when the texture is disposed.
56099
+ * @type {function}
56100
+ * @private
54944
56101
  */
54945
- this.id = _id$2 ++;
56102
+ this._onDisposeTexture = () => {
56103
+
56104
+ this.texture = null;
56105
+
56106
+ };
54946
56107
 
54947
56108
  /**
54948
- * The texture this binding is referring to.
56109
+ * The texture the sampler is referring to.
54949
56110
  *
54950
56111
  * @type {?Texture}
54951
56112
  */
@@ -54958,14 +56119,6 @@ class SampledTexture extends Binding {
54958
56119
  */
54959
56120
  this.version = texture ? texture.version : 0;
54960
56121
 
54961
- /**
54962
- * Whether the texture is a storage texture or not.
54963
- *
54964
- * @type {boolean}
54965
- * @default false
54966
- */
54967
- this.store = false;
54968
-
54969
56122
  /**
54970
56123
  * The binding's generation which is an additional version
54971
56124
  * qualifier.
@@ -54982,30 +56135,44 @@ class SampledTexture extends Binding {
54982
56135
  * @readonly
54983
56136
  * @default true
54984
56137
  */
54985
- this.isSampledTexture = true;
56138
+ this.isSampler = true;
54986
56139
 
54987
56140
  }
54988
56141
 
54989
56142
  /**
54990
- * Returns `true` whether this binding requires an update for the
54991
- * given generation.
54992
- *
54993
- * @param {number} generation - The generation.
54994
- * @return {boolean} Whether an update is required or not.
56143
+ * Sets the texture of this sampler.
56144
+ * @param {?Texture} value - The texture to set.
54995
56145
  */
54996
- needsBindingsUpdate( generation ) {
56146
+ set texture( value ) {
54997
56147
 
54998
- const { texture } = this;
56148
+ if ( this._texture === value ) return;
54999
56149
 
55000
- if ( generation !== this.generation ) {
56150
+ if ( this._texture ) {
55001
56151
 
55002
- this.generation = generation;
56152
+ this._texture.removeEventListener( 'dispose', this._onDisposeTexture );
55003
56153
 
55004
- return true;
56154
+ }
56155
+
56156
+ this._texture = value;
56157
+
56158
+ this.generation = null;
56159
+ this.version = 0;
56160
+
56161
+ if ( this._texture ) {
56162
+
56163
+ this._texture.addEventListener( 'dispose', this._onDisposeTexture );
55005
56164
 
55006
56165
  }
55007
56166
 
55008
- return texture.isVideoTexture;
56167
+ }
56168
+
56169
+ /**
56170
+ * Gets the texture of this sampler.
56171
+ * @return {?Texture} The texture.
56172
+ */
56173
+ get texture() {
56174
+
56175
+ return this._texture;
55009
56176
 
55010
56177
  }
55011
56178
 
@@ -55033,6 +56200,54 @@ class SampledTexture extends Binding {
55033
56200
 
55034
56201
  }
55035
56202
 
56203
+ let _id$2 = 0;
56204
+
56205
+ /**
56206
+ * Represents a sampled texture binding type.
56207
+ *
56208
+ * @private
56209
+ * @augments Binding
56210
+ */
56211
+ class SampledTexture extends Sampler {
56212
+
56213
+ /**
56214
+ * Constructs a new sampled texture.
56215
+ *
56216
+ * @param {string} name - The sampled texture's name.
56217
+ * @param {?Texture} texture - The texture this binding is referring to.
56218
+ */
56219
+ constructor( name, texture ) {
56220
+
56221
+ super( name, texture );
56222
+
56223
+ /**
56224
+ * This identifier.
56225
+ *
56226
+ * @type {number}
56227
+ */
56228
+ this.id = _id$2 ++;
56229
+
56230
+ /**
56231
+ * Whether the texture is a storage texture or not.
56232
+ *
56233
+ * @type {boolean}
56234
+ * @default false
56235
+ */
56236
+ this.store = false;
56237
+
56238
+ /**
56239
+ * This flag can be used for type testing.
56240
+ *
56241
+ * @type {boolean}
56242
+ * @readonly
56243
+ * @default true
56244
+ */
56245
+ this.isSampledTexture = true;
56246
+
56247
+ }
56248
+
56249
+ }
56250
+
55036
56251
  /**
55037
56252
  * A special form of sampled texture binding type.
55038
56253
  * It's texture value is managed by a node object.
@@ -55078,18 +56293,6 @@ class NodeSampledTexture extends SampledTexture {
55078
56293
 
55079
56294
  }
55080
56295
 
55081
- /**
55082
- * Overwrites the default to additionally check if the node value has changed.
55083
- *
55084
- * @param {number} generation - The generation.
55085
- * @return {boolean} Whether an update is required or not.
55086
- */
55087
- needsBindingsUpdate( generation ) {
55088
-
55089
- return this.textureNode.value !== this.texture || super.needsBindingsUpdate( generation );
55090
-
55091
- }
55092
-
55093
56296
  /**
55094
56297
  * Updates the binding.
55095
56298
  *
@@ -55423,7 +56626,7 @@ ${ flowData.code }
55423
56626
  attribute.pboNode = pbo;
55424
56627
  attribute.pbo = pbo.value;
55425
56628
 
55426
- this.getUniformFromNode( attribute.pboNode, 'texture', this.shaderStage, this.context.label );
56629
+ this.getUniformFromNode( attribute.pboNode, 'texture', this.shaderStage, this.context.nodeName );
55427
56630
 
55428
56631
  }
55429
56632
 
@@ -55467,7 +56670,7 @@ ${ flowData.code }
55467
56670
 
55468
56671
  }
55469
56672
 
55470
- const nodeUniform = this.getUniformFromNode( attribute.pboNode, 'texture', this.shaderStage, this.context.label );
56673
+ const nodeUniform = this.getUniformFromNode( attribute.pboNode, 'texture', this.shaderStage, this.context.nodeName );
55471
56674
  const textureName = this.getPropertyName( nodeUniform );
55472
56675
 
55473
56676
  this.increaseUsage( indexNode ); // force cache generate to be used as index in x,y
@@ -60929,8 +62132,6 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
60929
62132
 
60930
62133
  }
60931
62134
 
60932
- const _drawingBufferSize = /*@__PURE__*/ new Vector2();
60933
-
60934
62135
  /**
60935
62136
  * A backend implementation targeting WebGL 2.
60936
62137
  *
@@ -61096,7 +62297,7 @@ class WebGLBackend extends Backend {
61096
62297
  * A unique collection of bindings.
61097
62298
  *
61098
62299
  * @private
61099
- * @type {WeakSet}
62300
+ * @type {WeakSet<Array<BindGroup>>}
61100
62301
  */
61101
62302
  this._knownBindings = new WeakSet();
61102
62303
 
@@ -61368,7 +62569,7 @@ class WebGLBackend extends Backend {
61368
62569
 
61369
62570
  } else {
61370
62571
 
61371
- const { width, height } = this.getDrawingBufferSize( _drawingBufferSize );
62572
+ const { width, height } = this.getDrawingBufferSize();
61372
62573
  state.viewport( 0, 0, width, height );
61373
62574
 
61374
62575
  }
@@ -61568,7 +62769,7 @@ class WebGLBackend extends Backend {
61568
62769
 
61569
62770
  } else {
61570
62771
 
61571
- const { width, height } = this.getDrawingBufferSize( _drawingBufferSize );
62772
+ const { width, height } = this.getDrawingBufferSize();
61572
62773
  state.viewport( 0, 0, width, height );
61573
62774
 
61574
62775
  }
@@ -61828,8 +63029,9 @@ class WebGLBackend extends Backend {
61828
63029
  * @param {Node} computeNode - The compute node.
61829
63030
  * @param {Array<BindGroup>} bindings - The bindings.
61830
63031
  * @param {ComputePipeline} pipeline - The compute pipeline.
63032
+ * @param {number|null} [count=null] - The count of compute invocations. If `null`, the count is determined by the compute node.
61831
63033
  */
61832
- compute( computeGroup, computeNode, bindings, pipeline ) {
63034
+ compute( computeGroup, computeNode, bindings, pipeline, count = null ) {
61833
63035
 
61834
63036
  const { state, gl } = this;
61835
63037
 
@@ -61866,13 +63068,23 @@ class WebGLBackend extends Backend {
61866
63068
  gl.bindTransformFeedback( gl.TRANSFORM_FEEDBACK, transformFeedbackGPU );
61867
63069
  gl.beginTransformFeedback( gl.POINTS );
61868
63070
 
63071
+ count = ( count !== null ) ? count : computeNode.count;
63072
+
63073
+ if ( Array.isArray( count ) ) {
63074
+
63075
+ warnOnce( 'WebGLBackend.compute(): The count parameter must be a single number, not an array.' );
63076
+
63077
+ count = count[ 0 ];
63078
+
63079
+ }
63080
+
61869
63081
  if ( attributes[ 0 ].isStorageInstancedBufferAttribute ) {
61870
63082
 
61871
- gl.drawArraysInstanced( gl.POINTS, 0, 1, computeNode.count );
63083
+ gl.drawArraysInstanced( gl.POINTS, 0, 1, count );
61872
63084
 
61873
63085
  } else {
61874
63086
 
61875
- gl.drawArrays( gl.POINTS, 0, computeNode.count );
63087
+ gl.drawArrays( gl.POINTS, 0, count );
61876
63088
 
61877
63089
  }
61878
63090
 
@@ -62487,7 +63699,9 @@ class WebGLBackend extends Backend {
62487
63699
  _getShaderErrors( gl, shader, type ) {
62488
63700
 
62489
63701
  const status = gl.getShaderParameter( shader, gl.COMPILE_STATUS );
62490
- const errors = gl.getShaderInfoLog( shader ).trim();
63702
+
63703
+ const shaderInfoLog = gl.getShaderInfoLog( shader ) || '';
63704
+ const errors = shaderInfoLog.trim();
62491
63705
 
62492
63706
  if ( status && errors === '' ) return '';
62493
63707
 
@@ -62519,11 +63733,11 @@ class WebGLBackend extends Backend {
62519
63733
 
62520
63734
  const gl = this.gl;
62521
63735
 
62522
- const programLog = gl.getProgramInfoLog( programGPU ).trim();
63736
+ const programInfoLog = gl.getProgramInfoLog( programGPU ) || '';
63737
+ const programLog = programInfoLog.trim();
62523
63738
 
62524
63739
  if ( gl.getProgramParameter( programGPU, gl.LINK_STATUS ) === false ) {
62525
63740
 
62526
-
62527
63741
  if ( typeof this.renderer.debug.onShaderError === 'function' ) {
62528
63742
 
62529
63743
  this.renderer.debug.onShaderError( gl, programGPU, glVertexShader, glFragmentShader );
@@ -63768,51 +64982,6 @@ const GPUFeatureName = {
63768
64982
  TextureFormatsTier2: 'texture-formats-tier2'
63769
64983
  };
63770
64984
 
63771
- /**
63772
- * Represents a sampler binding type.
63773
- *
63774
- * @private
63775
- * @augments Binding
63776
- */
63777
- class Sampler extends Binding {
63778
-
63779
- /**
63780
- * Constructs a new sampler.
63781
- *
63782
- * @param {string} name - The samplers's name.
63783
- * @param {?Texture} texture - The texture this binding is referring to.
63784
- */
63785
- constructor( name, texture ) {
63786
-
63787
- super( name );
63788
-
63789
- /**
63790
- * The texture the sampler is referring to.
63791
- *
63792
- * @type {?Texture}
63793
- */
63794
- this.texture = texture;
63795
-
63796
- /**
63797
- * The binding's version.
63798
- *
63799
- * @type {number}
63800
- */
63801
- this.version = texture ? texture.version : 0;
63802
-
63803
- /**
63804
- * This flag can be used for type testing.
63805
- *
63806
- * @type {boolean}
63807
- * @readonly
63808
- * @default true
63809
- */
63810
- this.isSampler = true;
63811
-
63812
- }
63813
-
63814
- }
63815
-
63816
64985
  /**
63817
64986
  * A special form of sampler binding type.
63818
64987
  * It's texture value is managed by a node object.
@@ -64530,10 +65699,6 @@ class WebGPUTextureUtils {
64530
65699
 
64531
65700
  textureGPU = this._getDefaultCubeTextureGPU( format );
64532
65701
 
64533
- } else if ( texture.isVideoTexture ) {
64534
-
64535
- this.backend.get( texture ).externalTexture = this._getDefaultVideoFrame();
64536
-
64537
65702
  } else {
64538
65703
 
64539
65704
  textureGPU = this._getDefaultTextureGPU( format );
@@ -64618,39 +65783,23 @@ class WebGPUTextureUtils {
64618
65783
 
64619
65784
  // texture creation
64620
65785
 
64621
- if ( texture.isVideoTexture ) {
64622
-
64623
- const video = texture.source.data;
64624
- const videoFrame = new VideoFrame( video );
64625
-
64626
- textureDescriptorGPU.size.width = videoFrame.displayWidth;
64627
- textureDescriptorGPU.size.height = videoFrame.displayHeight;
64628
-
64629
- videoFrame.close();
64630
-
64631
- textureData.externalTexture = video;
64632
-
64633
- } else {
64634
-
64635
- if ( format === undefined ) {
64636
-
64637
- console.warn( 'WebGPURenderer: Texture format not supported.' );
65786
+ if ( format === undefined ) {
64638
65787
 
64639
- this.createDefaultTexture( texture );
64640
- return;
64641
-
64642
- }
65788
+ console.warn( 'WebGPURenderer: Texture format not supported.' );
64643
65789
 
64644
- if ( texture.isCubeTexture ) {
65790
+ this.createDefaultTexture( texture );
65791
+ return;
64645
65792
 
64646
- textureDescriptorGPU.textureBindingViewDimension = GPUTextureViewDimension.Cube;
65793
+ }
64647
65794
 
64648
- }
65795
+ if ( texture.isCubeTexture ) {
64649
65796
 
64650
- textureData.texture = backend.device.createTexture( textureDescriptorGPU );
65797
+ textureDescriptorGPU.textureBindingViewDimension = GPUTextureViewDimension.Cube;
64651
65798
 
64652
65799
  }
64653
65800
 
65801
+ textureData.texture = backend.device.createTexture( textureDescriptorGPU );
65802
+
64654
65803
  if ( isMSAA ) {
64655
65804
 
64656
65805
  const msaaTextureDescriptorGPU = Object.assign( {}, textureDescriptorGPU );
@@ -64851,12 +66000,6 @@ class WebGPUTextureUtils {
64851
66000
 
64852
66001
  this._copyCubeMapToTexture( options.images, textureData.texture, textureDescriptorGPU, texture.flipY, texture.premultiplyAlpha );
64853
66002
 
64854
- } else if ( texture.isVideoTexture ) {
64855
-
64856
- const video = texture.source.data;
64857
-
64858
- textureData.externalTexture = video;
64859
-
64860
66003
  } else {
64861
66004
 
64862
66005
  this._copyImageToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY, texture.premultiplyAlpha );
@@ -64986,33 +66129,6 @@ class WebGPUTextureUtils {
64986
66129
 
64987
66130
  }
64988
66131
 
64989
- /**
64990
- * Returns the default video frame used as default data in context of video textures.
64991
- *
64992
- * @private
64993
- * @return {VideoFrame} The video frame.
64994
- */
64995
- _getDefaultVideoFrame() {
64996
-
64997
- let defaultVideoFrame = this.defaultVideoFrame;
64998
-
64999
- if ( defaultVideoFrame === null ) {
65000
-
65001
- const init = {
65002
- timestamp: 0,
65003
- codedWidth: 1,
65004
- codedHeight: 1,
65005
- format: 'RGBA',
65006
- };
65007
-
65008
- this.defaultVideoFrame = defaultVideoFrame = new VideoFrame( new Uint8Array( [ 0, 0, 0, 0xff ] ), init );
65009
-
65010
- }
65011
-
65012
- return defaultVideoFrame;
65013
-
65014
- }
65015
-
65016
66132
  /**
65017
66133
  * Uploads cube texture image data to the GPU memory.
65018
66134
  *
@@ -65070,8 +66186,8 @@ class WebGPUTextureUtils {
65070
66186
  origin: { x: 0, y: 0, z: originDepth },
65071
66187
  premultipliedAlpha: premultiplyAlpha
65072
66188
  }, {
65073
- width: image.width,
65074
- height: image.height,
66189
+ width: textureDescriptorGPU.size.width,
66190
+ height: textureDescriptorGPU.size.height,
65075
66191
  depthOrArrayLayers: 1
65076
66192
  }
65077
66193
  );
@@ -66233,18 +67349,6 @@ class WGSLNodeBuilder extends NodeBuilder {
66233
67349
 
66234
67350
  }
66235
67351
 
66236
- /**
66237
- * Checks if the given texture requires a manual conversion to the working color space.
66238
- *
66239
- * @param {Texture} texture - The texture to check.
66240
- * @return {boolean} Whether the given texture requires a conversion to working color space or not.
66241
- */
66242
- needsToWorkingColorSpace( texture ) {
66243
-
66244
- return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace;
66245
-
66246
- }
66247
-
66248
67352
  /**
66249
67353
  * Generates the WGSL snippet for sampled textures.
66250
67354
  *
@@ -66272,30 +67376,7 @@ class WGSLNodeBuilder extends NodeBuilder {
66272
67376
 
66273
67377
  } else {
66274
67378
 
66275
- return this._generateTextureSampleLevel( texture, textureProperty, uvSnippet, '0', depthSnippet );
66276
-
66277
- }
66278
-
66279
- }
66280
-
66281
- /**
66282
- * Generates the WGSL snippet when sampling video textures.
66283
- *
66284
- * @private
66285
- * @param {string} textureProperty - The name of the video texture uniform in the shader.
66286
- * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
66287
- * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
66288
- * @return {string} The WGSL snippet.
66289
- */
66290
- _generateVideoSample( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
66291
-
66292
- if ( shaderStage === 'fragment' ) {
66293
-
66294
- return `textureSampleBaseClampToEdge( ${ textureProperty }, ${ textureProperty }_sampler, vec2<f32>( ${ uvSnippet }.x, 1.0 - ${ uvSnippet }.y ) )`;
66295
-
66296
- } else {
66297
-
66298
- console.error( `WebGPURenderer: THREE.VideoTexture does not support ${ shaderStage } shader.` );
67379
+ return this.generateTextureSampleLevel( texture, textureProperty, uvSnippet, '0', depthSnippet );
66299
67380
 
66300
67381
  }
66301
67382
 
@@ -66312,7 +67393,7 @@ class WGSLNodeBuilder extends NodeBuilder {
66312
67393
  * @param {string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
66313
67394
  * @return {string} The WGSL snippet.
66314
67395
  */
66315
- _generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet ) {
67396
+ generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet ) {
66316
67397
 
66317
67398
  if ( this.isUnfilterable( texture ) === false ) {
66318
67399
 
@@ -66456,7 +67537,7 @@ class WGSLNodeBuilder extends NodeBuilder {
66456
67537
  }
66457
67538
 
66458
67539
  // Build parameters string based on texture type and multisampling
66459
- if ( isMultisampled || texture.isVideoTexture || texture.isStorageTexture ) {
67540
+ if ( isMultisampled || texture.isStorageTexture ) {
66460
67541
 
66461
67542
  textureDimensionsParams = textureProperty;
66462
67543
 
@@ -66553,11 +67634,7 @@ class WGSLNodeBuilder extends NodeBuilder {
66553
67634
 
66554
67635
  let snippet;
66555
67636
 
66556
- if ( texture.isVideoTexture === true ) {
66557
-
66558
- snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet } )`;
66559
-
66560
- } else if ( depthSnippet ) {
67637
+ if ( depthSnippet ) {
66561
67638
 
66562
67639
  snippet = `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, u32( ${ levelSnippet } ) )`;
66563
67640
 
@@ -66646,11 +67723,7 @@ class WGSLNodeBuilder extends NodeBuilder {
66646
67723
 
66647
67724
  let snippet = null;
66648
67725
 
66649
- if ( texture.isVideoTexture === true ) {
66650
-
66651
- snippet = this._generateVideoSample( textureProperty, uvSnippet, shaderStage );
66652
-
66653
- } else if ( this.isUnfilterable( texture ) ) {
67726
+ if ( this.isUnfilterable( texture ) ) {
66654
67727
 
66655
67728
  snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, '0', shaderStage );
66656
67729
 
@@ -66733,22 +67806,22 @@ class WGSLNodeBuilder extends NodeBuilder {
66733
67806
  * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
66734
67807
  * @return {string} The WGSL snippet.
66735
67808
  */
66736
- generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage ) {
67809
+ generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet ) {
66737
67810
 
66738
- let snippet = null;
67811
+ if ( this.isUnfilterable( texture ) === false ) {
66739
67812
 
66740
- if ( texture.isVideoTexture === true ) {
67813
+ return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
66741
67814
 
66742
- snippet = this._generateVideoSample( textureProperty, uvSnippet, shaderStage );
67815
+ } else if ( this.isFilteredTexture( texture ) ) {
67816
+
67817
+ return this.generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet );
66743
67818
 
66744
67819
  } else {
66745
67820
 
66746
- snippet = this._generateTextureSampleLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );
67821
+ return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet );
66747
67822
 
66748
67823
  }
66749
67824
 
66750
- return snippet;
66751
-
66752
67825
  }
66753
67826
 
66754
67827
  /**
@@ -66866,9 +67939,20 @@ class WGSLNodeBuilder extends NodeBuilder {
66866
67939
  */
66867
67940
  getNodeAccess( node, shaderStage ) {
66868
67941
 
66869
- if ( shaderStage !== 'compute' )
67942
+ if ( shaderStage !== 'compute' ) {
67943
+
67944
+ if ( node.isAtomic === true ) {
67945
+
67946
+ console.warn( 'WebGPURenderer: Atomic operations are only supported in compute shaders.' );
67947
+
67948
+ return NodeAccess.READ_WRITE;
67949
+
67950
+ }
67951
+
66870
67952
  return NodeAccess.READ_ONLY;
66871
67953
 
67954
+ }
67955
+
66872
67956
  return node.access;
66873
67957
 
66874
67958
  }
@@ -66921,7 +68005,15 @@ class WGSLNodeBuilder extends NodeBuilder {
66921
68005
 
66922
68006
  if ( type === 'texture' || type === 'storageTexture' ) {
66923
68007
 
66924
- texture = new NodeSampledTexture( uniformNode.name, uniformNode.node, group, access );
68008
+ if ( node.value.is3DTexture === true ) {
68009
+
68010
+ texture = new NodeSampledTexture3D( uniformNode.name, uniformNode.node, group, access );
68011
+
68012
+ } else {
68013
+
68014
+ texture = new NodeSampledTexture( uniformNode.name, uniformNode.node, group, access );
68015
+
68016
+ }
66925
68017
 
66926
68018
  } else if ( type === 'cubeTexture' ) {
66927
68019
 
@@ -67743,10 +68835,6 @@ ${ flowData.code }
67743
68835
 
67744
68836
  textureType = 'texture_3d<f32>';
67745
68837
 
67746
- } else if ( texture.isVideoTexture === true ) {
67747
-
67748
- textureType = 'texture_external';
67749
-
67750
68838
  } else {
67751
68839
 
67752
68840
  const componentPrefix = this.getComponentTypeFromTexture( texture ).charAt( 0 );
@@ -67912,7 +69000,11 @@ ${ flowData.code }
67912
69000
 
67913
69001
  } else {
67914
69002
 
67915
- this.computeShader = this._getWGSLComputeCode( shadersData.compute, ( this.object.workgroupSize || [ 64 ] ).join( ', ' ) );
69003
+ // Early strictly validated in computeNode
69004
+
69005
+ const workgroupSize = this.object.workgroupSize;
69006
+
69007
+ this.computeShader = this._getWGSLComputeCode( shadersData.compute, workgroupSize );
67916
69008
 
67917
69009
  }
67918
69010
 
@@ -68117,36 +69209,40 @@ fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} {
68117
69209
  */
68118
69210
  _getWGSLComputeCode( shaderData, workgroupSize ) {
68119
69211
 
69212
+ const [ workgroupSizeX, workgroupSizeY, workgroupSizeZ ] = workgroupSize;
69213
+
68120
69214
  return `${ this.getSignature() }
68121
69215
  // directives
68122
- ${shaderData.directives}
69216
+ ${ shaderData.directives }
68123
69217
 
68124
69218
  // system
68125
69219
  var<private> instanceIndex : u32;
68126
69220
 
68127
69221
  // locals
68128
- ${shaderData.scopedArrays}
69222
+ ${ shaderData.scopedArrays }
68129
69223
 
68130
69224
  // structs
68131
- ${shaderData.structs}
69225
+ ${ shaderData.structs }
68132
69226
 
68133
69227
  // uniforms
68134
- ${shaderData.uniforms}
69228
+ ${ shaderData.uniforms }
68135
69229
 
68136
69230
  // codes
68137
- ${shaderData.codes}
69231
+ ${ shaderData.codes }
68138
69232
 
68139
- @compute @workgroup_size( ${workgroupSize} )
68140
- fn main( ${shaderData.attributes} ) {
69233
+ @compute @workgroup_size( ${ workgroupSizeX }, ${ workgroupSizeY }, ${ workgroupSizeZ } )
69234
+ fn main( ${ shaderData.attributes } ) {
68141
69235
 
68142
69236
  // system
68143
- instanceIndex = globalId.x + globalId.y * numWorkgroups.x * u32(${workgroupSize}) + globalId.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize});
69237
+ instanceIndex = globalId.x
69238
+ + globalId.y * ( ${ workgroupSizeX } * numWorkgroups.x )
69239
+ + globalId.z * ( ${ workgroupSizeX } * numWorkgroups.x ) * ( ${ workgroupSizeY } * numWorkgroups.y );
68144
69240
 
68145
69241
  // vars
68146
- ${shaderData.vars}
69242
+ ${ shaderData.vars }
68147
69243
 
68148
69244
  // flow
68149
- ${shaderData.flow}
69245
+ ${ shaderData.flow }
68150
69246
 
68151
69247
  }
68152
69248
  `;
@@ -68354,29 +69450,14 @@ class WebGPUUtils {
68354
69450
  /**
68355
69451
  * Returns a modified sample count from the given sample count value.
68356
69452
  *
68357
- * That is required since WebGPU does not support arbitrary sample counts.
69453
+ * That is required since WebGPU only supports either 1 or 4.
68358
69454
  *
68359
69455
  * @param {number} sampleCount - The input sample count.
68360
69456
  * @return {number} The (potentially updated) output sample count.
68361
69457
  */
68362
69458
  getSampleCount( sampleCount ) {
68363
69459
 
68364
- let count = 1;
68365
-
68366
- if ( sampleCount > 1 ) {
68367
-
68368
- // WebGPU only supports power-of-two sample counts and 2 is not a valid value
68369
- count = Math.pow( 2, Math.floor( Math.log2( sampleCount ) ) );
68370
-
68371
- if ( count === 2 ) {
68372
-
68373
- count = 4;
68374
-
68375
- }
68376
-
68377
- }
68378
-
68379
- return count;
69460
+ return sampleCount >= 4 ? 4 : 1;
68380
69461
 
68381
69462
  }
68382
69463
 
@@ -68962,30 +70043,6 @@ class WebGPUBindingUtils {
68962
70043
 
68963
70044
  bindingGPU.buffer = buffer;
68964
70045
 
68965
- } else if ( binding.isSampler ) {
68966
-
68967
- const sampler = {}; // GPUSamplerBindingLayout
68968
-
68969
- if ( binding.texture.isDepthTexture ) {
68970
-
68971
- if ( binding.texture.compareFunction !== null ) {
68972
-
68973
- sampler.type = GPUSamplerBindingType.Comparison;
68974
-
68975
- } else if ( backend.compatibilityMode ) {
68976
-
68977
- sampler.type = GPUSamplerBindingType.NonFiltering;
68978
-
68979
- }
68980
-
68981
- }
68982
-
68983
- bindingGPU.sampler = sampler;
68984
-
68985
- } else if ( binding.isSampledTexture && binding.texture.isVideoTexture ) {
68986
-
68987
- bindingGPU.externalTexture = {}; // GPUExternalTextureBindingLayout
68988
-
68989
70046
  } else if ( binding.isSampledTexture && binding.store ) {
68990
70047
 
68991
70048
  const storageTexture = {}; // GPUStorageTextureBindingLayout
@@ -69093,6 +70150,26 @@ class WebGPUBindingUtils {
69093
70150
 
69094
70151
  bindingGPU.texture = texture;
69095
70152
 
70153
+ } else if ( binding.isSampler ) {
70154
+
70155
+ const sampler = {}; // GPUSamplerBindingLayout
70156
+
70157
+ if ( binding.texture.isDepthTexture ) {
70158
+
70159
+ if ( binding.texture.compareFunction !== null ) {
70160
+
70161
+ sampler.type = GPUSamplerBindingType.Comparison;
70162
+
70163
+ } else if ( backend.compatibilityMode ) {
70164
+
70165
+ sampler.type = GPUSamplerBindingType.NonFiltering;
70166
+
70167
+ }
70168
+
70169
+ }
70170
+
70171
+ bindingGPU.sampler = sampler;
70172
+
69096
70173
  } else {
69097
70174
 
69098
70175
  console.error( `WebGPUBindingUtils: Unsupported binding "${ binding }".` );
@@ -69274,12 +70351,6 @@ class WebGPUBindingUtils {
69274
70351
 
69275
70352
  entriesGPU.push( { binding: bindingPoint, resource: { buffer: bindingData.buffer } } );
69276
70353
 
69277
- } else if ( binding.isSampler ) {
69278
-
69279
- const textureGPU = backend.get( binding.texture );
69280
-
69281
- entriesGPU.push( { binding: bindingPoint, resource: textureGPU.sampler } );
69282
-
69283
70354
  } else if ( binding.isSampledTexture ) {
69284
70355
 
69285
70356
  const textureData = backend.get( binding.texture );
@@ -69293,7 +70364,15 @@ class WebGPUBindingUtils {
69293
70364
  } else {
69294
70365
 
69295
70366
  const mipLevelCount = binding.store ? 1 : textureData.texture.mipLevelCount;
69296
- const propertyName = `view-${ textureData.texture.width }-${ textureData.texture.height }-${ mipLevelCount }`;
70367
+ let propertyName = `view-${ textureData.texture.width }-${ textureData.texture.height }`;
70368
+
70369
+ if ( textureData.texture.depthOrArrayLayers > 1 ) {
70370
+
70371
+ propertyName += `-${ textureData.texture.depthOrArrayLayers }`;
70372
+
70373
+ }
70374
+
70375
+ propertyName += `-${ mipLevelCount }`;
69297
70376
 
69298
70377
  resourceGPU = textureData[ propertyName ];
69299
70378
 
@@ -69329,6 +70408,12 @@ class WebGPUBindingUtils {
69329
70408
 
69330
70409
  entriesGPU.push( { binding: bindingPoint, resource: resourceGPU } );
69331
70410
 
70411
+ } else if ( binding.isSampler ) {
70412
+
70413
+ const textureGPU = backend.get( binding.texture );
70414
+
70415
+ entriesGPU.push( { binding: bindingPoint, resource: textureGPU.sampler } );
70416
+
69332
70417
  }
69333
70418
 
69334
70419
  bindingPoint ++;
@@ -70042,7 +71127,7 @@ class WebGPUPipelineUtils {
70042
71127
  *
70043
71128
  * @private
70044
71129
  * @param {Material} material - The material.
70045
- * @return {string} The GPU color write mask.
71130
+ * @return {number} The GPU color write mask.
70046
71131
  */
70047
71132
  _getColorWriteMask( material ) {
70048
71133
 
@@ -71623,7 +72708,7 @@ class WebGPUBackend extends Backend {
71623
72708
 
71624
72709
  }
71625
72710
 
71626
- if ( supportsDepth && depthStencilAttachment && depthStencilAttachment.depthLoadOp === undefined ) {
72711
+ if ( supportsDepth && depthStencilAttachment ) {
71627
72712
 
71628
72713
  if ( depth ) {
71629
72714
 
@@ -71642,7 +72727,7 @@ class WebGPUBackend extends Backend {
71642
72727
 
71643
72728
  //
71644
72729
 
71645
- if ( supportsStencil && depthStencilAttachment && depthStencilAttachment.stencilLoadOp === undefined ) {
72730
+ if ( supportsStencil && depthStencilAttachment ) {
71646
72731
 
71647
72732
  if ( stencil ) {
71648
72733
 
@@ -71685,7 +72770,6 @@ class WebGPUBackend extends Backend {
71685
72770
 
71686
72771
  const groupGPU = this.get( computeGroup );
71687
72772
 
71688
-
71689
72773
  const descriptor = {
71690
72774
  label: 'computeGroup_' + computeGroup.id
71691
72775
  };
@@ -71705,9 +72789,11 @@ class WebGPUBackend extends Backend {
71705
72789
  * @param {Node} computeNode - The compute node.
71706
72790
  * @param {Array<BindGroup>} bindings - The bindings.
71707
72791
  * @param {ComputePipeline} pipeline - The compute pipeline.
72792
+ * @param {Array<number>|number} [dispatchSizeOrCount=null] - Array with [ x, y, z ] values for dispatch or a single number for the count.
71708
72793
  */
71709
- compute( computeGroup, computeNode, bindings, pipeline ) {
72794
+ compute( computeGroup, computeNode, bindings, pipeline, dispatchSizeOrCount = null ) {
71710
72795
 
72796
+ const computeNodeData = this.get( computeNode );
71711
72797
  const { passEncoderGPU } = this.get( computeGroup );
71712
72798
 
71713
72799
  // pipeline
@@ -71727,29 +72813,67 @@ class WebGPUBackend extends Backend {
71727
72813
 
71728
72814
  }
71729
72815
 
71730
- const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension;
72816
+ let dispatchSize;
71731
72817
 
71732
- const computeNodeData = this.get( computeNode );
72818
+ if ( dispatchSizeOrCount === null ) {
72819
+
72820
+ dispatchSizeOrCount = computeNode.count;
72821
+
72822
+ }
72823
+
72824
+ if ( typeof dispatchSizeOrCount === 'number' ) {
72825
+
72826
+ // If a single number is given, we calculate the dispatch size based on the workgroup size
72827
+
72828
+ const count = dispatchSizeOrCount;
72829
+
72830
+ if ( computeNodeData.dispatchSize === undefined || computeNodeData.count !== count ) {
72831
+
72832
+ // cache dispatch size to avoid recalculating it every time
71733
72833
 
71734
- if ( computeNodeData.dispatchSize === undefined ) computeNodeData.dispatchSize = { x: 0, y: 1, z: 1 };
72834
+ computeNodeData.dispatchSize = [ 0, 1, 1 ];
72835
+ computeNodeData.count = count;
72836
+
72837
+ const workgroupSize = computeNode.workgroupSize;
72838
+
72839
+ let size = workgroupSize[ 0 ];
72840
+
72841
+ for ( let i = 1; i < workgroupSize.length; i ++ )
72842
+ size *= workgroupSize[ i ];
72843
+
72844
+ const dispatchCount = Math.ceil( count / size );
72845
+
72846
+ //
72847
+
72848
+ const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension;
72849
+
72850
+ dispatchSize = [ dispatchCount, 1, 1 ];
72851
+
72852
+ if ( dispatchCount > maxComputeWorkgroupsPerDimension ) {
72853
+
72854
+ dispatchSize[ 0 ] = Math.min( dispatchCount, maxComputeWorkgroupsPerDimension );
72855
+ dispatchSize[ 1 ] = Math.ceil( dispatchCount / maxComputeWorkgroupsPerDimension );
72856
+
72857
+ }
71735
72858
 
71736
- const { dispatchSize } = computeNodeData;
72859
+ computeNodeData.dispatchSize = dispatchSize;
71737
72860
 
71738
- if ( computeNode.dispatchCount > maxComputeWorkgroupsPerDimension ) {
72861
+ }
71739
72862
 
71740
- dispatchSize.x = Math.min( computeNode.dispatchCount, maxComputeWorkgroupsPerDimension );
71741
- dispatchSize.y = Math.ceil( computeNode.dispatchCount / maxComputeWorkgroupsPerDimension );
72863
+ dispatchSize = computeNodeData.dispatchSize;
71742
72864
 
71743
72865
  } else {
71744
72866
 
71745
- dispatchSize.x = computeNode.dispatchCount;
72867
+ dispatchSize = dispatchSizeOrCount;
71746
72868
 
71747
72869
  }
71748
72870
 
72871
+ //
72872
+
71749
72873
  passEncoderGPU.dispatchWorkgroups(
71750
- dispatchSize.x,
71751
- dispatchSize.y,
71752
- dispatchSize.z
72874
+ dispatchSize[ 0 ],
72875
+ dispatchSize[ 1 ] || 1,
72876
+ dispatchSize[ 2 ] || 1
71753
72877
  );
71754
72878
 
71755
72879
  }
@@ -73141,6 +74265,15 @@ class PostProcessing {
73141
74265
  */
73142
74266
  this._quadMesh = new QuadMesh( material );
73143
74267
 
74268
+ /**
74269
+ * The context of the post processing stack.
74270
+ *
74271
+ * @private
74272
+ * @type {?Object}
74273
+ * @default null
74274
+ */
74275
+ this._context = null;
74276
+
73144
74277
  }
73145
74278
 
73146
74279
  /**
@@ -73150,15 +74283,17 @@ class PostProcessing {
73150
74283
  */
73151
74284
  render() {
73152
74285
 
74286
+ const renderer = this.renderer;
74287
+
73153
74288
  this._update();
73154
74289
 
73155
- const renderer = this.renderer;
74290
+ if ( this._context.onBeforePostProcessing !== null ) this._context.onBeforePostProcessing();
73156
74291
 
73157
74292
  const toneMapping = renderer.toneMapping;
73158
74293
  const outputColorSpace = renderer.outputColorSpace;
73159
74294
 
73160
74295
  renderer.toneMapping = NoToneMapping;
73161
- renderer.outputColorSpace = LinearSRGBColorSpace;
74296
+ renderer.outputColorSpace = ColorManagement.workingColorSpace;
73162
74297
 
73163
74298
  //
73164
74299
 
@@ -73174,6 +74309,20 @@ class PostProcessing {
73174
74309
  renderer.toneMapping = toneMapping;
73175
74310
  renderer.outputColorSpace = outputColorSpace;
73176
74311
 
74312
+ if ( this._context.onAfterPostProcessing !== null ) this._context.onAfterPostProcessing();
74313
+
74314
+ }
74315
+
74316
+ /**
74317
+ * Returns the current context of the post processing stack.
74318
+ *
74319
+ * @readonly
74320
+ * @type {?Object}
74321
+ */
74322
+ get context() {
74323
+
74324
+ return this._context;
74325
+
73177
74326
  }
73178
74327
 
73179
74328
  /**
@@ -73199,7 +74348,32 @@ class PostProcessing {
73199
74348
  const toneMapping = renderer.toneMapping;
73200
74349
  const outputColorSpace = renderer.outputColorSpace;
73201
74350
 
73202
- this._quadMesh.material.fragmentNode = this.outputColorTransform === true ? renderOutput( this.outputNode, toneMapping, outputColorSpace ) : this.outputNode.context( { toneMapping, outputColorSpace } );
74351
+ const context = {
74352
+ postProcessing: this,
74353
+ onBeforePostProcessing: null,
74354
+ onAfterPostProcessing: null
74355
+ };
74356
+
74357
+ let outputNode = this.outputNode;
74358
+
74359
+ if ( this.outputColorTransform === true ) {
74360
+
74361
+ outputNode = outputNode.context( context );
74362
+
74363
+ outputNode = renderOutput( outputNode, toneMapping, outputColorSpace );
74364
+
74365
+ } else {
74366
+
74367
+ context.toneMapping = toneMapping;
74368
+ context.outputColorSpace = outputColorSpace;
74369
+
74370
+ outputNode = outputNode.context( context );
74371
+
74372
+ }
74373
+
74374
+ this._context = context;
74375
+
74376
+ this._quadMesh.material.fragmentNode = outputNode;
73203
74377
  this._quadMesh.material.needsUpdate = true;
73204
74378
 
73205
74379
  this.needsUpdate = false;
@@ -73220,13 +74394,15 @@ class PostProcessing {
73220
74394
 
73221
74395
  this._update();
73222
74396
 
74397
+ if ( this._context.onBeforePostProcessing !== null ) this._context.onBeforePostProcessing();
74398
+
73223
74399
  const renderer = this.renderer;
73224
74400
 
73225
74401
  const toneMapping = renderer.toneMapping;
73226
74402
  const outputColorSpace = renderer.outputColorSpace;
73227
74403
 
73228
74404
  renderer.toneMapping = NoToneMapping;
73229
- renderer.outputColorSpace = LinearSRGBColorSpace;
74405
+ renderer.outputColorSpace = ColorManagement.workingColorSpace;
73230
74406
 
73231
74407
  //
73232
74408
 
@@ -73242,6 +74418,8 @@ class PostProcessing {
73242
74418
  renderer.toneMapping = toneMapping;
73243
74419
  renderer.outputColorSpace = outputColorSpace;
73244
74420
 
74421
+ if ( this._context.onAfterPostProcessing !== null ) this._context.onAfterPostProcessing();
74422
+
73245
74423
  }
73246
74424
 
73247
74425
  }
@@ -73299,6 +74477,25 @@ class StorageTexture extends Texture {
73299
74477
 
73300
74478
  }
73301
74479
 
74480
+ /**
74481
+ * Sets the size of the storage texture.
74482
+ *
74483
+ * @param {number} width - The new width of the storage texture.
74484
+ * @param {number} height - The new height of the storage texture.
74485
+ */
74486
+ setSize( width, height ) {
74487
+
74488
+ if ( this.image.width !== width || this.image.height !== height ) {
74489
+
74490
+ this.image.width = width;
74491
+ this.image.height = height;
74492
+
74493
+ this.dispose();
74494
+
74495
+ }
74496
+
74497
+ }
74498
+
73302
74499
  }
73303
74500
 
73304
74501
  /**
@@ -73838,4 +75035,4 @@ class ClippingGroup extends Group {
73838
75035
 
73839
75036
  }
73840
75037
 
73841
- export { ACESFilmicToneMapping, AONode, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightNode, AnalyticLightNode, ArrayCamera, ArrayElementNode, ArrayNode, AssignNode, AttributeNode, BackSide, BasicEnvironmentNode, BasicShadowMap, BatchNode, BoxGeometry, BufferAttribute, BufferAttributeNode, BufferGeometry, BufferNode, BumpMapNode, BundleGroup, BypassNode, ByteType, CacheNode, Camera, CineonToneMapping, ClampToEdgeWrapping, ClippingGroup, CodeNode, Color, ColorManagement, ColorSpaceNode, ComputeNode, ConstNode, ContextNode, ConvertNode, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureNode, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CylinderGeometry, DataArrayTexture, DataTexture, DebugNode, DecrementStencilOp, DecrementWrapStencilOp, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightNode, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicDrawUsage, EnvironmentNode, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExpressionNode, FileLoader, Float16BufferAttribute, Float32BufferAttribute, FloatType, FramebufferTexture, FrontFacingNode, FrontSide, Frustum, FrustumArray, FunctionCallNode, FunctionNode, FunctionOverloadingNode, GLSLNodeParser, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, Group, HalfFloatType, HemisphereLight, HemisphereLightNode, IESSpotLight, IESSpotLightNode, IncrementStencilOp, IncrementWrapStencilOp, IndexNode, IndirectStorageBufferAttribute, InstanceNode, InstancedBufferAttribute, InstancedInterleavedBuffer, InstancedMeshNode, IntType, InterleavedBuffer, InterleavedBufferAttribute, InvertStencilOp, IrradianceNode, JoinNode, KeepStencilOp, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, LightProbe, LightProbeNode, Lighting, LightingContextNode, LightingModel, LightingNode, LightsNode, Line2NodeMaterial, LineBasicMaterial, LineBasicNodeMaterial, LineDashedMaterial, LineDashedNodeMaterial, LinearFilter, LinearMipMapLinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoopNode, MRTNode, Material, MaterialLoader, MaterialNode, MaterialReferenceNode, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, MaxMipLevelNode, MemberNode, Mesh, MeshBasicMaterial, MeshBasicNodeMaterial, MeshLambertMaterial, MeshLambertNodeMaterial, MeshMatcapMaterial, MeshMatcapNodeMaterial, MeshNormalMaterial, MeshNormalNodeMaterial, MeshPhongMaterial, MeshPhongNodeMaterial, MeshPhysicalMaterial, MeshPhysicalNodeMaterial, MeshSSSNodeMaterial, MeshStandardMaterial, MeshStandardNodeMaterial, MeshToonMaterial, MeshToonNodeMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, ModelNode, MorphNode, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoToneMapping, Node, NodeAccess, NodeAttribute, NodeBuilder, NodeCache, NodeCode, NodeFrame, NodeFunctionInput, NodeLoader, NodeMaterial, NodeMaterialLoader, NodeMaterialObserver, NodeObjectLoader, NodeShaderStage, NodeType, NodeUniform, NodeUpdateType, NodeUtils, NodeVar, NodeVarying, NormalBlending, NormalMapNode, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, Object3D, Object3DNode, ObjectLoader, ObjectSpaceNormalMap, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, OutputStructNode, PCFShadowMap, PMREMGenerator, PMREMNode, ParameterNode, PassNode, PerspectiveCamera, PhongLightingModel, PhysicalLightingModel, Plane, PlaneGeometry, PointLight, PointLightNode, PointUVNode, PointsMaterial, PointsNodeMaterial, PostProcessing, PosterizeNode, ProjectorLight, ProjectorLightNode, PropertyNode, QuadMesh, Quaternion, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGBIntegerFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RTTNode, RangeNode, RectAreaLight, RectAreaLightNode, RedFormat, RedIntegerFormat, ReferenceNode, ReflectorNode, ReinhardToneMapping, RemapNode, RenderOutputNode, RenderTarget, RendererReferenceNode, RendererUtils, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RotateNode, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SRGBColorSpace, SRGBTransfer, Scene, SceneNode, ScreenNode, ScriptableNode, ScriptableValueNode, SetNode, ShadowBaseNode, ShadowMaterial, ShadowNode, ShadowNodeMaterial, ShortType, SkinningNode, Sphere, SphereGeometry, SplitNode, SpotLight, SpotLightNode, SpriteMaterial, SpriteNodeMaterial, SpriteSheetUVNode, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StackNode, StaticDrawUsage, StorageArrayElementNode, StorageBufferAttribute, StorageBufferNode, StorageInstancedBufferAttribute, StorageTexture, StorageTextureNode, StructNode, StructTypeNode, SubBuildNode, SubtractEquation, SubtractiveBlending, TSL, TangentSpaceNormalMap, TempNode, Texture, Texture3DNode, TextureNode, TextureSizeNode, ToneMappingNode, ToonOutlinePassNode, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, UniformArrayNode, UniformGroupNode, UniformNode, UnsignedByteType, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, UserDataNode, VSMShadowMap, VarNode, VaryingNode, Vector2, Vector3, Vector4, VertexColorNode, ViewportDepthNode, ViewportDepthTextureNode, ViewportSharedTextureNode, ViewportTextureNode, VolumeNodeMaterial, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGPUCoordinateSystem, WebGPURenderer, WebXRController, ZeroFactor, ZeroStencilOp, createCanvasElement, defaultBuildStages, defaultShaderStages, shaderStages, vectorComponents };
75038
+ export { ACESFilmicToneMapping, AONode, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightNode, AnalyticLightNode, ArrayCamera, ArrayElementNode, ArrayNode, AssignNode, AttributeNode, BackSide, BasicEnvironmentNode, BasicShadowMap, BatchNode, BoxGeometry, BufferAttribute, BufferAttributeNode, BufferGeometry, BufferNode, BumpMapNode, BundleGroup, BypassNode, ByteType, CacheNode, Camera, CineonToneMapping, ClampToEdgeWrapping, ClippingGroup, CodeNode, Color, ColorManagement, ColorSpaceNode, ComputeNode, ConstNode, ContextNode, ConvertNode, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureNode, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CylinderGeometry, DataArrayTexture, DataTexture, DebugNode, DecrementStencilOp, DecrementWrapStencilOp, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightNode, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicDrawUsage, EnvironmentNode, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, EventNode, ExpressionNode, FileLoader, Float16BufferAttribute, Float32BufferAttribute, FloatType, FramebufferTexture, FrontFacingNode, FrontSide, Frustum, FrustumArray, FunctionCallNode, FunctionNode, FunctionOverloadingNode, GLSLNodeParser, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, Group, HalfFloatType, HemisphereLight, HemisphereLightNode, IESSpotLight, IESSpotLightNode, IncrementStencilOp, IncrementWrapStencilOp, IndexNode, IndirectStorageBufferAttribute, InstanceNode, InstancedBufferAttribute, InstancedInterleavedBuffer, InstancedMeshNode, IntType, InterleavedBuffer, InterleavedBufferAttribute, InvertStencilOp, IrradianceNode, JoinNode, KeepStencilOp, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, LightProbe, LightProbeNode, Lighting, LightingContextNode, LightingModel, LightingNode, LightsNode, Line2NodeMaterial, LineBasicMaterial, LineBasicNodeMaterial, LineDashedMaterial, LineDashedNodeMaterial, LinearFilter, LinearMipMapLinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoopNode, MRTNode, Material, MaterialLoader, MaterialNode, MaterialReferenceNode, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, MaxMipLevelNode, MemberNode, Mesh, MeshBasicMaterial, MeshBasicNodeMaterial, MeshLambertMaterial, MeshLambertNodeMaterial, MeshMatcapMaterial, MeshMatcapNodeMaterial, MeshNormalMaterial, MeshNormalNodeMaterial, MeshPhongMaterial, MeshPhongNodeMaterial, MeshPhysicalMaterial, MeshPhysicalNodeMaterial, MeshSSSNodeMaterial, MeshStandardMaterial, MeshStandardNodeMaterial, MeshToonMaterial, MeshToonNodeMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, ModelNode, MorphNode, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoToneMapping, Node, NodeAccess, NodeAttribute, NodeBuilder, NodeCache, NodeCode, NodeFrame, NodeFunctionInput, NodeLoader, NodeMaterial, NodeMaterialLoader, NodeMaterialObserver, NodeObjectLoader, NodeShaderStage, NodeType, NodeUniform, NodeUpdateType, NodeUtils, NodeVar, NodeVarying, NormalBlending, NormalMapNode, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, Object3D, Object3DNode, ObjectLoader, ObjectSpaceNormalMap, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, OutputStructNode, PCFShadowMap, PMREMGenerator, PMREMNode, ParameterNode, PassNode, PerspectiveCamera, PhongLightingModel, PhysicalLightingModel, Plane, PlaneGeometry, PointLight, PointLightNode, PointUVNode, PointsMaterial, PointsNodeMaterial, PostProcessing, PosterizeNode, ProjectorLight, ProjectorLightNode, PropertyNode, QuadMesh, Quaternion, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGBIntegerFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RTTNode, RangeNode, RectAreaLight, RectAreaLightNode, RedFormat, RedIntegerFormat, ReferenceNode, ReflectorNode, ReinhardToneMapping, RemapNode, RenderOutputNode, RenderTarget, RendererReferenceNode, RendererUtils, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RotateNode, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SRGBColorSpace, SRGBTransfer, Scene, SceneNode, ScreenNode, ScriptableNode, ScriptableValueNode, SetNode, ShadowBaseNode, ShadowMaterial, ShadowNode, ShadowNodeMaterial, ShortType, SkinningNode, Sphere, SphereGeometry, SplitNode, SpotLight, SpotLightNode, SpriteMaterial, SpriteNodeMaterial, SpriteSheetUVNode, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StackNode, StaticDrawUsage, StorageArrayElementNode, StorageBufferAttribute, StorageBufferNode, StorageInstancedBufferAttribute, StorageTexture, StorageTextureNode, StructNode, StructTypeNode, SubBuildNode, SubtractEquation, SubtractiveBlending, TSL, TangentSpaceNormalMap, TempNode, Texture, Texture3DNode, TextureNode, TextureSizeNode, ToneMappingNode, ToonOutlinePassNode, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, UniformArrayNode, UniformGroupNode, UniformNode, UnsignedByteType, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, UserDataNode, VSMShadowMap, VarNode, VaryingNode, Vector2, Vector3, Vector4, VertexColorNode, ViewportDepthNode, ViewportDepthTextureNode, ViewportSharedTextureNode, ViewportTextureNode, VolumeNodeMaterial, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGPUCoordinateSystem, WebGPURenderer, WebXRController, ZeroFactor, ZeroStencilOp, createCanvasElement, defaultBuildStages, defaultShaderStages, shaderStages, vectorComponents };