@plastic-software/three 0.178.0 → 0.180.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 (245) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +950 -230
  3. package/build/three.core.js +754 -138
  4. package/build/three.core.min.js +1 -1
  5. package/build/three.module.js +197 -96
  6. package/build/three.module.min.js +1 -1
  7. package/build/three.tsl.js +99 -25
  8. package/build/three.tsl.min.js +1 -1
  9. package/build/three.webgpu.js +4586 -1499
  10. package/build/three.webgpu.min.js +1 -1
  11. package/build/three.webgpu.nodes.js +4544 -1499
  12. package/build/three.webgpu.nodes.min.js +1 -1
  13. package/examples/jsm/Addons.js +2 -3
  14. package/examples/jsm/capabilities/WebGPU.js +1 -1
  15. package/examples/jsm/controls/ArcballControls.js +7 -7
  16. package/examples/jsm/controls/DragControls.js +6 -56
  17. package/examples/jsm/controls/FirstPersonControls.js +2 -2
  18. package/examples/jsm/controls/PointerLockControls.js +0 -8
  19. package/examples/jsm/csm/CSMShadowNode.js +4 -4
  20. package/examples/jsm/environments/RoomEnvironment.js +8 -3
  21. package/examples/jsm/exporters/GLTFExporter.js +30 -22
  22. package/examples/jsm/exporters/KTX2Exporter.js +4 -2
  23. package/examples/jsm/exporters/PLYExporter.js +1 -1
  24. package/examples/jsm/exporters/USDZExporter.js +676 -299
  25. package/examples/jsm/geometries/RoundedBoxGeometry.js +47 -8
  26. package/examples/jsm/interactive/HTMLMesh.js +5 -3
  27. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  28. package/examples/jsm/libs/meshopt_decoder.module.js +75 -58
  29. package/examples/jsm/lights/LightProbeGenerator.js +14 -3
  30. package/examples/jsm/lines/Line2.js +3 -3
  31. package/examples/jsm/lines/LineGeometry.js +1 -1
  32. package/examples/jsm/lines/LineSegments2.js +2 -2
  33. package/examples/jsm/lines/Wireframe.js +2 -2
  34. package/examples/jsm/lines/WireframeGeometry2.js +1 -1
  35. package/examples/jsm/lines/webgpu/LineSegments2.js +1 -1
  36. package/examples/jsm/lines/webgpu/Wireframe.js +1 -1
  37. package/examples/jsm/loaders/ColladaLoader.js +1 -1
  38. package/examples/jsm/loaders/EXRLoader.js +210 -22
  39. package/examples/jsm/loaders/FBXLoader.js +1 -1
  40. package/examples/jsm/loaders/GLTFLoader.js +9 -5
  41. package/examples/jsm/loaders/HDRCubeTextureLoader.js +5 -5
  42. package/examples/jsm/loaders/HDRLoader.js +486 -0
  43. package/examples/jsm/loaders/KTX2Loader.js +112 -32
  44. package/examples/jsm/loaders/MaterialXLoader.js +212 -30
  45. package/examples/jsm/loaders/RGBELoader.js +7 -473
  46. package/examples/jsm/loaders/TTFLoader.js +13 -1
  47. package/examples/jsm/loaders/USDLoader.js +219 -0
  48. package/examples/jsm/loaders/USDZLoader.js +4 -892
  49. package/examples/jsm/loaders/UltraHDRLoader.js +1 -1
  50. package/examples/jsm/loaders/lwo/IFFParser.js +1 -1
  51. package/examples/jsm/loaders/usd/USDAParser.js +741 -0
  52. package/examples/jsm/loaders/usd/USDCParser.js +17 -0
  53. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  54. package/examples/jsm/math/ColorSpaces.js +19 -1
  55. package/examples/jsm/math/ConvexHull.js +2 -2
  56. package/examples/jsm/math/Lut.js +2 -2
  57. package/examples/jsm/misc/MD2CharacterComplex.js +1 -1
  58. package/examples/jsm/misc/ProgressiveLightMap.js +1 -1
  59. package/examples/jsm/misc/Volume.js +1 -1
  60. package/examples/jsm/objects/LensflareMesh.js +3 -3
  61. package/examples/jsm/objects/SkyMesh.js +2 -2
  62. package/examples/jsm/physics/RapierPhysics.js +14 -5
  63. package/examples/jsm/postprocessing/GTAOPass.js +10 -9
  64. package/examples/jsm/postprocessing/OutlinePass.js +17 -17
  65. package/examples/jsm/postprocessing/SSAOPass.js +10 -9
  66. package/examples/jsm/postprocessing/SSRPass.js +37 -8
  67. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +11 -2
  68. package/examples/jsm/transpiler/GLSLDecoder.js +23 -20
  69. package/examples/jsm/transpiler/TSLEncoder.js +2 -10
  70. package/examples/jsm/transpiler/WGSLEncoder.js +24 -0
  71. package/examples/jsm/tsl/display/AnamorphicNode.js +27 -4
  72. package/examples/jsm/tsl/display/BloomNode.js +7 -6
  73. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +2 -1
  74. package/examples/jsm/tsl/display/DepthOfFieldNode.js +439 -90
  75. package/examples/jsm/tsl/display/GTAONode.js +8 -0
  76. package/examples/jsm/tsl/display/GaussianBlurNode.js +51 -41
  77. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  78. package/examples/jsm/tsl/display/SSRNode.js +180 -65
  79. package/examples/jsm/tsl/display/{TRAAPassNode.js → TRAANode.js} +181 -172
  80. package/examples/jsm/tsl/display/boxBlur.js +64 -0
  81. package/examples/jsm/tsl/display/hashBlur.js +15 -18
  82. package/examples/jsm/tsl/lighting/TiledLightsNode.js +1 -1
  83. package/examples/jsm/utils/BufferGeometryUtils.js +1 -1
  84. package/examples/jsm/utils/ShadowMapViewerGPU.js +12 -5
  85. package/examples/jsm/webxr/OculusHandModel.js +1 -1
  86. package/package.json +1 -1
  87. package/src/Three.Core.js +2 -0
  88. package/src/Three.TSL.js +98 -24
  89. package/src/animation/AnimationClip.js +17 -2
  90. package/src/animation/KeyframeTrack.js +1 -1
  91. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  92. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  93. package/src/cameras/Camera.js +14 -0
  94. package/src/cameras/OrthographicCamera.js +1 -1
  95. package/src/cameras/PerspectiveCamera.js +1 -1
  96. package/src/constants.js +11 -3
  97. package/src/core/BufferGeometry.js +2 -2
  98. package/{examples/jsm/misc → src/core}/Timer.js +4 -42
  99. package/src/extras/PMREMGenerator.js +11 -0
  100. package/src/extras/TextureUtils.js +2 -1
  101. package/src/extras/lib/earcut.js +1 -1
  102. package/src/helpers/CameraHelper.js +41 -11
  103. package/src/helpers/SkeletonHelper.js +35 -6
  104. package/src/lights/LightShadow.js +21 -8
  105. package/src/lights/PointLightShadow.js +1 -1
  106. package/src/lights/webgpu/ProjectorLight.js +1 -1
  107. package/src/loaders/FileLoader.js +25 -2
  108. package/src/loaders/ImageBitmapLoader.js +23 -0
  109. package/src/loaders/Loader.js +14 -0
  110. package/src/loaders/LoadingManager.js +23 -0
  111. package/src/materials/Material.js +12 -0
  112. package/src/materials/MeshBasicMaterial.js +1 -1
  113. package/src/materials/MeshDistanceMaterial.js +1 -1
  114. package/src/materials/nodes/Line2NodeMaterial.js +0 -8
  115. package/src/materials/nodes/NodeMaterial.js +1 -1
  116. package/src/materials/nodes/PointsNodeMaterial.js +86 -28
  117. package/src/materials/nodes/SpriteNodeMaterial.js +3 -15
  118. package/src/materials/nodes/manager/NodeMaterialObserver.js +87 -2
  119. package/src/math/ColorManagement.js +7 -1
  120. package/src/math/Frustum.js +19 -8
  121. package/src/math/FrustumArray.js +10 -5
  122. package/src/math/Line3.js +129 -2
  123. package/src/math/Matrix4.js +48 -27
  124. package/src/math/Spherical.js +2 -2
  125. package/src/nodes/Nodes.js +4 -0
  126. package/src/nodes/TSL.js +4 -0
  127. package/src/nodes/accessors/BufferNode.js +1 -1
  128. package/src/nodes/accessors/Camera.js +142 -16
  129. package/src/nodes/accessors/ClippingNode.js +6 -5
  130. package/src/nodes/accessors/CubeTextureNode.js +2 -2
  131. package/src/nodes/accessors/InstanceNode.js +3 -1
  132. package/src/nodes/accessors/Normal.js +11 -11
  133. package/src/nodes/accessors/Object3DNode.js +1 -1
  134. package/src/nodes/accessors/ReferenceBaseNode.js +1 -1
  135. package/src/nodes/accessors/ReferenceNode.js +19 -4
  136. package/src/nodes/accessors/SceneNode.js +1 -1
  137. package/src/nodes/accessors/StorageTextureNode.js +1 -1
  138. package/src/nodes/accessors/Texture3DNode.js +13 -0
  139. package/src/nodes/accessors/TextureNode.js +83 -19
  140. package/src/nodes/code/FunctionCallNode.js +19 -0
  141. package/src/nodes/code/FunctionNode.js +23 -0
  142. package/src/nodes/core/ArrayNode.js +12 -0
  143. package/src/nodes/core/AssignNode.js +6 -2
  144. package/src/nodes/core/ContextNode.js +44 -1
  145. package/src/nodes/core/Node.js +30 -22
  146. package/src/nodes/core/NodeBuilder.js +71 -32
  147. package/src/nodes/core/NodeFrame.js +1 -1
  148. package/src/nodes/core/NodeUniform.js +1 -1
  149. package/src/nodes/core/NodeUtils.js +5 -3
  150. package/src/nodes/core/StackNode.js +71 -4
  151. package/src/nodes/core/StructNode.js +5 -5
  152. package/src/nodes/core/StructTypeNode.js +1 -0
  153. package/src/nodes/core/SubBuildNode.js +2 -2
  154. package/src/nodes/core/UniformNode.js +79 -14
  155. package/src/nodes/core/VarNode.js +83 -15
  156. package/src/nodes/display/FrontFacingNode.js +4 -8
  157. package/src/nodes/display/PassNode.js +148 -2
  158. package/src/nodes/display/ScreenNode.js +42 -13
  159. package/src/nodes/display/ViewportDepthTextureNode.js +16 -4
  160. package/src/nodes/display/ViewportSharedTextureNode.js +12 -0
  161. package/src/nodes/display/ViewportTextureNode.js +94 -4
  162. package/src/nodes/functions/PhysicalLightingModel.js +2 -2
  163. package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
  164. package/src/nodes/gpgpu/ComputeNode.js +67 -23
  165. package/src/nodes/gpgpu/SubgroupFunctionNode.js +430 -0
  166. package/src/nodes/gpgpu/WorkgroupInfoNode.js +28 -3
  167. package/src/nodes/lighting/LightsNode.js +1 -1
  168. package/src/nodes/lighting/ProjectorLightNode.js +19 -6
  169. package/src/nodes/lighting/ShadowFilterNode.js +1 -1
  170. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  171. package/src/nodes/materialx/lib/mx_noise.js +165 -1
  172. package/src/nodes/math/BitcastNode.js +156 -0
  173. package/src/nodes/math/ConditionalNode.js +19 -3
  174. package/src/nodes/math/MathNode.js +72 -60
  175. package/src/nodes/math/OperatorNode.js +26 -25
  176. package/src/nodes/tsl/TSLCore.js +477 -142
  177. package/src/nodes/utils/DebugNode.js +1 -1
  178. package/src/nodes/utils/EventNode.js +83 -0
  179. package/src/nodes/utils/JoinNode.js +3 -1
  180. package/src/nodes/utils/MemberNode.js +58 -7
  181. package/src/nodes/utils/RTTNode.js +10 -1
  182. package/src/nodes/utils/ReflectorNode.js +51 -7
  183. package/src/nodes/utils/SampleNode.js +12 -2
  184. package/src/nodes/utils/SplitNode.js +11 -0
  185. package/src/nodes/utils/Timer.js +0 -47
  186. package/src/objects/BatchedMesh.js +6 -4
  187. package/src/objects/LOD.js +1 -1
  188. package/src/objects/Sprite.js +2 -2
  189. package/src/renderers/WebGLRenderer.js +21 -31
  190. package/src/renderers/common/Attributes.js +1 -1
  191. package/src/renderers/common/Backend.js +19 -1
  192. package/src/renderers/common/Bindings.js +21 -18
  193. package/src/renderers/common/ChainMap.js +1 -1
  194. package/src/renderers/common/Color4.js +2 -2
  195. package/src/renderers/common/DataMap.js +1 -1
  196. package/src/renderers/common/Pipelines.js +1 -1
  197. package/src/renderers/common/PostProcessing.js +60 -5
  198. package/src/renderers/common/RenderContext.js +2 -2
  199. package/src/renderers/common/RenderObject.js +14 -2
  200. package/src/renderers/common/Renderer.js +55 -32
  201. package/src/renderers/common/SampledTexture.js +4 -72
  202. package/src/renderers/common/Sampler.js +91 -0
  203. package/src/renderers/common/Storage3DTexture.js +21 -0
  204. package/src/renderers/common/StorageArrayTexture.js +21 -0
  205. package/src/renderers/common/StorageTexture.js +19 -0
  206. package/src/renderers/common/Textures.js +52 -14
  207. package/src/renderers/common/TimestampQueryPool.js +3 -3
  208. package/src/renderers/common/XRManager.js +51 -17
  209. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  210. package/src/renderers/common/nodes/NodeLibrary.js +5 -5
  211. package/src/renderers/common/nodes/NodeSampledTexture.js +0 -12
  212. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  213. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  214. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  215. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  216. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +21 -11
  217. package/src/renderers/shaders/ShaderLib/depth.glsl.js +11 -2
  218. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  219. package/src/renderers/webgl/WebGLMaterials.js +6 -6
  220. package/src/renderers/webgl/WebGLProgram.js +24 -18
  221. package/src/renderers/webgl/WebGLPrograms.js +4 -4
  222. package/src/renderers/webgl/WebGLShadowMap.js +11 -1
  223. package/src/renderers/webgl/WebGLTextures.js +20 -7
  224. package/src/renderers/webgl/WebGLUtils.js +3 -2
  225. package/src/renderers/webgl-fallback/WebGLBackend.js +207 -146
  226. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +112 -19
  227. package/src/renderers/webgl-fallback/utils/WebGLState.js +1 -1
  228. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -3
  229. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -10
  230. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +3 -2
  231. package/src/renderers/webgpu/WebGPUBackend.js +87 -44
  232. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +169 -99
  233. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +35 -31
  234. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -2
  235. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +10 -19
  236. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +120 -84
  237. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +3 -3
  238. package/src/renderers/webgpu/utils/WebGPUUtils.js +2 -17
  239. package/src/renderers/webxr/WebXRDepthSensing.js +6 -10
  240. package/src/renderers/webxr/WebXRManager.js +86 -11
  241. package/src/textures/ExternalTexture.js +56 -0
  242. package/src/textures/FramebufferTexture.js +2 -2
  243. package/src/textures/Source.js +12 -2
  244. package/src/textures/VideoTexture.js +27 -2
  245. package/examples/jsm/loaders/RGBMLoader.js +0 -1148
