super-three 0.164.0 → 0.165.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 (124) hide show
  1. package/README.md +3 -3
  2. package/build/three.cjs +664 -217
  3. package/build/three.module.js +664 -217
  4. package/build/three.module.min.js +1 -1
  5. package/examples/jsm/controls/TransformControls.js +1 -1
  6. package/examples/jsm/environments/RoomEnvironment.js +1 -5
  7. package/examples/jsm/exporters/GLTFExporter.js +1 -1
  8. package/examples/jsm/exporters/USDZExporter.js +6 -4
  9. package/examples/jsm/helpers/ViewHelper.js +32 -67
  10. package/examples/jsm/libs/tween.module.js +75 -64
  11. package/examples/jsm/lines/LineMaterial.js +1 -15
  12. package/examples/jsm/lines/LineSegments2.js +15 -0
  13. package/examples/jsm/lines/Wireframe.js +16 -1
  14. package/examples/jsm/loaders/DRACOLoader.js +1 -1
  15. package/examples/jsm/loaders/FBXLoader.js +24 -13
  16. package/examples/jsm/loaders/GLTFLoader.js +2 -0
  17. package/examples/jsm/loaders/LDrawLoader.js +3 -2
  18. package/examples/jsm/loaders/MMDLoader.js +31 -12
  19. package/examples/jsm/modifiers/CurveModifier.js +11 -9
  20. package/examples/jsm/nodes/Nodes.js +12 -11
  21. package/examples/jsm/nodes/accessors/BitangentNode.js +7 -83
  22. package/examples/jsm/nodes/accessors/BufferNode.js +6 -0
  23. package/examples/jsm/nodes/accessors/CameraNode.js +12 -119
  24. package/examples/jsm/nodes/accessors/MaterialNode.js +2 -0
  25. package/examples/jsm/nodes/accessors/ModelNode.js +3 -0
  26. package/examples/jsm/nodes/accessors/NormalNode.js +9 -101
  27. package/examples/jsm/nodes/accessors/PositionNode.js +6 -100
  28. package/examples/jsm/nodes/accessors/ReferenceNode.js +6 -0
  29. package/examples/jsm/nodes/accessors/ReflectVectorNode.js +2 -31
  30. package/examples/jsm/nodes/accessors/{TextureStoreNode.js → StorageTextureNode.js} +19 -6
  31. package/examples/jsm/nodes/accessors/TangentNode.js +11 -97
  32. package/examples/jsm/nodes/accessors/Texture3DNode.js +100 -0
  33. package/examples/jsm/nodes/accessors/UVNode.js +2 -46
  34. package/examples/jsm/nodes/core/AttributeNode.js +15 -3
  35. package/examples/jsm/nodes/core/ContextNode.js +6 -0
  36. package/examples/jsm/nodes/core/Node.js +15 -2
  37. package/examples/jsm/nodes/core/NodeBuilder.js +20 -9
  38. package/examples/jsm/nodes/core/NodeKeywords.js +1 -1
  39. package/examples/jsm/nodes/core/OutputStructNode.js +1 -5
  40. package/examples/jsm/nodes/core/PropertyNode.js +1 -0
  41. package/examples/jsm/nodes/core/VaryingNode.js +40 -9
  42. package/examples/jsm/nodes/display/AfterImageNode.js +14 -2
  43. package/examples/jsm/nodes/display/PassNode.js +3 -1
  44. package/examples/jsm/nodes/display/ViewportNode.js +1 -1
  45. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +61 -17
  46. package/examples/jsm/nodes/functions/ToonLightingModel.js +49 -0
  47. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +2 -1
  48. package/examples/jsm/nodes/lighting/LightsNode.js +17 -0
  49. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +1 -1
  50. package/examples/jsm/nodes/materials/Materials.js +3 -0
  51. package/examples/jsm/nodes/materials/MeshMatcapNodeMaterial.js +52 -0
  52. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +21 -4
  53. package/examples/jsm/nodes/materials/MeshToonNodeMaterial.js +34 -0
  54. package/examples/jsm/nodes/materials/NodeMaterial.js +13 -5
  55. package/examples/jsm/nodes/materials/VolumeNodeMaterial.js +106 -0
  56. package/examples/jsm/nodes/math/HashNode.js +2 -2
  57. package/examples/jsm/nodes/shadernode/ShaderNode.js +55 -33
  58. package/examples/jsm/nodes/utils/ArrayElementNode.js +1 -1
  59. package/examples/jsm/nodes/utils/MatcapUVNode.js +1 -1
  60. package/examples/jsm/nodes/utils/TimerNode.js +1 -1
  61. package/examples/jsm/objects/Lensflare.js +2 -2
  62. package/examples/jsm/postprocessing/RenderPass.js +1 -1
  63. package/examples/jsm/renderers/CSS2DRenderer.js +25 -5
  64. package/examples/jsm/renderers/CSS3DRenderer.js +24 -3
  65. package/examples/jsm/renderers/common/Attributes.js +2 -0
  66. package/examples/jsm/renderers/common/Bindings.js +17 -0
  67. package/examples/jsm/renderers/common/ChainMap.js +18 -48
  68. package/examples/jsm/renderers/common/ClippingContext.js +4 -4
  69. package/examples/jsm/renderers/common/Pipelines.js +2 -2
  70. package/examples/jsm/renderers/common/RenderBundle.js +18 -0
  71. package/examples/jsm/renderers/common/RenderBundles.js +38 -0
  72. package/examples/jsm/renderers/common/RenderList.js +9 -0
  73. package/examples/jsm/renderers/common/RenderObject.js +6 -0
  74. package/examples/jsm/renderers/common/Renderer.js +139 -11
  75. package/examples/jsm/renderers/common/Uniform.js +1 -1
  76. package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +18 -4
  77. package/examples/jsm/renderers/common/nodes/NodeSampler.js +6 -0
  78. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +17 -5
  79. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +93 -6
  80. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +50 -4
  81. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +69 -11
  82. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +10 -1
  83. package/examples/jsm/renderers/webgpu/utils/WebGPUConstants.js +6 -0
  84. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +62 -19
  85. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -3
  86. package/examples/jsm/utils/BufferGeometryUtils.js +18 -16
  87. package/examples/jsm/utils/GPUStatsPanel.js +2 -0
  88. package/examples/jsm/utils/SortUtils.js +8 -5
  89. package/package.json +3 -2
  90. package/src/animation/tracks/BooleanKeyframeTrack.js +10 -1
  91. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -2
  92. package/src/animation/tracks/StringKeyframeTrack.js +10 -1
  93. package/src/constants.js +1 -1
  94. package/src/core/Object3D.js +2 -0
  95. package/src/core/Raycaster.js +6 -2
  96. package/src/loaders/FileLoader.js +4 -0
  97. package/src/loaders/LoaderUtils.js +3 -1
  98. package/src/loaders/ObjectLoader.js +1 -0
  99. package/src/objects/BatchedMesh.js +91 -1
  100. package/src/renderers/WebGLRenderer.js +288 -57
  101. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +15 -0
  102. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -1
  103. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +9 -1
  104. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +8 -22
  105. package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +1 -1
  106. package/src/renderers/shaders/ShaderChunk/morphinstance_vertex.glsl.js +1 -1
  107. package/src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl.js +3 -14
  108. package/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl.js +10 -31
  109. package/src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl.js +3 -23
  110. package/src/renderers/webgl/WebGLBackground.js +6 -0
  111. package/src/renderers/webgl/WebGLExtensions.js +3 -1
  112. package/src/renderers/webgl/WebGLLights.js +9 -12
  113. package/src/renderers/webgl/WebGLMaterials.js +1 -5
  114. package/src/renderers/webgl/WebGLMorphtargets.js +1 -2
  115. package/src/renderers/webgl/WebGLProgram.js +2 -31
  116. package/src/renderers/webgl/WebGLPrograms.js +14 -14
  117. package/src/renderers/webgl/WebGLRenderStates.js +2 -2
  118. package/src/renderers/webgl/WebGLTextures.js +139 -70
  119. package/src/renderers/webxr/WebXRDepthSensing.js +3 -3
  120. package/src/renderers/webxr/WebXRManager.js +6 -2
  121. package/src/textures/CompressedArrayTexture.js +14 -0
  122. package/src/textures/DataArrayTexture.js +14 -0
  123. package/src/textures/DepthTexture.js +1 -3
  124. package/src/utils.js +30 -1
