super-three 0.160.1 → 0.161.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 (145) hide show
  1. package/LICENSE +1 -1
  2. package/build/three.cjs +379 -108
  3. package/build/three.module.js +380 -108
  4. package/build/three.module.min.js +1 -1
  5. package/examples/jsm/Addons.js +5 -1
  6. package/examples/jsm/capabilities/WebGPU.js +13 -9
  7. package/examples/jsm/controls/OrbitControls.js +102 -13
  8. package/examples/jsm/curves/NURBSUtils.js +59 -4
  9. package/examples/jsm/curves/NURBSVolume.js +62 -0
  10. package/examples/jsm/exporters/USDZExporter.js +8 -7
  11. package/examples/jsm/helpers/TextureHelper.js +3 -3
  12. package/examples/jsm/loaders/3DMLoader.js +44 -43
  13. package/examples/jsm/loaders/DDSLoader.js +1 -0
  14. package/examples/jsm/loaders/KTX2Loader.js +20 -5
  15. package/examples/jsm/loaders/LUT3dlLoader.js +78 -46
  16. package/examples/jsm/loaders/LUTCubeLoader.js +81 -67
  17. package/examples/jsm/loaders/LUTImageLoader.js +3 -2
  18. package/examples/jsm/loaders/MaterialXLoader.js +115 -16
  19. package/examples/jsm/loaders/SVGLoader.js +4 -3
  20. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  21. package/examples/jsm/materials/MeshPostProcessingMaterial.js +144 -0
  22. package/examples/jsm/misc/Timer.js +13 -4
  23. package/examples/jsm/nodes/Nodes.js +16 -5
  24. package/examples/jsm/nodes/accessors/BufferAttributeNode.js +5 -3
  25. package/examples/jsm/nodes/accessors/CameraNode.js +9 -4
  26. package/examples/jsm/nodes/accessors/CubeTextureNode.js +12 -1
  27. package/examples/jsm/nodes/accessors/StorageBufferNode.js +27 -0
  28. package/examples/jsm/nodes/accessors/TextureStoreNode.js +56 -3
  29. package/examples/jsm/nodes/accessors/VertexColorNode.js +70 -0
  30. package/examples/jsm/nodes/core/AttributeNode.js +1 -1
  31. package/examples/jsm/nodes/core/NodeBuilder.js +23 -18
  32. package/examples/jsm/nodes/core/NodeFrame.js +16 -8
  33. package/examples/jsm/nodes/core/constants.js +1 -0
  34. package/examples/jsm/nodes/display/AfterImageNode.js +148 -0
  35. package/examples/jsm/nodes/display/AnamorphicNode.js +148 -0
  36. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +3 -0
  37. package/examples/jsm/nodes/display/GaussianBlurNode.js +33 -13
  38. package/examples/jsm/nodes/display/PassNode.js +3 -2
  39. package/examples/jsm/nodes/display/ToneMappingNode.js +46 -3
  40. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +1 -4
  41. package/examples/jsm/nodes/display/ViewportNode.js +0 -2
  42. package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +4 -4
  43. package/examples/jsm/nodes/fog/FogNode.js +2 -1
  44. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  45. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +13 -5
  46. package/examples/jsm/nodes/lighting/LightingContextNode.js +1 -1
  47. package/examples/jsm/nodes/lighting/LightsNode.js +1 -1
  48. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +18 -30
  49. package/examples/jsm/nodes/materials/Materials.js +1 -0
  50. package/examples/jsm/nodes/materials/MeshSSSNodeMaterial.js +84 -0
  51. package/examples/jsm/nodes/materials/NodeMaterial.js +6 -4
  52. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +1 -7
  53. package/examples/jsm/nodes/math/MathNode.js +12 -2
  54. package/examples/jsm/nodes/math/MathUtils.js +15 -0
  55. package/examples/jsm/nodes/math/OperatorNode.js +13 -5
  56. package/examples/jsm/nodes/math/TriNoise3D.js +71 -0
  57. package/examples/jsm/nodes/shadernode/ShaderNode.js +10 -1
  58. package/examples/jsm/nodes/utils/ArrayElementNode.js +6 -0
  59. package/examples/jsm/nodes/utils/JoinNode.js +2 -2
  60. package/examples/jsm/nodes/utils/LoopNode.js +3 -3
  61. package/examples/jsm/nodes/utils/ReflectorNode.js +227 -0
  62. package/examples/jsm/nodes/utils/RotateNode.js +68 -0
  63. package/examples/jsm/nodes/utils/RotateUVNode.js +1 -9
  64. package/examples/jsm/nodes/utils/SplitNode.js +4 -4
  65. package/examples/jsm/objects/GroundedSkybox.js +50 -0
  66. package/examples/jsm/objects/QuadMesh.js +8 -2
  67. package/examples/jsm/objects/Water2.js +8 -8
  68. package/examples/jsm/postprocessing/GTAOPass.js +11 -1
  69. package/examples/jsm/renderers/common/Backend.js +14 -0
  70. package/examples/jsm/renderers/common/Bindings.js +1 -1
  71. package/examples/jsm/renderers/common/DataMap.js +1 -1
  72. package/examples/jsm/renderers/common/Info.js +25 -1
  73. package/examples/jsm/renderers/common/Pipelines.js +8 -8
  74. package/examples/jsm/renderers/common/PostProcessing.js +2 -2
  75. package/examples/jsm/renderers/common/ProgrammableStage.js +3 -1
  76. package/examples/jsm/renderers/common/RenderObject.js +2 -0
  77. package/examples/jsm/renderers/common/Renderer.js +238 -22
  78. package/examples/jsm/renderers/common/StorageBufferAttribute.js +17 -0
  79. package/examples/jsm/renderers/common/Textures.js +25 -5
  80. package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +2 -1
  81. package/examples/jsm/renderers/common/nodes/Nodes.js +4 -2
  82. package/examples/jsm/renderers/webgl/WebGLBackend.js +631 -270
  83. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +37 -30
  84. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +89 -8
  85. package/examples/jsm/renderers/webgl/utils/WebGLConstants.js +11 -0
  86. package/examples/jsm/renderers/webgl/utils/WebGLState.js +197 -0
  87. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +377 -11
  88. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +2 -2
  89. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +1 -21
  90. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +2 -2
  91. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +289 -102
  92. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +7 -2
  93. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +56 -39
  94. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +9 -1
  95. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +38 -4
  96. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +85 -12
  97. package/examples/jsm/transpiler/AST.js +1 -1
  98. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  99. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  100. package/examples/jsm/transpiler/TSLEncoder.js +1 -1
  101. package/examples/jsm/utils/BufferGeometryUtils.js +23 -27
  102. package/examples/jsm/utils/SortUtils.js +2 -0
  103. package/examples/jsm/webxr/ARButton.js +12 -2
  104. package/examples/jsm/webxr/VRButton.js +12 -2
  105. package/examples/jsm/webxr/XRButton.js +12 -2
  106. package/examples/jsm/webxr/XRControllerModelFactory.js +6 -1
  107. package/examples/jsm/webxr/XRHandMeshModel.js +3 -1
  108. package/package.json +2 -2
  109. package/src/audio/Audio.js +1 -3
  110. package/src/cameras/PerspectiveCamera.js +35 -0
  111. package/src/constants.js +1 -2
  112. package/src/core/BufferAttribute.js +2 -1
  113. package/src/core/InterleavedBuffer.js +2 -1
  114. package/src/core/InterleavedBufferAttribute.js +20 -0
  115. package/src/materials/ShaderMaterial.js +2 -1
  116. package/src/math/Triangle.js +0 -30
  117. package/src/objects/BatchedMesh.js +6 -7
  118. package/src/objects/SkinnedMesh.js +0 -8
  119. package/src/renderers/WebGLRenderer.js +5 -1
  120. package/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl.js +9 -0
  121. package/src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl.js +56 -11
  122. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +15 -7
  123. package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -2
  124. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +1 -2
  125. package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +1 -1
  126. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +1 -2
  127. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +1 -1
  128. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +1 -2
  129. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +3 -1
  130. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +1 -1
  131. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +1 -1
  132. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +1 -1
  133. package/src/renderers/shaders/ShaderLib/points.glsl.js +1 -1
  134. package/src/renderers/shaders/ShaderLib/sprite.glsl.js +1 -1
  135. package/src/renderers/webgl/WebGLAttributes.js +2 -2
  136. package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
  137. package/src/renderers/webgl/WebGLProgram.js +30 -3
  138. package/src/renderers/webgl/WebGLPrograms.js +19 -11
  139. package/src/renderers/webgl/WebGLTextures.js +90 -16
  140. package/src/renderers/webxr/WebXRDepthSensing.js +105 -0
  141. package/src/renderers/webxr/WebXRManager.js +46 -0
  142. package/src/textures/Source.js +1 -0
  143. package/build/three.js +0 -54519
  144. package/build/three.min.js +0 -7
  145. package/examples/jsm/objects/GroundProjectedSkybox.js +0 -172
