super-three 0.170.0 → 0.171.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 (172) hide show
  1. package/build/three.cjs +24410 -24422
  2. package/build/three.core.js +37002 -0
  3. package/build/three.core.min.js +6 -0
  4. package/build/three.module.js +10573 -47578
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +533 -0
  7. package/build/three.tsl.min.js +6 -0
  8. package/build/three.webgpu.js +2907 -37975
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +2914 -37959
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/capabilities/WebGPU.js +1 -10
  13. package/examples/jsm/controls/ArcballControls.js +25 -21
  14. package/examples/jsm/controls/OrbitControls.js +41 -9
  15. package/examples/jsm/controls/PointerLockControls.js +2 -5
  16. package/examples/jsm/csm/CSMShadowNode.js +7 -5
  17. package/examples/jsm/geometries/DecalGeometry.js +5 -1
  18. package/examples/jsm/lighting/TiledLighting.js +1 -1
  19. package/examples/jsm/lines/LineGeometry.js +25 -0
  20. package/examples/jsm/lines/LineMaterial.js +1 -7
  21. package/examples/jsm/lines/webgpu/Line2.js +2 -1
  22. package/examples/jsm/lines/webgpu/LineSegments2.js +2 -1
  23. package/examples/jsm/lines/webgpu/Wireframe.js +2 -1
  24. package/examples/jsm/loaders/KTX2Loader.js +3 -0
  25. package/examples/jsm/loaders/MMDLoader.js +2 -6
  26. package/examples/jsm/loaders/MaterialXLoader.js +2 -2
  27. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -6
  28. package/examples/jsm/misc/ProgressiveLightMapGPU.js +2 -2
  29. package/examples/jsm/objects/InstancedPoints.js +2 -4
  30. package/examples/jsm/objects/LensflareMesh.js +4 -2
  31. package/examples/jsm/objects/SkyMesh.js +5 -3
  32. package/examples/jsm/objects/Water2Mesh.js +7 -3
  33. package/examples/jsm/objects/WaterMesh.js +5 -3
  34. package/examples/jsm/transpiler/AST.js +2 -2
  35. package/examples/jsm/transpiler/GLSLDecoder.js +57 -25
  36. package/examples/jsm/transpiler/TSLEncoder.js +11 -6
  37. package/examples/jsm/tsl/display/AfterImageNode.js +3 -3
  38. package/examples/jsm/tsl/display/AnaglyphPassNode.js +2 -2
  39. package/examples/jsm/tsl/display/AnamorphicNode.js +2 -2
  40. package/examples/jsm/tsl/display/BloomNode.js +3 -3
  41. package/examples/jsm/tsl/display/DenoiseNode.js +48 -12
  42. package/examples/jsm/tsl/display/DepthOfFieldNode.js +3 -2
  43. package/examples/jsm/tsl/display/DotScreenNode.js +2 -2
  44. package/examples/jsm/tsl/display/FXAANode.js +3 -3
  45. package/examples/jsm/tsl/display/FilmNode.js +3 -2
  46. package/examples/jsm/tsl/display/GTAONode.js +62 -27
  47. package/examples/jsm/tsl/display/GaussianBlurNode.js +6 -8
  48. package/examples/jsm/tsl/display/LensflareNode.js +3 -3
  49. package/examples/jsm/tsl/display/Lut3DNode.js +3 -2
  50. package/examples/jsm/tsl/display/OutlineNode.js +2 -2
  51. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -1
  52. package/examples/jsm/tsl/display/PixelationPassNode.js +4 -4
  53. package/examples/jsm/tsl/display/RGBShiftNode.js +2 -1
  54. package/examples/jsm/tsl/display/SMAANode.js +3 -3
  55. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  56. package/examples/jsm/tsl/display/SSRNode.js +31 -8
  57. package/examples/jsm/tsl/display/SobelOperatorNode.js +3 -3
  58. package/examples/jsm/tsl/display/StereoCompositePassNode.js +4 -4
  59. package/examples/jsm/tsl/display/StereoPassNode.js +2 -2
  60. package/examples/jsm/tsl/display/TRAAPassNode.js +2 -2
  61. package/examples/jsm/tsl/display/TransitionNode.js +3 -2
  62. package/examples/jsm/tsl/lighting/TiledLightsNode.js +6 -9
  63. package/examples/jsm/utils/SceneOptimizer.js +410 -0
  64. package/examples/jsm/utils/UVsDebug.js +1 -1
  65. package/package.json +3 -3
  66. package/src/Three.Core.js +178 -0
  67. package/src/Three.TSL.js +526 -0
  68. package/src/Three.WebGPU.Nodes.js +5 -186
  69. package/src/Three.WebGPU.js +4 -186
  70. package/src/Three.js +1 -177
  71. package/src/animation/AnimationClip.js +2 -2
  72. package/src/animation/AnimationObjectGroup.js +2 -2
  73. package/src/audio/Audio.js +38 -0
  74. package/src/cameras/PerspectiveCamera.js +6 -6
  75. package/src/cameras/StereoCamera.js +2 -2
  76. package/src/constants.js +1 -1
  77. package/src/core/BufferGeometry.js +5 -3
  78. package/src/core/InterleavedBuffer.js +4 -4
  79. package/src/core/Object3D.js +2 -2
  80. package/src/extras/core/Curve.js +3 -3
  81. package/src/extras/core/Shape.js +2 -2
  82. package/src/geometries/EdgesGeometry.js +2 -2
  83. package/src/geometries/LatheGeometry.js +2 -2
  84. package/src/lights/SpotLightShadow.js +2 -2
  85. package/src/materials/LineBasicMaterial.js +2 -6
  86. package/src/materials/LineDashedMaterial.js +1 -6
  87. package/src/materials/Material.js +3 -16
  88. package/src/materials/MeshBasicMaterial.js +2 -6
  89. package/src/materials/MeshDepthMaterial.js +2 -6
  90. package/src/materials/MeshDistanceMaterial.js +2 -6
  91. package/src/materials/MeshLambertMaterial.js +2 -6
  92. package/src/materials/MeshMatcapMaterial.js +2 -6
  93. package/src/materials/MeshNormalMaterial.js +2 -6
  94. package/src/materials/MeshPhongMaterial.js +3 -7
  95. package/src/materials/MeshPhysicalMaterial.js +4 -8
  96. package/src/materials/MeshStandardMaterial.js +2 -6
  97. package/src/materials/MeshToonMaterial.js +2 -6
  98. package/src/materials/PointsMaterial.js +2 -6
  99. package/src/materials/RawShaderMaterial.js +2 -6
  100. package/src/materials/ShaderMaterial.js +2 -6
  101. package/src/materials/ShadowMaterial.js +2 -6
  102. package/src/materials/SpriteMaterial.js +2 -6
  103. package/src/materials/nodes/Line2NodeMaterial.js +32 -13
  104. package/src/materials/nodes/LineDashedNodeMaterial.js +4 -2
  105. package/src/materials/nodes/NodeMaterial.js +64 -16
  106. package/src/materials/nodes/manager/NodeMaterialObserver.js +13 -10
  107. package/src/math/ColorManagement.js +130 -122
  108. package/src/math/Line3.js +2 -2
  109. package/src/math/Quaternion.js +2 -2
  110. package/src/math/Spherical.js +3 -3
  111. package/src/math/Vector2.js +7 -7
  112. package/src/math/Vector3.js +9 -9
  113. package/src/math/Vector4.js +11 -9
  114. package/src/nodes/Nodes.js +1 -0
  115. package/src/nodes/TSL.js +3 -1
  116. package/src/nodes/accessors/Arrays.js +27 -0
  117. package/src/nodes/accessors/BuiltinNode.js +26 -0
  118. package/src/nodes/accessors/ClippingNode.js +76 -42
  119. package/src/nodes/accessors/InstanceNode.js +17 -20
  120. package/src/nodes/accessors/InstancedMeshNode.js +26 -0
  121. package/src/nodes/accessors/Lights.js +32 -0
  122. package/src/nodes/accessors/StorageBufferNode.js +29 -9
  123. package/src/nodes/accessors/StorageTextureNode.js +10 -4
  124. package/src/nodes/accessors/TextureNode.js +1 -1
  125. package/src/nodes/core/NodeBuilder.js +2 -9
  126. package/src/nodes/core/NodeUtils.js +28 -0
  127. package/src/nodes/core/constants.js +6 -0
  128. package/src/nodes/display/BlendModes.js +99 -0
  129. package/src/nodes/display/ToonOutlinePassNode.js +3 -3
  130. package/src/nodes/display/ViewportDepthNode.js +21 -6
  131. package/src/nodes/functions/material/getAlphaHashThreshold.js +13 -7
  132. package/src/nodes/functions/material/getParallaxCorrectNormal.js +1 -1
  133. package/src/nodes/lighting/AnalyticLightNode.js +12 -4
  134. package/src/nodes/lighting/PointLightNode.js +10 -1
  135. package/src/nodes/lighting/PointShadowNode.js +254 -0
  136. package/src/nodes/lighting/ShadowNode.js +176 -67
  137. package/src/nodes/lighting/SpotLightNode.js +14 -2
  138. package/src/nodes/utils/RTTNode.js +9 -1
  139. package/src/nodes/utils/StorageArrayElementNode.js +2 -2
  140. package/src/objects/BatchedMesh.js +54 -95
  141. package/src/objects/ClippingGroup.js +19 -0
  142. package/src/objects/Skeleton.js +2 -2
  143. package/src/renderers/WebGLRenderer.js +94 -23
  144. package/src/renderers/common/Animation.js +23 -11
  145. package/src/renderers/common/Background.js +1 -1
  146. package/src/renderers/common/Bindings.js +20 -4
  147. package/src/renderers/common/ClippingContext.js +77 -85
  148. package/src/renderers/common/RenderList.js +9 -6
  149. package/src/renderers/common/RenderObject.js +27 -27
  150. package/src/renderers/common/RenderObjects.js +12 -6
  151. package/src/renderers/common/Renderer.js +63 -57
  152. package/src/renderers/common/Textures.js +11 -3
  153. package/src/renderers/common/UniformsGroup.js +16 -4
  154. package/src/renderers/common/extras/PMREMGenerator.js +89 -13
  155. package/src/renderers/common/nodes/NodeLibrary.js +2 -2
  156. package/src/renderers/common/nodes/NodeStorageBuffer.js +2 -3
  157. package/src/renderers/common/nodes/NodeUniform.js +42 -0
  158. package/src/renderers/webgl/WebGLBackground.js +20 -1
  159. package/src/renderers/webgl/WebGLGeometries.js +0 -28
  160. package/src/renderers/webgl-fallback/WebGLBackend.js +13 -6
  161. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +43 -12
  162. package/src/renderers/webgl-fallback/utils/WebGLState.js +26 -1
  163. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +4 -1
  164. package/src/renderers/webgpu/WebGPUBackend.js +47 -31
  165. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +13 -26
  166. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +184 -74
  167. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -2
  168. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -7
  169. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +5 -1
  170. package/src/textures/Source.js +2 -2
  171. package/src/textures/Texture.js +2 -2
  172. package/src/nodes/display/BlendMode.js +0 -54
