super-three 0.158.0 → 0.160.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/build/three.cjs +1720 -380
  2. package/build/three.js +1720 -380
  3. package/build/three.min.js +1 -1
  4. package/build/three.module.js +1719 -381
  5. package/build/three.module.min.js +1 -1
  6. package/examples/jsm/Addons.js +2 -1
  7. package/examples/jsm/controls/OrbitControls.js +50 -40
  8. package/examples/jsm/csm/CSMShader.js +52 -47
  9. package/examples/jsm/exporters/GLTFExporter.js +79 -1
  10. package/examples/jsm/exporters/USDZExporter.js +27 -19
  11. package/examples/jsm/helpers/TextureHelper.js +237 -0
  12. package/examples/jsm/interactive/HTMLMesh.js +9 -2
  13. package/examples/jsm/lines/LineMaterial.js +16 -33
  14. package/examples/jsm/loaders/ColladaLoader.js +0 -6
  15. package/examples/jsm/loaders/DRACOLoader.js +4 -3
  16. package/examples/jsm/loaders/FBXLoader.js +294 -124
  17. package/examples/jsm/loaders/GLTFLoader.js +71 -3
  18. package/examples/jsm/loaders/MaterialXLoader.js +73 -54
  19. package/examples/jsm/loaders/NRRDLoader.js +0 -13
  20. package/examples/jsm/loaders/SVGLoader.js +4 -4
  21. package/examples/jsm/loaders/USDZLoader.js +3 -17
  22. package/examples/jsm/math/Octree.js +15 -4
  23. package/examples/jsm/misc/Timer.js +119 -0
  24. package/examples/jsm/misc/TubePainter.js +3 -6
  25. package/examples/jsm/modifiers/CurveModifier.js +20 -2
  26. package/examples/jsm/nodes/Nodes.js +11 -7
  27. package/examples/jsm/nodes/accessors/CameraNode.js +18 -2
  28. package/examples/jsm/nodes/accessors/CubeTextureNode.js +5 -73
  29. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +11 -2
  30. package/examples/jsm/nodes/accessors/ModelNode.js +1 -1
  31. package/examples/jsm/nodes/accessors/ModelViewProjectionNode.js +12 -3
  32. package/examples/jsm/nodes/accessors/MorphNode.js +191 -16
  33. package/examples/jsm/nodes/accessors/ReferenceNode.js +25 -1
  34. package/examples/jsm/nodes/accessors/TextureNode.js +122 -36
  35. package/examples/jsm/nodes/code/CodeNode.js +3 -3
  36. package/examples/jsm/nodes/core/AttributeNode.js +7 -1
  37. package/examples/jsm/nodes/core/CacheNode.js +4 -1
  38. package/examples/jsm/nodes/core/ConstNode.js +1 -1
  39. package/examples/jsm/nodes/core/Node.js +6 -3
  40. package/examples/jsm/nodes/core/NodeBuilder.js +84 -27
  41. package/examples/jsm/nodes/core/NodeFrame.js +10 -8
  42. package/examples/jsm/nodes/core/NodeUniform.js +12 -0
  43. package/examples/jsm/nodes/core/NodeUtils.js +3 -7
  44. package/examples/jsm/nodes/core/OutputStructNode.js +3 -3
  45. package/examples/jsm/nodes/core/PropertyNode.js +17 -2
  46. package/examples/jsm/nodes/core/StructTypeNode.js +4 -4
  47. package/examples/jsm/nodes/core/UniformGroup.js +13 -0
  48. package/examples/jsm/nodes/core/UniformGroupNode.js +36 -0
  49. package/examples/jsm/nodes/core/UniformNode.js +17 -0
  50. package/examples/jsm/nodes/core/VarNode.js +2 -0
  51. package/examples/jsm/nodes/core/VaryingNode.js +1 -7
  52. package/examples/jsm/nodes/display/BumpMapNode.js +1 -1
  53. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +6 -10
  54. package/examples/jsm/nodes/display/GaussianBlurNode.js +170 -0
  55. package/examples/jsm/nodes/display/PassNode.js +182 -0
  56. package/examples/jsm/nodes/display/ViewportDepthNode.js +31 -3
  57. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +2 -2
  58. package/examples/jsm/nodes/display/ViewportNode.js +5 -8
  59. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +1 -1
  60. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +52 -17
  61. package/examples/jsm/nodes/lighting/EnvironmentNode.js +8 -12
  62. package/examples/jsm/nodes/lighting/LightsNode.js +34 -32
  63. package/examples/jsm/nodes/materials/InstancedPointsNodeMaterial.js +1 -1
  64. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +12 -12
  65. package/examples/jsm/nodes/materials/MeshBasicNodeMaterial.js +1 -0
  66. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +1 -1
  67. package/examples/jsm/nodes/materials/NodeMaterial.js +66 -41
  68. package/examples/jsm/nodes/materials/PointsNodeMaterial.js +0 -10
  69. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +0 -7
  70. package/examples/jsm/nodes/materialx/MaterialXNodes.js +10 -10
  71. package/examples/jsm/nodes/materialx/lib/mx_hsv.js +128 -54
  72. package/examples/jsm/nodes/materialx/lib/mx_noise.js +1430 -618
  73. package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +24 -14
  74. package/examples/jsm/nodes/math/MathNode.js +2 -0
  75. package/examples/jsm/nodes/math/OperatorNode.js +19 -6
  76. package/examples/jsm/nodes/shadernode/ShaderNode.js +32 -3
  77. package/examples/jsm/nodes/utils/FunctionOverloadingNode.js +95 -0
  78. package/examples/jsm/nodes/utils/RemapNode.js +2 -2
  79. package/examples/jsm/nodes/utils/SplitNode.js +8 -2
  80. package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +3 -3
  81. package/examples/jsm/objects/QuadMesh.js +60 -0
  82. package/examples/jsm/postprocessing/GTAOPass.js +572 -0
  83. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  84. package/examples/jsm/renderers/common/Animation.js +10 -21
  85. package/examples/jsm/renderers/common/Backend.js +19 -3
  86. package/examples/jsm/renderers/common/Background.js +20 -22
  87. package/examples/jsm/renderers/common/Bindings.js +30 -21
  88. package/examples/jsm/renderers/common/ChainMap.js +3 -3
  89. package/examples/jsm/renderers/common/Color4.js +37 -0
  90. package/examples/jsm/renderers/common/Geometries.js +4 -4
  91. package/examples/jsm/renderers/common/Info.js +12 -2
  92. package/examples/jsm/renderers/common/Pipelines.js +3 -51
  93. package/examples/jsm/renderers/common/PostProcessing.js +25 -0
  94. package/examples/jsm/renderers/common/RenderContext.js +1 -1
  95. package/examples/jsm/renderers/common/RenderContexts.js +1 -1
  96. package/examples/jsm/renderers/common/RenderObject.js +13 -1
  97. package/examples/jsm/renderers/common/RenderObjects.js +4 -2
  98. package/examples/jsm/renderers/common/Renderer.js +137 -37
  99. package/examples/jsm/renderers/common/StorageTexture.js +1 -0
  100. package/examples/jsm/renderers/common/Textures.js +4 -1
  101. package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +10 -2
  102. package/examples/jsm/renderers/common/nodes/NodeUniformsGroup.js +44 -0
  103. package/examples/jsm/renderers/common/nodes/Nodes.js +74 -7
  104. package/examples/jsm/renderers/webgl/WebGLBackend.js +91 -33
  105. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +100 -31
  106. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +57 -5
  107. package/examples/jsm/renderers/webgl/utils/WebGLCapabilities.js +36 -0
  108. package/examples/jsm/renderers/webgl/utils/WebGLExtensions.js +11 -1
  109. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +71 -2
  110. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +42 -0
  111. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +1 -1
  112. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +33 -3
  113. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +4 -14
  114. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +186 -137
  115. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +1 -1
  116. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +209 -90
  117. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -10
  118. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +11 -3
  119. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +2 -3
  120. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +88 -6
  121. package/examples/jsm/shaders/FXAAShader.js +133 -133
  122. package/examples/jsm/shaders/GTAOShader.js +424 -0
  123. package/examples/jsm/shaders/OutputShader.js +4 -0
  124. package/examples/jsm/shaders/PoissonDenoiseShader.js +226 -0
  125. package/examples/jsm/shaders/SAOShader.js +2 -3
  126. package/examples/jsm/shaders/SSAOShader.js +2 -3
  127. package/examples/jsm/transpiler/AST.js +40 -1
  128. package/examples/jsm/transpiler/GLSLDecoder.js +50 -8
  129. package/examples/jsm/transpiler/ShaderToyDecoder.js +4 -4
  130. package/examples/jsm/transpiler/TSLEncoder.js +124 -20
  131. package/examples/jsm/utils/SortUtils.js +158 -0
  132. package/examples/jsm/utils/TextureUtils.js +33 -21
  133. package/examples/jsm/webxr/ARButton.js +14 -0
  134. package/examples/jsm/webxr/VRButton.js +23 -8
  135. package/examples/jsm/webxr/XRButton.js +25 -11
  136. package/package.json +5 -6
  137. package/src/Three.js +1 -0
  138. package/src/constants.js +2 -1
  139. package/src/core/BufferAttribute.js +21 -2
  140. package/src/core/InterleavedBuffer.js +21 -1
  141. package/src/core/Object3D.js +60 -12
  142. package/src/core/UniformsGroup.js +7 -1
  143. package/src/extras/curves/LineCurve3.js +4 -0
  144. package/src/loaders/AudioLoader.js +1 -1
  145. package/src/loaders/BufferGeometryLoader.js +0 -7
  146. package/src/loaders/ImageBitmapLoader.js +25 -1
  147. package/src/loaders/ObjectLoader.js +49 -0
  148. package/src/materials/ShaderMaterial.js +2 -1
  149. package/src/math/ColorManagement.js +0 -16
  150. package/src/math/Quaternion.js +5 -4
  151. package/src/math/Sphere.js +2 -0
  152. package/src/math/Triangle.js +17 -5
  153. package/src/objects/BatchedMesh.js +1020 -0
  154. package/src/objects/Skeleton.js +1 -3
  155. package/src/renderers/WebGL3DRenderTarget.js +2 -2
  156. package/src/renderers/WebGLArrayRenderTarget.js +2 -2
  157. package/src/renderers/WebGLRenderer.js +24 -19
  158. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +19 -0
  159. package/src/renderers/shaders/ShaderChunk/batching_vertex.glsl.js +5 -0
  160. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +0 -5
  161. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +31 -4
  162. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +9 -4
  163. package/src/renderers/shaders/ShaderChunk/project_vertex.glsl.js +6 -0
  164. package/src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl.js +9 -17
  165. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +84 -0
  166. package/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js +6 -0
  167. package/src/renderers/shaders/ShaderChunk.js +4 -0
  168. package/src/renderers/shaders/ShaderLib/depth.glsl.js +2 -0
  169. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +2 -0
  170. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +2 -0
  171. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -0
  172. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +3 -0
  173. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +2 -0
  174. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -0
  175. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -0
  176. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +2 -0
  177. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +3 -0
  178. package/src/renderers/webgl/WebGLAttributes.js +39 -5
  179. package/src/renderers/webgl/WebGLBufferRenderer.js +31 -0
  180. package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
  181. package/src/renderers/webgl/WebGLExtensions.js +1 -0
  182. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +31 -0
  183. package/src/renderers/webgl/WebGLLights.js +11 -2
  184. package/src/renderers/webgl/WebGLProgram.js +20 -1
  185. package/src/renderers/webgl/WebGLPrograms.js +5 -0
  186. package/src/renderers/webgl/WebGLShadowMap.js +35 -0
  187. package/src/renderers/webgl/WebGLTextures.js +7 -11
  188. package/src/renderers/webgl/WebGLUniforms.js +11 -1
  189. package/src/renderers/webgl/WebGLUniformsGroups.js +72 -93
  190. package/src/renderers/webxr/WebXRManager.js +16 -0
  191. package/examples/jsm/objects/BatchedMesh.js +0 -586
