super-three 0.169.1 → 0.170.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 (193) hide show
  1. package/build/three.cjs +974 -562
  2. package/build/three.module.js +975 -559
  3. package/build/three.module.min.js +1 -1
  4. package/build/three.webgpu.js +8398 -9842
  5. package/build/three.webgpu.min.js +1 -1
  6. package/build/three.webgpu.nodes.js +8398 -9842
  7. package/build/three.webgpu.nodes.min.js +1 -1
  8. package/examples/jsm/Addons.js +3 -3
  9. package/examples/jsm/animation/MMDAnimationHelper.js +2 -0
  10. package/examples/jsm/animation/MMDPhysics.js +2 -0
  11. package/examples/jsm/controls/TransformControls.js +22 -6
  12. package/examples/jsm/csm/CSM.js +2 -2
  13. package/examples/jsm/csm/CSMFrustum.js +7 -4
  14. package/examples/jsm/csm/CSMHelper.js +2 -0
  15. package/examples/jsm/csm/CSMShadowNode.js +435 -0
  16. package/examples/jsm/curves/NURBSCurve.js +34 -3
  17. package/examples/jsm/exporters/GLTFExporter.js +138 -71
  18. package/examples/jsm/exporters/KTX2Exporter.js +35 -12
  19. package/examples/jsm/exporters/MMDExporter.js +6 -0
  20. package/examples/jsm/exporters/USDZExporter.js +21 -3
  21. package/examples/jsm/geometries/DecalGeometry.js +65 -20
  22. package/examples/jsm/geometries/InstancedPointsGeometry.js +2 -0
  23. package/examples/jsm/helpers/TextureHelperGPU.js +175 -0
  24. package/examples/jsm/interactive/HTMLMesh.js +1 -0
  25. package/examples/jsm/lighting/TiledLighting.js +18 -0
  26. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  27. package/examples/jsm/lines/LineMaterial.js +7 -2
  28. package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
  29. package/examples/jsm/lines/webgpu/LineSegments2.js +0 -15
  30. package/examples/jsm/lines/webgpu/Wireframe.js +56 -0
  31. package/examples/jsm/loaders/3DMLoader.js +1 -0
  32. package/examples/jsm/loaders/3MFLoader.js +91 -0
  33. package/examples/jsm/loaders/FBXLoader.js +12 -2
  34. package/examples/jsm/loaders/GLTFLoader.js +2 -0
  35. package/examples/jsm/loaders/KTX2Loader.js +140 -49
  36. package/examples/jsm/loaders/LDrawLoader.js +22 -136
  37. package/examples/jsm/loaders/LottieLoader.js +1 -0
  38. package/examples/jsm/loaders/MMDLoader.js +9 -2
  39. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
  40. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
  41. package/examples/jsm/materials/MeshGouraudMaterial.js +6 -2
  42. package/examples/jsm/math/ColorSpaces.js +76 -0
  43. package/examples/jsm/misc/ProgressiveLightMap.js +52 -40
  44. package/examples/jsm/misc/ProgressiveLightMapGPU.js +293 -0
  45. package/examples/jsm/misc/VolumeSlice.js +1 -0
  46. package/examples/jsm/objects/WaterMesh.js +8 -8
  47. package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
  48. package/examples/jsm/postprocessing/SSRPass.js +6 -0
  49. package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
  50. package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
  51. package/examples/jsm/shaders/FXAAShader.js +225 -224
  52. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  53. package/{src/nodes → examples/jsm/tsl}/display/AfterImageNode.js +17 -20
  54. package/{src/nodes → examples/jsm/tsl}/display/AnaglyphPassNode.js +2 -6
  55. package/{src/nodes → examples/jsm/tsl}/display/AnamorphicNode.js +12 -18
  56. package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +1 -3
  57. package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +11 -40
  58. package/{src/nodes → examples/jsm/tsl}/display/DenoiseNode.js +18 -41
  59. package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +2 -8
  60. package/{src/nodes → examples/jsm/tsl}/display/DotScreenNode.js +2 -9
  61. package/examples/jsm/tsl/display/FXAANode.js +316 -0
  62. package/{src/nodes → examples/jsm/tsl}/display/FilmNode.js +2 -6
  63. package/{src/nodes → examples/jsm/tsl}/display/GTAONode.js +30 -70
  64. package/{src/nodes → examples/jsm/tsl}/display/GaussianBlurNode.js +74 -36
  65. package/examples/jsm/tsl/display/LensflareNode.js +161 -0
  66. package/{src/nodes → examples/jsm/tsl}/display/Lut3DNode.js +1 -4
  67. package/{src/nodes → examples/jsm/tsl}/display/MotionBlur.js +2 -3
  68. package/examples/jsm/tsl/display/OutlineNode.js +434 -0
  69. package/{src/nodes → examples/jsm/tsl}/display/ParallaxBarrierPassNode.js +1 -5
  70. package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +3 -15
  71. package/{src/nodes → examples/jsm/tsl}/display/RGBShiftNode.js +1 -6
  72. package/examples/jsm/tsl/display/SMAANode.js +620 -0
  73. package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +10 -25
  74. package/examples/jsm/tsl/display/SSRNode.js +343 -0
  75. package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +1 -2
  76. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +3 -11
  77. package/{src/nodes → examples/jsm/tsl}/display/StereoCompositePassNode.js +9 -11
  78. package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +10 -11
  79. package/examples/jsm/tsl/display/TRAAPassNode.js +355 -0
  80. package/{src/nodes → examples/jsm/tsl}/display/TransitionNode.js +1 -6
  81. package/examples/jsm/tsl/display/hashBlur.js +24 -0
  82. package/examples/jsm/tsl/lighting/TiledLightsNode.js +392 -0
  83. package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +2 -1
  84. package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
  85. package/examples/jsm/webxr/Text2D.js +6 -6
  86. package/package.json +2 -2
  87. package/src/Three.WebGPU.Nodes.js +4 -0
  88. package/src/Three.WebGPU.js +4 -0
  89. package/src/constants.js +1 -6
  90. package/src/core/BufferGeometry.js +44 -6
  91. package/src/geometries/CylinderGeometry.js +2 -2
  92. package/src/materials/LineBasicMaterial.js +6 -2
  93. package/src/materials/LineDashedMaterial.js +6 -2
  94. package/src/materials/Material.js +14 -1
  95. package/src/materials/MeshBasicMaterial.js +6 -2
  96. package/src/materials/MeshDepthMaterial.js +6 -2
  97. package/src/materials/MeshDistanceMaterial.js +6 -2
  98. package/src/materials/MeshLambertMaterial.js +6 -2
  99. package/src/materials/MeshMatcapMaterial.js +6 -2
  100. package/src/materials/MeshNormalMaterial.js +6 -2
  101. package/src/materials/MeshPhongMaterial.js +6 -2
  102. package/src/materials/MeshPhysicalMaterial.js +6 -2
  103. package/src/materials/MeshStandardMaterial.js +6 -2
  104. package/src/materials/MeshToonMaterial.js +6 -2
  105. package/src/materials/PointsMaterial.js +6 -2
  106. package/src/materials/RawShaderMaterial.js +6 -2
  107. package/src/materials/ShaderMaterial.js +6 -2
  108. package/src/materials/ShadowMaterial.js +6 -2
  109. package/src/materials/SpriteMaterial.js +6 -2
  110. package/src/materials/nodes/NodeMaterial.js +31 -9
  111. package/src/materials/nodes/SpriteNodeMaterial.js +11 -2
  112. package/src/materials/nodes/manager/NodeMaterialObserver.js +111 -2
  113. package/src/math/ColorManagement.js +118 -85
  114. package/src/math/Vector4.js +11 -0
  115. package/src/nodes/Nodes.js +1 -21
  116. package/src/nodes/TSL.js +6 -24
  117. package/src/nodes/accessors/Camera.js +0 -1
  118. package/src/nodes/accessors/SceneNode.js +35 -1
  119. package/src/nodes/accessors/StorageBufferNode.js +32 -10
  120. package/src/nodes/accessors/VelocityNode.js +13 -3
  121. package/src/nodes/code/FunctionCallNode.js +16 -5
  122. package/src/nodes/code/ScriptableNode.js +4 -4
  123. package/src/nodes/core/Node.js +1 -0
  124. package/src/nodes/core/NodeBuilder.js +29 -5
  125. package/src/nodes/core/VarNode.js +15 -3
  126. package/src/nodes/display/ColorAdjustment.js +53 -4
  127. package/src/nodes/display/ColorSpaceFunctions.js +5 -5
  128. package/src/nodes/display/ColorSpaceNode.js +27 -39
  129. package/src/nodes/display/PassNode.js +6 -4
  130. package/src/nodes/display/ToneMappingNode.js +1 -1
  131. package/src/nodes/display/ViewportDepthNode.js +33 -1
  132. package/src/nodes/functions/PhysicalLightingModel.js +21 -15
  133. package/src/nodes/functions/material/getAlphaHashThreshold.js +64 -0
  134. package/src/nodes/functions/material/getGeometryRoughness.js +8 -2
  135. package/src/nodes/functions/material/getParallaxCorrectNormal.js +22 -0
  136. package/src/nodes/gpgpu/ComputeNode.js +9 -1
  137. package/src/nodes/lighting/AnalyticLightNode.js +12 -416
  138. package/src/nodes/lighting/LightsNode.js +24 -12
  139. package/src/nodes/lighting/PointLightNode.js +36 -26
  140. package/src/nodes/lighting/RectAreaLightNode.js +3 -0
  141. package/src/nodes/lighting/ShadowNode.js +484 -0
  142. package/src/nodes/utils/LoopNode.js +2 -2
  143. package/src/nodes/utils/Oscillators.js +6 -0
  144. package/src/nodes/utils/PostProcessingUtils.js +89 -0
  145. package/src/nodes/utils/ReflectorNode.js +101 -15
  146. package/src/nodes/utils/Timer.js +29 -0
  147. package/src/objects/BatchedMesh.js +458 -241
  148. package/src/renderers/WebGLRenderer.js +120 -117
  149. package/src/renderers/common/Attributes.js +4 -0
  150. package/src/renderers/common/Backend.js +2 -0
  151. package/src/renderers/common/Background.js +14 -4
  152. package/src/renderers/common/Bindings.js +3 -2
  153. package/src/renderers/common/Constants.js +2 -1
  154. package/src/renderers/common/Geometries.js +20 -0
  155. package/src/renderers/common/IndirectStorageBufferAttribute.js +15 -0
  156. package/src/renderers/common/Lighting.js +45 -0
  157. package/src/renderers/common/PostProcessingUtils.js +86 -0
  158. package/src/renderers/common/RenderList.js +39 -11
  159. package/src/renderers/common/RenderLists.js +4 -2
  160. package/src/renderers/common/RenderObject.js +18 -1
  161. package/src/renderers/common/Renderer.js +165 -26
  162. package/src/renderers/common/Textures.js +30 -14
  163. package/src/renderers/common/nodes/NodeLibrary.js +1 -14
  164. package/src/renderers/common/nodes/Nodes.js +2 -2
  165. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  166. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  167. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  168. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  169. package/src/renderers/webgl/WebGLCapabilities.js +0 -7
  170. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  171. package/src/renderers/webgl/WebGLProgram.js +24 -28
  172. package/src/renderers/webgl/WebGLPrograms.js +5 -2
  173. package/src/renderers/webgl/WebGLState.js +37 -1
  174. package/src/renderers/webgl/WebGLTextures.js +29 -12
  175. package/src/renderers/webgl-fallback/WebGLBackend.js +98 -31
  176. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +2 -7
  177. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +33 -8
  178. package/src/renderers/webgpu/WebGPUBackend.js +105 -25
  179. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +1 -1
  180. package/src/renderers/webgpu/WebGPURenderer.js +1 -1
  181. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +0 -8
  182. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -8
  183. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +10 -20
  184. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +12 -4
  185. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +29 -9
  186. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +24 -6
  187. package/src/renderers/webgpu/utils/WebGPUUtils.js +0 -1
  188. package/src/renderers/webxr/WebXRManager.js +4 -4
  189. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  190. package/src/nodes/display/FXAANode.js +0 -332
  191. package/src/nodes/utils/OscNode.js +0 -85
  192. package/src/nodes/utils/TimerNode.js +0 -97
  193. /package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +0 -0