@@ -1,104 +1,10 @@
1
- import Node, { addNodeClass } from '../core/Node.js';
2
1
  import { attribute } from '../core/AttributeNode.js';
3
2
  import { varying } from '../core/VaryingNode.js';
4
- import { normalize } from '../math/MathNode.js';
5
3
  import { modelWorldMatrix, modelViewMatrix } from './ModelNode.js';
6
- import { nodeImmutable } from '../shadernode/ShaderNode.js';
7
4
 
8
- class PositionNode extends Node {
9
-
10
- constructor( scope = PositionNode.LOCAL ) {
11
-
12
- super( 'vec3' );
13
-
14
- this.scope = scope;
15
-
16
- }
17
-
18
- isGlobal() {
19
-
20
- return true;
21
-
22
- }
23
-
24
- getHash( /*builder*/ ) {
25
-
26
- return `position-${this.scope}`;
27
-
28
- }
29
-
30
- generate( builder ) {
31
-
32
- const scope = this.scope;
33
-
34
- let outputNode = null;
35
-
36
- if ( scope === PositionNode.GEOMETRY ) {
37
-
38
- outputNode = attribute( 'position', 'vec3' );
39
-
40
- } else if ( scope === PositionNode.LOCAL ) {
41
-
42
- outputNode = varying( positionGeometry );
43
-
44
- } else if ( scope === PositionNode.WORLD ) {
45
-
46
- const vertexPositionNode = modelWorldMatrix.mul( positionLocal );
47
- outputNode = varying( vertexPositionNode );
48
-
49
- } else if ( scope === PositionNode.VIEW ) {
50
-
51
- const vertexPositionNode = modelViewMatrix.mul( positionLocal );
52
- outputNode = varying( vertexPositionNode );
53
-
54
- } else if ( scope === PositionNode.VIEW_DIRECTION ) {
55
-
56
- const vertexPositionNode = positionView.negate();
57
- outputNode = normalize( varying( vertexPositionNode ) );
58
-
59
- } else if ( scope === PositionNode.WORLD_DIRECTION ) {
60
-
61
- const vertexPositionNode = positionLocal.transformDirection( modelWorldMatrix );
62
- outputNode = normalize( varying( vertexPositionNode ) );
63
-
64
- }
65
-
66
- return outputNode.build( builder, this.getNodeType( builder ) );
67
-
68
- }
69
-
70
- serialize( data ) {
71
-
72
- super.serialize( data );
73
-
74
- data.scope = this.scope;
75
-
76
- }
77
-
78
- deserialize( data ) {
79
-
80
- super.deserialize( data );
81
-
82
- this.scope = data.scope;
83
-
84
- }
85
-
86
- }
87
-
88
- PositionNode.GEOMETRY = 'geometry';
89
- PositionNode.LOCAL = 'local';
90
- PositionNode.WORLD = 'world';
91
- PositionNode.WORLD_DIRECTION = 'worldDirection';
92
- PositionNode.VIEW = 'view';
93
- PositionNode.VIEW_DIRECTION = 'viewDirection';
94
-
95
- export default PositionNode;
96
-
97
- export const positionGeometry = nodeImmutable( PositionNode, PositionNode.GEOMETRY );
98
- export const positionLocal = nodeImmutable( PositionNode, PositionNode.LOCAL ).temp( 'Position' );
99
- export const positionWorld = nodeImmutable( PositionNode, PositionNode.WORLD );
100
- export const positionWorldDirection = nodeImmutable( PositionNode, PositionNode.WORLD_DIRECTION );
101
- export const positionView = nodeImmutable( PositionNode, PositionNode.VIEW );
102
- export const positionViewDirection = nodeImmutable( PositionNode, PositionNode.VIEW_DIRECTION );
103
-
104
- addNodeClass( 'PositionNode', PositionNode );
5
+ export const positionGeometry = /*#__PURE__*/ attribute( 'position', 'vec3' );
6
+ export const positionLocal = /*#__PURE__*/ positionGeometry.toVar( 'positionLocal' );
7
+ export const positionWorld = /*#__PURE__*/ varying( modelWorldMatrix.mul( positionLocal ).xyz, 'v_positionWorld' );
8
+ export const positionWorldDirection = /*#__PURE__*/ varying( positionLocal.transformDirection( modelWorldMatrix ), 'v_positionWorldDirection' ).normalize().toVar( 'positionWorldDirection' );
9
+ export const positionView = /*#__PURE__*/ varying( modelViewMatrix.mul( positionLocal ).xyz, 'v_positionView' );
10
+ export const positionViewDirection = /*#__PURE__*/ varying( positionView.negate(), 'v_positionViewDirection' ).normalize().toVar( 'positionViewDirection' );
@@ -90,6 +90,12 @@ class ReferenceNode extends Node {
90
90
 
91
91
  getNodeType( builder ) {
92
92
 
93
+ if ( this.node === null ) {
94
+
95
+ this.updateValue();
96
+
97
+ }
98
+
93
99
  return this.node.getNodeType( builder );
94
100
 
95
101
  }
@@ -1,35 +1,6 @@
1
- import Node, { addNodeClass } from '../core/Node.js';
2
1
  import { cameraViewMatrix } from './CameraNode.js';
3
2
  import { transformedNormalView } from './NormalNode.js';
4
3
  import { positionViewDirection } from './PositionNode.js';
5
- import { nodeImmutable } from '../shadernode/ShaderNode.js';
6
4
 
7
- class ReflectVectorNode extends Node {
8
-
9
- constructor() {
10
-
11
- super( 'vec3' );
12
-
13
- }
14
-
15
- getHash( /*builder*/ ) {
16
-
17
- return 'reflectVector';
18
-
19
- }
20
-
21
- setup() {
22
-
23
- const reflectView = positionViewDirection.negate().reflect( transformedNormalView );
24
-
25
- return reflectView.transformDirection( cameraViewMatrix );
26
-
27
- }
28
-
29
- }
30
-
31
- export default ReflectVectorNode;
32
-
33
- export const reflectVector = nodeImmutable( ReflectVectorNode );
34
-
35
- addNodeClass( 'ReflectVectorNode', ReflectVectorNode );
5
+ export const reflectView = /*#__PURE__*/ positionViewDirection.negate().reflect( transformedNormalView );
6
+ export const reflectVector = /*#__PURE__*/ reflectView.transformDirection( cameraViewMatrix ).toVar( 'reflectVector' );
@@ -1,8 +1,9 @@
1
1
  import { addNodeClass } from '../core/Node.js';
2
2
  import TextureNode from './TextureNode.js';
3
3
  import { nodeProxy } from '../shadernode/ShaderNode.js';
4
+ import { GPUStorageTextureAccess } from '../../renderers/webgpu/utils/WebGPUConstants.js';
4
5
 
5
- class TextureStoreNode extends TextureNode {
6
+ class StorageTextureNode extends TextureNode {
6
7
 
7
8
  constructor( value, uvNode, storeNode = null ) {
8
9
 
@@ -10,7 +11,9 @@ class TextureStoreNode extends TextureNode {
10
11
 
11
12
  this.storeNode = storeNode;
12
13
 
13
- this.isStoreTextureNode = true;
14
+ this.isStorageTextureNode = true;
15
+
16
+ this.access = GPUStorageTextureAccess.WriteOnly;
14
17
 
15
18
  }
16
19
 
@@ -29,6 +32,13 @@ class TextureStoreNode extends TextureNode {
29
32
 
30
33
  }
31
34
 
35
+ setAccess( value ) {
36
+
37
+ this.access = value;
38
+ return this;
39
+
40
+ }
41
+
32
42
  generate( builder, output ) {
33
43
 
34
44
  let snippet;
@@ -65,13 +75,16 @@ class TextureStoreNode extends TextureNode {
65
75
 
66
76
  }
67
77
 
68
- export default TextureStoreNode;
78
+ export default StorageTextureNode;
79
+
80
+ export const storageTexture = nodeProxy( StorageTextureNode );
69
81
 
70
- const textureStoreBase = nodeProxy( TextureStoreNode );
82
+ export const storageTextureReadOnly = ( value, uvNode, storeNode ) => storageTexture( value, uvNode, storeNode ).setAccess( 'read-only' );
83
+ export const storageTextureReadWrite = ( value, uvNode, storeNode ) => storageTexture( value, uvNode, storeNode ).setAccess( 'read-write' );
71
84
 
72
85
  export const textureStore = ( value, uvNode, storeNode ) => {
73
86
 
74
- const node = textureStoreBase( value, uvNode, storeNode );
87
+ const node = storageTexture( value, uvNode, storeNode );
75
88
 
76
89
  if ( storeNode !== null ) node.append();
77
90
 
@@ -79,4 +92,4 @@ export const textureStore = ( value, uvNode, storeNode ) => {
79
92
 
80
93
  };
81
94
 
82
- addNodeClass( 'TextureStoreNode', TextureStoreNode );
95
+ addNodeClass( 'StorageTextureNode', StorageTextureNode );
@@ -1,109 +1,23 @@
1
- import Node, { addNodeClass } from '../core/Node.js';
2
1
  import { attribute } from '../core/AttributeNode.js';
3
- import { temp } from '../core/VarNode.js';
4
2
  import { varying } from '../core/VaryingNode.js';
5
- import { normalize } from '../math/MathNode.js';
6
3
  import { cameraViewMatrix } from './CameraNode.js';
7
4
  import { modelViewMatrix } from './ModelNode.js';
8
- import { nodeImmutable, vec4 } from '../shadernode/ShaderNode.js';
5
+ import { tslFn, vec4 } from '../shadernode/ShaderNode.js';
9
6
 
10
- class TangentNode extends Node {
7
+ export const tangentGeometry = /*#__PURE__*/ tslFn( ( stack, builder ) => {
11
8
 
12
- constructor( scope = TangentNode.LOCAL ) {
9
+ if ( builder.geometry.hasAttribute( 'tangent' ) === false ) {
13
10
 
14
- super();
15
-
16
- this.scope = scope;
17
-
18
- }
19
-
20
- getHash( /*builder*/ ) {
21
-
22
- return `tangent-${this.scope}`;
23
-
24
- }
25
-
26
- getNodeType() {
27
-
28
- const scope = this.scope;
29
-
30
- if ( scope === TangentNode.GEOMETRY ) {
31
-
32
- return 'vec4';
33
-
34
- }
35
-
36
- return 'vec3';
37
-
38
- }
39
-
40
-
41
- generate( builder ) {
42
-
43
- const scope = this.scope;
44
-
45
- let outputNode = null;
46
-
47
- if ( scope === TangentNode.GEOMETRY ) {
48
-
49
- outputNode = attribute( 'tangent', 'vec4' );
50
-
51
- if ( builder.geometry.hasAttribute( 'tangent' ) === false ) {
52
-
53
- builder.geometry.computeTangents();
54
-
55
- }
56
-
57
- } else if ( scope === TangentNode.LOCAL ) {
58
-
59
- outputNode = varying( tangentGeometry.xyz );
60
-
61
- } else if ( scope === TangentNode.VIEW ) {
62
-
63
- const vertexNode = modelViewMatrix.mul( vec4( tangentLocal, 0 ) ).xyz;
64
- outputNode = normalize( varying( vertexNode ) );
65
-
66
- } else if ( scope === TangentNode.WORLD ) {
67
-
68
- const vertexNode = tangentView.transformDirection( cameraViewMatrix );
69
- outputNode = normalize( varying( vertexNode ) );
70
-
71
- }
72
-
73
- return outputNode.build( builder, this.getNodeType( builder ) );
74
-
75
- }
76
-
77
- serialize( data ) {
78
-
79
- super.serialize( data );
80
-
81
- data.scope = this.scope;
11
+ builder.geometry.computeTangents();
82
12
 
83
13
  }
84
14
 
85
- deserialize( data ) {
86
-
87
- super.deserialize( data );
88
-
89
- this.scope = data.scope;
90
-
91
- }
92
-
93
- }
94
-
95
- TangentNode.GEOMETRY = 'geometry';
96
- TangentNode.LOCAL = 'local';
97
- TangentNode.VIEW = 'view';
98
- TangentNode.WORLD = 'world';
99
-
100
- export default TangentNode;
15
+ return attribute( 'tangent', 'vec4' );
101
16
 
102
- export const tangentGeometry = nodeImmutable( TangentNode, TangentNode.GEOMETRY );
103
- export const tangentLocal = nodeImmutable( TangentNode, TangentNode.LOCAL );
104
- export const tangentView = nodeImmutable( TangentNode, TangentNode.VIEW );
105
- export const tangentWorld = nodeImmutable( TangentNode, TangentNode.WORLD );
106
- export const transformedTangentView = temp( tangentView, 'TransformedTangentView' );
107
- export const transformedTangentWorld = normalize( transformedTangentView.transformDirection( cameraViewMatrix ) );
17
+ } )();
108
18
 
109
- addNodeClass( 'TangentNode', TangentNode );
19
+ export const tangentLocal = /*#__PURE__*/ tangentGeometry.xyz.toVar( 'tangentLocal' );
20
+ export const tangentView = /*#__PURE__*/ varying( modelViewMatrix.mul( vec4( tangentLocal, 0 ) ).xyz, 'v_tangentView' ).normalize().toVar( 'tangentView' );
21
+ export const tangentWorld = /*#__PURE__*/ varying( tangentView.transformDirection( cameraViewMatrix ), 'v_tangentWorld' ).normalize().toVar( 'tangentWorld' );
22
+ export const transformedTangentView = /*#__PURE__*/ tangentView.toVar( 'transformedTangentView' );
23
+ export const transformedTangentWorld = /*#__PURE__*/ transformedTangentView.transformDirection( cameraViewMatrix ).normalize().toVar( 'transformedTangentWorld' );
@@ -0,0 +1,100 @@
1
+ import TextureNode from './TextureNode.js';
2
+ import { addNodeClass } from '../core/Node.js';
3
+ import { nodeProxy, vec3, tslFn, If } from '../shadernode/ShaderNode.js';
4
+
5
+ const normal = tslFn( ( { texture, uv } ) => {
6
+
7
+ const epsilon = 0.0001;
8
+
9
+ const ret = vec3().temp();
10
+
11
+ If( uv.x.lessThan( epsilon ), () => {
12
+
13
+ ret.assign( vec3( 1, 0, 0 ) );
14
+
15
+ } ).elseif( uv.y.lessThan( epsilon ), () => {
16
+
17
+ ret.assign( vec3( 0, 1, 0 ) );
18
+
19
+ } ).elseif( uv.z.lessThan( epsilon ), () => {
20
+
21
+ ret.assign( vec3( 0, 0, 1 ) );
22
+
23
+ } ).elseif( uv.x.greaterThan( 1 - epsilon ), () => {
24
+
25
+ ret.assign( vec3( - 1, 0, 0 ) );
26
+
27
+ } ).elseif( uv.y.greaterThan( 1 - epsilon ), () => {
28
+
29
+ ret.assign( vec3( 0, - 1, 0 ) );
30
+
31
+ } ).elseif( uv.z.greaterThan( 1 - epsilon ), () => {
32
+
33
+ ret.assign( vec3( 0, 0, - 1 ) );
34
+
35
+ } ).else( () => {
36
+
37
+ const step = 0.01;
38
+
39
+ const x = texture.uv( uv.add( vec3( - step, 0.0, 0.0 ) ) ).r.sub( texture.uv( uv.add( vec3( step, 0.0, 0.0 ) ) ).r );
40
+ const y = texture.uv( uv.add( vec3( 0.0, - step, 0.0 ) ) ).r.sub( texture.uv( uv.add( vec3( 0.0, step, 0.0 ) ) ).r );
41
+ const z = texture.uv( uv.add( vec3( 0.0, 0.0, - step ) ) ).r.sub( texture.uv( uv.add( vec3( 0.0, 0.0, step ) ) ).r );
42
+
43
+ ret.assign( vec3( x, y, z ) );
44
+
45
+ } );
46
+
47
+ return ret.normalize();
48
+
49
+ } );
50
+
51
+
52
+ class Texture3DNode extends TextureNode {
53
+
54
+ constructor( value, uvNode = null, levelNode = null ) {
55
+
56
+ super( value, uvNode, levelNode );
57
+
58
+ this.isTexture3DNode = true;
59
+
60
+ }
61
+
62
+ getInputType( /*builder*/ ) {
63
+
64
+ return 'texture3D';
65
+
66
+ }
67
+
68
+ getDefaultUV() {
69
+
70
+ return vec3( 0.5, 0.5, 0.5 );
71
+
72
+ }
73
+
74
+ setUpdateMatrix( /*updateMatrix*/ ) { } // Ignore .updateMatrix for 3d TextureNode
75
+
76
+ setupUV( builder, uvNode ) {
77
+
78
+ return uvNode;
79
+
80
+ }
81
+
82
+ generateUV( builder, uvNode ) {
83
+
84
+ return uvNode.build( builder, 'vec3' );
85
+
86
+ }
87
+
88
+ normal( uvNode ) {
89
+
90
+ return normal( { texture: this, uv: uvNode } );
91
+
92
+ }
93
+
94
+ }
95
+
96
+ export default Texture3DNode;
97
+
98
+ export const texture3D = nodeProxy( Texture3DNode );
99
+
100
+ addNodeClass( 'Texture3DNode', Texture3DNode );
@@ -1,47 +1,3 @@
1
- import { addNodeClass } from '../core/Node.js';
2
- import AttributeNode from '../core/AttributeNode.js';
3
- import { nodeObject } from '../shadernode/ShaderNode.js';
1
+ import { attribute } from '../core/AttributeNode.js';
4
2
 
5
- class UVNode extends AttributeNode {
6
-
7
- constructor( index = 0 ) {
8
-
9
- super( null, 'vec2' );
10
-
11
- this.isUVNode = true;
12
-
13
- this.index = index;
14
-
15
- }
16
-
17
- getAttributeName( /*builder*/ ) {
18
-
19
- const index = this.index;
20
-
21
- return 'uv' + ( index > 0 ? index : '' );
22
-
23
- }
24
-
25
- serialize( data ) {
26
-
27
- super.serialize( data );
28
-
29
- data.index = this.index;
30
-
31
- }
32
-
33
- deserialize( data ) {
34
-
35
- super.deserialize( data );
36
-
37
- this.index = data.index;
38
-
39
- }
40
-
41
- }
42
-
43
- export default UVNode;
44
-
45
- export const uv = ( ...params ) => nodeObject( new UVNode( ...params ) );
46
-
47
- addNodeClass( 'UVNode', UVNode );
3
+ export const uv = ( index ) => attribute( 'uv' + ( index > 0 ? index : '' ), 'vec2' );
@@ -4,10 +4,12 @@ import { nodeObject } from '../shadernode/ShaderNode.js';
4
4
 
5
5
  class AttributeNode extends Node {
6
6
 
7
- constructor( attributeName, nodeType = null ) {
7
+ constructor( attributeName, nodeType = null, defaultNode = null ) {
8
8
 
9
9
  super( nodeType );
10
10
 
11
+ this.defaultNode = defaultNode;
12
+
11
13
  this._attributeName = attributeName;
12
14
 
13
15
  }
@@ -93,7 +95,17 @@ class AttributeNode extends Node {
93
95
 
94
96
  console.warn( `AttributeNode: Vertex attribute "${ attributeName }" not found on geometry.` );
95
97
 
96
- return builder.generateConst( nodeType );
98
+ const { defaultNode } = this;
99
+
100
+ if ( defaultNode !== null ) {
101
+
102
+ return defaultNode.build( builder, nodeType );
103
+
104
+ } else {
105
+
106
+ return builder.generateConst( nodeType );
107
+
108
+ }
97
109
 
98
110
  }
99
111
 
@@ -103,6 +115,6 @@ class AttributeNode extends Node {
103
115
 
104
116
  export default AttributeNode;
105
117
 
106
- export const attribute = ( name, nodeType ) => nodeObject( new AttributeNode( name, nodeType ) );
118
+ export const attribute = ( name, nodeType, defaultNode ) => nodeObject( new AttributeNode( name, nodeType, nodeObject( defaultNode ) ) );
107
119
 
108
120
  addNodeClass( 'AttributeNode', AttributeNode );
@@ -20,6 +20,12 @@ class ContextNode extends Node {
20
20
 
21
21
  }
22
22
 
23
+ analyze( builder ) {
24
+
25
+ this.node.build( builder );
26
+
27
+ }
28
+
23
29
  setup( builder ) {
24
30
 
25
31
  const previousContext = builder.getContext();
@@ -25,6 +25,8 @@ class Node extends EventDispatcher {
25
25
  this._cacheKey = null;
26
26
  this._cacheKeyVersion = 0;
27
27
 
28
+ this.global = false;
29
+
28
30
  this.isNode = true;
29
31
 
30
32
  Object.defineProperty( this, 'id', { value: _nodeId ++ } );
@@ -98,7 +100,7 @@ class Node extends EventDispatcher {
98
100
 
99
101
  isGlobal( /*builder*/ ) {
100
102
 
101
- return false;
103
+ return this.global;
102
104
 
103
105
  }
104
106
 
@@ -163,6 +165,15 @@ class Node extends EventDispatcher {
163
165
 
164
166
  }
165
167
 
168
+ getElementType( builder ) {
169
+
170
+ const type = this.getNodeType( builder );
171
+ const elementType = builder.getElementType( type );
172
+
173
+ return elementType;
174
+
175
+ }
176
+
166
177
  getNodeType( builder ) {
167
178
 
168
179
  const nodeProperties = builder.getNodeProperties( this );
@@ -190,9 +201,11 @@ class Node extends EventDispatcher {
190
201
 
191
202
  const nodeProperties = builder.getNodeProperties( this );
192
203
 
204
+ let index = 0;
205
+
193
206
  for ( const childNode of this.getChildren() ) {
194
207
 
195
- nodeProperties[ '_node' + childNode.id ] = childNode;
208
+ nodeProperties[ 'node' + index ++ ] = childNode;
196
209
 
197
210
  }
198
211
 
@@ -80,7 +80,7 @@ class NodeBuilder {
80
80
  this.computeShader = null;
81
81
 
82
82
  this.flowNodes = { vertex: [], fragment: [], compute: [] };
83
- this.flowCode = { vertex: '', fragment: '', compute: [] };
83
+ this.flowCode = { vertex: '', fragment: '', compute: '' };
84
84
  this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 };
85
85
  this.structs = { vertex: [], fragment: [], compute: [], index: 0 };
86
86
  this.bindings = { vertex: [], fragment: [], compute: [] };
@@ -415,12 +415,6 @@ class NodeBuilder {
415
415
 
416
416
  }
417
417
 
418
- generateMethod( method ) {
419
-
420
- return method;
421
-
422
- }
423
-
424
418
  hasGeometryAttribute( name ) {
425
419
 
426
420
  return this.geometry && this.geometry.getAttribute( name ) !== undefined;
@@ -473,7 +467,7 @@ class NodeBuilder {
473
467
 
474
468
  isReference( type ) {
475
469
 
476
- return type === 'void' || type === 'property' || type === 'sampler' || type === 'texture' || type === 'cubeTexture' || type === 'storageTexture';
470
+ return type === 'void' || type === 'property' || type === 'sampler' || type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D';
477
471
 
478
472
  }
479
473
 
@@ -498,6 +492,16 @@ class NodeBuilder {
498
492
 
499
493
  }
500
494
 
495
+ getElementType( type ) {
496
+
497
+ if ( type === 'mat2' ) return 'vec2';
498
+ if ( type === 'mat3' ) return 'vec3';
499
+ if ( type === 'mat4' ) return 'vec4';
500
+
501
+ return this.getComponentType( type );
502
+
503
+ }
504
+
501
505
  getComponentType( type ) {
502
506
 
503
507
  type = this.getVectorType( type );
@@ -519,7 +523,7 @@ class NodeBuilder {
519
523
  getVectorType( type ) {
520
524
 
521
525
  if ( type === 'color' ) return 'vec3';
522
- if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' ) return 'vec4';
526
+ if ( type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D' ) return 'vec4';
523
527
 
524
528
  return type;
525
529
 
@@ -907,7 +911,9 @@ class NodeBuilder {
907
911
 
908
912
  const previousFlow = this.flow;
909
913
  const previousVars = this.vars;
914
+ const previousCache = this.cache;
910
915
  const previousBuildStage = this.buildStage;
916
+ const previousStack = this.stack;
911
917
 
912
918
  const flow = {
913
919
  code: ''
@@ -915,6 +921,8 @@ class NodeBuilder {
915
921
 
916
922
  this.flow = flow;
917
923
  this.vars = {};
924
+ this.cache = new NodeCache();
925
+ this.stack = stack();
918
926
 
919
927
  for ( const buildStage of defaultBuildStages ) {
920
928
 
@@ -928,6 +936,9 @@ class NodeBuilder {
928
936
 
929
937
  this.flow = previousFlow;
930
938
  this.vars = previousVars;
939
+ this.cache = previousCache;
940
+ this.stack = previousStack;
941
+
931
942
  this.setBuildStage( previousBuildStage );
932
943
 
933
944
  return flow;
@@ -3,7 +3,7 @@ class NodeKeywords {
3
3
  constructor() {
4
4
 
5
5
  this.keywords = [];
6
- this.nodes = [];
6
+ this.nodes = {};
7
7
  this.keywordsCallback = {};
8
8
 
9
9
  }