@@ -1,12 +1,12 @@
1
1
 
2
2
  import Node from '../core/Node.js';
3
- import { nodeObject } from '../tsl/TSLBase.js';
3
+ import { nodeObject, Fn, bool, float } from '../tsl/TSLBase.js';
4
4
  import { positionView } from './Position.js';
5
- import { diffuseColor, property } from '../core/PropertyNode.js';
6
- import { Fn } from '../tsl/TSLBase.js';
5
+ import { diffuseColor } from '../core/PropertyNode.js';
7
6
  import { Loop } from '../utils/LoopNode.js';
8
7
  import { smoothstep } from '../math/MathNode.js';
9
8
  import { uniformArray } from './UniformArrayNode.js';
9
+ import { builtin } from './BuiltinNode.js';
10
10
 
11
11
  class ClippingNode extends Node {
12
12
 
@@ -29,69 +29,73 @@ class ClippingNode extends Node {
29
29
  super.setup( builder );
30
30
 
31
31
  const clippingContext = builder.clippingContext;
32
- const { localClipIntersection, localClippingCount, globalClippingCount } = clippingContext;
32
+ const { intersectionPlanes, unionPlanes } = clippingContext;
33
33
 
34
- const numClippingPlanes = globalClippingCount + localClippingCount;
35
- const numUnionClippingPlanes = localClipIntersection ? numClippingPlanes - localClippingCount : numClippingPlanes;
34
+ this.hardwareClipping = builder.material.hardwareClipping;
36
35
 
37
36
  if ( this.scope === ClippingNode.ALPHA_TO_COVERAGE ) {
38
37
 
39
- return this.setupAlphaToCoverage( clippingContext.planes, numClippingPlanes, numUnionClippingPlanes );
38
+ return this.setupAlphaToCoverage( intersectionPlanes, unionPlanes );
39
+
40
+ } else if ( this.scope === ClippingNode.HARDWARE ) {
41
+
42
+ return this.setupHardwareClipping( unionPlanes, builder );
40
43
 
41
44
  } else {
42
45
 
43
- return this.setupDefault( clippingContext.planes, numClippingPlanes, numUnionClippingPlanes );
46
+ return this.setupDefault( intersectionPlanes, unionPlanes );
44
47
 
45
48
  }
46
49
 
47
50
  }
48
51
 
49
- setupAlphaToCoverage( planes, numClippingPlanes, numUnionClippingPlanes ) {
52
+ setupAlphaToCoverage( intersectionPlanes, unionPlanes ) {
50
53
 
51
54
  return Fn( () => {
52
55
 
53
- const clippingPlanes = uniformArray( planes );
56
+ const distanceToPlane = float().toVar( 'distanceToPlane' );
57
+ const distanceGradient = float().toVar( 'distanceToGradient' );
54
58
 
55
- const distanceToPlane = property( 'float', 'distanceToPlane' );
56
- const distanceGradient = property( 'float', 'distanceToGradient' );
59
+ const clipOpacity = float( 1 ).toVar( 'clipOpacity' );
57
60
 
58
- const clipOpacity = property( 'float', 'clipOpacity' );
61
+ const numUnionPlanes = unionPlanes.length;
59
62
 
60
- clipOpacity.assign( 1 );
63
+ if ( ! this.hardwareClipping && numUnionPlanes > 0 ) {
61
64
 
62
- let plane;
65
+ const clippingPlanes = uniformArray( unionPlanes );
63
66
 
64
- Loop( numUnionClippingPlanes, ( { i } ) => {
67
+ Loop( numUnionPlanes, ( { i } ) => {
65
68
 
66
- plane = clippingPlanes.element( i );
69
+ const plane = clippingPlanes.element( i );
67
70
 
68
- distanceToPlane.assign( positionView.dot( plane.xyz ).negate().add( plane.w ) );
69
- distanceGradient.assign( distanceToPlane.fwidth().div( 2.0 ) );
71
+ distanceToPlane.assign( positionView.dot( plane.xyz ).negate().add( plane.w ) );
72
+ distanceGradient.assign( distanceToPlane.fwidth().div( 2.0 ) );
70
73
 
71
- clipOpacity.mulAssign( smoothstep( distanceGradient.negate(), distanceGradient, distanceToPlane ) );
74
+ clipOpacity.mulAssign( smoothstep( distanceGradient.negate(), distanceGradient, distanceToPlane ) );
72
75
 
73
- clipOpacity.equal( 0.0 ).discard();
76
+ } );
74
77
 
75
- } );
78
+ }
76
79
 
77
- if ( numUnionClippingPlanes < numClippingPlanes ) {
80
+ const numIntersectionPlanes = intersectionPlanes.length;
78
81
 
79
- const unionClipOpacity = property( 'float', 'unionclipOpacity' );
82
+ if ( numIntersectionPlanes > 0 ) {
80
83
 
81
- unionClipOpacity.assign( 1 );
84
+ const clippingPlanes = uniformArray( intersectionPlanes );
85
+ const intersectionClipOpacity = float( 1 ).toVar( 'intersectionClipOpacity' );
82
86
 
83
- Loop( { start: numUnionClippingPlanes, end: numClippingPlanes }, ( { i } ) => {
87
+ Loop( numIntersectionPlanes, ( { i } ) => {
84
88
 
85
- plane = clippingPlanes.element( i );
89
+ const plane = clippingPlanes.element( i );
86
90
 
87
91
  distanceToPlane.assign( positionView.dot( plane.xyz ).negate().add( plane.w ) );
88
92
  distanceGradient.assign( distanceToPlane.fwidth().div( 2.0 ) );
89
93
 
90
- unionClipOpacity.mulAssign( smoothstep( distanceGradient.negate(), distanceGradient, distanceToPlane ).oneMinus() );
94
+ intersectionClipOpacity.mulAssign( smoothstep( distanceGradient.negate(), distanceGradient, distanceToPlane ).oneMinus() );
91
95
 
92
96
  } );
93
97
 
94
- clipOpacity.mulAssign( unionClipOpacity.oneMinus() );
98
+ clipOpacity.mulAssign( intersectionClipOpacity.oneMinus() );
95
99
 
96
100
  }
97
101
 
@@ -103,30 +107,35 @@ class ClippingNode extends Node {
103
107
 
104
108
  }
105
109
 
106
- setupDefault( planes, numClippingPlanes, numUnionClippingPlanes ) {
110
+ setupDefault( intersectionPlanes, unionPlanes ) {
107
111
 
108
112
  return Fn( () => {
109
113
 
110
- const clippingPlanes = uniformArray( planes );
114
+ const numUnionPlanes = unionPlanes.length;
111
115
 
112
- let plane;
116
+ if ( ! this.hardwareClipping && numUnionPlanes > 0 ) {
113
117
 
114
- Loop( numUnionClippingPlanes, ( { i } ) => {
118
+ const clippingPlanes = uniformArray( unionPlanes );
115
119
 
116
- plane = clippingPlanes.element( i );
117
- positionView.dot( plane.xyz ).greaterThan( plane.w ).discard();
120
+ Loop( numUnionPlanes, ( { i } ) => {
118
121
 
119
- } );
122
+ const plane = clippingPlanes.element( i );
123
+ positionView.dot( plane.xyz ).greaterThan( plane.w ).discard();
124
+
125
+ } );
120
126
 
121
- if ( numUnionClippingPlanes < numClippingPlanes ) {
127
+ }
122
128
 
123
- const clipped = property( 'bool', 'clipped' );
129
+ const numIntersectionPlanes = intersectionPlanes.length;
124
130
 
125
- clipped.assign( true );
131
+ if ( numIntersectionPlanes > 0 ) {
126
132
 
127
- Loop( { start: numUnionClippingPlanes, end: numClippingPlanes }, ( { i } ) => {
133
+ const clippingPlanes = uniformArray( intersectionPlanes );
134
+ const clipped = bool( true ).toVar( 'clipped' );
128
135
 
129
- plane = clippingPlanes.element( i );
136
+ Loop( numIntersectionPlanes, ( { i } ) => {
137
+
138
+ const plane = clippingPlanes.element( i );
130
139
  clipped.assign( positionView.dot( plane.xyz ).greaterThan( plane.w ).and( clipped ) );
131
140
 
132
141
  } );
@@ -139,13 +148,38 @@ class ClippingNode extends Node {
139
148
 
140
149
  }
141
150
 
151
+ setupHardwareClipping( unionPlanes, builder ) {
152
+
153
+ const numUnionPlanes = unionPlanes.length;
154
+
155
+ builder.enableHardwareClipping( numUnionPlanes );
156
+
157
+ return Fn( () => {
158
+
159
+ const clippingPlanes = uniformArray( unionPlanes );
160
+ const hw_clip_distances = builtin( builder.getClipDistance() );
161
+
162
+ Loop( numUnionPlanes, ( { i } ) => {
163
+
164
+ const plane = clippingPlanes.element( i );
165
+
166
+ const distance = positionView.dot( plane.xyz ).sub( plane.w ).negate();
167
+ hw_clip_distances.element( i ).assign( distance );
168
+
169
+ } );
170
+
171
+ } )();
172
+
173
+ }
174
+
142
175
  }
143
176
 
144
177
  ClippingNode.ALPHA_TO_COVERAGE = 'alphaToCoverage';
145
178
  ClippingNode.DEFAULT = 'default';
179
+ ClippingNode.HARDWARE = 'hardware';
146
180
 
147
181
  export default ClippingNode;
148
182
 
149
183
  export const clipping = () => nodeObject( new ClippingNode() );
150
-
151
184
  export const clippingAlpha = () => nodeObject( new ClippingNode( ClippingNode.ALPHA_TO_COVERAGE ) );
185
+ export const hardwareClipping = () => nodeObject( new ClippingNode( ClippingNode.HARDWARE ) );
@@ -20,11 +20,13 @@ class InstanceNode extends Node {
20
20
 
21
21
  }
22
22
 
23
- constructor( instanceMesh ) {
23
+ constructor( count, instanceMatrix, instanceColor ) {
24
24
 
25
25
  super( 'void' );
26
26
 
27
- this.instanceMesh = instanceMesh;
27
+ this.count = count;
28
+ this.instanceMatrix = instanceMatrix;
29
+ this.instanceColor = instanceColor;
28
30
 
29
31
  this.instanceMatrixNode = null;
30
32
 
@@ -39,28 +41,25 @@ class InstanceNode extends Node {
39
41
 
40
42
  setup( builder ) {
41
43
 
42
- let instanceMatrixNode = this.instanceMatrixNode;
43
- let instanceColorNode = this.instanceColorNode;
44
+ const { count, instanceMatrix, instanceColor } = this;
44
45
 
45
- const instanceMesh = this.instanceMesh;
46
+ let { instanceMatrixNode, instanceColorNode } = this;
46
47
 
47
48
  if ( instanceMatrixNode === null ) {
48
49
 
49
- const instanceAttribute = instanceMesh.instanceMatrix;
50
-
51
50
  // Both WebGPU and WebGL backends have UBO max limited to 64kb. Matrix count number bigger than 1000 ( 16 * 4 * 1000 = 64kb ) will fallback to attribute.
52
51
 
53
- if ( instanceMesh.count <= 1000 ) {
52
+ if ( count <= 1000 ) {
54
53
 
55
- instanceMatrixNode = buffer( instanceAttribute.array, 'mat4', Math.max( instanceMesh.count, 1 ) ).element( instanceIndex );
54
+ instanceMatrixNode = buffer( instanceMatrix.array, 'mat4', Math.max( count, 1 ) ).element( instanceIndex );
56
55
 
57
56
  } else {
58
57
 
59
- const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
58
+ const buffer = new InstancedInterleavedBuffer( instanceMatrix.array, 16, 1 );
60
59
 
61
60
  this.buffer = buffer;
62
61
 
63
- const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
62
+ const bufferFn = instanceMatrix.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
64
63
 
65
64
  const instanceBuffers = [
66
65
  // F.Signature -> bufferAttribute( array, type, stride, offset )
@@ -78,13 +77,11 @@ class InstanceNode extends Node {
78
77
 
79
78
  }
80
79
 
81
- const instanceColorAttribute = instanceMesh.instanceColor;
82
-
83
- if ( instanceColorAttribute && instanceColorNode === null ) {
80
+ if ( instanceColor && instanceColorNode === null ) {
84
81
 
85
- const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
82
+ const buffer = new InstancedBufferAttribute( instanceColor.array, 3 );
86
83
 
87
- const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
84
+ const bufferFn = instanceColor.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
88
85
 
89
86
  this.bufferColor = buffer;
90
87
 
@@ -123,15 +120,15 @@ class InstanceNode extends Node {
123
120
 
124
121
  update( /*frame*/ ) {
125
122
 
126
- if ( this.instanceMesh.instanceMatrix.usage !== DynamicDrawUsage && this.buffer != null && this.instanceMesh.instanceMatrix.version !== this.buffer.version ) {
123
+ if ( this.instanceMatrix.usage !== DynamicDrawUsage && this.buffer != null && this.instanceMatrix.version !== this.buffer.version ) {
127
124
 
128
- this.buffer.version = this.instanceMesh.instanceMatrix.version;
125
+ this.buffer.version = this.instanceMatrix.version;
129
126
 
130
127
  }
131
128
 
132
- if ( this.instanceMesh.instanceColor && this.instanceMesh.instanceColor.usage !== DynamicDrawUsage && this.bufferColor != null && this.instanceMesh.instanceColor.version !== this.bufferColor.version ) {
129
+ if ( this.instanceColor && this.instanceColor.usage !== DynamicDrawUsage && this.bufferColor != null && this.instanceColor.version !== this.bufferColor.version ) {
133
130
 
134
- this.bufferColor.version = this.instanceMesh.instanceColor.version;
131
+ this.bufferColor.version = this.instanceColor.version;
135
132
 
136
133
  }
137
134
 
@@ -0,0 +1,26 @@
1
+ import InstanceNode from './InstanceNode.js';
2
+ import { nodeProxy } from '../tsl/TSLBase.js';
3
+
4
+ class InstancedMeshNode extends InstanceNode {
5
+
6
+ static get type() {
7
+
8
+ return 'InstancedMeshNode';
9
+
10
+ }
11
+
12
+ constructor( instanceMesh ) {
13
+
14
+ const { count, instanceMatrix, instanceColor } = instanceMesh;
15
+
16
+ super( count, instanceMatrix, instanceColor );
17
+
18
+ this.instanceMesh = instanceMesh;
19
+
20
+ }
21
+
22
+ }
23
+
24
+ export default InstancedMeshNode;
25
+
26
+ export const instancedMesh = /*@__PURE__*/ nodeProxy( InstancedMeshNode );
@@ -2,6 +2,7 @@ import { uniform } from '../core/UniformNode.js';
2
2
  import { renderGroup } from '../core/UniformGroupNode.js';
3
3
  import { Vector3 } from '../../math/Vector3.js';
4
4
  import { cameraViewMatrix } from './Camera.js';
5
+ import { positionWorld } from './Position.js';
5
6
 
6
7
  let uniformsLib;
7
8
 
@@ -17,6 +18,37 @@ function getLightData( light ) {
17
18
 
18
19
  }
19
20
 
21
+ export function lightShadowMatrix( light ) {
22
+
23
+ const data = getLightData( light );
24
+
25
+ return data.shadowMatrix || ( data.shadowMatrix = uniform( 'mat4' ).setGroup( renderGroup ).onRenderUpdate( () => {
26
+
27
+ light.shadow.updateMatrices( light );
28
+
29
+ return light.shadow.matrix;
30
+
31
+ } ) );
32
+
33
+ }
34
+
35
+ export function lightProjectionUV( light ) {
36
+
37
+ const data = getLightData( light );
38
+
39
+ if ( data.projectionUV === undefined ) {
40
+
41
+ const spotLightCoord = lightShadowMatrix( light ).mul( positionWorld );
42
+
43
+ data.projectionUV = spotLightCoord.xyz.div( spotLightCoord.w );
44
+
45
+
46
+ }
47
+
48
+ return data.projectionUV;
49
+
50
+ }
51
+
20
52
  export function lightPosition( light ) {
21
53
 
22
54
  const data = getLightData( light );
@@ -2,7 +2,8 @@ import BufferNode from './BufferNode.js';
2
2
  import { bufferAttribute } from './BufferAttributeNode.js';
3
3
  import { nodeObject, varying } from '../tsl/TSLBase.js';
4
4
  import { storageElement } from '../utils/StorageArrayElementNode.js';
5
- import { GPUBufferBindingType } from '../../renderers/webgpu/utils/WebGPUConstants.js';
5
+ import { NodeAccess } from '../core/constants.js';
6
+ import { getTypeFromLength } from '../core/NodeUtils.js';
6
7
 
7
8
  class StorageBufferNode extends BufferNode {
8
9
 
@@ -12,16 +13,23 @@ class StorageBufferNode extends BufferNode {
12
13
 
13
14
  }
14
15
 
15
- constructor( value, bufferType, bufferCount = 0 ) {
16
+ constructor( value, bufferType = null, bufferCount = 0 ) {
17
+
18
+ if ( bufferType === null && ( value.isStorageBufferAttribute || value.isStorageInstancedBufferAttribute ) ) {
19
+
20
+ bufferType = getTypeFromLength( value.itemSize );
21
+ bufferCount = value.count;
22
+
23
+ }
16
24
 
17
25
  super( value, bufferType, bufferCount );
18
26
 
19
27
  this.isStorageBufferNode = true;
20
28
 
21
- this.access = GPUBufferBindingType.Storage;
29
+ this.access = NodeAccess.READ_WRITE;
22
30
  this.isAtomic = false;
31
+ this.isPBO = false;
23
32
 
24
- this.bufferObject = false;
25
33
  this.bufferCount = bufferCount;
26
34
 
27
35
  this._attribute = null;
@@ -76,14 +84,20 @@ class StorageBufferNode extends BufferNode {
76
84
 
77
85
  }
78
86
 
79
- setBufferObject( value ) {
87
+ setPBO( value ) {
80
88
 
81
- this.bufferObject = value;
89
+ this.isPBO = value;
82
90
 
83
91
  return this;
84
92
 
85
93
  }
86
94
 
95
+ getPBO() {
96
+
97
+ return this.isPBO;
98
+
99
+ }
100
+
87
101
  setAccess( value ) {
88
102
 
89
103
  this.access = value;
@@ -94,7 +108,7 @@ class StorageBufferNode extends BufferNode {
94
108
 
95
109
  toReadOnly() {
96
110
 
97
- return this.setAccess( GPUBufferBindingType.ReadOnlyStorage );
111
+ return this.setAccess( NodeAccess.READ_ONLY );
98
112
 
99
113
  }
100
114
 
@@ -164,6 +178,12 @@ class StorageBufferNode extends BufferNode {
164
178
 
165
179
  export default StorageBufferNode;
166
180
 
167
- // Read-Write Storage
168
181
  export const storage = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ) );
169
- export const storageObject = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ).setBufferObject( true ) );
182
+
183
+ export const storageObject = ( value, type, count ) => { // @deprecated, r171
184
+
185
+ console.warn( 'THREE.TSL: "storageObject()" is deprecated. Use "storage().setPBO( true )" instead.' );
186
+
187
+ return storage( value, type, count ).setPBO( true );
188
+
189
+ };
@@ -1,6 +1,6 @@
1
1
  import TextureNode from './TextureNode.js';
2
2
  import { nodeProxy } from '../tsl/TSLBase.js';
3
- import { GPUStorageTextureAccess } from '../../renderers/webgpu/utils/WebGPUConstants.js';
3
+ import { NodeAccess } from '../core/constants.js';
4
4
 
5
5
  class StorageTextureNode extends TextureNode {
6
6
 
@@ -18,7 +18,7 @@ class StorageTextureNode extends TextureNode {
18
18
 
19
19
  this.isStorageTextureNode = true;
20
20
 
21
- this.access = GPUStorageTextureAccess.WriteOnly;
21
+ this.access = NodeAccess.WRITE_ONLY;
22
22
 
23
23
  }
24
24
 
@@ -62,15 +62,21 @@ class StorageTextureNode extends TextureNode {
62
62
 
63
63
  }
64
64
 
65
+ toReadWrite() {
66
+
67
+ return this.setAccess( NodeAccess.READ_WRITE );
68
+
69
+ }
70
+
65
71
  toReadOnly() {
66
72
 
67
- return this.setAccess( GPUStorageTextureAccess.ReadOnly );
73
+ return this.setAccess( NodeAccess.READ_ONLY );
68
74
 
69
75
  }
70
76
 
71
77
  toWriteOnly() {
72
78
 
73
- return this.setAccess( GPUStorageTextureAccess.WriteOnly );
79
+ return this.setAccess( NodeAccess.WRITE_ONLY );
74
80
 
75
81
  }
76
82
 
@@ -126,7 +126,7 @@ class TextureNode extends UniformNode {
126
126
 
127
127
  const texture = this.value;
128
128
 
129
- if ( builder.isFlipY() && ( texture.isRenderTargetTexture === true || texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {
129
+ if ( builder.isFlipY() && ( ( texture.image instanceof ImageBitmap && texture.flipY === true ) || texture.isRenderTargetTexture === true || texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {
130
130
 
131
131
  if ( this.sampler ) {
132
132
 
@@ -7,6 +7,7 @@ import NodeCache from './NodeCache.js';
7
7
  import ParameterNode from './ParameterNode.js';
8
8
  import FunctionNode from '../code/FunctionNode.js';
9
9
  import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
10
+ import { getTypeFromLength } from './NodeUtils.js';
10
11
  import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js';
11
12
 
12
13
  import {
@@ -35,14 +36,6 @@ import { IntType, UnsignedIntType, LinearFilter, LinearMipmapNearestFilter, Near
35
36
 
36
37
  const rendererCache = new WeakMap();
37
38
 
38
- const typeFromLength = new Map( [
39
- [ 2, 'vec2' ],
40
- [ 3, 'vec3' ],
41
- [ 4, 'vec4' ],
42
- [ 9, 'mat3' ],
43
- [ 16, 'mat4' ]
44
- ] );
45
-
46
39
  const typeFromArray = new Map( [
47
40
  [ Int8Array, 'int' ],
48
41
  [ Int16Array, 'int' ],
@@ -708,7 +701,7 @@ class NodeBuilder {
708
701
 
709
702
  if ( length === 1 ) return componentType;
710
703
 
711
- const baseType = typeFromLength.get( length );
704
+ const baseType = getTypeFromLength( length );
712
705
  const prefix = componentType === 'float' ? '' : componentType[ 0 ];
713
706
 
714
707
  return prefix + baseType;
@@ -117,6 +117,34 @@ export function* getNodeChildren( node, toJSON = false ) {
117
117
 
118
118
  }
119
119
 
120
+ const typeFromLength = /*@__PURE__*/ new Map( [
121
+ [ 1, 'float' ],
122
+ [ 2, 'vec2' ],
123
+ [ 3, 'vec3' ],
124
+ [ 4, 'vec4' ],
125
+ [ 9, 'mat3' ],
126
+ [ 16, 'mat4' ]
127
+ ] );
128
+
129
+ export function getTypeFromLength( length ) {
130
+
131
+ return typeFromLength.get( length );
132
+
133
+ }
134
+
135
+ export function getLengthFromType( type ) {
136
+
137
+ if ( /float|int|uint/.test( type ) ) return 1;
138
+ if ( /vec2/.test( type ) ) return 2;
139
+ if ( /vec3/.test( type ) ) return 3;
140
+ if ( /vec4/.test( type ) ) return 4;
141
+ if ( /mat3/.test( type ) ) return 9;
142
+ if ( /mat4/.test( type ) ) return 16;
143
+
144
+ console.error( 'THREE.TSL: Unsupported type:', type );
145
+
146
+ }
147
+
120
148
  export function getValueType( value ) {
121
149
 
122
150
  if ( value === undefined || value === null ) return null;
@@ -22,6 +22,12 @@ export const NodeType = {
22
22
  MATRIX4: 'mat4'
23
23
  };
24
24
 
25
+ export const NodeAccess = {
26
+ READ_ONLY: 'readOnly',
27
+ WRITE_ONLY: 'writeOnly',
28
+ READ_WRITE: 'readWrite',
29
+ };
30
+
25
31
  export const defaultShaderStages = [ 'fragment', 'vertex' ];
26
32
  export const defaultBuildStages = [ 'setup', 'analyze', 'generate' ];
27
33
  export const shaderStages = [ ...defaultShaderStages, 'compute' ];
@@ -0,0 +1,99 @@
1
+ import { Fn, vec4 } from '../tsl/TSLBase.js';
2
+ import { mix, min, step } from '../math/MathNode.js';
3
+
4
+ export const blendBurn = /*@__PURE__*/ Fn( ( [ base, blend ] ) => {
5
+
6
+ return min( 1.0, base.oneMinus().div( blend ) ).oneMinus();
7
+
8
+ } ).setLayout( {
9
+ name: 'blendBurn',
10
+ type: 'vec3',
11
+ inputs: [
12
+ { name: 'base', type: 'vec3' },
13
+ { name: 'blend', type: 'vec3' }
14
+ ]
15
+ } );
16
+
17
+ export const blendDodge = /*@__PURE__*/ Fn( ( [ base, blend ] ) => {
18
+
19
+ return min( base.div( blend.oneMinus() ), 1.0 );
20
+
21
+ } ).setLayout( {
22
+ name: 'blendDodge',
23
+ type: 'vec3',
24
+ inputs: [
25
+ { name: 'base', type: 'vec3' },
26
+ { name: 'blend', type: 'vec3' }
27
+ ]
28
+ } );
29
+
30
+ export const blendScreen = /*@__PURE__*/ Fn( ( [ base, blend ] ) => {
31
+
32
+ return base.oneMinus().mul( blend.oneMinus() ).oneMinus();
33
+
34
+ } ).setLayout( {
35
+ name: 'blendScreen',
36
+ type: 'vec3',
37
+ inputs: [
38
+ { name: 'base', type: 'vec3' },
39
+ { name: 'blend', type: 'vec3' }
40
+ ]
41
+ } );
42
+
43
+ export const blendOverlay = /*@__PURE__*/ Fn( ( [ base, blend ] ) => {
44
+
45
+ return mix( base.mul( 2.0 ).mul( blend ), base.oneMinus().mul( 2.0 ).mul( blend.oneMinus() ).oneMinus(), step( 0.5, base ) );
46
+
47
+ } ).setLayout( {
48
+ name: 'blendOverlay',
49
+ type: 'vec3',
50
+ inputs: [
51
+ { name: 'base', type: 'vec3' },
52
+ { name: 'blend', type: 'vec3' }
53
+ ]
54
+ } );
55
+
56
+ export const blendColor = /*@__PURE__*/ Fn( ( [ base, blend ] ) => {
57
+
58
+ const outAlpha = blend.a.add( base.a.mul( blend.a.oneMinus() ) );
59
+
60
+ return vec4( blend.rgb.mul( blend.a ).add( base.rgb.mul( base.a ).mul( blend.a.oneMinus() ) ).div( outAlpha ), outAlpha );
61
+
62
+ } ).setLayout( {
63
+ name: 'blendColor',
64
+ type: 'vec4',
65
+ inputs: [
66
+ { name: 'base', type: 'vec4' },
67
+ { name: 'blend', type: 'vec4' }
68
+ ]
69
+ } );
70
+
71
+ // deprecated
72
+
73
+ export const burn = ( ...params ) => { // @deprecated, r171
74
+
75
+ console.warn( 'THREE.TSL: "burn" has been renamed. Use "blendBurn" instead.' );
76
+ return blendBurn( params );
77
+
78
+ };
79
+
80
+ export const dodge = ( ...params ) => { // @deprecated, r171
81
+
82
+ console.warn( 'THREE.TSL: "dodge" has been renamed. Use "blendDodge" instead.' );
83
+ return blendDodge( params );
84
+
85
+ };
86
+
87
+ export const screen = ( ...params ) => { // @deprecated, r171
88
+
89
+ console.warn( 'THREE.TSL: "screen" has been renamed. Use "blendScreen" instead.' );
90
+ return blendScreen( params );
91
+
92
+ };
93
+
94
+ export const overlay = ( ...params ) => { // @deprecated, r171
95
+
96
+ console.warn( 'THREE.TSL: "overlay" has been renamed. Use "blendOverlay" instead.' );
97
+ return blendOverlay( params );
98
+
99
+ };