@@ -1,7 +1,13 @@
1
1
  import { normalView } from '../../accessors/Normal.js';
2
- import { Fn } from '../../tsl/TSLBase.js';
2
+ import { float, Fn } from '../../tsl/TSLBase.js';
3
3
 
4
- const getGeometryRoughness = /*@__PURE__*/ Fn( () => {
4
+ const getGeometryRoughness = /*@__PURE__*/ Fn( ( builder ) => {
5
+
6
+ if ( builder.geometry.hasAttribute( 'normal' ) === false ) {
7
+
8
+ return float( 0 );
9
+
10
+ }
5
11
 
6
12
  const dxy = normalView.dFdx().abs().max( normalView.dFdy().abs() );
7
13
  const geometryRoughness = dxy.x.max( dxy.y ).max( dxy.z );
@@ -0,0 +1,22 @@
1
+ import { positionWorld } from '../../accessors/Position';
2
+ import { float, Fn, min, normalize, sub, vec3 } from '../../tsl/TSLBase.js';
3
+
4
+ // https://devlog-martinsh.blogspot.com/2011/09/box-projected-cube-environment-mapping.html
5
+
6
+ const getParallaxCorrectNormal = /*@__PURE__*/ Fn( ( [ normal, cubeSize, cubePos ] ) => {
7
+
8
+ const nDir = normalize( normal ).toVar( 'nDir' );
9
+ const rbmax = sub( float( 0.5 ).mul( cubeSize.sub( cubePos ) ), positionWorld ).div( nDir ).toVar( 'rbmax' );
10
+ const rbmin = sub( float( - 0.5 ).mul( cubeSize.sub( cubePos ) ), positionWorld ).div( nDir ).toVar( 'rbmin' );
11
+ const rbminmax = vec3().toVar( 'rbminmax' );
12
+ rbminmax.x = nDir.x.greaterThan( float( 0 ) ).select( rbmax.x, rbmin.x );
13
+ rbminmax.y = nDir.y.greaterThan( float( 0 ) ).select( rbmax.y, rbmin.y );
14
+ rbminmax.z = nDir.z.greaterThan( float( 0 ) ).select( rbmax.z, rbmin.z );
15
+
16
+ const correction = min( min( rbminmax.x, rbminmax.y ), rbminmax.z ).toVar( 'correction' );
17
+ const boxIntersection = positionWorld.add( nDir.mul( correction ) ).toVar( 'boxIntersection' );
18
+ return boxIntersection.sub( cubePos );
19
+
20
+ } );
21
+
22
+ export default getParallaxCorrectNormal;
@@ -25,6 +25,8 @@ class ComputeNode extends Node {
25
25
  this.version = 1;
26
26
  this.updateBeforeType = NodeUpdateType.OBJECT;
27
27
 
28
+ this.onInitFunction = null;
29
+
28
30
  this.updateDispatchCount();
29
31
 
30
32
  }
@@ -54,7 +56,13 @@ class ComputeNode extends Node {
54
56
 
55
57
  }
56
58
 
57
- onInit() { }
59
+ onInit( callback ) {
60
+
61
+ this.onInitFunction = callback;
62
+
63
+ return this;
64
+
65
+ }
58
66
 
59
67
  updateBefore( { renderer } ) {
60
68
 
@@ -1,206 +1,11 @@
1
1
  import LightingNode from './LightingNode.js';
2
2
  import { NodeUpdateType } from '../core/constants.js';
3
3
  import { uniform } from '../core/UniformNode.js';
4
- import { float, vec2, vec3, vec4, If, int, Fn } from '../tsl/TSLBase.js';
5
- import { reference } from '../accessors/ReferenceNode.js';
6
- import { texture } from '../accessors/TextureNode.js';
7
- import { positionWorld } from '../accessors/Position.js';
8
- import { normalWorld } from '../accessors/Normal.js';
9
- import { mix, fract, step, max, clamp, sqrt } from '../math/MathNode.js';
10
- import { add, sub } from '../math/OperatorNode.js';
11
4
  import { Color } from '../../math/Color.js';
12
- import { DepthTexture } from '../../textures/DepthTexture.js';
13
- import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
14
- import QuadMesh from '../../renderers/common/QuadMesh.js';
15
- import { Loop } from '../utils/LoopNode.js';
16
- import { screenCoordinate } from '../display/ScreenNode.js';
17
- import { HalfFloatType, LessCompare, RGFormat, VSMShadowMap, WebGPUCoordinateSystem } from '../../constants.js';
18
5
  import { renderGroup } from '../core/UniformGroupNode.js';
19
6
  import { hash } from '../core/NodeUtils.js';
20
-
21
- const BasicShadowMap = Fn( ( { depthTexture, shadowCoord } ) => {
22
-
23
- return texture( depthTexture, shadowCoord.xy ).compare( shadowCoord.z );
24
-
25
- } );
26
-
27
- const PCFShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
28
-
29
- const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
30
-
31
- const mapSize = reference( 'mapSize', 'vec2', shadow ).setGroup( renderGroup );
32
- const radius = reference( 'radius', 'float', shadow ).setGroup( renderGroup );
33
-
34
- const texelSize = vec2( 1 ).div( mapSize );
35
- const dx0 = texelSize.x.negate().mul( radius );
36
- const dy0 = texelSize.y.negate().mul( radius );
37
- const dx1 = texelSize.x.mul( radius );
38
- const dy1 = texelSize.y.mul( radius );
39
- const dx2 = dx0.div( 2 );
40
- const dy2 = dy0.div( 2 );
41
- const dx3 = dx1.div( 2 );
42
- const dy3 = dy1.div( 2 );
43
-
44
- return add(
45
- depthCompare( shadowCoord.xy.add( vec2( dx0, dy0 ) ), shadowCoord.z ),
46
- depthCompare( shadowCoord.xy.add( vec2( 0, dy0 ) ), shadowCoord.z ),
47
- depthCompare( shadowCoord.xy.add( vec2( dx1, dy0 ) ), shadowCoord.z ),
48
- depthCompare( shadowCoord.xy.add( vec2( dx2, dy2 ) ), shadowCoord.z ),
49
- depthCompare( shadowCoord.xy.add( vec2( 0, dy2 ) ), shadowCoord.z ),
50
- depthCompare( shadowCoord.xy.add( vec2( dx3, dy2 ) ), shadowCoord.z ),
51
- depthCompare( shadowCoord.xy.add( vec2( dx0, 0 ) ), shadowCoord.z ),
52
- depthCompare( shadowCoord.xy.add( vec2( dx2, 0 ) ), shadowCoord.z ),
53
- depthCompare( shadowCoord.xy, shadowCoord.z ),
54
- depthCompare( shadowCoord.xy.add( vec2( dx3, 0 ) ), shadowCoord.z ),
55
- depthCompare( shadowCoord.xy.add( vec2( dx1, 0 ) ), shadowCoord.z ),
56
- depthCompare( shadowCoord.xy.add( vec2( dx2, dy3 ) ), shadowCoord.z ),
57
- depthCompare( shadowCoord.xy.add( vec2( 0, dy3 ) ), shadowCoord.z ),
58
- depthCompare( shadowCoord.xy.add( vec2( dx3, dy3 ) ), shadowCoord.z ),
59
- depthCompare( shadowCoord.xy.add( vec2( dx0, dy1 ) ), shadowCoord.z ),
60
- depthCompare( shadowCoord.xy.add( vec2( 0, dy1 ) ), shadowCoord.z ),
61
- depthCompare( shadowCoord.xy.add( vec2( dx1, dy1 ) ), shadowCoord.z )
62
- ).mul( 1 / 17 );
63
-
64
- } );
65
-
66
- const PCFSoftShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
67
-
68
- const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
69
-
70
- const mapSize = reference( 'mapSize', 'vec2', shadow ).setGroup( renderGroup );
71
-
72
- const texelSize = vec2( 1 ).div( mapSize );
73
- const dx = texelSize.x;
74
- const dy = texelSize.y;
75
-
76
- const uv = shadowCoord.xy;
77
- const f = fract( uv.mul( mapSize ).add( 0.5 ) );
78
- uv.subAssign( f.mul( texelSize ) );
79
-
80
- return add(
81
- depthCompare( uv, shadowCoord.z ),
82
- depthCompare( uv.add( vec2( dx, 0 ) ), shadowCoord.z ),
83
- depthCompare( uv.add( vec2( 0, dy ) ), shadowCoord.z ),
84
- depthCompare( uv.add( texelSize ), shadowCoord.z ),
85
- mix(
86
- depthCompare( uv.add( vec2( dx.negate(), 0 ) ), shadowCoord.z ),
87
- depthCompare( uv.add( vec2( dx.mul( 2 ), 0 ) ), shadowCoord.z ),
88
- f.x
89
- ),
90
- mix(
91
- depthCompare( uv.add( vec2( dx.negate(), dy ) ), shadowCoord.z ),
92
- depthCompare( uv.add( vec2( dx.mul( 2 ), dy ) ), shadowCoord.z ),
93
- f.x
94
- ),
95
- mix(
96
- depthCompare( uv.add( vec2( 0, dy.negate() ) ), shadowCoord.z ),
97
- depthCompare( uv.add( vec2( 0, dy.mul( 2 ) ) ), shadowCoord.z ),
98
- f.y
99
- ),
100
- mix(
101
- depthCompare( uv.add( vec2( dx, dy.negate() ) ), shadowCoord.z ),
102
- depthCompare( uv.add( vec2( dx, dy.mul( 2 ) ) ), shadowCoord.z ),
103
- f.y
104
- ),
105
- mix(
106
- mix(
107
- depthCompare( uv.add( vec2( dx.negate(), dy.negate() ) ), shadowCoord.z ),
108
- depthCompare( uv.add( vec2( dx.mul( 2 ), dy.negate() ) ), shadowCoord.z ),
109
- f.x
110
- ),
111
- mix(
112
- depthCompare( uv.add( vec2( dx.negate(), dy.mul( 2 ) ) ), shadowCoord.z ),
113
- depthCompare( uv.add( vec2( dx.mul( 2 ), dy.mul( 2 ) ) ), shadowCoord.z ),
114
- f.x
115
- ),
116
- f.y
117
- )
118
- ).mul( 1 / 9 );
119
-
120
- } );
121
-
122
- // VSM
123
-
124
- const VSMShadowMapNode = Fn( ( { depthTexture, shadowCoord } ) => {
125
-
126
- const occlusion = float( 1 ).toVar();
127
-
128
- const distribution = texture( depthTexture ).uv( shadowCoord.xy ).rg;
129
-
130
- const hardShadow = step( shadowCoord.z, distribution.x );
131
-
132
- If( hardShadow.notEqual( float( 1.0 ) ), () => {
133
-
134
- const distance = shadowCoord.z.sub( distribution.x );
135
- const variance = max( 0, distribution.y.mul( distribution.y ) );
136
- let softnessProbability = variance.div( variance.add( distance.mul( distance ) ) ); // Chebeyshevs inequality
137
- softnessProbability = clamp( sub( softnessProbability, 0.3 ).div( 0.95 - 0.3 ) );
138
- occlusion.assign( clamp( max( hardShadow, softnessProbability ) ) );
139
-
140
- } );
141
-
142
- return occlusion;
143
-
144
- } );
145
-
146
- const VSMPassVertical = Fn( ( { samples, radius, size, shadowPass } ) => {
147
-
148
- const mean = float( 0 ).toVar();
149
- const squaredMean = float( 0 ).toVar();
150
-
151
- const uvStride = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( 2 ).div( samples.sub( 1 ) ) );
152
- const uvStart = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( - 1 ) );
153
-
154
- Loop( { start: int( 0 ), end: int( samples ), type: 'int', condition: '<' }, ( { i } ) => {
155
-
156
- const uvOffset = uvStart.add( float( i ).mul( uvStride ) );
157
-
158
- const depth = shadowPass.uv( add( screenCoordinate.xy, vec2( 0, uvOffset ).mul( radius ) ).div( size ) ).x;
159
- mean.addAssign( depth );
160
- squaredMean.addAssign( depth.mul( depth ) );
161
-
162
- } );
163
-
164
- mean.divAssign( samples );
165
- squaredMean.divAssign( samples );
166
-
167
- const std_dev = sqrt( squaredMean.sub( mean.mul( mean ) ) );
168
- return vec2( mean, std_dev );
169
-
170
- } );
171
-
172
- const VSMPassHorizontal = Fn( ( { samples, radius, size, shadowPass } ) => {
173
-
174
- const mean = float( 0 ).toVar();
175
- const squaredMean = float( 0 ).toVar();
176
-
177
- const uvStride = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( 2 ).div( samples.sub( 1 ) ) );
178
- const uvStart = samples.lessThanEqual( float( 1 ) ).select( float( 0 ), float( - 1 ) );
179
-
180
- Loop( { start: int( 0 ), end: int( samples ), type: 'int', condition: '<' }, ( { i } ) => {
181
-
182
- const uvOffset = uvStart.add( float( i ).mul( uvStride ) );
183
-
184
- const distribution = shadowPass.uv( add( screenCoordinate.xy, vec2( uvOffset, 0 ).mul( radius ) ).div( size ) );
185
- mean.addAssign( distribution.x );
186
- squaredMean.addAssign( add( distribution.y.mul( distribution.y ), distribution.x.mul( distribution.x ) ) );
187
-
188
- } );
189
-
190
- mean.divAssign( samples );
191
- squaredMean.divAssign( samples );
192
-
193
- const std_dev = sqrt( squaredMean.sub( mean.mul( mean ) ) );
194
- return vec2( mean, std_dev );
195
-
196
- } );
197
-
198
- const _shadowFilterLib = [ BasicShadowMap, PCFShadowMap, PCFSoftShadowMap, VSMShadowMapNode ];
199
-
200
- //
201
-
202
- let _overrideMaterial = null;
203
- const _quadMesh = /*@__PURE__*/ new QuadMesh();
7
+ import { shadow } from './ShadowNode.js';
8
+ import { nodeObject } from '../tsl/TSLCore.js';
204
9
 
