super-three 0.155.0 → 0.156.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 (108) hide show
  1. package/build/three.cjs +107 -125
  2. package/build/three.js +107 -125
  3. package/build/three.min.js +1 -1
  4. package/build/three.module.js +104 -126
  5. package/build/three.module.min.js +1 -1
  6. package/examples/jsm/controls/OrbitControls.js +13 -5
  7. package/examples/jsm/csm/CSMShader.js +35 -1
  8. package/examples/jsm/libs/tween.module.js +790 -735
  9. package/examples/jsm/libs/utif.module.js +1644 -1558
  10. package/examples/jsm/loaders/DDSLoader.js +46 -3
  11. package/examples/jsm/loaders/EXRLoader.js +4 -4
  12. package/examples/jsm/loaders/FBXLoader.js +2 -0
  13. package/examples/jsm/loaders/GLTFLoader.js +17 -7
  14. package/examples/jsm/loaders/KTX2Loader.js +126 -77
  15. package/examples/jsm/loaders/LogLuvLoader.js +2 -2
  16. package/examples/jsm/loaders/MMDLoader.js +10 -7
  17. package/examples/jsm/loaders/RGBELoader.js +48 -66
  18. package/examples/jsm/loaders/STLLoader.js +7 -0
  19. package/examples/jsm/nodes/Nodes.js +3 -0
  20. package/examples/jsm/nodes/accessors/BufferAttributeNode.js +28 -2
  21. package/examples/jsm/nodes/accessors/CubeTextureNode.js +18 -3
  22. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +2 -4
  23. package/examples/jsm/nodes/accessors/LineMaterialNode.js +31 -0
  24. package/examples/jsm/nodes/accessors/MaterialNode.js +55 -33
  25. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +3 -0
  26. package/examples/jsm/nodes/accessors/Object3DNode.js +2 -2
  27. package/examples/jsm/nodes/accessors/TextureNode.js +6 -2
  28. package/examples/jsm/nodes/accessors/TextureStoreNode.js +29 -0
  29. package/examples/jsm/nodes/core/AttributeNode.js +2 -2
  30. package/examples/jsm/nodes/core/Node.js +17 -1
  31. package/examples/jsm/nodes/core/NodeBuilder.js +94 -12
  32. package/examples/jsm/nodes/core/NodeUniform.js +1 -1
  33. package/examples/jsm/nodes/core/OutputStructNode.js +58 -0
  34. package/examples/jsm/nodes/core/PropertyNode.js +2 -0
  35. package/examples/jsm/nodes/core/StackNode.js +4 -4
  36. package/examples/jsm/nodes/core/StructTypeNode.js +24 -0
  37. package/examples/jsm/nodes/display/ViewportNode.js +19 -5
  38. package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +54 -0
  39. package/examples/jsm/nodes/materials/Materials.js +1 -0
  40. package/examples/jsm/nodes/materials/NodeMaterial.js +12 -3
  41. package/examples/jsm/nodes/math/HashNode.js +35 -0
  42. package/examples/jsm/nodes/shadernode/ShaderNode.js +4 -0
  43. package/examples/jsm/nodes/utils/SplitNode.js +1 -1
  44. package/examples/jsm/postprocessing/FilmPass.js +3 -5
  45. package/examples/jsm/postprocessing/RenderPass.js +30 -12
  46. package/examples/jsm/postprocessing/SAOPass.js +23 -98
  47. package/examples/jsm/postprocessing/SSAOPass.js +10 -30
  48. package/examples/jsm/renderers/common/Backend.js +11 -8
  49. package/examples/jsm/renderers/common/Binding.js +6 -0
  50. package/examples/jsm/renderers/common/Bindings.js +5 -4
  51. package/examples/jsm/renderers/common/Pipelines.js +2 -2
  52. package/examples/jsm/renderers/common/RenderContexts.js +26 -1
  53. package/examples/jsm/renderers/common/RenderList.js +12 -4
  54. package/examples/jsm/renderers/common/RenderObject.js +6 -2
  55. package/examples/jsm/renderers/common/Renderer.js +12 -3
  56. package/examples/jsm/renderers/common/SampledTexture.js +2 -1
  57. package/examples/jsm/renderers/common/Sampler.js +1 -1
  58. package/examples/jsm/renderers/common/StorageBuffer.js +1 -1
  59. package/examples/jsm/renderers/common/Textures.js +155 -15
  60. package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +2 -2
  61. package/examples/jsm/renderers/common/nodes/NodeSampler.js +1 -1
  62. package/examples/jsm/renderers/common/nodes/Nodes.js +43 -9
  63. package/examples/jsm/renderers/webgl/WebGLBackend.js +607 -0
  64. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +118 -17
  65. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +84 -0
  66. package/examples/jsm/renderers/webgl/utils/WebGLExtensions.js +26 -0
  67. package/examples/jsm/renderers/webgl/utils/WebGLState.js +529 -0
  68. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +199 -0
  69. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +242 -0
  70. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +340 -0
  71. package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/WebGLNodeBuilder.js +1 -1
  72. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +279 -40
  73. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +18 -2
  74. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +89 -59
  75. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -2
  76. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +15 -2
  77. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +34 -9
  78. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +26 -135
  79. package/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js +6 -5
  80. package/examples/jsm/shaders/FilmShader.js +11 -54
  81. package/examples/jsm/shaders/SAOShader.js +0 -13
  82. package/examples/jsm/shaders/SSAOShader.js +33 -26
  83. package/package.json +1 -1
  84. package/src/Three.js +1 -0
  85. package/src/audio/Audio.js +6 -0
  86. package/src/constants.js +4 -1
  87. package/src/core/Object3D.js +1 -14
  88. package/src/core/UniformsGroup.js +2 -2
  89. package/src/loaders/DataTextureLoader.js +0 -2
  90. package/src/materials/Material.js +2 -2
  91. package/src/math/Vector2.js +2 -2
  92. package/src/math/Vector3.js +3 -3
  93. package/src/math/Vector4.js +4 -4
  94. package/src/objects/Line.js +1 -1
  95. package/src/objects/Mesh.js +1 -1
  96. package/src/objects/Points.js +1 -1
  97. package/src/renderers/WebGLRenderer.js +21 -49
  98. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +11 -1
  99. package/src/renderers/shaders/ShaderLib/background.glsl.js +8 -0
  100. package/src/renderers/webgl/WebGLBackground.js +5 -14
  101. package/src/renderers/webgl/WebGLProgram.js +2 -0
  102. package/src/renderers/webgl/WebGLPrograms.js +5 -1
  103. package/src/renderers/webgl/WebGLTextures.js +4 -4
  104. package/src/renderers/webgl/WebGLUtils.js +27 -20
  105. package/src/textures/Texture.js +2 -2
  106. package/src/utils.js +9 -1
  107. /package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/SlotNode.js +0 -0
  108. /package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/WebGLNodes.js +0 -0