@@ -13,6 +13,8 @@ let currentStack = null;
13
13
 
14
14
  const NodeElements = new Map();
15
15
 
16
+ // Extend Node Class for TSL using prototype
17
+
16
18
  export function addMethodChaining( name, nodeElement ) {
17
19
 
18
20
  if ( NodeElements.has( name ) ) {
@@ -26,148 +28,274 @@ export function addMethodChaining( name, nodeElement ) {
26
28
 
27
29
  NodeElements.set( name, nodeElement );
28
30
 
31
+ if ( name !== 'assign' ) {
32
+
33
+ // Changing Node prototype to add method chaining
34
+
35
+ Node.prototype[ name ] = function ( ...params ) {
36
+
37
+ //if ( name === 'toVarIntent' ) return this;
38
+
39
+ return this.isStackNode ? this.add( nodeElement( ...params ) ) : nodeElement( this, ...params );
40
+
41
+ };
42
+
43
+ // Adding assign method chaining
44
+
45
+ Node.prototype[ name + 'Assign' ] = function ( ...params ) {
46
+
47
+ return this.isStackNode ? this.assign( params[ 0 ], nodeElement( ...params ) ) : this.assign( nodeElement( this, ...params ) );
48
+
49
+ };
50
+
51
+ }
52
+
29
53
  }
30
54
 
31
55
  const parseSwizzle = ( props ) => props.replace( /r|s/g, 'x' ).replace( /g|t/g, 'y' ).replace( /b|p/g, 'z' ).replace( /a|q/g, 'w' );
32
56
  const parseSwizzleAndSort = ( props ) => parseSwizzle( props ).split( '' ).sort().join( '' );
33
57
 
34
- const shaderNodeHandler = {
58
+ Node.prototype.assign = function ( ...params ) {
35
59
 
36
- setup( NodeClosure, params ) {
60
+ if ( this.isStackNode !== true ) {
37
61
 
38
- const inputs = params.shift();
62
+ if ( currentStack !== null ) {
39
63
 
40
- return NodeClosure( nodeObjects( inputs ), ...params );
64
+ currentStack.assign( this, ...params );
41
65
 
42
- },
66
+ } else {
43
67
 
44
- get( node, prop, nodeObj ) {
68
+ console.error( 'THREE.TSL: No stack defined for assign operation. Make sure the assign is inside a Fn().' );
45
69
 
46
- if ( typeof prop === 'string' && node[ prop ] === undefined ) {
70
+ }
47
71
 
48
- if ( node.isStackNode !== true && prop === 'assign' ) {
72
+ return this;
49
73
 
50
- return ( ...params ) => {
74
+ } else {
51
75
 
52
- currentStack.assign( nodeObj, ...params );
76
+ const nodeElement = NodeElements.get( 'assign' );
53
77
 
54
- return nodeObj;
78
+ return this.add( nodeElement( ...params ) );
55
79
 
56
- };
80
+ }
81
+
82
+ };
83
+
84
+ Node.prototype.toVarIntent = function () {
85
+
86
+ return this;
87
+
88
+ };
89
+
90
+ Node.prototype.get = function ( value ) {
91
+
92
+ return new MemberNode( this, value );
93
+
94
+ };
95
+
96
+ // Cache prototype for TSL
97
+
98
+ const proto = {};
99
+
100
+ // Set swizzle properties for xyzw, rgba, and stpq.
101
+
102
+ function setProtoSwizzle( property, altA, altB ) {
57
103
 
58
- } else if ( NodeElements.has( prop ) ) {
104
+ // swizzle properties
59
105
 
60
- const nodeElement = NodeElements.get( prop );
106
+ proto[ property ] = proto[ altA ] = proto[ altB ] = {
61
107
 
62
- return node.isStackNode ? ( ...params ) => nodeObj.add( nodeElement( ...params ) ) : ( ...params ) => nodeElement( nodeObj, ...params );
108
+ get() {
63
109
 
64
- } else if ( prop === 'self' ) {
110
+ this._cache = this._cache || {};
65
111
 
66
- return node;
112
+ //
67
113
 
68
- } else if ( prop.endsWith( 'Assign' ) && NodeElements.has( prop.slice( 0, prop.length - 'Assign'.length ) ) ) {
114
+ let split = this._cache[ property ];
69
115
 
70
- const nodeElement = NodeElements.get( prop.slice( 0, prop.length - 'Assign'.length ) );
116
+ if ( split === undefined ) {
71
117
 
72
- return node.isStackNode ? ( ...params ) => nodeObj.assign( params[ 0 ], nodeElement( ...params ) ) : ( ...params ) => nodeObj.assign( nodeElement( nodeObj, ...params ) );
118
+ split = new SplitNode( this, property );
73
119
 
74
- } else if ( /^[xyzwrgbastpq]{1,4}$/.test( prop ) === true ) {
120
+ this._cache[ property ] = split;
75
121
 
76
- // accessing properties ( swizzle )
122
+ }
123
+
124
+ return split;
125
+
126
+ },
127
+
128
+ set( value ) {
129
+
130
+ this[ property ].assign( nodeObject( value ) );
131
+
132
+ }
133
+
134
+ };
77
135
 
78
- prop = parseSwizzle( prop );
136
+ // set properties ( swizzle ) and sort to xyzw sequence
79
137
 
80
- return nodeObject( new SplitNode( nodeObj, prop ) );
138
+ const propUpper = property.toUpperCase();
139
+ const altAUpper = altA.toUpperCase();
140
+ const altBUpper = altB.toUpperCase();
81
141
 
82
- } else if ( /^set[XYZWRGBASTPQ]{1,4}$/.test( prop ) === true ) {
142
+ // Set methods for swizzle properties
83
143
 
84
- // set properties ( swizzle ) and sort to xyzw sequence
144
+ Node.prototype[ 'set' + propUpper ] = Node.prototype[ 'set' + altAUpper ] = Node.prototype[ 'set' + altBUpper ] = function ( value ) {
85
145
 
86
- prop = parseSwizzleAndSort( prop.slice( 3 ).toLowerCase() );
146
+ const swizzle = parseSwizzleAndSort( property );
87
147
 
88
- return ( value ) => nodeObject( new SetNode( node, prop, nodeObject( value ) ) );
148
+ return new SetNode( this, swizzle, nodeObject( value ) );
89
149
 
90
- } else if ( /^flip[XYZWRGBASTPQ]{1,4}$/.test( prop ) === true ) {
150
+ };
151
+
152
+ // Set methods for flip properties
153
+
154
+ Node.prototype[ 'flip' + propUpper ] = Node.prototype[ 'flip' + altAUpper ] = Node.prototype[ 'flip' + altBUpper ] = function () {
155
+
156
+ const swizzle = parseSwizzleAndSort( property );
157
+
158
+ return new FlipNode( this, swizzle );
159
+
160
+ };
161
+
162
+ }
91
163
 
92
- // set properties ( swizzle ) and sort to xyzw sequence
164
+ const swizzleA = [ 'x', 'y', 'z', 'w' ];
165
+ const swizzleB = [ 'r', 'g', 'b', 'a' ];
166
+ const swizzleC = [ 's', 't', 'p', 'q' ];
93
167
 
94
- prop = parseSwizzleAndSort( prop.slice( 4 ).toLowerCase() );
168
+ for ( let a = 0; a < 4; a ++ ) {
95
169
 
96
- return () => nodeObject( new FlipNode( nodeObject( node ), prop ) );
170
+ let prop = swizzleA[ a ];
171
+ let altA = swizzleB[ a ];
172
+ let altB = swizzleC[ a ];
97
173
 
98
- } else if ( prop === 'width' || prop === 'height' || prop === 'depth' ) {
174
+ setProtoSwizzle( prop, altA, altB );
99
175
 
100
- // accessing property
176
+ for ( let b = 0; b < 4; b ++ ) {
101
177
 
102
- if ( prop === 'width' ) prop = 'x';
103
- else if ( prop === 'height' ) prop = 'y';
104
- else if ( prop === 'depth' ) prop = 'z';
178
+ prop = swizzleA[ a ] + swizzleA[ b ];
179
+ altA = swizzleB[ a ] + swizzleB[ b ];
180
+ altB = swizzleC[ a ] + swizzleC[ b ];
105
181
 
106
- return nodeObject( new SplitNode( node, prop ) );
182
+ setProtoSwizzle( prop, altA, altB );
107
183
 
108
- } else if ( /^\d+$/.test( prop ) === true ) {
184
+ for ( let c = 0; c < 4; c ++ ) {
109
185
 
110
- // accessing array
186
+ prop = swizzleA[ a ] + swizzleA[ b ] + swizzleA[ c ];
187
+ altA = swizzleB[ a ] + swizzleB[ b ] + swizzleB[ c ];
188
+ altB = swizzleC[ a ] + swizzleC[ b ] + swizzleC[ c ];
111
189
 
112
- return nodeObject( new ArrayElementNode( nodeObj, new ConstNode( Number( prop ), 'uint' ) ) );
190
+ setProtoSwizzle( prop, altA, altB );
113
191
 
114
- } else if ( /^get$/.test( prop ) === true ) {
192
+ for ( let d = 0; d < 4; d ++ ) {
115
193
 
116
- // accessing properties
194
+ prop = swizzleA[ a ] + swizzleA[ b ] + swizzleA[ c ] + swizzleA[ d ];
195
+ altA = swizzleB[ a ] + swizzleB[ b ] + swizzleB[ c ] + swizzleB[ d ];
196
+ altB = swizzleC[ a ] + swizzleC[ b ] + swizzleC[ c ] + swizzleC[ d ];
117
197
 
118
- return ( value ) => nodeObject( new MemberNode( nodeObj, value ) );
198
+ setProtoSwizzle( prop, altA, altB );
119
199
 
120
200
  }
121
201
 
122
202
  }
123
203
 
124
- return Reflect.get( node, prop, nodeObj );
204
+ }
205
+
206
+ }
207
+
208
+ // Set/get static properties for array elements (0-31).
209
+
210
+ for ( let i = 0; i < 32; i ++ ) {
125
211
 
126
- },
212
+ proto[ i ] = {
127
213
 
128
- set( node, prop, value, nodeObj ) {
214
+ get() {
129
215
 
130
- if ( typeof prop === 'string' && node[ prop ] === undefined ) {
216
+ this._cache = this._cache || {};
131
217
 
132
- // setting properties
218
+ //
133
219
 
134
- if ( /^[xyzwrgbastpq]{1,4}$/.test( prop ) === true || prop === 'width' || prop === 'height' || prop === 'depth' || /^\d+$/.test( prop ) === true ) {
220
+ let element = this._cache[ i ];
135
221
 
136
- nodeObj[ prop ].assign( value );
222
+ if ( element === undefined ) {
137
223
 
138
- return true;
224
+ element = new ArrayElementNode( this, new ConstNode( i, 'uint' ) );
225
+
226
+ this._cache[ i ] = element;
139
227
 
140
228
  }
141
229
 
230
+ return element;
231
+
232
+ },
233
+
234
+ set( value ) {
235
+
236
+ this[ i ].assign( nodeObject( value ) );
237
+
142
238
  }
143
239
 
144
- return Reflect.set( node, prop, value, nodeObj );
240
+ };
145
241
 
146
- }
242
+ }
147
243
 
148
- };
244
+ /*
245
+ // Set properties for width, height, and depth.
149
246
 
150
- const nodeObjectsCacheMap = new WeakMap();
151
- const nodeBuilderFunctionsCacheMap = new WeakMap();
247
+ function setProtoProperty( property, target ) {
152
248
 
153
- const ShaderNodeObject = function ( obj, altType = null ) {
249
+ proto[ property ] = {
154
250
 
155
- const type = getValueType( obj );
251
+ get() {
156
252
 
157
- if ( type === 'node' ) {
253
+ this._cache = this._cache || {};
254
+
255
+ //
256
+
257
+ let split = this._cache[ target ];
158
258
 
159
- let nodeObject = nodeObjectsCacheMap.get( obj );
259
+ if ( split === undefined ) {
160
260
 
161
- if ( nodeObject === undefined ) {
261
+ split = new SplitNode( this, target );
162
262
 
163
- nodeObject = new Proxy( obj, shaderNodeHandler );
263
+ this._cache[ target ] = split;
264
+
265
+ }
164
266
 
165
- nodeObjectsCacheMap.set( obj, nodeObject );
166
- nodeObjectsCacheMap.set( nodeObject, nodeObject );
267
+ return split;
268
+
269
+ },
270
+
271
+ set( value ) {
272
+
273
+ this[ target ].assign( nodeObject( value ) );
167
274
 
168
275
  }
169
276
 
170
- return nodeObject;
277
+ };
278
+
279
+ }
280
+
281
+ setProtoProperty( 'width', 'x' );
282
+ setProtoProperty( 'height', 'y' );
283
+ setProtoProperty( 'depth', 'z' );
284
+ */
285
+
286
+ Object.defineProperties( Node.prototype, proto );
287
+
288
+ // --- FINISH ---
289
+
290
+ const nodeBuilderFunctionsCacheMap = new WeakMap();
291
+
292
+ const ShaderNodeObject = function ( obj, altType = null ) {
293
+
294
+ const type = getValueType( obj );
295
+
296
+ if ( type === 'node' ) {
297
+
298
+ return obj;
171
299
 
172
300
  } else if ( ( altType === null && ( type === 'float' || type === 'boolean' ) ) || ( type && type !== 'shader' && type !== 'string' ) ) {
173
301
 
@@ -211,7 +339,28 @@ const ShaderNodeArray = function ( array, altType = null ) {
211
339
 
212
340
  const ShaderNodeProxy = function ( NodeClass, scope = null, factor = null, settings = null ) {
213
341
 
214
- const assignNode = ( node ) => nodeObject( settings !== null ? Object.assign( node, settings ) : node );
342
+ function assignNode( node ) {
343
+
344
+ if ( settings !== null ) {
345
+
346
+ node = nodeObject( Object.assign( node, settings ) );
347
+
348
+ if ( settings.intent === true ) {
349
+
350
+ node = node.toVarIntent();
351
+
352
+ }
353
+
354
+ } else {
355
+
356
+ node = nodeObject( node );
357
+
358
+ }
359
+
360
+ return node;
361
+
362
+
363
+ }
215
364
 
216
365
  let fn, name = scope, minParams, maxParams;
217
366
 
@@ -297,12 +446,12 @@ const ShaderNodeImmutable = function ( NodeClass, ...params ) {
297
446
 
298
447
  class ShaderCallNodeInternal extends Node {
299
448
 
300
- constructor( shaderNode, inputNodes ) {
449
+ constructor( shaderNode, rawInputs ) {
301
450
 
302
451
  super();
303
452
 
304
453
  this.shaderNode = shaderNode;
305
- this.inputNodes = inputNodes;
454
+ this.rawInputs = rawInputs;
306
455
 
307
456
  this.isShaderCallNodeInternal = true;
308
457
 
@@ -322,7 +471,7 @@ class ShaderCallNodeInternal extends Node {
322
471
 
323
472
  call( builder ) {
324
473
 
325
- const { shaderNode, inputNodes } = this;
474
+ const { shaderNode, rawInputs } = this;
326
475
 
327
476
  const properties = builder.getNodeProperties( shaderNode );
328
477
 
@@ -367,12 +516,48 @@ class ShaderCallNodeInternal extends Node {
367
516
 
368
517
  builder.addInclude( functionNode );
369
518
 
370
- result = nodeObject( functionNode.call( inputNodes ) );
519
+ //
520
+
521
+ const inputs = rawInputs ? getLayoutParameters( rawInputs ) : null;
522
+
523
+ result = nodeObject( functionNode.call( inputs ) );
371
524
 
372
525
  } else {
373
526
 
527
+ const secureNodeBuilder = new Proxy( builder, {
528
+
529
+ get: ( target, property, receiver ) => {
530
+
531
+ let value;
532
+
533
+ if ( Symbol.iterator === property ) {
534
+
535
+ value = function* () {
536
+
537
+ yield undefined;
538
+
539
+ };
540
+
541
+ } else {
542
+
543
+ value = Reflect.get( target, property, receiver );
544
+
545
+ }
546
+
547
+ return value;
548
+
549
+ }
550
+
551
+ } );
552
+
553
+ //
554
+
555
+ const inputs = rawInputs ? getProxyParameters( rawInputs ) : null;
556
+
557
+ const hasParameters = Array.isArray( rawInputs ) ? rawInputs.length > 0 : rawInputs !== null;
558
+
374
559
  const jsFunc = shaderNode.jsFunc;
375
- const outputNode = inputNodes !== null || jsFunc.length > 1 ? jsFunc( inputNodes || [], builder ) : jsFunc( builder );
560
+ const outputNode = hasParameters || jsFunc.length > 1 ? jsFunc( inputs, secureNodeBuilder ) : jsFunc( secureNodeBuilder );
376
561
 
377
562
  result = nodeObject( outputNode );
378
563
 
@@ -475,6 +660,110 @@ class ShaderCallNodeInternal extends Node {
475
660
 
476
661
  }
477
662
 
663
+ function getLayoutParameters( params ) {
664
+
665
+ let output;
666
+
667
+ nodeObjects( params );
668
+
669
+ const isArrayAsParameter = params[ 0 ] && ( params[ 0 ].isNode || Object.getPrototypeOf( params[ 0 ] ) !== Object.prototype );
670
+
671
+ if ( isArrayAsParameter ) {
672
+
673
+ output = [ ...params ];
674
+
675
+ } else {
676
+
677
+ output = params[ 0 ];
678
+
679
+ }
680
+
681
+ return output;
682
+
683
+ }
684
+
685
+ function getProxyParameters( params ) {
686
+
687
+ let index = 0;
688
+
689
+ nodeObjects( params );
690
+
691
+ return new Proxy( params, {
692
+
693
+ get: ( target, property, receiver ) => {
694
+
695
+ let value;
696
+
697
+ if ( property === 'length' ) {
698
+
699
+ value = params.length;
700
+
701
+ return value;
702
+
703
+ }
704
+
705
+ if ( Symbol.iterator === property ) {
706
+
707
+ value = function* () {
708
+
709
+ for ( const inputNode of params ) {
710
+
711
+ yield nodeObject( inputNode );
712
+
713
+ }
714
+
715
+ };
716
+
717
+ } else {
718
+
719
+ if ( params.length > 0 ) {
720
+
721
+ if ( Object.getPrototypeOf( params[ 0 ] ) === Object.prototype ) {
722
+
723
+ const objectTarget = params[ 0 ];
724
+
725
+ if ( objectTarget[ property ] === undefined ) {
726
+
727
+ value = objectTarget[ index ++ ];
728
+
729
+ } else {
730
+
731
+ value = Reflect.get( objectTarget, property, receiver );
732
+
733
+ }
734
+
735
+ } else if ( params[ 0 ] instanceof Node ) {
736
+
737
+ if ( params[ property ] === undefined ) {
738
+
739
+ value = params[ index ++ ];
740
+
741
+ } else {
742
+
743
+ value = Reflect.get( params, property, receiver );
744
+
745
+ }
746
+
747
+ }
748
+
749
+ } else {
750
+
751
+ value = Reflect.get( target, property, receiver );
752
+
753
+ }
754
+
755
+ value = nodeObject( value );
756
+
757
+ }
758
+
759
+ return value;
760
+
761
+ }
762
+
763
+ } );
764
+
765
+ }
766
+
478
767
  class ShaderNodeInternal extends Node {
479
768
 
480
769
  constructor( jsFunc, nodeType ) {
@@ -498,11 +787,9 @@ class ShaderNodeInternal extends Node {
498
787
 
499
788
  }
500
789
 
501
- call( inputs = null ) {
790
+ call( rawInputs = null ) {
502
791
 
503
- nodeObjects( inputs );
504
-
505
- return nodeObject( new ShaderCallNodeInternal( this, inputs ) );
792
+ return nodeObject( new ShaderCallNodeInternal( this, rawInputs ) );
506
793
 
507
794
  }
508
795
 
@@ -558,7 +845,25 @@ const ConvertType = function ( type, cacheMap = null ) {
558
845
 
559
846
  return ( ...params ) => {
560
847
 
561
- if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => typeof param !== 'object' ) ) ) {
848
+ for ( const param of params ) {
849
+
850
+ if ( param === undefined ) {
851
+
852
+ console.error( `THREE.TSL: Invalid parameter for the type "${ type }".` );
853
+
854
+ return nodeObject( new ConstNode( 0, type ) );
855
+
856
+ }
857
+
858
+ }
859
+
860
+ if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => {
861
+
862
+ const paramType = typeof param;
863
+
864
+ return paramType !== 'object' && paramType !== 'function';
865
+
866
+ } ) ) ) {
562
867
 
563
868
  params = [ getValueFromType( type, ...params ) ];
564
869
 
@@ -566,20 +871,20 @@ const ConvertType = function ( type, cacheMap = null ) {
566
871
 
567
872
  if ( params.length === 1 && cacheMap !== null && cacheMap.has( params[ 0 ] ) ) {
568
873
 
569
- return nodeObject( cacheMap.get( params[ 0 ] ) );
874
+ return nodeObjectIntent( cacheMap.get( params[ 0 ] ) );
570
875
 
571
876
  }
572
877
 
573
878
  if ( params.length === 1 ) {
574
879
 
575
880
  const node = getConstNode( params[ 0 ], type );
576
- if ( node.nodeType === type ) return nodeObject( node );
577
- return nodeObject( new ConvertNode( node, type ) );
881
+ if ( node.nodeType === type ) return nodeObjectIntent( node );
882
+ return nodeObjectIntent( new ConvertNode( node, type ) );
578
883
 
579
884
  }
580
885
 
581
886
  const nodes = params.map( param => getConstNode( param ) );
582
- return nodeObject( new JoinNode( nodes, type ) );
887
+ return nodeObjectIntent( new JoinNode( nodes, type ) );
583
888
 
584
889
  };
585
890
 
@@ -597,131 +902,161 @@ export const getConstNodeType = ( value ) => ( value !== undefined && value !==
597
902
 
598
903
  export function ShaderNode( jsFunc, nodeType ) {
599
904
 
600
- return new Proxy( new ShaderNodeInternal( jsFunc, nodeType ), shaderNodeHandler );
905
+ return new ShaderNodeInternal( jsFunc, nodeType );
601
906
 
602
907
  }
603
908
 
604
909
  export const nodeObject = ( val, altType = null ) => /* new */ ShaderNodeObject( val, altType );
910
+ export const nodeObjectIntent = ( val, altType = null ) => /* new */ nodeObject( val, altType ).toVarIntent();
605
911
  export const nodeObjects = ( val, altType = null ) => new ShaderNodeObjects( val, altType );
606
912
  export const nodeArray = ( val, altType = null ) => new ShaderNodeArray( val, altType );
607
- export const nodeProxy = ( ...params ) => new ShaderNodeProxy( ...params );
608
- export const nodeImmutable = ( ...params ) => new ShaderNodeImmutable( ...params );
913
+ export const nodeProxy = ( NodeClass, scope = null, factor = null, settings = null ) => new ShaderNodeProxy( NodeClass, scope, factor, settings );
914
+ export const nodeImmutable = ( NodeClass, ...params ) => new ShaderNodeImmutable( NodeClass, ...params );
915
+ export const nodeProxyIntent = ( NodeClass, scope = null, factor = null, settings = {} ) => new ShaderNodeProxy( NodeClass, scope, factor, { intent: true, ...settings } );
609
916
 
610
917
  let fnId = 0;
611
918
 
612
- export const Fn = ( jsFunc, layout = null ) => {
919
+ class FnNode extends Node {
613
920
 
614
- let nodeType = null;
921
+ constructor( jsFunc, layout = null ) {
615
922
 
616
- if ( layout !== null ) {
617
-
618
- if ( typeof layout === 'object' ) {
923
+ super();
619
924
 
620
- nodeType = layout.return;
925
+ let nodeType = null;
621
926
 
622
- } else {
927
+ if ( layout !== null ) {
623
928
 
624
- if ( typeof layout === 'string' ) {
929
+ if ( typeof layout === 'object' ) {
625
930
 
626
- nodeType = layout;
931
+ nodeType = layout.return;
627
932
 
628
933
  } else {
629
934
 
630
- console.error( 'THREE.TSL: Invalid layout type.' );
935
+ if ( typeof layout === 'string' ) {
936
+
937
+ nodeType = layout;
938
+
939
+ } else {
940
+
941
+ console.error( 'THREE.TSL: Invalid layout type.' );
942
+
943
+ }
944
+
945
+ layout = null;
631
946
 
632
947
  }
633
948
 
634
- layout = null;
949
+ }
950
+
951
+ this.shaderNode = new ShaderNode( jsFunc, nodeType );
952
+
953
+ if ( layout !== null ) {
954
+
955
+ this.setLayout( layout );
635
956
 
636
957
  }
637
958
 
959
+ this.isFn = true;
960
+
638
961
  }
639
962
 
640
- const shaderNode = new ShaderNode( jsFunc, nodeType );
963
+ setLayout( layout ) {
641
964
 
642
- const fn = ( ...params ) => {
965
+ const nodeType = this.shaderNode.nodeType;
643
966
 
644
- let inputs;
967
+ if ( typeof layout.inputs !== 'object' ) {
645
968
 
646
- nodeObjects( params );
969
+ const fullLayout = {
970
+ name: 'fn' + fnId ++,
971
+ type: nodeType,
972
+ inputs: []
973
+ };
647
974
 
648
- const isArrayAsParameter = params[ 0 ] && ( params[ 0 ].isNode || Object.getPrototypeOf( params[ 0 ] ) !== Object.prototype );
975
+ for ( const name in layout ) {
649
976
 
650
- if ( isArrayAsParameter ) {
977
+ if ( name === 'return' ) continue;
651
978
 
652
- inputs = [ ...params ];
979
+ fullLayout.inputs.push( {
980
+ name: name,
981
+ type: layout[ name ]
982
+ } );
653
983
 
654
- } else {
984
+ }
655
985
 
656
- inputs = params[ 0 ];
986
+ layout = fullLayout;
657
987
 
658
988
  }
659
989
 
660
- const fnCall = shaderNode.call( inputs );
990
+ this.shaderNode.setLayout( layout );
661
991
 
662
- if ( nodeType === 'void' ) fnCall.toStack();
992
+ return this;
663
993
 
664
- return fnCall;
994
+ }
665
995
 
666
- };
996
+ getNodeType( builder ) {
667
997
 
668
- fn.shaderNode = shaderNode;
669
- fn.id = shaderNode.id;
998
+ return this.shaderNode.getNodeType( builder ) || 'float';
670
999
 
671
- fn.isFn = true;
1000
+ }
672
1001
 
673
- fn.getNodeType = ( ...params ) => shaderNode.getNodeType( ...params );
674
- fn.getCacheKey = ( ...params ) => shaderNode.getCacheKey( ...params );
1002
+ call( ...params ) {
675
1003
 
676
- fn.setLayout = ( layout ) => {
1004
+ const fnCall = this.shaderNode.call( params );
677
1005
 
678
- shaderNode.setLayout( layout );
1006
+ if ( this.shaderNode.nodeType === 'void' ) fnCall.toStack();
679
1007
 
680
- return fn;
1008
+ return fnCall.toVarIntent();
681
1009
 
682
- };
1010
+ }
683
1011
 
684
- fn.once = ( subBuilds = null ) => {
1012
+ once( subBuilds = null ) {
685
1013
 
686
- shaderNode.once = true;
687
- shaderNode.subBuilds = subBuilds;
1014
+ this.shaderNode.once = true;
1015
+ this.shaderNode.subBuilds = subBuilds;
688
1016
 
689
- return fn;
1017
+ return this;
690
1018
 
691
- };
1019
+ }
692
1020
 
693
- if ( layout !== null ) {
1021
+ generate( builder ) {
694
1022
 
695
- if ( typeof layout.inputs !== 'object' ) {
1023
+ const type = this.getNodeType( builder );
696
1024
 
697
- const fullLayout = {
698
- name: 'fn' + fnId ++,
699
- type: nodeType,
700
- inputs: []
701
- };
1025
+ console.error( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
702
1026
 
703
- for ( const name in layout ) {
1027
+ return builder.generateConst( type );
704
1028
 
705
- if ( name === 'return' ) continue;
1029
+ }
706
1030
 
707
- fullLayout.inputs.push( {
708
- name: name,
709
- type: layout[ name ]
710
- } );
1031
+ }
711
1032
 
712
- }
1033
+ export function Fn( jsFunc, layout = null ) {
713
1034
 
714
- layout = fullLayout;
1035
+ const instance = new FnNode( jsFunc, layout );
715
1036
 
716
- }
1037
+ return new Proxy( () => {}, {
717
1038
 
718
- fn.setLayout( layout );
1039
+ apply( target, thisArg, params ) {
719
1040
 
720
- }
1041
+ return instance.call( ...params );
721
1042
 
722
- return fn;
1043
+ },
723
1044
 
724
- };
1045
+ get( target, prop, receiver ) {
1046
+
1047
+ return Reflect.get( instance, prop, receiver );
1048
+
1049
+ },
1050
+
1051
+ set( target, prop, value, receiver ) {
1052
+
1053
+ return Reflect.set( instance, prop, value, receiver );
1054
+
1055
+ }
1056
+
1057
+ } );
1058
+
1059
+ }
725
1060
 
726
1061
  //
727
1062