super-three 0.169.1 → 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 (255) hide show
  1. package/build/three.cjs +24628 -24228
  2. package/build/three.core.js +37002 -0
  3. package/build/three.core.min.js +6 -0
  4. package/build/three.module.js +10519 -47108
  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 +17071 -53583
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +17134 -53623
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +3 -3
  13. package/examples/jsm/animation/MMDAnimationHelper.js +2 -0
  14. package/examples/jsm/animation/MMDPhysics.js +2 -0
  15. package/examples/jsm/capabilities/WebGPU.js +1 -10
  16. package/examples/jsm/controls/ArcballControls.js +25 -21
  17. package/examples/jsm/controls/OrbitControls.js +41 -9
  18. package/examples/jsm/controls/PointerLockControls.js +2 -5
  19. package/examples/jsm/controls/TransformControls.js +22 -6
  20. package/examples/jsm/csm/CSM.js +2 -2
  21. package/examples/jsm/csm/CSMFrustum.js +7 -4
  22. package/examples/jsm/csm/CSMHelper.js +2 -0
  23. package/examples/jsm/csm/CSMShadowNode.js +437 -0
  24. package/examples/jsm/curves/NURBSCurve.js +34 -3
  25. package/examples/jsm/exporters/GLTFExporter.js +138 -71
  26. package/examples/jsm/exporters/KTX2Exporter.js +35 -12
  27. package/examples/jsm/exporters/MMDExporter.js +6 -0
  28. package/examples/jsm/exporters/USDZExporter.js +21 -3
  29. package/examples/jsm/geometries/DecalGeometry.js +70 -21
  30. package/examples/jsm/geometries/InstancedPointsGeometry.js +2 -0
  31. package/examples/jsm/helpers/TextureHelperGPU.js +175 -0
  32. package/examples/jsm/interactive/HTMLMesh.js +1 -0
  33. package/examples/jsm/lighting/TiledLighting.js +18 -0
  34. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  35. package/examples/jsm/lines/LineGeometry.js +25 -0
  36. package/examples/jsm/lines/LineMaterial.js +0 -1
  37. package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
  38. package/examples/jsm/lines/webgpu/Line2.js +2 -1
  39. package/examples/jsm/lines/webgpu/LineSegments2.js +2 -16
  40. package/examples/jsm/lines/webgpu/Wireframe.js +57 -0
  41. package/examples/jsm/loaders/3DMLoader.js +1 -0
  42. package/examples/jsm/loaders/3MFLoader.js +91 -0
  43. package/examples/jsm/loaders/FBXLoader.js +12 -2
  44. package/examples/jsm/loaders/GLTFLoader.js +2 -0
  45. package/examples/jsm/loaders/KTX2Loader.js +143 -49
  46. package/examples/jsm/loaders/LDrawLoader.js +22 -136
  47. package/examples/jsm/loaders/LottieLoader.js +1 -0
  48. package/examples/jsm/loaders/MMDLoader.js +3 -0
  49. package/examples/jsm/loaders/MaterialXLoader.js +2 -2
  50. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
  51. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
  52. package/examples/jsm/math/ColorSpaces.js +76 -0
  53. package/examples/jsm/misc/ProgressiveLightMap.js +52 -40
  54. package/examples/jsm/misc/ProgressiveLightMapGPU.js +293 -0
  55. package/examples/jsm/misc/VolumeSlice.js +1 -0
  56. package/examples/jsm/objects/InstancedPoints.js +2 -4
  57. package/examples/jsm/objects/LensflareMesh.js +4 -2
  58. package/examples/jsm/objects/SkyMesh.js +5 -3
  59. package/examples/jsm/objects/Water2Mesh.js +7 -3
  60. package/examples/jsm/objects/WaterMesh.js +12 -10
  61. package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
  62. package/examples/jsm/postprocessing/SSRPass.js +6 -0
  63. package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
  64. package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
  65. package/examples/jsm/shaders/FXAAShader.js +225 -224
  66. package/examples/jsm/transpiler/AST.js +2 -2
  67. package/examples/jsm/transpiler/GLSLDecoder.js +57 -25
  68. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  69. package/examples/jsm/transpiler/TSLEncoder.js +11 -6
  70. package/{src/nodes → examples/jsm/tsl}/display/AfterImageNode.js +18 -21
  71. package/{src/nodes → examples/jsm/tsl}/display/AnaglyphPassNode.js +2 -6
  72. package/{src/nodes → examples/jsm/tsl}/display/AnamorphicNode.js +12 -18
  73. package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +1 -3
  74. package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +12 -41
  75. package/{src/nodes → examples/jsm/tsl}/display/DenoiseNode.js +60 -47
  76. package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +4 -9
  77. package/{src/nodes → examples/jsm/tsl}/display/DotScreenNode.js +2 -9
  78. package/examples/jsm/tsl/display/FXAANode.js +316 -0
  79. package/{src/nodes → examples/jsm/tsl}/display/FilmNode.js +4 -7
  80. package/{src/nodes → examples/jsm/tsl}/display/GTAONode.js +73 -78
  81. package/{src/nodes → examples/jsm/tsl}/display/GaussianBlurNode.js +78 -42
  82. package/examples/jsm/tsl/display/LensflareNode.js +161 -0
  83. package/{src/nodes → examples/jsm/tsl}/display/Lut3DNode.js +3 -5
  84. package/{src/nodes → examples/jsm/tsl}/display/MotionBlur.js +2 -3
  85. package/examples/jsm/tsl/display/OutlineNode.js +434 -0
  86. package/{src/nodes → examples/jsm/tsl}/display/ParallaxBarrierPassNode.js +2 -5
  87. package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +5 -17
  88. package/{src/nodes → examples/jsm/tsl}/display/RGBShiftNode.js +2 -6
  89. package/examples/jsm/tsl/display/SMAANode.js +620 -0
  90. package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +10 -25
  91. package/examples/jsm/tsl/display/SSRNode.js +366 -0
  92. package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +1 -2
  93. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +4 -12
  94. package/{src/nodes → examples/jsm/tsl}/display/StereoCompositePassNode.js +9 -11
  95. package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +10 -11
  96. package/examples/jsm/tsl/display/TRAAPassNode.js +355 -0
  97. package/{src/nodes → examples/jsm/tsl}/display/TransitionNode.js +3 -7
  98. package/examples/jsm/tsl/display/hashBlur.js +24 -0
  99. package/examples/jsm/tsl/lighting/TiledLightsNode.js +389 -0
  100. package/examples/jsm/utils/SceneOptimizer.js +410 -0
  101. package/examples/jsm/utils/UVsDebug.js +1 -1
  102. package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +2 -1
  103. package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
  104. package/examples/jsm/webxr/Text2D.js +6 -6
  105. package/package.json +4 -4
  106. package/src/Three.Core.js +178 -0
  107. package/src/Three.TSL.js +526 -0
  108. package/src/Three.WebGPU.Nodes.js +9 -186
  109. package/src/Three.WebGPU.js +8 -186
  110. package/src/Three.js +1 -177
  111. package/src/animation/AnimationClip.js +2 -2
  112. package/src/animation/AnimationObjectGroup.js +2 -2
  113. package/src/audio/Audio.js +38 -0
  114. package/src/cameras/PerspectiveCamera.js +6 -6
  115. package/src/cameras/StereoCamera.js +2 -2
  116. package/src/constants.js +1 -6
  117. package/src/core/BufferGeometry.js +48 -8
  118. package/src/core/InterleavedBuffer.js +4 -4
  119. package/src/core/Object3D.js +2 -2
  120. package/src/extras/core/Curve.js +3 -3
  121. package/src/extras/core/Shape.js +2 -2
  122. package/src/geometries/CylinderGeometry.js +2 -2
  123. package/src/geometries/EdgesGeometry.js +2 -2
  124. package/src/geometries/LatheGeometry.js +2 -2
  125. package/src/lights/SpotLightShadow.js +2 -2
  126. package/src/materials/LineDashedMaterial.js +0 -1
  127. package/src/materials/Material.js +2 -2
  128. package/src/materials/MeshPhongMaterial.js +1 -1
  129. package/src/materials/MeshPhysicalMaterial.js +2 -2
  130. package/src/materials/MeshStandardMaterial.js +2 -2
  131. package/src/materials/nodes/Line2NodeMaterial.js +32 -13
  132. package/src/materials/nodes/LineDashedNodeMaterial.js +4 -2
  133. package/src/materials/nodes/NodeMaterial.js +93 -23
  134. package/src/materials/nodes/SpriteNodeMaterial.js +11 -2
  135. package/src/materials/nodes/manager/NodeMaterialObserver.js +119 -7
  136. package/src/math/ColorManagement.js +143 -102
  137. package/src/math/Line3.js +2 -2
  138. package/src/math/Quaternion.js +2 -2
  139. package/src/math/Spherical.js +3 -3
  140. package/src/math/Vector2.js +7 -7
  141. package/src/math/Vector3.js +9 -9
  142. package/src/math/Vector4.js +22 -9
  143. package/src/nodes/Nodes.js +2 -21
  144. package/src/nodes/TSL.js +9 -25
  145. package/src/nodes/accessors/Arrays.js +27 -0
  146. package/src/nodes/accessors/BuiltinNode.js +26 -0
  147. package/src/nodes/accessors/Camera.js +0 -1
  148. package/src/nodes/accessors/ClippingNode.js +76 -42
  149. package/src/nodes/accessors/InstanceNode.js +17 -20
  150. package/src/nodes/accessors/InstancedMeshNode.js +26 -0
  151. package/src/nodes/accessors/Lights.js +32 -0
  152. package/src/nodes/accessors/SceneNode.js +35 -1
  153. package/src/nodes/accessors/StorageBufferNode.js +61 -19
  154. package/src/nodes/accessors/StorageTextureNode.js +10 -4
  155. package/src/nodes/accessors/TextureNode.js +1 -1
  156. package/src/nodes/accessors/VelocityNode.js +13 -3
  157. package/src/nodes/code/FunctionCallNode.js +16 -5
  158. package/src/nodes/code/ScriptableNode.js +4 -4
  159. package/src/nodes/core/Node.js +1 -0
  160. package/src/nodes/core/NodeBuilder.js +31 -14
  161. package/src/nodes/core/NodeUtils.js +28 -0
  162. package/src/nodes/core/VarNode.js +15 -3
  163. package/src/nodes/core/constants.js +6 -0
  164. package/src/nodes/display/BlendModes.js +99 -0
  165. package/src/nodes/display/ColorAdjustment.js +53 -4
  166. package/src/nodes/display/ColorSpaceFunctions.js +5 -5
  167. package/src/nodes/display/ColorSpaceNode.js +27 -39
  168. package/src/nodes/display/PassNode.js +6 -4
  169. package/src/nodes/display/ToneMappingNode.js +1 -1
  170. package/src/nodes/display/ToonOutlinePassNode.js +3 -3
  171. package/src/nodes/display/ViewportDepthNode.js +48 -1
  172. package/src/nodes/functions/PhysicalLightingModel.js +21 -15
  173. package/src/nodes/functions/material/getAlphaHashThreshold.js +70 -0
  174. package/src/nodes/functions/material/getGeometryRoughness.js +8 -2
  175. package/src/nodes/functions/material/getParallaxCorrectNormal.js +22 -0
  176. package/src/nodes/gpgpu/ComputeNode.js +9 -1
  177. package/src/nodes/lighting/AnalyticLightNode.js +23 -419
  178. package/src/nodes/lighting/LightsNode.js +24 -12
  179. package/src/nodes/lighting/PointLightNode.js +41 -22
  180. package/src/nodes/lighting/PointShadowNode.js +254 -0
  181. package/src/nodes/lighting/RectAreaLightNode.js +3 -0
  182. package/src/nodes/lighting/ShadowNode.js +593 -0
  183. package/src/nodes/lighting/SpotLightNode.js +14 -2
  184. package/src/nodes/utils/LoopNode.js +2 -2
  185. package/src/nodes/utils/Oscillators.js +6 -0
  186. package/src/nodes/utils/PostProcessingUtils.js +89 -0
  187. package/src/nodes/utils/RTTNode.js +9 -1
  188. package/src/nodes/utils/ReflectorNode.js +101 -15
  189. package/src/nodes/utils/StorageArrayElementNode.js +2 -2
  190. package/src/nodes/utils/Timer.js +29 -0
  191. package/src/objects/BatchedMesh.js +472 -296
  192. package/src/objects/ClippingGroup.js +19 -0
  193. package/src/objects/Skeleton.js +2 -2
  194. package/src/renderers/WebGLRenderer.js +183 -109
  195. package/src/renderers/common/Animation.js +23 -11
  196. package/src/renderers/common/Attributes.js +4 -0
  197. package/src/renderers/common/Backend.js +2 -0
  198. package/src/renderers/common/Background.js +15 -5
  199. package/src/renderers/common/Bindings.js +23 -6
  200. package/src/renderers/common/ClippingContext.js +77 -85
  201. package/src/renderers/common/Constants.js +2 -1
  202. package/src/renderers/common/Geometries.js +20 -0
  203. package/src/renderers/common/IndirectStorageBufferAttribute.js +15 -0
  204. package/src/renderers/common/Lighting.js +45 -0
  205. package/src/renderers/common/PostProcessingUtils.js +86 -0
  206. package/src/renderers/common/RenderList.js +48 -17
  207. package/src/renderers/common/RenderLists.js +4 -2
  208. package/src/renderers/common/RenderObject.js +45 -28
  209. package/src/renderers/common/RenderObjects.js +12 -6
  210. package/src/renderers/common/Renderer.js +222 -77
  211. package/src/renderers/common/Textures.js +41 -17
  212. package/src/renderers/common/UniformsGroup.js +16 -4
  213. package/src/renderers/common/extras/PMREMGenerator.js +89 -13
  214. package/src/renderers/common/nodes/NodeLibrary.js +2 -15
  215. package/src/renderers/common/nodes/NodeStorageBuffer.js +2 -3
  216. package/src/renderers/common/nodes/NodeUniform.js +42 -0
  217. package/src/renderers/common/nodes/Nodes.js +2 -2
  218. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  219. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  220. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  221. package/src/renderers/webgl/WebGLBackground.js +20 -1
  222. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  223. package/src/renderers/webgl/WebGLCapabilities.js +0 -7
  224. package/src/renderers/webgl/WebGLGeometries.js +0 -28
  225. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  226. package/src/renderers/webgl/WebGLProgram.js +24 -28
  227. package/src/renderers/webgl/WebGLPrograms.js +5 -2
  228. package/src/renderers/webgl/WebGLState.js +37 -1
  229. package/src/renderers/webgl/WebGLTextures.js +29 -12
  230. package/src/renderers/webgl-fallback/WebGLBackend.js +111 -37
  231. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +2 -7
  232. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +43 -12
  233. package/src/renderers/webgl-fallback/utils/WebGLState.js +26 -1
  234. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +37 -9
  235. package/src/renderers/webgpu/WebGPUBackend.js +152 -56
  236. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +1 -1
  237. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  238. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +0 -8
  239. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +13 -34
  240. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +192 -92
  241. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +12 -4
  242. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -2
  243. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -7
  244. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +29 -9
  245. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +29 -7
  246. package/src/renderers/webgpu/utils/WebGPUUtils.js +0 -1
  247. package/src/renderers/webxr/WebXRManager.js +4 -4
  248. package/src/textures/Source.js +2 -2
  249. package/src/textures/Texture.js +2 -2
  250. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  251. package/src/nodes/display/BlendMode.js +0 -54
  252. package/src/nodes/display/FXAANode.js +0 -332
  253. package/src/nodes/utils/OscNode.js +0 -85
  254. package/src/nodes/utils/TimerNode.js +0 -97
  255. /package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +0 -0