205
10
  class AnalyticLightNode extends LightingNode {
206
11
 
@@ -223,16 +28,9 @@ class AnalyticLightNode extends LightingNode {
223
28
 
224
29
  this.baseColorNode = null;
225
30
 
226
- this.shadowMap = null;
227
31
  this.shadowNode = null;
228
32
  this.shadowColorNode = null;
229
33
 
230
- this.vsmShadowMapVertical = null;
231
- this.vsmShadowMapHorizontal = null;
232
-
233
- this.vsmMaterialVertical = null;
234
- this.vsmMaterialHorizontal = null;
235
-
236
34
  this.isAnalyticLightNode = true;
237
35
 
238
36
  }
@@ -251,7 +49,7 @@ class AnalyticLightNode extends LightingNode {
251
49
 
252
50
  setupShadow( builder ) {
253
51
 
254
- const { object, renderer } = builder;
52
+ const { renderer } = builder;
255
53
 
256
54
  if ( renderer.shadowMap.enabled === false ) return;
257
55
 
@@ -259,101 +57,23 @@ class AnalyticLightNode extends LightingNode {
259
57
 
260
58
  if ( shadowColorNode === null ) {
261
59
 
262
- if ( _overrideMaterial === null ) {
263
-
264
- _overrideMaterial = new NodeMaterial();
265
- _overrideMaterial.fragmentNode = vec4( 0, 0, 0, 1 );
266
- _overrideMaterial.isShadowNodeMaterial = true; // Use to avoid other overrideMaterial override material.fragmentNode unintentionally when using material.shadowNode
267
- _overrideMaterial.name = 'ShadowMaterial';
268
-
269
- }
270
-
271
- const shadowMapType = renderer.shadowMap.type;
272
- const shadow = this.light.shadow;
273
-
274
- const depthTexture = new DepthTexture();
275
- depthTexture.compareFunction = LessCompare;
276
-
277
- const shadowMap = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
278
- shadowMap.depthTexture = depthTexture;
279
-
280
- shadow.camera.updateProjectionMatrix();
281
-
282
- // VSM
283
-
284
- if ( shadowMapType === VSMShadowMap ) {
285
-
286
- depthTexture.compareFunction = null; // VSM does not use textureSampleCompare()/texture2DCompare()
287
-
288
- this.vsmShadowMapVertical = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height, { format: RGFormat, type: HalfFloatType } );
289
- this.vsmShadowMapHorizontal = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height, { format: RGFormat, type: HalfFloatType } );
290
-
291
- const shadowPassVertical = texture( depthTexture );
292
- const shadowPassHorizontal = texture( this.vsmShadowMapVertical.texture );
293
-
294
- const samples = reference( 'blurSamples', 'float', shadow ).setGroup( renderGroup );
295
- const radius = reference( 'radius', 'float', shadow ).setGroup( renderGroup );
296
- const size = reference( 'mapSize', 'vec2', shadow ).setGroup( renderGroup );
60
+ const customShadowNode = this.light.shadow.shadowNode;
297
61
 
298
- let material = this.vsmMaterialVertical || ( this.vsmMaterialVertical = new NodeMaterial() );
299
- material.fragmentNode = VSMPassVertical( { samples, radius, size, shadowPass: shadowPassVertical } ).context( builder.getSharedContext() );
300
- material.name = 'VSMVertical';
62
+ let shadowNode;
301
63
 
302
- material = this.vsmMaterialHorizontal || ( this.vsmMaterialHorizontal = new NodeMaterial() );
303
- material.fragmentNode = VSMPassHorizontal( { samples, radius, size, shadowPass: shadowPassHorizontal } ).context( builder.getSharedContext() );
304
- material.name = 'VSMHorizontal';
64
+ if ( customShadowNode !== undefined ) {
305
65
 
306
- }
307
-
308
- //
309
-
310
- const shadowIntensity = reference( 'intensity', 'float', shadow ).setGroup( renderGroup );
311
- const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
312
- const normalBias = reference( 'normalBias', 'float', shadow ).setGroup( renderGroup );
313
-
314
- const position = object.material.shadowPositionNode || positionWorld;
315
-
316
- let shadowCoord = uniform( shadow.matrix ).setGroup( renderGroup ).mul( position.add( normalWorld.mul( normalBias ) ) );
317
- shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
66
+ shadowNode = nodeObject( customShadowNode );
318
67
 
319
- let coordZ = shadowCoord.z.add( bias );
68
+ } else {
320
69
 
321
- if ( renderer.coordinateSystem === WebGPUCoordinateSystem ) {
322
-
323
- coordZ = coordZ.mul( 2 ).sub( 1 ); // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ]
70
+ shadowNode = shadow( this.light );
324
71
 
325
72
  }
326
73
 
327
- shadowCoord = vec3(
328
- shadowCoord.x,
329
- shadowCoord.y.oneMinus(), // follow webgpu standards
330
- coordZ
331
- );
332
-
333
- const frustumTest = shadowCoord.x.greaterThanEqual( 0 )
334
- .and( shadowCoord.x.lessThanEqual( 1 ) )
335
- .and( shadowCoord.y.greaterThanEqual( 0 ) )
336
- .and( shadowCoord.y.lessThanEqual( 1 ) )
337
- .and( shadowCoord.z.lessThanEqual( 1 ) );
338
-
339
- //
340
-
341
- const filterFn = shadow.filterNode || _shadowFilterLib[ renderer.shadowMap.type ] || null;
342
-
343
- if ( filterFn === null ) {
344
-
345
- throw new Error( 'THREE.WebGPURenderer: Shadow map type not supported yet.' );
346
-
347
- }
348
-
349
- const shadowColor = texture( shadowMap.texture, shadowCoord );
350
- const shadowNode = frustumTest.select( filterFn( { depthTexture: ( shadowMapType === VSMShadowMap ) ? this.vsmShadowMapHorizontal.texture : depthTexture, shadowCoord, shadow } ), float( 1 ) );
351
-
352
- this.shadowMap = shadowMap;
353
- this.light.shadow.map = shadowMap;
354
-
355
74
  this.shadowNode = shadowNode;
356
- this.shadowColorNode = shadowColorNode = this.colorNode.mul( mix( 1, shadowNode.rgb.mix( shadowColor, 1 ), shadowIntensity.mul( shadowColor.a ) ) );
75
+
76
+ this.shadowColorNode = shadowColorNode = this.colorNode.mul( shadowNode );
357
77
 
358
78
  this.baseColorNode = this.colorNode;
359
79
 
@@ -363,8 +83,6 @@ class AnalyticLightNode extends LightingNode {
363
83
 
364
84
  this.colorNode = shadowColorNode;
365
85
 
366
- this.updateBeforeType = NodeUpdateType.RENDER;
367
-
368
86
  }
369
87
 
370
88
  setup( builder ) {
@@ -381,129 +99,7 @@ class AnalyticLightNode extends LightingNode {
381
99
 
382
100
  } else if ( this.shadowNode !== null ) {
383
101
 
384
- this.disposeShadow();
385
-
386
- }
387
-
388
- }
389
-
390
- updateShadow( frame ) {
391
-
392
- const { shadowMap, light } = this;
393
- const { renderer, scene, camera } = frame;
394
-
395
- const shadowType = renderer.shadowMap.type;
396
-
397
- const depthVersion = shadowMap.depthTexture.version;
398
- this._depthVersionCached = depthVersion;
399
-
400
- const currentOverrideMaterial = scene.overrideMaterial;
401
-
402
- scene.overrideMaterial = _overrideMaterial;
403
-
404
- shadowMap.setSize( light.shadow.mapSize.width, light.shadow.mapSize.height );
405
-
406
- light.shadow.updateMatrices( light );
407
- light.shadow.camera.layers.mask = camera.layers.mask;
408
-
409
- const currentRenderTarget = renderer.getRenderTarget();
410
- const currentRenderObjectFunction = renderer.getRenderObjectFunction();
411
-
412
- renderer.setRenderObjectFunction( ( object, ...params ) => {
413
-
414
- if ( object.castShadow === true || ( object.receiveShadow && shadowType === VSMShadowMap ) ) {
415
-
416
- renderer.renderObject( object, ...params );
417
-
418
- }
419
-
420
- } );
421
-
422
- renderer.setRenderTarget( shadowMap );
423
- renderer.render( scene, light.shadow.camera );
424
-
425
- renderer.setRenderObjectFunction( currentRenderObjectFunction );
426
-
427
- // vsm blur pass
428
-
429
- if ( light.isPointLight !== true && shadowType === VSMShadowMap ) {
430
-
431
- this.vsmPass( frame, light );
432
-
433
- }
434
-
435
- renderer.setRenderTarget( currentRenderTarget );
436
-
437
- scene.overrideMaterial = currentOverrideMaterial;
438
-
439
- }
440
-
441
- vsmPass( frame, light ) {
442
-
443
- const { renderer } = frame;
444
-
445
- this.vsmShadowMapVertical.setSize( light.shadow.mapSize.width, light.shadow.mapSize.height );
446
- this.vsmShadowMapHorizontal.setSize( light.shadow.mapSize.width, light.shadow.mapSize.height );
447
-
448
- renderer.setRenderTarget( this.vsmShadowMapVertical );
449
- _quadMesh.material = this.vsmMaterialVertical;
450
- _quadMesh.render( renderer );
451
-
452
- renderer.setRenderTarget( this.vsmShadowMapHorizontal );
453
- _quadMesh.material = this.vsmMaterialHorizontal;
454
- _quadMesh.render( renderer );
455
-
456
- }
457
-
458
- disposeShadow() {
459
-
460
- this.shadowMap.dispose();
461
- this.shadowMap = null;
462
-
463
- if ( this.vsmShadowMapVertical !== null ) {
464
-
465
- this.vsmShadowMapVertical.dispose();
466
- this.vsmShadowMapVertical = null;
467
-
468
- this.vsmMaterialVertical.dispose();
469
- this.vsmMaterialVertical = null;
470
-
471
- }
472
-
473
- if ( this.vsmShadowMapHorizontal !== null ) {
474
-
475
- this.vsmShadowMapHorizontal.dispose();
476
- this.vsmShadowMapHorizontal = null;
477
-
478
- this.vsmMaterialHorizontal.dispose();
479
- this.vsmMaterialHorizontal = null;
480
-
481
- }
482
-
483
- this.shadowNode = null;
484
- this.shadowColorNode = null;
485
-
486
- this.baseColorNode = null;
487
-
488
- this.updateBeforeType = NodeUpdateType.NONE;
489
-
490
- }
491
-
492
- updateBefore( frame ) {
493
-
494
- const shadow = this.light.shadow;
495
-
496
- const needsUpdate = shadow.needsUpdate || shadow.autoUpdate;
497
-
498
- if ( needsUpdate ) {
499
-
500
- this.updateShadow( frame );
501
-
502
- if ( this.shadowMap.depthTexture.version === this._depthVersionCached ) {
503
-
504
- shadow.needsUpdate = false;
505
-
506
- }
102
+ this.shadowNode.dispose();
507
103
 
508
104
  }
509
105
 
@@ -1,5 +1,5 @@
1
1
  import Node from '../core/Node.js';
2
- import { nodeObject, nodeProxy, vec3 } from '../tsl/TSLBase.js';
2
+ import { nodeObject, vec3 } from '../tsl/TSLBase.js';
3
3
 
4
4
  const sortLights = ( lights ) => {
5
5
 
@@ -33,7 +33,7 @@ class LightsNode extends Node {
33
33
 
34
34
  }
35
35
 
36
- constructor( lights = [] ) {
36
+ constructor() {
37
37
 
38
38
  super( 'vec3' );
39
39
 
@@ -42,7 +42,7 @@ class LightsNode extends Node {
42
42
 
43
43
  this.outgoingLightNode = vec3().toVar( 'outgoingLight' );
44
44
 
45
- this._lights = lights;
45
+ this._lights = [];
46
46
 
47
47
  this._lightNodes = null;
48
48
  this._lightNodesHash = null;
@@ -61,7 +61,7 @@ class LightsNode extends Node {
61
61
 
62
62
  for ( const lightNode of this._lightNodes ) {
63
63
 
64
- hash.push( lightNode.getHash() );
64
+ hash.push( lightNode.getSelf().getHash() );
65
65
 
66
66
  }
67
67
 
@@ -92,7 +92,7 @@ class LightsNode extends Node {
92
92
  const previousLightNodes = this._lightNodes;
93
93
 
94
94
  const lights = sortLights( this._lights );
95
- const nodeLibrary = builder.renderer.nodes.library;
95
+ const nodeLibrary = builder.renderer.library;
96
96
 
97
97
  for ( const light of lights ) {
98
98
 
@@ -125,7 +125,7 @@ class LightsNode extends Node {
125
125
 
126
126
  if ( ! _lightsNodeRef.has( light ) ) {
127
127
 
128
- lightNode = new lightNodeClass( light );
128
+ lightNode = nodeObject( new lightNodeClass( light ) );
129
129
  _lightsNodeRef.set( light, lightNode );
130
130
 
131
131
  } else {
@@ -146,6 +146,16 @@ class LightsNode extends Node {
146
146
 
147
147
  }
148
148
 
149
+ setupLights( builder, lightNodes ) {
150
+
151
+ for ( const lightNode of lightNodes ) {
152
+
153
+ lightNode.build( builder );
154
+
155
+ }
156
+
157
+ }
158
+
149
159
  setup( builder ) {
150
160
 
151
161
  if ( this._lightNodes === null ) this.setupLightsNode( builder );
@@ -174,11 +184,7 @@ class LightsNode extends Node {
174
184
 
175
185
  // lights
176
186
 
177
- for ( const lightNode of _lightNodes ) {
178
-
179
- lightNode.build( builder );
180
-
181
- }
187
+ this.setupLights( builder, _lightNodes );
182
188
 
183
189
  //
184
190
 
@@ -243,8 +249,14 @@ class LightsNode extends Node {
243
249
 
244
250
  }
245
251
 
252
+ get hasLights() {
253
+
254
+ return this._lights.length > 0;
255
+
256
+ }
257
+
246
258
  }
247
259
 
248
260
  export default LightsNode;
249
261
 
250
- export const lights = /*@__PURE__*/ nodeProxy( LightsNode );
262
+ export const lights = ( lights = [] ) => nodeObject( new LightsNode() ).setLights( lights );