super-three 0.170.0 → 0.170.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,6 +1,5 @@
1
1
  import Node from '../core/Node.js';
2
2
  import { NodeUpdateType } from '../core/constants.js';
3
- import { uniform } from '../core/UniformNode.js';
4
3
  import { float, vec2, vec3, vec4, If, int, Fn, nodeObject } from '../tsl/TSLBase.js';
5
4
  import { reference } from '../accessors/ReferenceNode.js';
6
5
  import { texture } from '../accessors/TextureNode.js';
@@ -13,17 +12,68 @@ import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
13
12
  import QuadMesh from '../../renderers/common/QuadMesh.js';
14
13
  import { Loop } from '../utils/LoopNode.js';
15
14
  import { screenCoordinate } from '../display/ScreenNode.js';
16
- import { HalfFloatType, LessCompare, RGFormat, VSMShadowMap, WebGPUCoordinateSystem } from '../../constants.js';
15
+ import { HalfFloatType, LessCompare, NoBlending, RGFormat, VSMShadowMap, WebGPUCoordinateSystem } from '../../constants.js';
17
16
  import { renderGroup } from '../core/UniformGroupNode.js';
18
- import { perspectiveDepthToLogarithmicDepth } from '../display/ViewportDepthNode.js';
17
+ import { viewZToLogarithmicDepth } from '../display/ViewportDepthNode.js';
18
+ import { objectPosition } from '../accessors/Object3DNode.js';
19
+ import { lightShadowMatrix } from '../accessors/Lights.js';
19
20
 
20
- const BasicShadowMap = Fn( ( { depthTexture, shadowCoord } ) => {
21
+ const shadowMaterialLib = /*@__PURE__*/ new WeakMap();
22
+ const shadowWorldPosition = /*@__PURE__*/ vec3().toVar( 'shadowWorldPosition' );
23
+
24
+ const linearDistance = /*@__PURE__*/ Fn( ( [ position, cameraNear, cameraFar ] ) => {
25
+
26
+ let dist = positionWorld.sub( position ).length();
27
+ dist = dist.sub( cameraNear ).div( cameraFar.sub( cameraNear ) );
28
+ dist = dist.saturate(); // clamp to [ 0, 1 ]
29
+
30
+ return dist;
31
+
32
+ } );
33
+
34
+ const linearShadowDistance = ( light ) => {
35
+
36
+ const camera = light.shadow.camera;
37
+
38
+ const nearDistance = reference( 'near', 'float', camera ).setGroup( renderGroup );
39
+ const farDistance = reference( 'far', 'float', camera ).setGroup( renderGroup );
40
+
41
+ const referencePosition = objectPosition( light );
42
+
43
+ return linearDistance( referencePosition, nearDistance, farDistance );
44
+
45
+ };
46
+
47
+ const getShadowMaterial = ( light ) => {
48
+
49
+ let material = shadowMaterialLib.get( light );
50
+
51
+ if ( material === undefined ) {
52
+
53
+ const depthNode = light.isPointLight ? linearShadowDistance( light ) : null;
54
+
55
+ material = new NodeMaterial();
56
+ material.colorNode = vec4( 0, 0, 0, 1 );
57
+ material.depthNode = depthNode;
58
+ material.isShadowNodeMaterial = true; // Use to avoid other overrideMaterial override material.colorNode unintentionally when using material.shadowNode
59
+ material.blending = NoBlending;
60
+ material.name = 'ShadowMaterial';
61
+
62
+ shadowMaterialLib.set( light, material );
63
+
64
+ }
65
+
66
+ return material;
67
+
68
+ };
69
+
70
+ export const BasicShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord } ) => {
21
71
 
22
72
  return texture( depthTexture, shadowCoord.xy ).compare( shadowCoord.z );
23
73
 
24
74
  } );
25
75
 
26
- const PCFShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
76
+ export const PCFShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, shadow } ) => {
27
77
 
28
78
  const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
29
79
 
@@ -62,7 +112,7 @@ const PCFShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
62
112
 
63
113
  } );
64
114
 