@@ -25,10 +25,6 @@ class RGBELoader extends DataTextureLoader {
25
25
  parse( buffer ) {
26
26
 
27
27
  const
28
- /* return codes for rgbe routines */
29
- //RGBE_RETURN_SUCCESS = 0,
30
- RGBE_RETURN_FAILURE = - 1,
31
-
32
28
  /* default error routine. change this to change error handling */
33
29
  rgbe_read_error = 1,
34
30
  rgbe_write_error = 2,
@@ -38,19 +34,14 @@ class RGBELoader extends DataTextureLoader {
38
34
 
39
35
  switch ( rgbe_error_code ) {
40
36
 
41
- case rgbe_read_error: console.error( 'THREE.RGBELoader Read Error: ' + ( msg || '' ) );
42
- break;
43
- case rgbe_write_error: console.error( 'THREE.RGBELoader Write Error: ' + ( msg || '' ) );
44
- break;
45
- case rgbe_format_error: console.error( 'THREE.RGBELoader Bad File Format: ' + ( msg || '' ) );
46
- break;
37
+ case rgbe_read_error: throw new Error( 'THREE.RGBELoader: Read Error: ' + ( msg || '' ) );
38
+ case rgbe_write_error: throw new Error( 'THREE.RGBELoader: Write Error: ' + ( msg || '' ) );
39
+ case rgbe_format_error: throw new Error( 'THREE.RGBELoader: Bad File Format: ' + ( msg || '' ) );
47
40
  default:
48
- case rgbe_memory_error: console.error( 'THREE.RGBELoader: Error: ' + ( msg || '' ) );
41
+ case rgbe_memory_error: throw new Error( 'THREE.RGBELoader: Memory Error: ' + ( msg || '' ) );
49
42
 
50
43
  }
51
44
 
52
- return RGBE_RETURN_FAILURE;
53
-
54
45
  },
55
46
 
56
47
  /* offsets to red, green, and blue components in a data (float) pixel */
@@ -138,14 +129,14 @@ class RGBELoader extends DataTextureLoader {
138
129
 
139
130
  if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) {
140
131
 
141
- return rgbe_error( rgbe_read_error, 'no header found' );
132
+ rgbe_error( rgbe_read_error, 'no header found' );
142
133
 
143
134
  }
144
135
 
145
136
  /* if you want to require the magic token then uncomment the next line */
146
137
  if ( ! ( match = line.match( magic_token_re ) ) ) {
147
138
 
148
- return rgbe_error( rgbe_format_error, 'bad initial token' );
139
+ rgbe_error( rgbe_format_error, 'bad initial token' );
149
140
 
150
141
  }
151
142
 
@@ -199,13 +190,13 @@ class RGBELoader extends DataTextureLoader {
199
190
 
200
191
  if ( ! ( header.valid & RGBE_VALID_FORMAT ) ) {
201
192
 
202
- return rgbe_error( rgbe_format_error, 'missing format specifier' );
193
+ rgbe_error( rgbe_format_error, 'missing format specifier' );
203
194
 
204
195
  }
205
196
 
206
197
  if ( ! ( header.valid & RGBE_VALID_DIMENSIONS ) ) {
207
198
 
208
- return rgbe_error( rgbe_format_error, 'missing image size specifier' );
199
+ rgbe_error( rgbe_format_error, 'missing image size specifier' );
209
200
 
210
201
  }
211
202
 
@@ -231,7 +222,7 @@ class RGBELoader extends DataTextureLoader {
231
222
 
232
223
  if ( scanline_width !== ( ( buffer[ 2 ] << 8 ) | buffer[ 3 ] ) ) {
233
224
 
234
- return rgbe_error( rgbe_format_error, 'wrong scanline width' );
225
+ rgbe_error( rgbe_format_error, 'wrong scanline width' );
235
226
 
236
227
  }
237
228
 
@@ -239,7 +230,7 @@ class RGBELoader extends DataTextureLoader {
239
230
 
240
231
  if ( ! data_rgba.length ) {
241
232
 
242
- return rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' );
233
+ rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' );
243
234
 
244
235
  }
245
236
 
@@ -255,7 +246,7 @@ class RGBELoader extends DataTextureLoader {
255
246
 
256
247
  if ( pos + 4 > buffer.byteLength ) {
257
248
 
258
- return rgbe_error( rgbe_read_error );
249
+ rgbe_error( rgbe_read_error );
259
250
 
260
251
  }
261
252
 
@@ -266,7 +257,7 @@ class RGBELoader extends DataTextureLoader {
266
257
 
267
258
  if ( ( 2 != rgbeStart[ 0 ] ) || ( 2 != rgbeStart[ 1 ] ) || ( ( ( rgbeStart[ 2 ] << 8 ) | rgbeStart[ 3 ] ) != scanline_width ) ) {
268
259
 
269
- return rgbe_error( rgbe_format_error, 'bad rgbe scanline format' );
260
+ rgbe_error( rgbe_format_error, 'bad rgbe scanline format' );
270
261
 
271
262
  }
272
263
 
@@ -282,7 +273,7 @@ class RGBELoader extends DataTextureLoader {
282
273
 
283
274
  if ( ( 0 === count ) || ( ptr + count > ptr_end ) ) {
284
275
 
285
- return rgbe_error( rgbe_format_error, 'bad scanline data' );
276
+ rgbe_error( rgbe_format_error, 'bad scanline data' );
286
277
 
287
278
  }
288
279
 
@@ -362,70 +353,61 @@ class RGBELoader extends DataTextureLoader {
362
353
  byteArray.pos = 0;
363
354
  const rgbe_header_info = RGBE_ReadHeader( byteArray );
364
355
 
365
- if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {
366
-
367
- const w = rgbe_header_info.width,
368
- h = rgbe_header_info.height,
369
- image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h );
370
-
371
- if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {
372
-
373
- let data, type;
374
- let numElements;
375
-
376
- switch ( this.type ) {
377
-
378
- case FloatType:
356
+ const w = rgbe_header_info.width,
357
+ h = rgbe_header_info.height,
358
+ image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h );
379
359
 
380
- numElements = image_rgba_data.length / 4;
381
- const floatArray = new Float32Array( numElements * 4 );
382
360
 
383
- for ( let j = 0; j < numElements; j ++ ) {
361
+ let data, type;
362
+ let numElements;
384
363
 
385
- RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 4 );
364
+ switch ( this.type ) {
386
365
 
387
- }
366
+ case FloatType:
388
367
 
389
- data = floatArray;
390
- type = FloatType;
391
- break;
368
+ numElements = image_rgba_data.length / 4;
369
+ const floatArray = new Float32Array( numElements * 4 );
392
370
 
393
- case HalfFloatType:
371
+ for ( let j = 0; j < numElements; j ++ ) {
394
372
 
395
- numElements = image_rgba_data.length / 4;
396
- const halfArray = new Uint16Array( numElements * 4 );
373
+ RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 4 );
397
374
 
398
- for ( let j = 0; j < numElements; j ++ ) {
375
+ }
399
376
 
400
- RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 4 );
377
+ data = floatArray;
378
+ type = FloatType;
379
+ break;
401
380
 
402
- }
381
+ case HalfFloatType:
403
382
 
404
- data = halfArray;
405
- type = HalfFloatType;
406
- break;
383
+ numElements = image_rgba_data.length / 4;
384
+ const halfArray = new Uint16Array( numElements * 4 );
407
385
 
408
- default:
386
+ for ( let j = 0; j < numElements; j ++ ) {
409
387
 
410
- console.error( 'THREE.RGBELoader: unsupported type: ', this.type );
411
- break;
388
+ RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 4 );
412
389
 
413
390
  }
414
391
 
415
- return {
416
- width: w, height: h,
417
- data: data,
418
- header: rgbe_header_info.string,
419
- gamma: rgbe_header_info.gamma,
420
- exposure: rgbe_header_info.exposure,
421
- type: type
422
- };
392
+ data = halfArray;
393
+ type = HalfFloatType;
394
+ break;
423
395
 
424
- }
396
+ default:
397
+
398
+ throw new Error( 'THREE.RGBELoader: unsupported type: ', this.type );
399
+ break;
425
400
 
426
401
  }
427
402
 
428
- return null;
403
+ return {
404
+ width: w, height: h,
405
+ data: data,
406
+ header: rgbe_header_info.string,
407
+ gamma: rgbe_header_info.gamma,
408
+ exposure: rgbe_header_info.exposure,
409
+ type: type
410
+ };
429
411
 
430
412
  }
431
413
 
@@ -274,6 +274,7 @@ class STLLoader extends Loader {
274
274
  const geometry = new BufferGeometry();
275
275
  const patternSolid = /solid([\s\S]*?)endsolid/g;
276
276
  const patternFace = /facet([\s\S]*?)endfacet/g;
277
+ const patternName = /solid\s(.+)/;
277
278
  let faceCounter = 0;
278
279
 
279
280
  const patternFloat = /[\s]+([+-]?(?:\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?)/.source;
@@ -282,6 +283,7 @@ class STLLoader extends Loader {
282
283
 
283
284
  const vertices = [];
284
285
  const normals = [];
286
+ const groupNames = [];
285
287
 
286
288
  const normal = new Vector3();
287
289
 
@@ -297,6 +299,9 @@ class STLLoader extends Loader {
297
299
 
298
300
  const solid = result[ 0 ];
299
301
 
302
+ const name = ( result = patternName.exec( solid ) ) !== null ? result[ 1 ] : '';
303
+ groupNames.push( name );
304
+
300
305
  while ( ( result = patternFace.exec( solid ) ) !== null ) {
301
306
 
302
307
  let vertexCountPerFace = 0;
@@ -345,6 +350,8 @@ class STLLoader extends Loader {
345
350
  const start = startVertex;
346
351
  const count = endVertex - startVertex;
347
352
 
353
+ geometry.userData.groupNames = groupNames;
354
+
348
355
  geometry.addGroup( start, count, groupCount );
349
356
  groupCount ++;
350
357
 
@@ -30,6 +30,7 @@ export { default as TempNode } from './core/TempNode.js';
30
30
  export { default as UniformNode, uniform } from './core/UniformNode.js';
31
31
  export { default as VarNode, temp } from './core/VarNode.js';
32
32
  export { default as VaryingNode, varying } from './core/VaryingNode.js';
33
+ export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js';
33
34
 
34
35
  import * as NodeUtils from './core/NodeUtils.js';
35
36
  export { NodeUtils };
@@ -38,6 +39,7 @@ export { NodeUtils };
38
39
  export { default as MathNode, EPSILON, INFINITY, radians, degrees, exp, exp2, log, log2, sqrt, inverseSqrt, floor, ceil, normalize, fract, sin, cos, tan, asin, acos, atan, abs, sign, length, negate, oneMinus, dFdx, dFdy, round, reciprocal, trunc, fwidth, atan2, min, max, mod, step, reflect, distance, difference, dot, cross, pow, pow2, pow3, pow4, transformDirection, mix, clamp, saturate, refract, smoothstep, faceForward } from './math/MathNode.js';
39
40
  export { default as OperatorNode, add, sub, mul, div, remainder, equal, assign, lessThan, greaterThan, lessThanEqual, greaterThanEqual, and, or, xor, bitAnd, bitOr, bitXor, shiftLeft, shiftRight } from './math/OperatorNode.js';
40
41
  export { default as CondNode, cond } from './math/CondNode.js';
42
+ export { default as HashNode, hash } from './math/HashNode.js';
41
43
 
42
44
  // utils
43
45
  export { default as ArrayElementNode } from './utils/ArrayElementNode.js';
@@ -86,6 +88,7 @@ export { default as SceneNode, backgroundBlurriness, backgroundIntensity } from
86
88
  export { default as StorageBufferNode, storage } from './accessors/StorageBufferNode.js';
87
89
  export { default as TangentNode, tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView, transformedTangentWorld } from './accessors/TangentNode.js';
88
90
  export { default as TextureNode, texture, /*textureLevel,*/ sampler } from './accessors/TextureNode.js';
91
+ export { default as TextureStoreNode, textureStore } from './accessors/TextureStoreNode.js';
89
92
  export { default as UVNode, uv } from './accessors/UVNode.js';
90
93
  export { default as UserDataNode, userData } from './accessors/UserDataNode.js';
91
94
 
@@ -1,12 +1,12 @@
1
1
  import InputNode from '../core/InputNode.js';
2
2
  import { addNodeClass } from '../core/Node.js';
3
3
  import { varying } from '../core/VaryingNode.js';
4
- import { nodeObject } from '../shadernode/ShaderNode.js';
4
+ import { nodeObject, addNodeElement } from '../shadernode/ShaderNode.js';
5
5
  import { InterleavedBufferAttribute, InterleavedBuffer, StaticDrawUsage, DynamicDrawUsage } from 'three';
6
6
 
7
7
  class BufferAttributeNode extends InputNode {
8
8
 
9
- constructor( value, bufferType, bufferStride = 0, bufferOffset = 0 ) {
9
+ constructor( value, bufferType = null, bufferStride = 0, bufferOffset = 0 ) {
10
10
 
11
11
  super( value, bufferType );
12
12
 
@@ -19,10 +19,34 @@ class BufferAttributeNode extends InputNode {
19
19
  this.usage = StaticDrawUsage;
20
20
  this.instanced = false;
21
21
 
22
+ this.attribute = null;
23
+
24
+ if ( value && value.isBufferAttribute === true ) {
25
+
26
+ this.attribute = value;
27
+ this.usage = value.usage;
28
+ this.instanced = value.isInstancedBufferAttribute;
29
+
30
+ }
31
+
32
+ }
33
+
34
+ getNodeType( builder ) {
35
+
36
+ if ( this.bufferType === null ) {
37
+
38
+ this.bufferType = builder.getTypeFromAttribute( this.attribute );
39
+
40
+ }
41
+
42
+ return this.bufferType;
43
+
22
44
  }
23
45
 
24
46
  construct( builder ) {
25
47
 
48
+ if ( this.attribute !== null ) return;
49
+
26
50
  const type = this.getNodeType( builder );
27
51
  const array = this.value;
28
52
  const itemSize = builder.getTypeLength( type );
@@ -96,4 +120,6 @@ export const dynamicBufferAttribute = ( array, type, stride, offset ) => bufferA
96
120
  export const instancedBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setInstanced( true );
97
121
  export const instancedDynamicBufferAttribute = ( array, type, stride, offset ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true );
98
122
 
123
+ addNodeElement( 'toAttribute', ( bufferNode ) => bufferAttribute( bufferNode.value ) );
124
+
99
125
  addNodeClass( BufferAttributeNode );
@@ -2,6 +2,8 @@ import TextureNode from './TextureNode.js';
2
2
  import UniformNode from '../core/UniformNode.js';
3
3
  import { reflectVector } from './ReflectVectorNode.js';
4
4
  import { addNodeClass } from '../core/Node.js';
5
+ import { colorSpaceToLinear } from '../display/ColorSpaceNode.js';
6
+ import { expression } from '../code/ExpressionNode.js';
5
7
  import { addNodeElement, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
6
8
 
7
9
  class CubeTextureNode extends TextureNode {
@@ -52,6 +54,7 @@ class CubeTextureNode extends TextureNode {
52
54
 
53
55
  } else {
54
56
 
57
+ const nodeType = this.getNodeType( builder );
55
58
  const nodeData = builder.getDataFromNode( this );
56
59
 
57
60
  let propertyName = nodeData.propertyName;
@@ -81,12 +84,24 @@ class CubeTextureNode extends TextureNode {
81
84
 
82
85
  builder.addLineFlowCode( `${propertyName} = ${snippet}` );
83
86
 
84
- nodeData.snippet = snippet;
85
- nodeData.propertyName = propertyName;
87
+ if ( builder.context.tempWrite !== false ) {
88
+
89
+ nodeData.snippet = snippet;
90
+ nodeData.propertyName = propertyName;
91
+
92
+ }
93
+
94
+ }
95
+
96
+ let snippet = propertyName;
97
+
98
+ if ( builder.needsColorSpaceToLinear( this.value ) ) {
99
+
100
+ snippet = colorSpaceToLinear( expression( snippet, nodeType ), this.value.colorSpace ).construct( builder ).build( builder, nodeType );
86
101
 
87
102
  }
88
103
 
89
- return builder.format( propertyName, 'vec4', output );
104
+ return builder.format( snippet, 'vec4', output );
90
105
 
91
106
  }
92
107
 
@@ -1,5 +1,3 @@
1
- // @TODO: Is this needed? Can it be moved in MaterialNode?
2
-
3
1
  import MaterialNode from './MaterialNode.js';
4
2
  import { materialReference } from './MaterialReferenceNode.js';
5
3
  import { normalView } from './NormalNode.js';
@@ -42,7 +40,7 @@ class ExtendedMaterialNode extends MaterialNode {
42
40
 
43
41
  if ( material.normalMap ) {
44
42
 
45
- node = normalMap( this.getTexture( 'normalMap' ), materialReference( 'normalScale', 'vec2' ) );
43
+ node = normalMap( this.getTexture( builder, 'normalMap' ), materialReference( 'normalScale', 'vec2' ) );
46
44
 
47
45
  } else if ( material.bumpMap ) {
48
46
 
@@ -56,7 +54,7 @@ class ExtendedMaterialNode extends MaterialNode {
56
54
 
57
55
  } else if ( scope === ExtendedMaterialNode.CLEARCOAT_NORMAL ) {
58
56
 
59
- node = material.clearcoatNormalMap ? normalMap( this.getTexture( 'clearcoatNormalMap' ), materialReference( 'clearcoatNormalScale', 'vec2' ) ) : normalView;
57
+ node = material.clearcoatNormalMap ? normalMap( this.getTexture( builder, 'clearcoatNormalMap' ), materialReference( 'clearcoatNormalScale', 'vec2' ) ) : normalView;
60
58
 
61
59
  }
62
60
 
@@ -0,0 +1,31 @@
1
+ import MaterialNode from './MaterialNode.js';
2
+ import { addNodeClass } from '../core/Node.js';
3
+ import { nodeImmutable } from '../shadernode/ShaderNode.js';
4
+
5
+ class LineMaterialNode extends MaterialNode {
6
+
7
+ constructor( scope ) {
8
+
9
+ super( scope );
10
+
11
+ }
12
+
13
+ construct( builder ) {
14
+
15
+ return this.getFloat( builder, this.scope );
16
+
17
+ }
18
+
19
+ }
20
+
21
+ LineMaterialNode.SCALE = 'scale';
22
+ LineMaterialNode.DASH_SIZE = 'dashSize';
23
+ LineMaterialNode.GAP_SIZE = 'gapSize';
24
+
25
+ export default LineMaterialNode;
26
+
27
+ export const materialLineScale = nodeImmutable( LineMaterialNode, LineMaterialNode.SCALE );
28
+ export const materialLineDashSize = nodeImmutable( LineMaterialNode, LineMaterialNode.DASH_SIZE );
29
+ export const materialLineGapSize = nodeImmutable( LineMaterialNode, LineMaterialNode.GAP_SIZE );
30
+
31
+ addNodeClass( LineMaterialNode );
@@ -3,6 +3,8 @@ import { reference } from './ReferenceNode.js';
3
3
  import { materialReference } from './MaterialReferenceNode.js';
4
4
  import { nodeImmutable, float } from '../shadernode/ShaderNode.js';
5
5
 
6
+ const cache = new WeakMap();
7
+
6
8
  class MaterialNode extends Node {
7
9
 
8
10
  constructor( scope ) {
@@ -13,29 +15,49 @@ class MaterialNode extends Node {
13
15
 
14
16
  }
15
17
 
16
- getFloat( property ) {
18
+ getCache( builder, property, type ) {
17
19
 
18
- //@TODO: Check if it can be cached by property name.
20
+ const material = builder.context.material;
19
21
 
20
- return materialReference( property, 'float' );
22
+ let cacheMaterial = cache.get( material );
21
23
 
22
- }
24
+ if ( cacheMaterial === undefined ) {
25
+
26
+ cacheMaterial = {};
27
+
28
+ cache.set( material, cacheMaterial );
29
+
30
+ }
31
+
32
+ let node = cacheMaterial[ property ];
33
+
34
+ if ( node === undefined ) {
23
35
 
24
- getColor( property ) {
36
+ node = materialReference( property, type );
25
37
 
26
- //@TODO: Check if it can be cached by property name.
38
+ cacheMaterial[ property ] = node;
27
39
 
28
- return materialReference( property, 'color' );
40
+ }
41
+
42
+ return node;
29
43
 
30
44
  }
31
45
 
32
- getTexture( property ) {
46
+ getFloat( builder, property ) {
33
47
 
34
- //@TODO: Check if it can be cached by property name.
48
+ return this.getCache( builder, property, 'float' );
49
+
50
+ }
51
+
52
+ getColor( builder, property ) {
53
+
54
+ return this.getCache( builder, property, 'color' );
55
+
56
+ }
35
57
 
36
- const textureRefNode = materialReference( property, 'texture' );
58
+ getTexture( builder, property ) {
37
59
 
38
- return textureRefNode;
60
+ return this.getCache( builder, property, 'texture' );
39
61
 
40
62
  }
41
63
 
@@ -48,19 +70,19 @@ class MaterialNode extends Node {
48
70
 
49
71
  if ( scope === MaterialNode.ALPHA_TEST || scope === MaterialNode.SHININESS || scope === MaterialNode.REFLECTIVITY || scope === MaterialNode.ROTATION || scope === MaterialNode.IRIDESCENCE || scope === MaterialNode.IRIDESCENCE_IOR ) {
50
72
 
51
- node = this.getFloat( scope );
73
+ node = this.getFloat( builder, scope );
52
74
 
53
75
  } else if ( scope === MaterialNode.SPECULAR_COLOR ) {
54
76
 
55
- node = this.getColor( 'specular' );
77
+ node = this.getColor( builder, 'specular' );
56
78
 
57
79
  } else if ( scope === MaterialNode.COLOR ) {
58
80
 
59
- const colorNode = this.getColor( 'color' );
81
+ const colorNode = this.getColor( builder, 'color' );
60
82
 
61
83
  if ( material.map && material.map.isTexture === true ) {
62
84
 
63
- node = colorNode.mul( this.getTexture( 'map' ) );
85
+ node = colorNode.mul( this.getTexture( builder, 'map' ) );
64
86
 
65
87
  } else {
66
88
 
@@ -70,11 +92,11 @@ class MaterialNode extends Node {
70
92
 
71
93
  } else if ( scope === MaterialNode.OPACITY ) {
72
94
 
73
- const opacityNode = this.getFloat( 'opacity' );
95
+ const opacityNode = this.getFloat( builder, 'opacity' );
74
96
 
75
97
  if ( material.alphaMap && material.alphaMap.isTexture === true ) {
76
98
 
77
- node = opacityNode.mul( this.getTexture( 'alphaMap' ) );
99
+ node = opacityNode.mul( this.getTexture( builder, 'alphaMap' ) );
78
100
 
79
101
  } else {
80
102
 
@@ -86,7 +108,7 @@ class MaterialNode extends Node {
86
108
 
87
109
  if ( material.specularMap && material.specularMap.isTexture === true ) {
88
110
 
89
- node = this.getTexture( 'specularMap' ).r;
111
+ node = this.getTexture( builder, 'specularMap' ).r;
90
112
 
91
113
  } else {
92
114
 
@@ -96,11 +118,11 @@ class MaterialNode extends Node {
96
118
 
97
119
  } else if ( scope === MaterialNode.ROUGHNESS ) {
98
120
 
99
- const roughnessNode = this.getFloat( 'roughness' );
121
+ const roughnessNode = this.getFloat( builder, 'roughness' );
100
122
 
101
123
  if ( material.roughnessMap && material.roughnessMap.isTexture === true ) {
102
124
 
103
- node = roughnessNode.mul( this.getTexture( 'roughnessMap' ).g );
125
+ node = roughnessNode.mul( this.getTexture( builder, 'roughnessMap' ).g );
104
126
 
105
127
  } else {
106
128
 
@@ -110,11 +132,11 @@ class MaterialNode extends Node {
110
132
 
111
133
  } else if ( scope === MaterialNode.METALNESS ) {
112
134
 
113
- const metalnessNode = this.getFloat( 'metalness' );
135
+ const metalnessNode = this.getFloat( builder, 'metalness' );
114
136
 
115
137
  if ( material.metalnessMap && material.metalnessMap.isTexture === true ) {
116
138
 
117
- node = metalnessNode.mul( this.getTexture( 'metalnessMap' ).b );
139
+ node = metalnessNode.mul( this.getTexture( builder, 'metalnessMap' ).b );
118
140
 
119
141
  } else {
120
142
 
@@ -124,11 +146,11 @@ class MaterialNode extends Node {
124
146
 
125
147
  } else if ( scope === MaterialNode.EMISSIVE ) {
126
148
 
127
- const emissiveNode = this.getColor( 'emissive' );
149
+ const emissiveNode = this.getColor( builder, 'emissive' );
128
150
 
129
151
  if ( material.emissiveMap && material.emissiveMap.isTexture === true ) {
130
152
 
131
- node = emissiveNode.mul( this.getTexture( 'emissiveMap' ) );
153
+ node = emissiveNode.mul( this.getTexture( builder, 'emissiveMap' ) );
132
154
 
133
155
  } else {
134
156
 
@@ -138,11 +160,11 @@ class MaterialNode extends Node {
138
160
 
139
161
  } else if ( scope === MaterialNode.CLEARCOAT ) {
140
162
 
141
- const clearcoatNode = this.getFloat( 'clearcoat' );
163
+ const clearcoatNode = this.getFloat( builder, 'clearcoat' );
142
164
 
143
165
  if ( material.clearcoatMap && material.clearcoatMap.isTexture === true ) {
144
166
 
145
- node = clearcoatNode.mul( this.getTexture( 'clearcoatMap' ).r );
167
+ node = clearcoatNode.mul( this.getTexture( builder, 'clearcoatMap' ).r );
146
168
 
147
169
  } else {
148
170
 
@@ -152,11 +174,11 @@ class MaterialNode extends Node {
152
174
 
153
175
  } else if ( scope === MaterialNode.CLEARCOAT_ROUGHNESS ) {
154
176
 
155
- const clearcoatRoughnessNode = this.getFloat( 'clearcoatRoughness' );
177
+ const clearcoatRoughnessNode = this.getFloat( builder, 'clearcoatRoughness' );
156
178
 
157
179
  if ( material.clearcoatRoughnessMap && material.clearcoatRoughnessMap.isTexture === true ) {
158
180
 
159
- node = clearcoatRoughnessNode.mul( this.getTexture( 'clearcoatRoughnessMap' ).r );
181
+ node = clearcoatRoughnessNode.mul( this.getTexture( builder, 'clearcoatRoughnessMap' ).r );
160
182
 
161
183
  } else {
162
184
 
@@ -166,11 +188,11 @@ class MaterialNode extends Node {
166
188
 
167
189
  } else if ( scope === MaterialNode.SHEEN ) {
168
190
 
169
- const sheenNode = this.getColor( 'sheenColor' ).mul( this.getFloat( 'sheen' ) ); // Move this mul() to CPU
191
+ const sheenNode = this.getColor( builder, 'sheenColor' ).mul( this.getFloat( builder, 'sheen' ) ); // Move this mul() to CPU
170
192
 
171
193
  if ( material.sheenColorMap && material.sheenColorMap.isTexture === true ) {
172
194
 
173
- node = sheenNode.mul( this.getTexture( 'sheenColorMap' ).rgb );
195
+ node = sheenNode.mul( this.getTexture( builder, 'sheenColorMap' ).rgb );
174
196
 
175
197
  } else {
176
198
 
@@ -180,11 +202,11 @@ class MaterialNode extends Node {
180
202
 
181
203
  } else if ( scope === MaterialNode.SHEEN_ROUGHNESS ) {
182
204
 
183
- const sheenRoughnessNode = this.getFloat( 'sheenRoughness' );
205
+ const sheenRoughnessNode = this.getFloat( builder, 'sheenRoughness' );
184
206
 
185
207
  if ( material.sheenRoughnessMap && material.sheenRoughnessMap.isTexture === true ) {
186
208
 
187
- node = sheenRoughnessNode.mul( this.getTexture( 'sheenRoughnessMap' ).a );
209
+ node = sheenRoughnessNode.mul( this.getTexture( builder, 'sheenRoughnessMap' ).a );
188
210
 
189
211
  } else {
190
212
 
@@ -202,7 +224,7 @@ class MaterialNode extends Node {
202
224
 
203
225
  const iridescenceThicknessMinimum = reference( 0, 'float', material.iridescenceThicknessRange );
204
226
 
205
- node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum );
227
+ node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( builder, 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum );
206
228
 
207
229
  } else {
208
230
 
@@ -1,4 +1,5 @@
1
1
  import ReferenceNode from './ReferenceNode.js';
2
+ import { NodeUpdateType } from '../core/constants.js';
2
3
  import { addNodeClass } from '../core/Node.js';
3
4
  import { nodeObject } from '../shadernode/ShaderNode.js';
4
5
 
@@ -10,6 +11,8 @@ class MaterialReferenceNode extends ReferenceNode {
10
11
 
11
12
  this.material = material;
12
13
 
14
+ this.updateType = NodeUpdateType.RENDER;
15
+
13
16
  }
14
17
 
15
18
  construct( builder ) {