@@ -2,15 +2,15 @@ import UniformNode, { uniform } from '../core/UniformNode.js';
2
2
  import { uv } from './UVNode.js';
3
3
  import { textureSize } from './TextureSizeNode.js';
4
4
  import { colorSpaceToLinear } from '../display/ColorSpaceNode.js';
5
- import { context } from '../core/ContextNode.js';
6
5
  import { expression } from '../code/ExpressionNode.js';
7
6
  import { addNodeClass } from '../core/Node.js';
7
+ import { maxMipLevel } from '../utils/MaxMipLevelNode.js';
8
8
  import { addNodeElement, nodeProxy, vec3, nodeObject } from '../shadernode/ShaderNode.js';
9
9
  import { NodeUpdateType } from '../core/constants.js';
10
10
 
11
11
  class TextureNode extends UniformNode {
12
12
 
13
- constructor( value, uvNode = null, levelNode = null, compareNode = null ) {
13
+ constructor( value, uvNode = null, levelNode = null ) {
14
14
 
15
15
  super( value );
16
16
 
@@ -18,8 +18,10 @@ class TextureNode extends UniformNode {
18
18
 
19
19
  this.uvNode = uvNode;
20
20
  this.levelNode = levelNode;
21
- this.compareNode = compareNode;
21
+ this.compareNode = null;
22
+ this.depthNode = null;
22
23
 
24
+ this.sampler = true;
23
25
  this.updateMatrix = false;
24
26
  this.updateType = NodeUpdateType.NONE;
25
27
 
@@ -76,6 +78,20 @@ class TextureNode extends UniformNode {
76
78
 
77
79
  }
78
80
 
81
+ setupUV( builder, uvNode ) {
82
+
83
+ const texture = this.value;
84
+
85
+ if ( builder.isFlipY() && ( texture.isRenderTargetTexture === true || texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {
86
+
87
+ uvNode = uvNode.setY( uvNode.y.oneMinus() );
88
+
89
+ }
90
+
91
+ return uvNode;
92
+
93
+ }
94
+
79
95
  setup( builder ) {
80
96
 
81
97
  const properties = builder.getNodeProperties( this );
@@ -84,9 +100,9 @@ class TextureNode extends UniformNode {
84
100
 
85
101
  let uvNode = this.uvNode;
86
102
 
87
- if ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUVNode ) {
103
+ if ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUV ) {
88
104
 
89
- uvNode = builder.context.getUVNode( this );
105
+ uvNode = builder.context.getUV( this );
90
106
 
91
107
  }
92
108
 
@@ -98,28 +114,71 @@ class TextureNode extends UniformNode {
98
114
 
99
115
  }
100
116
 
117
+ uvNode = this.setupUV( builder, uvNode );
118
+
101
119
  //
102
120
 
103
121
  let levelNode = this.levelNode;
104
122
 
105
- if ( levelNode === null && builder.context.getSamplerLevelNode ) {
123
+ if ( levelNode === null && builder.context.getTextureLevel ) {
124
+
125
+ levelNode = builder.context.getTextureLevel( this );
126
+
127
+ }
128
+
129
+ if ( levelNode !== null && builder.context.getTextureLevelAlgorithm !== undefined ) {
106
130
 
107
- levelNode = builder.context.getSamplerLevelNode( this );
131
+ levelNode = builder.context.getTextureLevelAlgorithm( this, levelNode );
108
132
 
109
133
  }
110
134
 
111
135
  //
112
136
 
113
137
  properties.uvNode = uvNode;
114
- properties.levelNode = levelNode ? builder.context.getMIPLevelAlgorithmNode( this, levelNode ) : null;
138
+ properties.levelNode = levelNode;
139
+ properties.compareNode = this.compareNode;
140
+ properties.depthNode = this.depthNode;
141
+
142
+ }
143
+
144
+ generateUV( builder, uvNode ) {
145
+
146
+ return uvNode.build( builder, this.sampler === true ? 'vec2' : 'ivec2' );
147
+
148
+ }
149
+
150
+ generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, depthSnippet, compareSnippet ) {
151
+
152
+ const texture = this.value;
153
+
154
+ let snippet;
155
+
156
+ if ( levelSnippet ) {
157
+
158
+ snippet = builder.generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );
159
+
160
+ } else if ( compareSnippet ) {
161
+
162
+ snippet = builder.generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet );
163
+
164
+ } else if ( this.sampler === false ) {
165
+
166
+ snippet = builder.generateTextureLoad( texture, textureProperty, uvSnippet, depthSnippet );
167
+
168
+ } else {
169
+
170
+ snippet = builder.generateTexture( texture, textureProperty, uvSnippet, depthSnippet );
171
+
172
+ }
173
+
174
+ return snippet;
115
175
 
116
176
  }
117
177
 
118
178
  generate( builder, output ) {
119
179
 
120
- const { uvNode, levelNode } = builder.getNodeProperties( this );
180
+ const properties = builder.getNodeProperties( this );
121
181
 
122
- const compareNode = this.compareNode;
123
182
  const texture = this.value;
124
183
 
125
184
  if ( ! texture || texture.isTexture !== true ) {
@@ -146,30 +205,18 @@ class TextureNode extends UniformNode {
146
205
 
147
206
  if ( propertyName === undefined ) {
148
207
 
149
- const uvSnippet = uvNode.build( builder, 'vec2' );
150
- const nodeVar = builder.getVarFromNode( this );
151
-
152
- propertyName = builder.getPropertyName( nodeVar );
153
-
154
- let snippet = null;
155
-
156
- if ( levelNode && levelNode.isNode === true ) {
157
-
158
- const levelSnippet = levelNode.build( builder, 'float' );
208
+ const { uvNode, levelNode, compareNode, depthNode } = properties;
159
209
 
160
- snippet = builder.getTextureLevel( texture, textureProperty, uvSnippet, levelSnippet );
210
+ const uvSnippet = this.generateUV( builder, uvNode );
211
+ const levelSnippet = levelNode ? levelNode.build( builder, 'float' ) : null;
212
+ const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
213
+ const compareSnippet = compareNode ? compareNode.build( builder, 'float' ) : null;
161
214
 
162
- } else if ( compareNode !== null ) {
163
-
164
- const compareSnippet = compareNode.build( builder, 'float' );
165
-
166
- snippet = builder.getTextureCompare( texture, textureProperty, uvSnippet, compareSnippet );
167
-
168
- } else {
215
+ const nodeVar = builder.getVarFromNode( this );
169
216
 
170
- snippet = builder.getTexture( texture, textureProperty, uvSnippet );
217
+ propertyName = builder.getPropertyName( nodeVar );
171
218
 
172
- }
219
+ const snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, depthSnippet, compareSnippet );
173
220
 
174
221
  builder.addLineFlowCode( `${propertyName} = ${snippet}` );
175
222
 
@@ -185,9 +232,9 @@ class TextureNode extends UniformNode {
185
232
  let snippet = propertyName;
186
233
  const nodeType = this.getNodeType( builder );
187
234
 
188
- if ( builder.needsColorSpaceToLinear( this.value ) ) {
235
+ if ( builder.needsColorSpaceToLinear( texture ) ) {
189
236
 
190
- snippet = colorSpaceToLinear( expression( snippet, nodeType ), this.value.colorSpace ).setup( builder ).build( builder, nodeType );
237
+ snippet = colorSpaceToLinear( expression( snippet, nodeType ), texture.colorSpace ).setup( builder ).build( builder, nodeType );
191
238
 
192
239
  }
193
240
 
@@ -197,6 +244,22 @@ class TextureNode extends UniformNode {
197
244
 
198
245
  }
199
246
 
247
+ setSampler( value ) {
248
+
249
+ this.sampler = value;
250
+
251
+ return this;
252
+
253
+ }
254
+
255
+ getSampler() {
256
+
257
+ return this.sampler;
258
+
259
+ }
260
+
261
+ // @TODO: Move to TSL
262
+
200
263
  uv( uvNode ) {
201
264
 
202
265
  const textureNode = this.clone();
@@ -206,14 +269,21 @@ class TextureNode extends UniformNode {
206
269
 
207
270
  }
208
271
 
272
+ blur( levelNode ) {
273
+
274
+ const textureNode = this.clone();
275
+ textureNode.levelNode = levelNode.mul( maxMipLevel( textureNode ) );
276
+
277
+ return nodeObject( textureNode );
278
+
279
+ }
280
+
209
281
  level( levelNode ) {
210
282
 
211
283
  const textureNode = this.clone();
212
284
  textureNode.levelNode = levelNode;
213
285
 
214
- return context( textureNode, {
215
- getMIPLevelAlgorithmNode: ( textureNode, levelNode ) => levelNode
216
- } );
286
+ return textureNode;
217
287
 
218
288
  }
219
289
 
@@ -232,6 +302,17 @@ class TextureNode extends UniformNode {
232
302
 
233
303
  }
234
304
 
305
+ depth( depthNode ) {
306
+
307
+ const textureNode = this.clone();
308
+ textureNode.depthNode = nodeObject( depthNode );
309
+
310
+ return nodeObject( textureNode );
311
+
312
+ }
313
+
314
+ // --
315
+
235
316
  serialize( data ) {
236
317
 
237
318
  super.serialize( data );
@@ -262,7 +343,10 @@ class TextureNode extends UniformNode {
262
343
 
263
344
  clone() {
264
345
 
265
- return new this.constructor( this.value, this.uvNode, this.levelNode, this.compareNode );
346
+ const newNode = new this.constructor( this.value, this.uvNode, this.levelNode );
347
+ newNode.sampler = this.sampler;
348
+
349
+ return newNode;
266
350
 
267
351
  }
268
352
 
@@ -271,6 +355,8 @@ class TextureNode extends UniformNode {
271
355
  export default TextureNode;
272
356
 
273
357
  export const texture = nodeProxy( TextureNode );
358
+ export const textureLoad = ( ...params ) => texture( ...params ).setSampler( false );
359
+
274
360
  //export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level );
275
361
 
276
362
  export const sampler = ( aTexture ) => ( aTexture.isNode === true ? aTexture : texture( aTexture ) ).convert( 'sampler' );
@@ -12,13 +12,13 @@ class CodeNode extends Node {
12
12
  this.code = code;
13
13
  this.language = language;
14
14
 
15
- this._includes = includes;
15
+ this.includes = includes;
16
16
 
17
17
  }
18
18
 
19
19
  setIncludes( includes ) {
20
20
 
21
- this._includes = includes;
21
+ this.includes = includes;
22
22
 
23
23
  return this;
24
24
 
@@ -26,7 +26,7 @@ class CodeNode extends Node {
26
26
 
27
27
  getIncludes( /*builder*/ ) {
28
28
 
29
- return this._includes;
29
+ return this.includes;
30
30
 
31
31
  }
32
32
 
@@ -12,6 +12,12 @@ class AttributeNode extends Node {
12
12
 
13
13
  }
14
14
 
15
+ isGlobal() {
16
+
17
+ return true;
18
+
19
+ }
20
+
15
21
  getHash( builder ) {
16
22
 
17
23
  return this.getAttributeName( builder );
@@ -87,7 +93,7 @@ class AttributeNode extends Node {
87
93
 
88
94
  console.warn( `AttributeNode: Attribute "${ attributeName }" not found.` );
89
95
 
90
- return builder.getConst( nodeType );
96
+ return builder.generateConst( nodeType );
91
97
 
92
98
  }
93
99
 
@@ -24,8 +24,9 @@ class CacheNode extends Node {
24
24
  build( builder, ...params ) {
25
25
 
26
26
  const previousCache = builder.getCache();
27
+ const cache = this.cache || builder.globalCache;
27
28
 
28
- builder.setCache( this.cache );
29
+ builder.setCache( cache );
29
30
 
30
31
  const data = this.node.build( builder, ...params );
31
32
 
@@ -40,7 +41,9 @@ class CacheNode extends Node {
40
41
  export default CacheNode;
41
42
 
42
43
  export const cache = nodeProxy( CacheNode );
44
+ export const globalCache = ( node ) => cache( node, null );
43
45
 
44
46
  addNodeElement( 'cache', cache );
47
+ addNodeElement( 'globalCache', globalCache );
45
48
 
46
49
  addNodeClass( 'CacheNode', CacheNode );
@@ -13,7 +13,7 @@ class ConstNode extends InputNode {
13
13
 
14
14
  generateConst( builder ) {
15
15
 
16
- return builder.getConst( this.getNodeType( builder ), this.value );
16
+ return builder.generateConst( this.getNodeType( builder ), this.value );
17
17
 
18
18
  }
19
19
 
@@ -54,8 +54,6 @@ class Node extends EventDispatcher {
54
54
 
55
55
  * getChildren() {
56
56
 
57
- const self = this;
58
-
59
57
  for ( const { childNode } of getNodeChildren( this ) ) {
60
58
 
61
59
  yield childNode;
@@ -460,7 +458,12 @@ export default Node;
460
458
  export function addNodeClass( type, nodeClass ) {
461
459
 
462
460
  if ( typeof nodeClass !== 'function' || ! type ) throw new Error( `Node class ${ type } is not a class` );
463
- if ( NodeClasses.has( type ) ) throw new Error( `Redefinition of node class ${ type }` );
461
+ if ( NodeClasses.has( type ) ) {
462
+
463
+ console.warn( `Redefinition of node class ${ type }` );
464
+ return;
465
+
466
+ }
464
467
 
465
468
  NodeClasses.set( type, nodeClass );
466
469
  nodeClass.type = type;
@@ -6,6 +6,7 @@ import NodeCode from './NodeCode.js';
6
6
  import NodeKeywords from './NodeKeywords.js';
7
7
  import NodeCache from './NodeCache.js';
8
8
  import ParameterNode from './ParameterNode.js';
9
+ import FunctionNode from '../code/FunctionNode.js';
9
10
  import { createNodeMaterialFromType } from '../materials/NodeMaterial.js';
10
11
  import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js';
11
12
 
@@ -19,9 +20,10 @@ import { REVISION, RenderTarget, NoColorSpace, LinearEncoding, sRGBEncoding, SRG
19
20
  import { stack } from './StackNode.js';
20
21
  import { getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js';
21
22
 
22
- import { maxMipLevel } from '../utils/MaxMipLevelNode.js';
23
-
24
23
  import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js';
24
+ import ChainMap from '../../renderers/common/ChainMap.js';
25
+
26
+ const uniformsGroupCache = new ChainMap();
25
27
 
26
28
  const typeFromLength = new Map( [
27
29
  [ 2, 'vec2' ],
@@ -41,8 +43,6 @@ const typeFromArray = new Map( [
41
43
  [ Float32Array, 'float' ]
42
44
  ] );
43
45
 
44
- const isNonPaddingElementArray = new Set( [ Int32Array, Uint32Array, Float32Array ] );
45
-
46
46
  const toFloat = ( value ) => {
47
47
 
48
48
  value = Number( value );
@@ -94,10 +94,11 @@ class NodeBuilder {
94
94
  this.stacks = [];
95
95
  this.tab = '\t';
96
96
 
97
+ this.currentFunctionNode = null;
98
+
97
99
  this.context = {
98
100
  keywords: new NodeKeywords(),
99
- material: this.material,
100
- getMIPLevelAlgorithmNode: ( textureNode, levelNode ) => levelNode.mul( maxMipLevel( textureNode ) )
101
+ material: this.material
101
102
  };
102
103
 
103
104
  this.cache = new NodeCache();
@@ -128,6 +129,41 @@ class NodeBuilder {
128
129
 
129
130
  }
130
131
 
132
+ _getSharedBindings( bindings ) {
133
+
134
+ const shared = [];
135
+
136
+ for ( const binding of bindings ) {
137
+
138
+ if ( binding.shared === true ) {
139
+
140
+ // nodes is the chainmap key
141
+ const nodes = binding.getNodes();
142
+
143
+ let sharedBinding = uniformsGroupCache.get( nodes );
144
+
145
+ if ( sharedBinding === undefined ) {
146
+
147
+ uniformsGroupCache.set( nodes, binding );
148
+
149
+ sharedBinding = binding;
150
+
151
+ }
152
+
153
+ shared.push( sharedBinding );
154
+
155
+ } else {
156
+
157
+ shared.push( binding );
158
+
159
+ }
160
+
161
+ }
162
+
163
+ return shared;
164
+
165
+ }
166
+
131
167
  getBindings() {
132
168
 
133
169
  let bindingsArray = this.bindingsArray;
@@ -136,7 +172,7 @@ class NodeBuilder {
136
172
 
137
173
  const bindings = this.bindings;
138
174
 
139
- this.bindingsArray = bindingsArray = ( this.material !== null ) ? [ ...bindings.vertex, ...bindings.fragment ] : bindings.compute;
175
+ this.bindingsArray = bindingsArray = this._getSharedBindings( ( this.material !== null ) ? [ ...bindings.vertex, ...bindings.fragment ] : bindings.compute );
140
176
 
141
177
  }
142
178
 
@@ -297,20 +333,19 @@ class NodeBuilder {
297
333
 
298
334
  }
299
335
 
300
- getTexture( /* texture, textureProperty, uvSnippet */ ) {
336
+ generateTexture( /* texture, textureProperty, uvSnippet */ ) {
301
337
 
302
338
  console.warn( 'Abstract function.' );
303
339
 
304
340
  }
305
341
 
306
- getTextureLevel( /* texture, textureProperty, uvSnippet, levelSnippet */ ) {
342
+ generateTextureLod( /* texture, textureProperty, uvSnippet, levelSnippet */ ) {
307
343
 
308
344
  console.warn( 'Abstract function.' );
309
345
 
310
346
  }
311
347
 
312
- // @TODO: rename to .generateConst()
313
- getConst( type, value = null ) {
348
+ generateConst( type, value = null ) {
314
349
 
315
350
  if ( value === null ) {
316
351
 
@@ -333,23 +368,23 @@ class NodeBuilder {
333
368
 
334
369
  const componentType = this.getComponentType( type );
335
370
 
336
- const getConst = value => this.getConst( componentType, value );
371
+ const generateConst = value => this.generateConst( componentType, value );
337
372
 
338
373
  if ( typeLength === 2 ) {
339
374
 
340
- return `${ this.getType( type ) }( ${ getConst( value.x ) }, ${ getConst( value.y ) } )`;
375
+ return `${ this.getType( type ) }( ${ generateConst( value.x ) }, ${ generateConst( value.y ) } )`;
341
376
 
342
377
  } else if ( typeLength === 3 ) {
343
378
 
344
- return `${ this.getType( type ) }( ${ getConst( value.x ) }, ${ getConst( value.y ) }, ${ getConst( value.z ) } )`;
379
+ return `${ this.getType( type ) }( ${ generateConst( value.x ) }, ${ generateConst( value.y ) }, ${ generateConst( value.z ) } )`;
345
380
 
346
381
  } else if ( typeLength === 4 ) {
347
382
 
348
- return `${ this.getType( type ) }( ${ getConst( value.x ) }, ${ getConst( value.y ) }, ${ getConst( value.z ) }, ${ getConst( value.w ) } )`;
383
+ return `${ this.getType( type ) }( ${ generateConst( value.x ) }, ${ generateConst( value.y ) }, ${ generateConst( value.z ) }, ${ generateConst( value.w ) } )`;
349
384
 
350
385
  } else if ( typeLength > 4 && value && ( value.isMatrix3 || value.isMatrix4 ) ) {
351
386
 
352
- return `${ this.getType( type ) }( ${ value.elements.map( getConst ).join( ', ' ) } )`;
387
+ return `${ this.getType( type ) }( ${ value.elements.map( generateConst ).join( ', ' ) } )`;
353
388
 
354
389
  } else if ( typeLength > 4 ) {
355
390
 
@@ -518,7 +553,7 @@ class NodeBuilder {
518
553
  if ( attribute.isInterleavedBufferAttribute ) dataAttribute = attribute.data;
519
554
 
520
555
  const array = dataAttribute.array;
521
- const itemSize = isNonPaddingElementArray.has( array.constructor ) ? attribute.itemSize : dataAttribute.stride || attribute.itemSize;
556
+ const itemSize = attribute.itemSize;
522
557
  const normalized = attribute.normalized;
523
558
 
524
559
  let arrayType;
@@ -591,9 +626,9 @@ class NodeBuilder {
591
626
 
592
627
  }
593
628
 
594
- getDataFromNode( node, shaderStage = this.shaderStage ) {
629
+ getDataFromNode( node, shaderStage = this.shaderStage, cache = null ) {
595
630
 
596
- const cache = node.isGlobal( this ) ? this.globalCache : this.cache;
631
+ cache = cache === null ? ( node.isGlobal( this ) ? this.globalCache : this.cache ) : cache;
597
632
 
598
633
  let nodeData = cache.getNodeData( node );
599
634
 
@@ -641,17 +676,15 @@ class NodeBuilder {
641
676
 
642
677
  }
643
678
 
644
- getStructTypeFromNode( node, shaderStage = this.shaderStage, name = null ) {
679
+ getStructTypeFromNode( node, shaderStage = this.shaderStage ) {
645
680
 
646
681
  const nodeData = this.getDataFromNode( node, shaderStage );
647
682
 
648
- let nodeStruct = nodeData.structType;
649
-
650
- if ( nodeStruct === undefined ) {
683
+ if ( nodeData.structType === undefined ) {
651
684
 
652
685
  const index = this.structs.index ++;
653
686
 
654
- node.name = `StructType${index}`;
687
+ node.name = `StructType${ index }`;
655
688
  this.structs[ shaderStage ].push( node );
656
689
 
657
690
  nodeData.structType = node;
@@ -664,7 +697,7 @@ class NodeBuilder {
664
697
 
665
698
  getUniformFromNode( node, type, shaderStage = this.shaderStage, name = null ) {
666
699
 
667
- const nodeData = this.getDataFromNode( node, shaderStage );
700
+ const nodeData = this.getDataFromNode( node, shaderStage, this.globalCache );
668
701
 
669
702
  let nodeUniform = nodeData.uniform;
670
703
 
@@ -708,7 +741,7 @@ class NodeBuilder {
708
741
 
709
742
  }
710
743
 
711
- getVaryingFromNode( node, type ) {
744
+ getVaryingFromNode( node, name = null, type = node.getNodeType( this ) ) {
712
745
 
713
746
  const nodeData = this.getDataFromNode( node, 'any' );
714
747
 
@@ -719,7 +752,9 @@ class NodeBuilder {
719
752
  const varyings = this.varyings;
720
753
  const index = varyings.length;
721
754
 
722
- nodeVarying = new NodeVarying( 'nodeVarying' + index, type );
755
+ if ( name === null ) name = 'nodeVarying' + index;
756
+
757
+ nodeVarying = new NodeVarying( name, type );
723
758
 
724
759
  varyings.push( nodeVarying );
725
760
 
@@ -814,6 +849,22 @@ class NodeBuilder {
814
849
 
815
850
  }
816
851
 
852
+ buildFunctionNode( shaderNode ) {
853
+
854
+ const fn = new FunctionNode();
855
+
856
+ const previous = this.currentFunctionNode;
857
+
858
+ this.currentFunctionNode = fn;
859
+
860
+ fn.code = this.buildFunctionCode( shaderNode );
861
+
862
+ this.currentFunctionNode = previous;
863
+
864
+ return fn;
865
+
866
+ }
867
+
817
868
  flowShaderNode( shaderNode ) {
818
869
 
819
870
  const layout = shaderNode.layout;
@@ -886,6 +937,12 @@ class NodeBuilder {
886
937
 
887
938
  }
888
939
 
940
+ getFunctionOperator() {
941
+
942
+ return null;
943
+
944
+ }
945
+
889
946
  flowChildNode( node, output = null ) {
890
947
 
891
948
  const previousFlow = this.flow;
@@ -47,10 +47,10 @@ class NodeFrame {
47
47
  const updateType = node.getUpdateBeforeType();
48
48
  const reference = node.updateReference( this );
49
49
 
50
- const { frameMap, renderMap } = this._getMaps( this.updateBeforeMap, reference );
51
-
52
50
  if ( updateType === NodeUpdateType.FRAME ) {
53
51
 
52
+ const { frameMap } = this._getMaps( this.updateBeforeMap, reference );
53
+
54
54
  if ( frameMap.get( node ) !== this.frameId ) {
55
55
 
56
56
  frameMap.set( node, this.frameId );
@@ -61,10 +61,11 @@ class NodeFrame {
61
61
 
62
62
  } else if ( updateType === NodeUpdateType.RENDER ) {
63
63
 
64
- if ( renderMap.get( node ) !== this.renderId || frameMap.get( node ) !== this.frameId ) {
64
+ const { renderMap } = this._getMaps( this.updateBeforeMap, reference );
65
+
66
+ if ( renderMap.get( node ) !== this.renderId ) {
65
67
 
66
68
  renderMap.set( node, this.renderId );
67
- frameMap.set( node, this.frameId );
68
69
 
69
70
  node.updateBefore( this );
70
71
 
@@ -83,10 +84,10 @@ class NodeFrame {
83
84
  const updateType = node.getUpdateType();
84
85
  const reference = node.updateReference( this );
85
86
 
86
- const { frameMap, renderMap } = this._getMaps( this.updateMap, reference );
87
-
88
87
  if ( updateType === NodeUpdateType.FRAME ) {
89
88
 
89
+ const { frameMap } = this._getMaps( this.updateMap, reference );
90
+
90
91
  if ( frameMap.get( node ) !== this.frameId ) {
91
92
 
92
93
  frameMap.set( node, this.frameId );
@@ -97,10 +98,11 @@ class NodeFrame {
97
98
 
98
99
  } else if ( updateType === NodeUpdateType.RENDER ) {
99
100
 
100
- if ( renderMap.get( node ) !== this.renderId || frameMap.get( node ) !== this.frameId ) {
101
+ const { renderMap } = this._getMaps( this.updateMap, reference );
102
+
103
+ if ( renderMap.get( node ) !== this.renderId ) {
101
104
 
102
105
  renderMap.set( node, this.renderId );
103
- frameMap.set( node, this.frameId );
104
106
 
105
107
  node.update( this );
106
108
 
@@ -23,6 +23,18 @@ class NodeUniform {
23
23
 
24
24
  }
25
25
 
26
+ get id() {
27
+
28
+ return this.node.id;
29
+
30
+ }
31
+
32
+ get groupNode() {
33
+
34
+ return this.node.groupNode;
35
+
36
+ }
37
+
26
38
  }
27
39
 
28
40
  export default NodeUniform;