@@ -2,7 +2,7 @@ import LightingNode from './LightingNode.js';
2
2
  import { NodeUpdateType } from '../core/constants.js';
3
3
  import { uniform } from '../core/UniformNode.js';
4
4
  import { addNodeClass } from '../core/Node.js';
5
- import { /*vec2,*/ vec3 } from '../shadernode/ShaderNode.js';
5
+ import { /*vec2,*/ vec3, vec4 } from '../shadernode/ShaderNode.js';
6
6
  import { reference } from '../accessors/ReferenceNode.js';
7
7
  import { texture } from '../accessors/TextureNode.js';
8
8
  import { positionWorld } from '../accessors/PositionNode.js';
@@ -12,7 +12,7 @@ import { WebGPUCoordinateSystem } from 'three';
12
12
 
13
13
  import { Color, DepthTexture, NearestFilter, LessCompare } from 'three';
14
14
 
15
- let depthMaterial = null;
15
+ let overrideMaterial = null;
16
16
 
17
17
  class AnalyticLightNode extends LightingNode {
18
18
 
@@ -54,7 +54,13 @@ class AnalyticLightNode extends LightingNode {
54
54
 
55
55
  if ( shadowNode === null ) {
56
56
 
57
- if ( depthMaterial === null ) depthMaterial = builder.createNodeMaterial( 'MeshBasicNodeMaterial' );
57
+ if ( overrideMaterial === null ) {
58
+
59
+ overrideMaterial = builder.createNodeMaterial();
60
+ overrideMaterial.fragmentNode = vec4( 0, 0, 0, 1 );
61
+ overrideMaterial.isShadowNodeMaterial = true; // Use to avoid other overrideMaterial override material.fragmentNode unintentionally when using material.shadowNode
62
+
63
+ }
58
64
 
59
65
  const shadow = this.light.shadow;
60
66
  const rtt = builder.getRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
@@ -142,8 +148,10 @@ class AnalyticLightNode extends LightingNode {
142
148
  */
143
149
  //
144
150
 
151
+ const shadowColor = texture( rtt.texture, shadowCoord );
152
+
145
153
  this.rtt = rtt;
146
- this.colorNode = this.colorNode.mul( frustumTest.mix( 1, shadowNode ) );
154
+ this.colorNode = this.colorNode.mul( frustumTest.mix( 1, shadowNode.mix( shadowColor.a.mix( 1, shadowColor ), 1 ) ) );
147
155
 
148
156
  this.shadowNode = shadowNode;
149
157
 
@@ -169,7 +177,7 @@ class AnalyticLightNode extends LightingNode {
169
177
 
170
178
  const currentOverrideMaterial = scene.overrideMaterial;
171
179
 
172
- scene.overrideMaterial = depthMaterial;
180
+ scene.overrideMaterial = overrideMaterial;
173
181
 
174
182
  rtt.setSize( light.shadow.mapSize.width, light.shadow.mapSize.height );
175
183
 
@@ -39,7 +39,7 @@ class LightingContextNode extends ContextNode {
39
39
  ambientOcclusion: float( 1 ).temp( 'ambientOcclusion' ),
40
40
  reflectedLight,
41
41
  backdrop: backdropNode,
42
- backdropAlpha : backdropAlphaNode
42
+ backdropAlpha: backdropAlphaNode
43
43
  };
44
44
 
45
45
  return context;
@@ -169,7 +169,7 @@ class LightsNode extends Node {
169
169
  export default LightsNode;
170
170
 
171
171
  export const lights = ( lights ) => nodeObject( new LightsNode().fromLights( lights ) );
172
- export const lightNodes = nodeProxy( LightsNode );
172
+ export const lightsNode = nodeProxy( LightsNode );
173
173
 
174
174
  export function addLightNode( lightClass, lightNodeClass ) {
175
175
 
@@ -133,50 +133,38 @@ class Line2NodeMaterial extends NodeMaterial {
133
133
  if ( useWorldUnits ) {
134
134
 
135
135
  // get the offset direction as perpendicular to the view vector
136
- const worldDir = end.xyz.sub( start.xyz ).normalize();
137
136
 
138
- const offset = positionGeometry.y.lessThan( 0.5 ).cond(
139
- start.xyz.cross( worldDir ).normalize(),
140
- end.xyz.cross( worldDir ).normalize()
137
+ const worldDir = end.xyz.sub( start.xyz ).normalize();
138
+ const tmpFwd = mix( start.xyz, end.xyz, 0.5 ).normalize();
139
+ const worldUp = worldDir.cross( tmpFwd ).normalize();
140
+ const worldFwd = worldDir.cross( worldUp );
141
141
 
142
- );
142
+ const worldPos = varyingProperty( 'vec4', 'worldPos' );
143
143
 
144
- // sign flip
145
- offset.assign( positionGeometry.x.lessThan( 0.0 ).cond( offset.negate(), offset ) );
144
+ worldPos.assign( positionGeometry.y.lessThan( 0.5 ).cond( start, end) );
146
145
 
147
- const forwardOffset = worldDir.dot( vec3( 0.0, 0.0, 1.0 ) );
146
+ // height offset
147
+ const hw = materialLineWidth.mul( 0.5 );
148
+ worldPos.addAssign( vec4( positionGeometry.x.lessThan( 0.0 ).cond( worldUp.mul( hw ), worldUp.mul( hw ).negate() ), 0 ) );
148
149
 
149
150
  // don't extend the line if we're rendering dashes because we
150
151
  // won't be rendering the endcaps
151
152
  if ( ! useDash ) {
152
153
 
153
- // extend the line bounds to encompass endcaps
154
- start.assign( start.sub( vec4( worldDir.mul( materialLineWidth ).mul( 0.5 ), 0 ) ) );
155
- end.assign( end.add( vec4( worldDir.mul( materialLineWidth ).mul( 0.5 ), 0 ) ) );
154
+ // cap extension
155
+ worldPos.addAssign( vec4( positionGeometry.y.lessThan( 0.5 ).cond( worldDir.mul( hw ).negate(), worldDir.mul( hw ) ), 0 ) );
156
156
 
157
- // shift the position of the quad so it hugs the forward edge of the line
158
- offset.assign( offset.sub( vec3( dir.mul( forwardOffset ), 0 ) ) );
159
- offset.z.assign( offset.z.add( 0.5 ) );
160
-
161
- }
162
-
163
- // endcaps
157
+ // add width to the box
158
+ worldPos.addAssign( vec4( worldFwd.mul( hw ), 0 ) );
164
159
 
165
- If( positionGeometry.y.greaterThan( 1.0 ).or( positionGeometry.y.lessThan( 0.0 ) ), () => {
160
+ // endcaps
161
+ If( positionGeometry.y.greaterThan( 1.0 ).or( positionGeometry.y.lessThan( 0.0 ) ), () => {
166
162
 
167
- offset.assign( offset.add( vec3( dir.mul( 2.0 ).mul( forwardOffset ), 0 ) ) );
163
+ worldPos.subAssign( vec4( worldFwd.mul( 2.0 ).mul( hw ), 0 ) );
168
164
 
169
- } );
170
-
171
- // adjust for linewidth
172
- offset.assign( offset.mul( materialLineWidth ).mul( 0.5 ) );
173
-
174
- // set the world position
175
-
176
- const worldPos = varyingProperty( 'vec4', 'worldPos' );
165
+ } );
177
166
 
178
- worldPos.assign( positionGeometry.y.lessThan( 0.5 ).cond( start, end ) );
179
- worldPos.assign( worldPos.add( vec4( offset, 0 ) ) );
167
+ }
180
168
 
181
169
  // project the worldpos
182
170
  clip.assign( cameraProjectionMatrix.mul( worldPos ) );
@@ -11,5 +11,6 @@ export { default as MeshLambertNodeMaterial } from './MeshLambertNodeMaterial.js
11
11
  export { default as MeshPhongNodeMaterial } from './MeshPhongNodeMaterial.js';
12
12
  export { default as MeshStandardNodeMaterial } from './MeshStandardNodeMaterial.js';
13
13
  export { default as MeshPhysicalNodeMaterial } from './MeshPhysicalNodeMaterial.js';
14
+ export { default as MeshSSSNodeMaterial } from './MeshSSSNodeMaterial.js';
14
15
  export { default as PointsNodeMaterial } from './PointsNodeMaterial.js';
15
16
  export { default as SpriteNodeMaterial } from './SpriteNodeMaterial.js';
@@ -0,0 +1,84 @@
1
+ import { addNodeMaterial } from './NodeMaterial.js';
2
+ import { transformedNormalView } from '../accessors/NormalNode.js';
3
+ import { positionViewDirection } from '../accessors/PositionNode.js';
4
+ import PhysicalLightingModel from '../functions/PhysicalLightingModel.js';
5
+ import MeshPhysicalNodeMaterial from './MeshPhysicalNodeMaterial.js';
6
+ import { float, vec3 } from '../shadernode/ShaderNode.js';
7
+
8
+ class SSSLightingModel extends PhysicalLightingModel {
9
+
10
+ constructor( useClearcoat, useSheen, useIridescence, useSSS ) {
11
+
12
+ super( useClearcoat, useSheen, useIridescence );
13
+
14
+ this.useSSS = useSSS;
15
+
16
+ }
17
+
18
+ direct( { lightDirection, lightColor, reflectedLight }, stack, builder ) {
19
+
20
+ if ( this.useSSS === true ) {
21
+
22
+ const material = builder.material;
23
+
24
+ const { thicknessColorNode, thicknessDistortionNode, thicknessAmbientNode, thicknessAttenuationNode, thicknessPowerNode, thicknessScaleNode } = material;
25
+
26
+ const scatteringHalf = lightDirection.add( transformedNormalView.mul( thicknessDistortionNode ) ).normalize();
27
+ const scatteringDot = float( positionViewDirection.dot( scatteringHalf.negate() ).saturate().pow( thicknessPowerNode ).mul( thicknessScaleNode ) );
28
+ const scatteringIllu = vec3( scatteringDot.add( thicknessAmbientNode ).mul( thicknessColorNode ) );
29
+
30
+ reflectedLight.directDiffuse.addAssign( scatteringIllu.mul( thicknessAttenuationNode.mul( lightColor ) ) );
31
+
32
+ }
33
+
34
+ super.direct( { lightDirection, lightColor, reflectedLight }, stack, builder );
35
+
36
+ }
37
+
38
+ }
39
+
40
+ class MeshSSSNodeMaterial extends MeshPhysicalNodeMaterial {
41
+
42
+ constructor( parameters ) {
43
+
44
+ super( parameters );
45
+
46
+ this.thicknessColorNode = null;
47
+ this.thicknessDistortionNode = float( 0.1 );
48
+ this.thicknessAmbientNode = float( 0.0 );
49
+ this.thicknessAttenuationNode = float( .1 );
50
+ this.thicknessPowerNode = float( 2.0 );
51
+ this.thicknessScaleNode = float( 10.0 );
52
+
53
+ }
54
+
55
+ get useSSS() {
56
+
57
+ return this.thicknessColorNode !== null;
58
+
59
+ }
60
+
61
+ setupLightingModel( /*builder*/ ) {
62
+
63
+ return new SSSLightingModel( this.useClearcoat, this.useSheen, this.useIridescence, this.useSSS );
64
+
65
+ }
66
+
67
+ copy( source ) {
68
+
69
+ this.thicknessColorNode = source.thicknessColorNode;
70
+ this.thicknessDistortionNode = source.thicknessDistortionNode;
71
+ this.thicknessAmbientNode = source.thicknessAmbientNode;
72
+ this.thicknessAttenuationNode = source.thicknessAttenuationNode;
73
+ this.thicknessPowerNode = source.thicknessPowerNode;
74
+ this.thicknessScaleNode = source.thicknessScaleNode;
75
+
76
+ return super.copy( source );
77
+
78
+ }
79
+
80
+ }
81
+
82
+ export default MeshSSSNodeMaterial;
83
+
84
+ addNodeMaterial( 'MeshSSSNodeMaterial', MeshSSSNodeMaterial );
@@ -11,7 +11,7 @@ import { skinning } from '../accessors/SkinningNode.js';
11
11
  import { morph } from '../accessors/MorphNode.js';
12
12
  import { texture } from '../accessors/TextureNode.js';
13
13
  import { cubeTexture } from '../accessors/CubeTextureNode.js';
14
- import { lightNodes } from '../lighting/LightsNode.js';
14
+ import { lightsNode } from '../lighting/LightsNode.js';
15
15
  import { mix } from '../math/MathNode.js';
16
16
  import { float, vec3, vec4 } from '../shadernode/ShaderNode.js';
17
17
  import AONode from '../lighting/AONode.js';
@@ -53,6 +53,7 @@ class NodeMaterial extends ShaderMaterial {
53
53
  this.positionNode = null;
54
54
 
55
55
  this.depthNode = null;
56
+ this.shadowNode = null;
56
57
 
57
58
  this.outputNode = null;
58
59
 
@@ -289,15 +290,15 @@ class NodeMaterial extends ShaderMaterial {
289
290
 
290
291
  }
291
292
 
292
- let lightsNode = this.lightsNode || builder.lightsNode;
293
+ let lightsN = this.lightsNode || builder.lightsNode;
293
294
 
294
295
  if ( materialLightsNode.length > 0 ) {
295
296
 
296
- lightsNode = lightNodes( [ ...lightsNode.lightNodes, ...materialLightsNode ] );
297
+ lightsN = lightsNode( [ ...lightsN.lightNodes, ...materialLightsNode ] );
297
298
 
298
299
  }
299
300
 
300
- return lightsNode;
301
+ return lightsN;
301
302
 
302
303
  }
303
304
 
@@ -496,6 +497,7 @@ class NodeMaterial extends ShaderMaterial {
496
497
  this.positionNode = source.positionNode;
497
498
 
498
499
  this.depthNode = source.depthNode;
500
+ this.shadowNode = source.shadowNode;
499
501
 
500
502
  this.outputNode = source.outputNode;
501
503
 
@@ -61,13 +61,7 @@ class SpriteNodeMaterial extends NodeMaterial {
61
61
 
62
62
  const rotation = float( rotationNode || materialRotation );
63
63
 
64
- const cosAngle = rotation.cos();
65
- const sinAngle = rotation.sin();
66
-
67
- const rotatedPosition = vec2( // @TODO: Maybe we can create mat2 and write something like rotationMatrix.mul( alignedPosition )?
68
- vec2( cosAngle, sinAngle.negate() ).dot( alignedPosition ),
69
- vec2( sinAngle, cosAngle ).dot( alignedPosition )
70
- );
64
+ const rotatedPosition = alignedPosition.rotate( rotation );
71
65
 
72
66
  mvPosition = vec4( mvPosition.xy.add( rotatedPosition ), mvPosition.zw );
73
67
 
@@ -57,6 +57,10 @@ class MathNode extends TempNode {
57
57
 
58
58
  return 'vec3';
59
59
 
60
+ } else if ( method === MathNode.MOD ) {
61
+
62
+ return this.aNode.getNodeType( builder );
63
+
60
64
  } else {
61
65
 
62
66
  return this.getInputType( builder );
@@ -120,7 +124,7 @@ class MathNode extends TempNode {
120
124
 
121
125
  const params = [];
122
126
 
123
- if ( method === MathNode.CROSS ) {
127
+ if ( method === MathNode.CROSS || method === MathNode.MOD ) {
124
128
 
125
129
  params.push(
126
130
  a.build( builder, type ),
@@ -165,7 +169,7 @@ class MathNode extends TempNode {
165
169
 
166
170
  }
167
171
 
168
- return builder.format( `${ builder.getMethod( method ) }( ${params.join( ', ' )} )`, type, output );
172
+ return builder.format( `${ builder.getMethod( method, type ) }( ${params.join( ', ' )} )`, type, output );
169
173
 
170
174
  }
171
175
 
@@ -249,6 +253,8 @@ export default MathNode;
249
253
 
250
254
  export const EPSILON = float( 1e-6 );
251
255
  export const INFINITY = float( 1e6 );
256
+ export const PI = float( Math.PI );
257
+ export const PI2 = float( Math.PI * 2 );
252
258
 
253
259
  export const radians = nodeProxy( MathNode, MathNode.RADIANS );
254
260
  export const degrees = nodeProxy( MathNode, MathNode.DEGREES );
@@ -297,6 +303,8 @@ export const pow3 = nodeProxy( MathNode, MathNode.POW, 3 );
297
303
  export const pow4 = nodeProxy( MathNode, MathNode.POW, 4 );
298
304
  export const transformDirection = nodeProxy( MathNode, MathNode.TRANSFORM_DIRECTION );
299
305
 
306
+ export const cbrt = ( a ) => mul( sign( a ), pow( abs( a ), 1.0 / 3.0 ) );
307
+ export const lengthSq = ( a ) => dot( a, a );
300
308
  export const mix = nodeProxy( MathNode, MathNode.MIX );
301
309
  export const clamp = ( value, low = 0, high = 1 ) => nodeObject( new MathNode( MathNode.CLAMP, nodeObject( value ), nodeObject( low ), nodeObject( high ) ) );
302
310
  export const saturate = ( value ) => clamp( value );
@@ -328,6 +336,7 @@ addNodeElement( 'atan', atan );
328
336
  addNodeElement( 'abs', abs );
329
337
  addNodeElement( 'sign', sign );
330
338
  addNodeElement( 'length', length );
339
+ addNodeElement( 'lengthSq', lengthSq );
331
340
  addNodeElement( 'negate', negate );
332
341
  addNodeElement( 'oneMinus', oneMinus );
333
342
  addNodeElement( 'dFdx', dFdx );
@@ -357,5 +366,6 @@ addNodeElement( 'smoothstep', smoothstepElement );
357
366
  addNodeElement( 'faceForward', faceForward );
358
367
  addNodeElement( 'difference', difference );
359
368
  addNodeElement( 'saturate', saturate );
369
+ addNodeElement( 'cbrt', cbrt );
360
370
 
361
371
  addNodeClass( 'MathNode', MathNode );
@@ -0,0 +1,15 @@
1
+ import { sub, mul, div, add } from './OperatorNode.js';
2
+ import { addNodeElement } from '../shadernode/ShaderNode.js';
3
+ import { PI, pow, sin } from './MathNode.js';
4
+
5
+ // remapping functions https://iquilezles.org/articles/functions/
6
+ export const parabola = ( x, k ) => pow( mul( 4.0, x.mul( sub( 1.0, x ) ) ), k );
7
+ export const gain = ( x, k ) => x.lessThan( 0.5 ) ? parabola( x.mul( 2.0 ), k ).div( 2.0 ) : sub( 1.0, parabola( mul( sub( 1.0, x ), 2.0 ), k ).div( 2.0 ) );
8
+ export const pcurve = ( x, a, b ) => pow( div( pow( x, a ), add( pow( x, a ), pow( sub( 1.0, x ), b ) ) ), 1.0 / a );
9
+ export const sinc = ( x, k ) => sin( PI.mul( k.mul( x ).sub( 1.0 ) ) ).div( PI.mul( k.mul( x ).sub( 1.0 ) ) );
10
+
11
+
12
+ addNodeElement( 'parabola', parabola );
13
+ addNodeElement( 'gain', gain );
14
+ addNodeElement( 'pcurve', pcurve );
15
+ addNodeElement( 'sinc', sinc );
@@ -37,7 +37,7 @@ class OperatorNode extends TempNode {
37
37
  const bNode = this.bNode;
38
38
 
39
39
  const typeA = aNode.getNodeType( builder );
40
- const typeB = bNode.getNodeType( builder );
40
+ const typeB = typeof bNode !== 'undefined' ? bNode.getNodeType( builder ) : null;
41
41
 
42
42
  if ( typeA === 'void' || typeB === 'void' ) {
43
43
 
@@ -47,11 +47,11 @@ class OperatorNode extends TempNode {
47
47
 
48
48
  return typeA;
49
49
 
50
- } else if ( op === '&' || op === '|' || op === '^' || op === '>>' || op === '<<' ) {
50
+ } else if ( op === '~' || op === '&' || op === '|' || op === '^' || op === '>>' || op === '<<' ) {
51
51
 
52
52
  return builder.getIntegerType( typeA );
53
53
 
54
- } else if ( op === '==' || op === '&&' || op === '||' || op === '^^' ) {
54
+ } else if ( op === '!' || op === '==' || op === '&&' || op === '||' || op === '^^' ) {
55
55
 
56
56
  return 'bool';
57
57
 
@@ -108,7 +108,7 @@ class OperatorNode extends TempNode {
108
108
  if ( type !== 'void' ) {
109
109
 
110
110
  typeA = aNode.getNodeType( builder );
111
- typeB = bNode.getNodeType( builder );
111
+ typeB = typeof bNode !== 'undefined' ? bNode.getNodeType( builder ) : null;
112
112
 
113
113
  if ( op === '<' || op === '>' || op === '<=' || op === '>=' || op === '==' ) {
114
114
 
@@ -154,7 +154,7 @@ class OperatorNode extends TempNode {
154
154
  }
155
155
 
156
156
  const a = aNode.build( builder, typeA );
157
- const b = bNode.build( builder, typeB );
157
+ const b = typeof bNode !== 'undefined' ? bNode.build( builder, typeB ) : null;
158
158
 
159
159
  const outputLength = builder.getTypeLength( output );
160
160
  const fnOpSnippet = builder.getFunctionOperator( op );
@@ -177,6 +177,10 @@ class OperatorNode extends TempNode {
177
177
 
178
178
  return builder.format( `${ builder.getMethod( 'greaterThanEqual' ) }( ${ a }, ${ b } )`, type, output );
179
179
 
180
+ } else if ( op === '!' || op === '~' ) {
181
+
182
+ return builder.format( `(${op}${a})`, typeA, output );
183
+
180
184
  } else if ( fnOpSnippet ) {
181
185
 
182
186
  return builder.format( `${ fnOpSnippet }( ${ a }, ${ b } )`, type, output );
@@ -236,8 +240,10 @@ export const lessThanEqual = nodeProxy( OperatorNode, '<=' );
236
240
  export const greaterThanEqual = nodeProxy( OperatorNode, '>=' );
237
241
  export const and = nodeProxy( OperatorNode, '&&' );
238
242
  export const or = nodeProxy( OperatorNode, '||' );
243
+ export const not = nodeProxy( OperatorNode, '!' );
239
244
  export const xor = nodeProxy( OperatorNode, '^^' );
240
245
  export const bitAnd = nodeProxy( OperatorNode, '&' );
246
+ export const bitNot = nodeProxy( OperatorNode, '~' );
241
247
  export const bitOr = nodeProxy( OperatorNode, '|' );
242
248
  export const bitXor = nodeProxy( OperatorNode, '^' );
243
249
  export const shiftLeft = nodeProxy( OperatorNode, '<<' );
@@ -256,8 +262,10 @@ addNodeElement( 'lessThanEqual', lessThanEqual );
256
262
  addNodeElement( 'greaterThanEqual', greaterThanEqual );
257
263
  addNodeElement( 'and', and );
258
264
  addNodeElement( 'or', or );
265
+ addNodeElement( 'not', not );
259
266
  addNodeElement( 'xor', xor );
260
267
  addNodeElement( 'bitAnd', bitAnd );
268
+ addNodeElement( 'bitNot', bitNot );
261
269
  addNodeElement( 'bitOr', bitOr );
262
270
  addNodeElement( 'bitXor', bitXor );
263
271
  addNodeElement( 'shiftLeft', shiftLeft );
@@ -0,0 +1,71 @@
1
+ // https://github.com/cabbibo/glsl-tri-noise-3d
2
+
3
+ import { loop } from '../utils/LoopNode.js';
4
+ import { float, vec3, tslFn } from '../shadernode/ShaderNode.js';
5
+
6
+ const tri = tslFn( ( [ x ] ) => {
7
+
8
+ return x.fract().sub( .5 ).abs();
9
+
10
+ } );
11
+
12
+ const tri3 = tslFn( ( [ p ] ) => {
13
+
14
+ return vec3( tri( p.z.add( tri( p.y.mul( 1. ) ) ) ), tri( p.z.add( tri( p.x.mul( 1. ) ) ) ), tri( p.y.add( tri( p.x.mul( 1. ) ) ) ) );
15
+
16
+ } );
17
+
18
+ const triNoise3D = tslFn( ( [ p_immutable, spd, time ] ) => {
19
+
20
+ const p = vec3( p_immutable ).toVar();
21
+ const z = float( 1.4 ).toVar();
22
+ const rz = float( 0.0 ).toVar();
23
+ const bp = vec3( p ).toVar();
24
+
25
+ loop( { start: float( 0.0 ), end: float( 3.0 ), type: 'float', condition: '<=' }, () => {
26
+
27
+ const dg = vec3( tri3( bp.mul( 2.0 ) ) ).toVar();
28
+ p.addAssign( dg.add( time.mul( float( 0.1 ).mul( spd ) ) ) );
29
+ bp.mulAssign( 1.8 );
30
+ z.mulAssign( 1.5 );
31
+ p.mulAssign( 1.2 );
32
+
33
+ const t = float( tri( p.z.add( tri( p.x.add( tri( p.y ) ) ) ) ) ).toVar();
34
+ rz.addAssign( t.div( z ) );
35
+ bp.addAssign( 0.14 );
36
+
37
+ } );
38
+
39
+ return rz;
40
+
41
+ } );
42
+
43
+ // layouts
44
+
45
+ tri.setLayout( {
46
+ name: 'tri',
47
+ type: 'float',
48
+ inputs: [
49
+ { name: 'x', type: 'float' }
50
+ ]
51
+ } );
52
+
53
+ tri3.setLayout( {
54
+ name: 'tri3',
55
+ type: 'vec3',
56
+ inputs: [
57
+ { name: 'p', type: 'vec3' }
58
+ ]
59
+ } );
60
+
61
+ triNoise3D.setLayout( {
62
+ name: 'triNoise3D',
63
+ type: 'float',
64
+ inputs: [
65
+ { name: 'p', type: 'vec3' },
66
+ { name: 'spd', type: 'float' },
67
+ { name: 'time', type: 'float' }
68
+ ]
69
+ } );
70
+
71
+ export { tri, tri3, triNoise3D };
@@ -341,7 +341,7 @@ class ShaderNodeInternal extends Node {
341
341
 
342
342
  get isArrayInput() {
343
343
 
344
- return /^\(\s+?\[/.test( this.jsFunc.toString() );
344
+ return /^\((\s+)?\[/.test( this.jsFunc.toString() );
345
345
 
346
346
  }
347
347
 
@@ -574,6 +574,11 @@ export const ivec4 = new ConvertType( 'ivec4' );
574
574
  export const uvec4 = new ConvertType( 'uvec4' );
575
575
  export const bvec4 = new ConvertType( 'bvec4' );
576
576
 
577
+ export const mat2 = new ConvertType( 'mat2' );
578
+ export const imat2 = new ConvertType( 'imat2' );
579
+ export const umat2 = new ConvertType( 'umat2' );
580
+ export const bmat2 = new ConvertType( 'bmat2' );
581
+
577
582
  export const mat3 = new ConvertType( 'mat3' );
578
583
  export const imat3 = new ConvertType( 'imat3' );
579
584
  export const umat3 = new ConvertType( 'umat3' );
@@ -604,6 +609,10 @@ addNodeElement( 'vec4', vec4 );
604
609
  addNodeElement( 'ivec4', ivec4 );
605
610
  addNodeElement( 'uvec4', uvec4 );
606
611
  addNodeElement( 'bvec4', bvec4 );
612
+ addNodeElement( 'mat2', mat2 );
613
+ addNodeElement( 'imat2', imat2 );
614
+ addNodeElement( 'umat2', umat2 );
615
+ addNodeElement( 'bmat2', bmat2 );
607
616
  addNodeElement( 'mat3', mat3 );
608
617
  addNodeElement( 'imat3', imat3 );
609
618
  addNodeElement( 'umat3', umat3 );
@@ -24,6 +24,12 @@ class ArrayElementNode extends Node { // @TODO: If extending from TempNode it br
24
24
  const nodeSnippet = this.node.build( builder );
25
25
  const indexSnippet = this.indexNode.build( builder, 'uint' );
26
26
 
27
+ if ( this.node.isStorageBufferNode && ! builder.isAvailable( 'storageBuffer' ) ) {
28
+
29
+ return nodeSnippet;
30
+
31
+ }
32
+
27
33
  return `${nodeSnippet}[ ${indexSnippet} ]`;
28
34
 
29
35
  }
@@ -28,7 +28,7 @@ class JoinNode extends TempNode {
28
28
  const type = this.getNodeType( builder );
29
29
  const nodes = this.nodes;
30
30
 
31
- const primitiveType = builder.getPrimitiveType( type );
31
+ const primitiveType = builder.getComponentType( type );
32
32
 
33
33
  const snippetValues = [];
34
34
 
@@ -36,7 +36,7 @@ class JoinNode extends TempNode {
36
36
 
37
37
  let inputSnippet = input.build( builder );
38
38
 
39
- const inputPrimitiveType = builder.getPrimitiveType( input.getNodeType( builder ) );
39
+ const inputPrimitiveType = builder.getComponentType( input.getNodeType( builder ) );
40
40
 
41
41
  if ( inputPrimitiveType !== primitiveType ) {
42
42
 
@@ -144,15 +144,15 @@ class LoopNode extends Node {
144
144
 
145
145
  if ( ! update ) {
146
146
 
147
- if ( type === 'int' ) {
147
+ if ( type === 'int' || type === 'uint' ) {
148
148
 
149
149
  if ( condition.includes( '<' ) ) update = '++';
150
150
  else update = '--';
151
151
 
152
152
  } else {
153
153
 
154
- if ( condition.includes( '<' ) ) update = '+= 1';
155
- else update = '-= 1';
154
+ if ( condition.includes( '<' ) ) update = '+= 1.';
155
+ else update = '-= 1.';
156
156
 
157
157
  }
158
158