@@ -0,0 +1,593 @@
1
+ import Node from '../core/Node.js';
2
+ import { NodeUpdateType } from '../core/constants.js';
3
+ import { float, vec2, vec3, vec4, If, int, Fn, nodeObject } from '../tsl/TSLBase.js';
4
+ import { reference } from '../accessors/ReferenceNode.js';
5
+ import { texture } from '../accessors/TextureNode.js';
6
+ import { positionWorld } from '../accessors/Position.js';
7
+ import { transformedNormalWorld } from '../accessors/Normal.js';
8
+ import { mix, fract, step, max, clamp, sqrt } from '../math/MathNode.js';
9
+ import { add, sub } from '../math/OperatorNode.js';
10
+ import { DepthTexture } from '../../textures/DepthTexture.js';
11
+ import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
12
+ import QuadMesh from '../../renderers/common/QuadMesh.js';
13
+ import { Loop } from '../utils/LoopNode.js';
14
+ import { screenCoordinate } from '../display/ScreenNode.js';
15
+ import { HalfFloatType, LessCompare, NoBlending, RGFormat, VSMShadowMap, WebGPUCoordinateSystem } from '../../constants.js';
16
+ import { renderGroup } from '../core/UniformGroupNode.js';
17
+ import { viewZToLogarithmicDepth } from '../display/ViewportDepthNode.js';
18
+ import { objectPosition } from '../accessors/Object3DNode.js';
19
+ import { lightShadowMatrix } from '../accessors/Lights.js';
20
+
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 } ) => {
71
+
72
+ return texture( depthTexture, shadowCoord.xy ).compare( shadowCoord.z );
73
+
74
+ } );
75
+
76
+ export const PCFShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, shadow } ) => {
77
+
78
+ const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
79
+
80
+ const mapSize = reference( 'mapSize', 'vec2', shadow ).setGroup( renderGroup );
81
+ const radius = reference( 'radius', 'float', shadow ).setGroup( renderGroup );
82
+
83
+ const texelSize = vec2( 1 ).div( mapSize );
84
+ const dx0 = texelSize.x.negate().mul( radius );
85
+ const dy0 = texelSize.y.negate().mul( radius );
86
+ const dx1 = texelSize.x.mul( radius );
87
+ const dy1 = texelSize.y.mul( radius );
88
+ const dx2 = dx0.div( 2 );
89
+ const dy2 = dy0.div( 2 );
90
+ const dx3 = dx1.div( 2 );
91
+ const dy3 = dy1.div( 2 );
92
+
93
+ return add(
94
+ depthCompare( shadowCoord.xy.add( vec2( dx0, dy0 ) ), shadowCoord.z ),
95
+ depthCompare( shadowCoord.xy.add( vec2( 0, dy0 ) ), shadowCoord.z ),
96
+ depthCompare( shadowCoord.xy.add( vec2( dx1, dy0 ) ), shadowCoord.z ),
97
+ depthCompare( shadowCoord.xy.add( vec2( dx2, dy2 ) ), shadowCoord.z ),
98
+ depthCompare( shadowCoord.xy.add( vec2( 0, dy2 ) ), shadowCoord.z ),
99
+ depthCompare( shadowCoord.xy.add( vec2( dx3, dy2 ) ), shadowCoord.z ),
100
+ depthCompare( shadowCoord.xy.add( vec2( dx0, 0 ) ), shadowCoord.z ),
101
+ depthCompare( shadowCoord.xy.add( vec2( dx2, 0 ) ), shadowCoord.z ),
102
+ depthCompare( shadowCoord.xy, shadowCoord.z ),
103
+ depthCompare( shadowCoord.xy.add( vec2( dx3, 0 ) ), shadowCoord.z ),
104
+ depthCompare( shadowCoord.xy.add( vec2( dx1, 0 ) ), shadowCoord.z ),
105
+ depthCompare( shadowCoord.xy.add( vec2( dx2, dy3 ) ), shadowCoord.z ),
106
+ depthCompare( shadowCoord.xy.add( vec2( 0, dy3 ) ), shadowCoord.z ),
107
+ depthCompare( shadowCoord.xy.add( vec2( dx3, dy3 ) ), shadowCoord.z ),
108
+ depthCompare( shadowCoord.xy.add( vec2( dx0, dy1 ) ), shadowCoord.z ),
109
+ depthCompare( shadowCoord.xy.add( vec2( 0, dy1 ) ), shadowCoord.z ),
110
+ depthCompare( shadowCoord.xy.add( vec2( dx1, dy1 ) ), shadowCoord.z )
111
+ ).mul( 1 / 17 );
112
+
113
+ } );
114
+
115
+ export const PCFSoftShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, shadow } ) => {
116
+
117
+ const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
118
+
119
+ const mapSize = reference( 'mapSize', 'vec2', shadow ).setGroup( renderGroup );
120
+
121
+ const texelSize = vec2( 1 ).div( mapSize );
122
+ const dx = texelSize.x;
123
+ const dy = texelSize.y;
124
+
125
+ const uv = shadowCoord.xy;
126
+ const f = fract( uv.mul( mapSize ).add( 0.5 ) );
127
+ uv.subAssign( f.mul( texelSize ) );
128
+
129
+ return add(
130
+ depthCompare( uv, shadowCoord.z ),
131
+ depthCompare( uv.add( vec2( dx, 0 ) ), shadowCoord.z ),
132
+ depthCompare( uv.add( vec2( 0, dy ) ), shadowCoord.z ),
133
+ depthCompare( uv.add( texelSize ), shadowCoord.z ),
134
+ mix(
135
+ depthCompare( uv.add( vec2( dx.negate(), 0 ) ), shadowCoord.z ),
136
+ depthCompare( uv.add( vec2( dx.mul( 2 ), 0 ) ), shadowCoord.z ),
137
+ f.x
138
+ ),
139
+ mix(
140
+ depthCompare( uv.add( vec2( dx.negate(), dy ) ), shadowCoord.z ),
141
+ depthCompare( uv.add( vec2( dx.mul( 2 ), dy ) ), shadowCoord.z ),
142
+ f.x
143
+ ),
144
+ mix(
145
+ depthCompare( uv.add( vec2( 0, dy.negate() ) ), shadowCoord.z ),
146
+ depthCompare( uv.add( vec2( 0, dy.mul( 2 ) ) ), shadowCoord.z ),
147
+ f.y
148
+ ),
149
+ mix(
150
+ depthCompare( uv.add( vec2( dx, dy.negate() ) ), shadowCoord.z ),
151
+ depthCompare( uv.add( vec2( dx, dy.mul( 2 ) ) ), shadowCoord.z ),
152
+ f.y
153
+ ),
154
+ mix(
155
+ mix(
156
+ depthCompare( uv.add( vec2( dx.negate(), dy.negate() ) ), shadowCoord.z ),
157
+ depthCompare( uv.add( vec2( dx.mul( 2 ), dy.negate() ) ), shadowCoord.z ),
158
+ f.x
159
+ ),
160
+ mix(
161
+ depthCompare( uv.add( vec2( dx.negate(), dy.mul( 2 ) ) ), shadowCoord.z ),
162
+ depthCompare( uv.add( vec2( dx.mul( 2 ), dy.mul( 2 ) ) ), shadowCoord.z ),
163
+ f.x
164
+ ),
165
+ f.y
166
+ )
167
+ ).mul( 1 / 9 );
168
+
169
+ } );
170
+
171
+ // VSM
172
+
173
+ export const VSMShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord } ) => {
174
+
175
+ const occlusion = float( 1 ).toVar();
176
+
177
+ const distribution = texture( depthTexture ).uv( shadowCoord.xy ).rg;
178
+
179
+ const hardShadow = step( shadowCoord.z, distribution.x );
180
+
181
+ If( hardShadow.notEqual( float( 1.0 ) ), () => {
182
+
183
+ const distance = shadowCoord.z.sub( distribution.x );
184
+ const variance = max( 0, distribution.y.mul( distribution.y ) );
185
+ let softnessProbability = variance.div( variance.add( distance.mul( distance ) ) ); // Chebeyshevs inequality
186
+ softnessProbability = clamp( sub( softnessProbability, 0.3 ).div( 0.95 - 0.3 ) );
187
+ occlusion.assign( clamp( max( hardShadow, softnessProbability ) ) );
188
+
189
+ } );
190
+
191
+ return occlusion;
192
+
193
+ } );
194
+
195
+ const VSMPassVertical = /*@__PURE__*/ Fn( ( { samples, radius, size, shadowPass } ) => {
196
+
197
+ const mean = float( 0 ).toVar();
198
+ const squaredMean = float( 0 ).toVar();
199
+
200
+ const uvStride = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( 2 ).div( samples.sub( 1 ) ) );
201
+ const uvStart = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( - 1 ) );
202
+
203
+ Loop( { start: int( 0 ), end: int( samples ), type: 'int', condition: '<' }, ( { i } ) => {
204
+
205
+ const uvOffset = uvStart.add( float( i ).mul( uvStride ) );
206
+
207
+ const depth = shadowPass.uv( add( screenCoordinate.xy, vec2( 0, uvOffset ).mul( radius ) ).div( size ) ).x;
208
+ mean.addAssign( depth );
209
+ squaredMean.addAssign( depth.mul( depth ) );
210
+
211
+ } );
212
+
213
+ mean.divAssign( samples );
214
+ squaredMean.divAssign( samples );
215
+
216
+ const std_dev = sqrt( squaredMean.sub( mean.mul( mean ) ) );
217
+ return vec2( mean, std_dev );
218
+
219
+ } );
220
+
221
+ const VSMPassHorizontal = /*@__PURE__*/ Fn( ( { samples, radius, size, shadowPass } ) => {
222
+
223
+ const mean = float( 0 ).toVar();
224
+ const squaredMean = float( 0 ).toVar();
225
+
226
+ const uvStride = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( 2 ).div( samples.sub( 1 ) ) );
227
+ const uvStart = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( - 1 ) );
228
+
229
+ Loop( { start: int( 0 ), end: int( samples ), type: 'int', condition: '<' }, ( { i } ) => {
230
+
231
+ const uvOffset = uvStart.add( float( i ).mul( uvStride ) );
232
+
233
+ const distribution = shadowPass.uv( add( screenCoordinate.xy, vec2( uvOffset, 0 ).mul( radius ) ).div( size ) );
234
+ mean.addAssign( distribution.x );
235
+ squaredMean.addAssign( add( distribution.y.mul( distribution.y ), distribution.x.mul( distribution.x ) ) );
236
+
237
+ } );
238
+
239
+ mean.divAssign( samples );
240
+ squaredMean.divAssign( samples );
241
+
242
+ const std_dev = sqrt( squaredMean.sub( mean.mul( mean ) ) );
243
+ return vec2( mean, std_dev );
244
+
245
+ } );
246
+
247
+ const _shadowFilterLib = [ BasicShadowFilter, PCFShadowFilter, PCFSoftShadowFilter, VSMShadowFilter ];
248
+
249
+ //
250
+
251
+ const _quadMesh = /*@__PURE__*/ new QuadMesh();
252
+
253
+ class ShadowNode extends Node {
254
+
255
+ static get type() {
256
+
257
+ return 'ShadowNode';
258
+
259
+ }
260
+
261
+ constructor( light, shadow = null ) {
262
+
263
+ super();
264
+
265
+ this.light = light;
266
+ this.shadow = shadow || light.shadow;
267
+
268
+ this.shadowMap = null;
269
+
270
+ this.vsmShadowMapVertical = null;
271
+ this.vsmShadowMapHorizontal = null;
272
+
273
+ this.vsmMaterialVertical = null;
274
+ this.vsmMaterialHorizontal = null;
275
+
276
+ this.updateBeforeType = NodeUpdateType.RENDER;
277
+ this._node = null;
278
+
279
+ this.isShadowNode = true;
280
+
281
+ }
282
+
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 ) {
298
+
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
+ }
318
+
319
+ } else {
320
+
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 );
331
+
332
+ }
333
+
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
+
356
+ const shadowMapType = renderer.shadowMap.type;
357
+
358
+ const depthTexture = new DepthTexture( shadow.mapSize.width, shadow.mapSize.height );
359
+ depthTexture.compareFunction = LessCompare;
360
+
361
+ const shadowMap = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
362
+ shadowMap.depthTexture = depthTexture;
363
+
364
+ shadow.camera.updateProjectionMatrix();
365
+
366
+ // VSM
367
+
368
+ if ( shadowMapType === VSMShadowMap ) {
369
+
370
+ depthTexture.compareFunction = null; // VSM does not use textureSampleCompare()/texture2DCompare()
371
+
372
+ this.vsmShadowMapVertical = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height, { format: RGFormat, type: HalfFloatType } );
373
+ this.vsmShadowMapHorizontal = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height, { format: RGFormat, type: HalfFloatType } );
374
+
375
+ const shadowPassVertical = texture( depthTexture );
376
+ const shadowPassHorizontal = texture( this.vsmShadowMapVertical.texture );
377
+
378
+ const samples = reference( 'blurSamples', 'float', shadow ).setGroup( renderGroup );
379
+ const radius = reference( 'radius', 'float', shadow ).setGroup( renderGroup );
380
+ const size = reference( 'mapSize', 'vec2', shadow ).setGroup( renderGroup );
381
+
382
+ let material = this.vsmMaterialVertical || ( this.vsmMaterialVertical = new NodeMaterial() );
383
+ material.fragmentNode = VSMPassVertical( { samples, radius, size, shadowPass: shadowPassVertical } ).context( builder.getSharedContext() );
384
+ material.name = 'VSMVertical';
385
+
386
+ material = this.vsmMaterialHorizontal || ( this.vsmMaterialHorizontal = new NodeMaterial() );
387
+ material.fragmentNode = VSMPassHorizontal( { samples, radius, size, shadowPass: shadowPassHorizontal } ).context( builder.getSharedContext() );
388
+ material.name = 'VSMHorizontal';
389
+
390
+ }
391
+
392
+ //
393
+
394
+ const shadowIntensity = reference( 'intensity', 'float', shadow ).setGroup( renderGroup );
395
+ const normalBias = reference( 'normalBias', 'float', shadow ).setGroup( renderGroup );
396
+
397
+ const shadowPosition = lightShadowMatrix( light ).mul( shadowWorldPosition.add( transformedNormalWorld.mul( normalBias ) ) );
398
+ const shadowCoord = this.setupShadowCoord( builder, shadowPosition );
399
+
400
+ //
401
+
402
+ const filterFn = shadow.filterNode || this.getShadowFilterFn( renderer.shadowMap.type ) || null;
403
+
404
+ if ( filterFn === null ) {
405
+
406
+ throw new Error( 'THREE.WebGPURenderer: Shadow map type not supported yet.' );
407
+
408
+ }
409
+
410
+ const shadowDepthTexture = ( shadowMapType === VSMShadowMap ) ? this.vsmShadowMapHorizontal.texture : depthTexture;
411
+
412
+ const shadowNode = this.setupShadowFilter( builder, { filterFn, shadowTexture: shadowMap.texture, depthTexture: shadowDepthTexture, shadowCoord, shadow } );
413
+
414
+ const shadowColor = texture( shadowMap.texture, shadowCoord );
415
+ const shadowOutput = mix( 1, shadowNode.rgb.mix( shadowColor, 1 ), shadowIntensity.mul( shadowColor.a ) ).toVar();
416
+
417
+ this.shadowMap = shadowMap;
418
+ this.shadow.map = shadowMap;
419
+
420
+ return shadowOutput;
421
+
422
+ }
423
+
424
+ setup( builder ) {
425
+
426
+ if ( builder.renderer.shadowMap.enabled === false ) return;
427
+
428
+ return Fn( ( { material } ) => {
429
+
430
+ shadowWorldPosition.assign( material.shadowPositionNode || positionWorld );
431
+
432
+ let node = this._node;
433
+
434
+ if ( node === null ) {
435
+
436
+ this._node = node = this.setupShadow( builder );
437
+
438
+ }
439
+
440
+ if ( builder.material.shadowNode ) { // @deprecated, r171
441
+
442
+ console.warn( 'THREE.NodeMaterial: ".shadowNode" is deprecated. Use ".castShadowNode" instead.' );
443
+
444
+ }
445
+
446
+ if ( builder.material.receivedShadowNode ) {
447
+
448
+ node = builder.material.receivedShadowNode( node );
449
+
450
+ }
451
+
452
+ return node;
453
+
454
+ } )();
455
+
456
+ }
457
+
458
+ renderShadow( frame ) {
459
+
460
+ const { shadow, shadowMap } = this;
461
+ const { renderer, scene } = frame;
462
+
463
+ shadowMap.setSize( shadow.mapSize.width, shadow.mapSize.height );
464
+
465
+ renderer.render( scene, shadow.camera );
466
+
467
+ }
468
+
469
+ updateShadow( frame ) {
470
+
471
+ const { shadowMap, light, shadow } = this;
472
+ const { renderer, scene, camera } = frame;
473
+
474
+ const shadowType = renderer.shadowMap.type;
475
+
476
+ const depthVersion = shadowMap.depthTexture.version;
477
+ this._depthVersionCached = depthVersion;
478
+
479
+ const currentOverrideMaterial = scene.overrideMaterial;
480
+
481
+ scene.overrideMaterial = getShadowMaterial( light );
482
+
483
+ shadow.camera.layers.mask = camera.layers.mask;
484
+
485
+ const currentRenderTarget = renderer.getRenderTarget();
486
+ const currentRenderObjectFunction = renderer.getRenderObjectFunction();
487
+ const currentMRT = renderer.getMRT();
488
+
489
+ renderer.setMRT( null );
490
+
491
+ renderer.setRenderObjectFunction( ( object, ...params ) => {
492
+
493
+ if ( object.castShadow === true || ( object.receiveShadow && shadowType === VSMShadowMap ) ) {
494
+
495
+ renderer.renderObject( object, ...params );
496
+
497
+ }
498
+
499
+ } );
500
+
501
+ renderer.setRenderTarget( shadowMap );
502
+
503
+ this.renderShadow( frame );
504
+
505
+ renderer.setRenderObjectFunction( currentRenderObjectFunction );
506
+
507
+ // vsm blur pass
508
+
509
+ if ( light.isPointLight !== true && shadowType === VSMShadowMap ) {
510
+
511
+ this.vsmPass( renderer );
512
+
513
+ }
514
+
515
+ renderer.setRenderTarget( currentRenderTarget );
516
+
517
+ renderer.setMRT( currentMRT );
518
+
519
+ scene.overrideMaterial = currentOverrideMaterial;
520
+
521
+ }
522
+
523
+ vsmPass( renderer ) {
524
+
525
+ const { shadow } = this;
526
+
527
+ this.vsmShadowMapVertical.setSize( shadow.mapSize.width, shadow.mapSize.height );
528
+ this.vsmShadowMapHorizontal.setSize( shadow.mapSize.width, shadow.mapSize.height );
529
+
530
+ renderer.setRenderTarget( this.vsmShadowMapVertical );
531
+ _quadMesh.material = this.vsmMaterialVertical;
532
+ _quadMesh.render( renderer );
533
+
534
+ renderer.setRenderTarget( this.vsmShadowMapHorizontal );
535
+ _quadMesh.material = this.vsmMaterialHorizontal;
536
+ _quadMesh.render( renderer );
537
+
538
+ }
539
+
540
+ dispose() {
541
+
542
+ this.shadowMap.dispose();
543
+ this.shadowMap = null;
544
+
545
+ if ( this.vsmShadowMapVertical !== null ) {
546
+
547
+ this.vsmShadowMapVertical.dispose();
548
+ this.vsmShadowMapVertical = null;
549
+
550
+ this.vsmMaterialVertical.dispose();
551
+ this.vsmMaterialVertical = null;
552
+
553
+ }
554
+
555
+ if ( this.vsmShadowMapHorizontal !== null ) {
556
+
557
+ this.vsmShadowMapHorizontal.dispose();
558
+ this.vsmShadowMapHorizontal = null;
559
+
560
+ this.vsmMaterialHorizontal.dispose();
561
+ this.vsmMaterialHorizontal = null;
562
+
563
+ }
564
+
565
+ this.updateBeforeType = NodeUpdateType.NONE;
566
+
567
+ }
568
+
569
+ updateBefore( frame ) {
570
+
571
+ const { shadow } = this;
572
+
573
+ const needsUpdate = shadow.needsUpdate || shadow.autoUpdate;
574
+
575
+ if ( needsUpdate ) {
576
+
577
+ this.updateShadow( frame );
578
+
579
+ if ( this.shadowMap.depthTexture.version === this._depthVersionCached ) {
580
+
581
+ shadow.needsUpdate = false;
582
+
583
+ }
584
+
585
+ }
586
+
587
+ }
588
+
589
+ }
590
+
591
+ export default ShadowNode;
592
+
593
+ export const shadow = ( light, shadow ) => nodeObject( new ShadowNode( light, shadow ) );
@@ -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
 
@@ -102,10 +102,10 @@ class LoopNode extends Node {
102
102
  condition = param.condition;
103
103
  update = param.update;
104
104
 
105
- if ( typeof start === 'number' ) start = start.toString();
105
+ if ( typeof start === 'number' ) start = builder.generateConst( type, start );
106
106
  else if ( start && start.isNode ) start = start.build( builder, type );
107
107
 
108
- if ( typeof end === 'number' ) end = end.toString();
108
+ if ( typeof end === 'number' ) end = builder.generateConst( type, end );
109
109
  else if ( end && end.isNode ) end = end.build( builder, type );
110
110
 
111
111
  if ( start !== undefined && end === undefined ) {
@@ -0,0 +1,6 @@
1
+ import { time } from './Timer.js';
2
+
3
+ export const oscSine = ( t = time ) => t.add( 0.75 ).mul( Math.PI * 2 ).sin().mul( 0.5 ).add( 0.5 );
4
+ export const oscSquare = ( t = time ) => t.fract().round();
5
+ export const oscTriangle = ( t = time ) => t.add( 0.5 ).fract().mul( 2 ).sub( 1 ).abs();
6
+ export const oscSawtooth = ( t = time ) => t.fract();