65
- const PCFSoftShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
115
+ export const PCFSoftShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, shadow } ) => {
66
116
 
67
117
  const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
68
118
 
@@ -120,7 +170,7 @@ const PCFSoftShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
120
170
 
121
171
  // VSM
122
172
 
123
- const VSMShadowMapNode = Fn( ( { depthTexture, shadowCoord } ) => {
173
+ export const VSMShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord } ) => {
124
174
 
125
175
  const occlusion = float( 1 ).toVar();
126
176
 
@@ -142,7 +192,7 @@ const VSMShadowMapNode = Fn( ( { depthTexture, shadowCoord } ) => {
142
192
 
143
193
  } );
144
194
 
145
- const VSMPassVertical = Fn( ( { samples, radius, size, shadowPass } ) => {
195
+ const VSMPassVertical = /*@__PURE__*/ Fn( ( { samples, radius, size, shadowPass } ) => {
146
196
 
147
197
  const mean = float( 0 ).toVar();
148
198
  const squaredMean = float( 0 ).toVar();
@@ -168,7 +218,7 @@ const VSMPassVertical = Fn( ( { samples, radius, size, shadowPass } ) => {
168
218
 
169
219
  } );
170
220
 
171
- const VSMPassHorizontal = Fn( ( { samples, radius, size, shadowPass } ) => {
221
+ const VSMPassHorizontal = /*@__PURE__*/ Fn( ( { samples, radius, size, shadowPass } ) => {
172
222
 
173
223
  const mean = float( 0 ).toVar();
174
224
  const squaredMean = float( 0 ).toVar();
@@ -194,11 +244,10 @@ const VSMPassHorizontal = Fn( ( { samples, radius, size, shadowPass } ) => {
194
244
 
195
245
  } );
196
246
 
197
- const _shadowFilterLib = [ BasicShadowMap, PCFShadowMap, PCFSoftShadowMap, VSMShadowMapNode ];
247
+ const _shadowFilterLib = [ BasicShadowFilter, PCFShadowFilter, PCFSoftShadowFilter, VSMShadowFilter ];
198
248
 
199
249
  //
200
250
 
201
- let _overrideMaterial = null;
202
251
  const _quadMesh = /*@__PURE__*/ new QuadMesh();
203
252
 
204
253
  class ShadowNode extends Node {
@@ -231,20 +280,79 @@ class ShadowNode extends Node {
231
280
 
232
281
  }
233
282
 
234
- setupShadow( builder ) {
283
+ setupShadowFilter( builder, { filterFn, depthTexture, shadowCoord, shadow } ) {
284
+
285
+ const frustumTest = shadowCoord.x.greaterThanEqual( 0 )
286
+ .and( shadowCoord.x.lessThanEqual( 1 ) )
287
+ .and( shadowCoord.y.greaterThanEqual( 0 ) )
288
+ .and( shadowCoord.y.lessThanEqual( 1 ) )
289
+ .and( shadowCoord.z.lessThanEqual( 1 ) );
290
+
291
+ const shadowNode = filterFn( { depthTexture, shadowCoord, shadow } );
292
+
293
+ return frustumTest.select( shadowNode, float( 1 ) );
294
+
295
+ }
296
+
297
+ setupShadowCoord( builder, shadowPosition ) {
235
298
 
236
- const { object, renderer } = builder;
299
+ const { shadow } = this;
300
+ const { renderer } = builder;
301
+
302
+ const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
303
+
304
+ let shadowCoord = shadowPosition;
305
+ let coordZ;
306
+
307
+ if ( shadow.camera.isOrthographicCamera || renderer.logarithmicDepthBuffer !== true ) {
308
+
309
+ shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
310
+
311
+ coordZ = shadowCoord.z;
312
+
313
+ if ( renderer.coordinateSystem === WebGPUCoordinateSystem ) {
314
+
315
+ coordZ = coordZ.mul( 2 ).sub( 1 ); // WebGPU: Conversion [ 0, 1 ] to [ - 1, 1 ]
316
+
317
+ }
237
318
 
238
- if ( _overrideMaterial === null ) {
319
+ } else {
239
320
 
240
- _overrideMaterial = new NodeMaterial();
241
- _overrideMaterial.fragmentNode = vec4( 0, 0, 0, 1 );
242
- _overrideMaterial.isShadowNodeMaterial = true; // Use to avoid other overrideMaterial override material.fragmentNode unintentionally when using material.shadowNode
243
- _overrideMaterial.name = 'ShadowMaterial';
321
+ const w = shadowCoord.w;
322
+ shadowCoord = shadowCoord.xy.div( w ); // <-- Only divide X/Y coords since we don't need Z
323
+
324
+ // The normally available "cameraNear" and "cameraFar" nodes cannot be used here because they do not get
325
+ // updated to use the shadow camera. So, we have to declare our own "local" ones here.
326
+ // TODO: How do we get the cameraNear/cameraFar nodes to use the shadow camera so we don't have to declare local ones here?
327
+ const cameraNearLocal = reference( 'near', 'float', shadow.camera ).setGroup( renderGroup );
328
+ const cameraFarLocal = reference( 'far', 'float', shadow.camera ).setGroup( renderGroup );
329
+
330
+ coordZ = viewZToLogarithmicDepth( w.negate(), cameraNearLocal, cameraFarLocal );
244
331
 
245
332
  }
246
333
 
247
- const shadow = this.shadow;
334
+ shadowCoord = vec3(
335
+ shadowCoord.x,
336
+ shadowCoord.y.oneMinus(), // follow webgpu standards
337
+ coordZ.add( bias )
338
+ );
339
+
340
+ return shadowCoord;
341
+
342
+ }
343
+
344
+ getShadowFilterFn( type ) {
345
+
346
+ return _shadowFilterLib[ type ];
347
+
348
+ }
349
+
350
+ setupShadow( builder ) {
351
+
352
+ const { renderer } = builder;
353
+
354
+ const { light, shadow } = this;
355
+
248
356
  const shadowMapType = renderer.shadowMap.type;
249
357
 
250
358
  const depthTexture = new DepthTexture( shadow.mapSize.width, shadow.mapSize.height );
@@ -284,79 +392,77 @@ class ShadowNode extends Node {
284
392
  //
285
393
 
286
394
  const shadowIntensity = reference( 'intensity', 'float', shadow ).setGroup( renderGroup );
287
- const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
288
395
  const normalBias = reference( 'normalBias', 'float', shadow ).setGroup( renderGroup );
289
396
 
290
- const position = object.material.shadowPositionNode || positionWorld;
397
+ const shadowPosition = lightShadowMatrix( light ).mul( shadowWorldPosition.add( transformedNormalWorld.mul( normalBias ) ) );
398
+ const shadowCoord = this.setupShadowCoord( builder, shadowPosition );
291
399
 
292
- let shadowCoord = uniform( shadow.matrix ).setGroup( renderGroup ).mul( position.add( transformedNormalWorld.mul( normalBias ) ) );
400
+ //
293
401
 
294
- let coordZ;
402
+ const filterFn = shadow.filterNode || this.getShadowFilterFn( renderer.shadowMap.type ) || null;
295
403
 
296
- if ( shadow.camera.isOrthographicCamera || renderer.logarithmicDepthBuffer !== true ) {
404
+ if ( filterFn === null ) {
297
405
 
298
- shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
406
+ throw new Error( 'THREE.WebGPURenderer: Shadow map type not supported yet.' );
299
407
 
300
- coordZ = shadowCoord.z;
408
+ }
301
409
 
302
- if ( renderer.coordinateSystem === WebGPUCoordinateSystem ) {
410
+ const shadowDepthTexture = ( shadowMapType === VSMShadowMap ) ? this.vsmShadowMapHorizontal.texture : depthTexture;
303
411
 
304
- coordZ = coordZ.mul( 2 ).sub( 1 ); // WebGPU: Conversion [ 0, 1 ] to [ - 1, 1 ]
412
+ const shadowNode = this.setupShadowFilter( builder, { filterFn, shadowTexture: shadowMap.texture, depthTexture: shadowDepthTexture, shadowCoord, shadow } );
305
413
 
306
- }
414
+ const shadowColor = texture( shadowMap.texture, shadowCoord );
415
+ const shadowOutput = mix( 1, shadowNode.rgb.mix( shadowColor, 1 ), shadowIntensity.mul( shadowColor.a ) ).toVar();
307
416
 
308
- } else {
417
+ this.shadowMap = shadowMap;
418
+ this.shadow.map = shadowMap;
309
419
 
310
- const w = shadowCoord.w;
311
- shadowCoord = shadowCoord.xy.div( w ); // <-- Only divide X/Y coords since we don't need Z
420
+ return shadowOutput;
312
421
 
313
- // The normally available "cameraNear" and "cameraFar" nodes cannot be used here because they do not get
314
- // updated to use the shadow camera. So, we have to declare our own "local" ones here.
315
- // TODO: How do we get the cameraNear/cameraFar nodes to use the shadow camera so we don't have to declare local ones here?
316
- const cameraNearLocal = uniform( 'float' ).onRenderUpdate( () => shadow.camera.near );
317
- const cameraFarLocal = uniform( 'float' ).onRenderUpdate( () => shadow.camera.far );
422
+ }
318
423
 
319
- coordZ = perspectiveDepthToLogarithmicDepth( w, cameraNearLocal, cameraFarLocal );
424
+ setup( builder ) {
320
425
 
321
- }
426
+ if ( builder.renderer.shadowMap.enabled === false ) return;
322
427
 
323
- shadowCoord = vec3(
324
- shadowCoord.x,
325
- shadowCoord.y.oneMinus(), // follow webgpu standards
326
- coordZ.add( bias )
327
- );
428
+ return Fn( ( { material } ) => {
328
429
 
329
- const frustumTest = shadowCoord.x.greaterThanEqual( 0 )
330
- .and( shadowCoord.x.lessThanEqual( 1 ) )
331
- .and( shadowCoord.y.greaterThanEqual( 0 ) )
332
- .and( shadowCoord.y.lessThanEqual( 1 ) )
333
- .and( shadowCoord.z.lessThanEqual( 1 ) );
430
+ shadowWorldPosition.assign( material.shadowPositionNode || positionWorld );
334
431
 
335
- //
432
+ let node = this._node;
336
433
 
337
- const filterFn = shadow.filterNode || _shadowFilterLib[ renderer.shadowMap.type ] || null;
434
+ if ( node === null ) {
338
435
 
339
- if ( filterFn === null ) {
436
+ this._node = node = this.setupShadow( builder );
340
437
 
341
- throw new Error( 'THREE.WebGPURenderer: Shadow map type not supported yet.' );
438
+ }
342
439
 
343
- }
440
+ if ( builder.material.shadowNode ) { // @deprecated, r171
344
441
 
345
- const shadowColor = texture( shadowMap.texture, shadowCoord );
346
- const shadowNode = frustumTest.select( filterFn( { depthTexture: ( shadowMapType === VSMShadowMap ) ? this.vsmShadowMapHorizontal.texture : depthTexture, shadowCoord, shadow } ), float( 1 ) );
442
+ console.warn( 'THREE.NodeMaterial: ".shadowNode" is deprecated. Use ".castShadowNode" instead.' );
347
443
 
348
- this.shadowMap = shadowMap;
349
- this.shadow.map = shadowMap;
444
+ }
445
+
446
+ if ( builder.material.receivedShadowNode ) {
447
+
448
+ node = builder.material.receivedShadowNode( node );
449
+
450
+ }
350
451
 
351
- return mix( 1, shadowNode.rgb.mix( shadowColor, 1 ), shadowIntensity.mul( shadowColor.a ) );
452
+ return node;
453
+
454
+ } )();
352
455
 
353
456
  }
354
457
 
355
- setup( builder ) {
458
+ renderShadow( frame ) {
356
459
 
357
- if ( builder.renderer.shadowMap.enabled === false ) return;
460
+ const { shadow, shadowMap } = this;
461
+ const { renderer, scene } = frame;
358
462
 
359
- return this._node !== null ? this._node : ( this._node = this.setupShadow( builder ) );
463
+ shadowMap.setSize( shadow.mapSize.width, shadow.mapSize.height );
464
+
465
+ renderer.render( scene, shadow.camera );
360
466
 
361
467
  }
362
468
 
@@ -372,15 +478,15 @@ class ShadowNode extends Node {
372
478
 
373
479
  const currentOverrideMaterial = scene.overrideMaterial;
374
480
 
375
- scene.overrideMaterial = _overrideMaterial;
376
-
377
- shadowMap.setSize( shadow.mapSize.width, shadow.mapSize.height );
481
+ scene.overrideMaterial = getShadowMaterial( light );
378
482
 
379
- shadow.updateMatrices( light );
380
483
  shadow.camera.layers.mask = camera.layers.mask;
381
484
 
382
485
  const currentRenderTarget = renderer.getRenderTarget();
383
486
  const currentRenderObjectFunction = renderer.getRenderObjectFunction();
487
+ const currentMRT = renderer.getMRT();
488
+
489
+ renderer.setMRT( null );
384
490
 
385
491
  renderer.setRenderObjectFunction( ( object, ...params ) => {
386
492
 
@@ -393,7 +499,8 @@ class ShadowNode extends Node {
393
499
  } );
394
500
 
395
501
  renderer.setRenderTarget( shadowMap );
396
- renderer.render( scene, shadow.camera );
502
+
503
+ this.renderShadow( frame );
397
504
 
398
505
  renderer.setRenderObjectFunction( currentRenderObjectFunction );
399
506
 
@@ -407,6 +514,8 @@ class ShadowNode extends Node {
407
514
 
408
515
  renderer.setRenderTarget( currentRenderTarget );
409
516
 
517
+ renderer.setMRT( currentMRT );
518
+
410
519
  scene.overrideMaterial = currentOverrideMaterial;
411
520
 
412
521
  }
@@ -4,7 +4,8 @@ import { uniform } from '../core/UniformNode.js';
4
4
  import { smoothstep } from '../math/MathNode.js';
5
5
  import { positionView } from '../accessors/Position.js';
6
6
  import { renderGroup } from '../core/UniformGroupNode.js';
7
- import { lightViewPosition, lightTargetDirection } from '../accessors/Lights.js';
7
+ import { lightViewPosition, lightTargetDirection, lightProjectionUV } from '../accessors/Lights.js';
8
+ import { texture } from '../accessors/TextureNode.js';
8
9
 
9
10
  class SpotLightNode extends AnalyticLightNode {
10
11
 
@@ -70,7 +71,18 @@ class SpotLightNode extends AnalyticLightNode {
70
71
  decayExponent: decayExponentNode
71
72
  } );
72
73
 
73
- const lightColor = colorNode.mul( spotAttenuation ).mul( lightAttenuation );
74
+ let lightColor = colorNode.mul( spotAttenuation ).mul( lightAttenuation );
75
+
76
+ if ( light.map ) {
77
+
78
+ const spotLightCoord = lightProjectionUV( light );
79
+ const projectedTexture = texture( light.map, spotLightCoord.xy ).onRenderUpdate( () => light.map );
80
+
81
+ const inSpotLightMap = spotLightCoord.mul( 2. ).sub( 1. ).abs().lessThan( 1. ).all();
82
+
83
+ lightColor = inSpotLightMap.select( lightColor.mul( projectedTexture ), lightColor );
84
+
85
+ }
74
86
 
75
87
  const reflectedLight = builder.context.reflectedLight;
76
88
 
@@ -130,4 +130,12 @@ class RTTNode extends TextureNode {
130
130
  export default RTTNode;
131
131
 
132
132
  export const rtt = ( node, ...params ) => nodeObject( new RTTNode( nodeObject( node ), ...params ) );
133
- export const convertToTexture = ( node, ...params ) => node.isTextureNode ? node : rtt( node, ...params );
133
+
134
+ export const convertToTexture = ( node, ...params ) => {
135
+
136
+ if ( node.isTextureNode ) return node;
137
+ if ( node.isPassNode ) return node.getTextureNode();
138
+
139
+ return rtt( node, ...params );
140
+
141
+ };
@@ -33,7 +33,7 @@ class StorageArrayElementNode extends ArrayElementNode {
33
33
 
34
34
  if ( builder.isAvailable( 'storageBuffer' ) === false ) {
35
35
 
36
- if ( this.node.bufferObject === true ) {
36
+ if ( this.node.isPBO === true ) {
37
37
 
38
38
  builder.setupPBO( this.node );
39
39
 
@@ -55,7 +55,7 @@ class StorageArrayElementNode extends ArrayElementNode {
55
55
 
56
56
  if ( builder.isAvailable( 'storageBuffer' ) === false ) {
57
57
 
58
- if ( this.node.bufferObject === true && isAssignContext !== true ) {
58
+ if ( this.node.isPBO === true && isAssignContext !== true && ( this.node.value.isInstancedBufferAttribute || builder.shaderStage !== 'compute' ) ) {
59
59
 
60
60
  snippet = builder.generatePBO( this );
61
61