super-three 0.169.0 → 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 (195) hide show
  1. package/build/three.cjs +989 -1131
  2. package/build/three.module.js +990 -1128
  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 +121 -126
  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/src/renderers/webvr/WebVRManager.js +0 -495
  194. package/src/renderers/webvr/WebVRUtils.js +0 -66
  195. /package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +0 -0
@@ -3,8 +3,6 @@ export * from './animation/CCDIKSolver.js';
3
3
  export * from './animation/MMDAnimationHelper.js';
4
4
  export * from './animation/MMDPhysics.js';
5
5
 
6
- export * from './cameras/CinematicCamera.js';
7
-
8
6
  export { default as WebGL } from './capabilities/WebGL.js';
9
7
 
10
8
  export * from './controls/ArcballControls.js';
@@ -131,6 +129,8 @@ export * from './loaders/VTKLoader.js';
131
129
  export * from './loaders/XYZLoader.js';
132
130
 
133
131
  export * from './materials/MeshGouraudMaterial.js';
132
+ export * from './materials/LDrawConditionalLineMaterial.js';
133
+ export * from './materials/MeshPostProcessingMaterial.js';
134
134
 
135
135
  export * from './math/Capsule.js';
136
136
  export * from './math/ColorConverter.js';
@@ -274,7 +274,7 @@ export * as SceneUtils from './utils/SceneUtils.js';
274
274
  export * from './utils/ShadowMapViewer.js';
275
275
  export * as SkeletonUtils from './utils/SkeletonUtils.js';
276
276
  export * as SortUtils from './utils/SortUtils.js';
277
- export * from './utils/TextureUtils.js';
277
+ export * from './utils/WebGLTextureUtils.js';
278
278
  export * from './utils/UVsDebug.js';
279
279
  export * from './utils/WorkerPool.js';
280
280
 
@@ -61,6 +61,8 @@ class MMDAnimationHelper {
61
61
  this.sharedPhysics = false;
62
62
  this.masterPhysics = null;
63
63
 
64
+ console.warn( 'THREE.MMDAnimationHelper: The module has been deprecated and will be removed with r172. Please migrate to https://github.com/takahirox/three-mmd-loader instead.' );
65
+
64
66
  }
65
67
 
66
68
  /**
@@ -68,6 +68,8 @@ class MMDPhysics {
68
68
 
69
69
  this._init( mesh, rigidBodyParams, constraintParams );
70
70
 
71
+ console.warn( 'THREE.MMDPhysics: The module has been deprecated and will be removed with r172. Please migrate to https://github.com/takahirox/three-mmd-loader instead.' );
72
+
71
73
  }
72
74
 
73
75
  /**
@@ -110,6 +110,12 @@ class TransformControls extends Controls {
110
110
  defineProperty( 'showX', true );
111
111
  defineProperty( 'showY', true );
112
112
  defineProperty( 'showZ', true );
113
+ defineProperty( 'minX', - Infinity );
114
+ defineProperty( 'maxX', Infinity );
115
+ defineProperty( 'minY', - Infinity );
116
+ defineProperty( 'maxY', Infinity );
117
+ defineProperty( 'minZ', - Infinity );
118
+ defineProperty( 'maxZ', Infinity );
113
119
 
114
120
  // Reusable utility variables
115
121
 
@@ -372,6 +378,10 @@ class TransformControls extends Controls {
372
378
 
373
379
  }
374
380
 
381
+ object.position.x = Math.max( this.minX, Math.min( this.maxX, object.position.x ) );
382
+ object.position.y = Math.max( this.minY, Math.min( this.maxY, object.position.y ) );
383
+ object.position.z = Math.max( this.minZ, Math.min( this.maxZ, object.position.z ) );
384
+
375
385
  } else if ( mode === 'scale' ) {
376
386
 
377
387
  if ( axis.search( 'XYZ' ) !== - 1 ) {
@@ -536,12 +546,7 @@ class TransformControls extends Controls {
536
546
 
537
547
  this.disconnect();
538
548
 
539
- this.traverse( function ( child ) {
540
-
541
- if ( child.geometry ) child.geometry.dispose();
542
- if ( child.material ) child.material.dispose();
543
-
544
- } );
549
+ this._root.dispose();
545
550
 
546
551
  }
547
552
 
@@ -811,6 +816,17 @@ class TransformControlsRoot extends Object3D {
811
816
 
812
817
  }
813
818
 
819
+ dispose() {
820
+
821
+ this.traverse( function ( child ) {
822
+
823
+ if ( child.geometry ) child.geometry.dispose();
824
+ if ( child.material ) child.material.dispose();
825
+
826
+ } );
827
+
828
+ }
829
+
814
830
  }
815
831
 
816
832
  class TransformControlsGizmo extends Object3D {
@@ -11,7 +11,7 @@ import { CSMFrustum } from './CSMFrustum.js';
11
11
  import { CSMShader } from './CSMShader.js';
12
12
 
13
13
  const _cameraToLightMatrix = new Matrix4();
14
- const _lightSpaceFrustum = new CSMFrustum();
14
+ const _lightSpaceFrustum = new CSMFrustum( { webGL: true } );
15
15
  const _center = new Vector3();
16
16
  const _bbox = new Box3();
17
17
  const _uniformArray = [];
@@ -38,7 +38,7 @@ export class CSM {
38
38
  this.lightMargin = data.lightMargin || 200;
39
39
  this.customSplitsCallback = data.customSplitsCallback;
40
40
  this.fade = false;
41
- this.mainFrustum = new CSMFrustum();
41
+ this.mainFrustum = new CSMFrustum( { webGL: true } );
42
42
  this.frustums = [];
43
43
  this.breaks = [];
44
44
 
@@ -8,6 +8,8 @@ class CSMFrustum {
8
8
 
9
9
  data = data || {};
10
10
 
11
+ this.zNear = data.webGL === true ? - 1 : 0;
12
+
11
13
  this.vertices = {
12
14
  near: [
13
15
  new Vector3(),
@@ -33,6 +35,7 @@ class CSMFrustum {
33
35
 
34
36
  setFromProjectionMatrix( projectionMatrix, maxFar ) {
35
37
 
38
+ const zNear = this.zNear;
36
39
  const isOrthographic = projectionMatrix.elements[ 2 * 4 + 3 ] === 0;
37
40
 
38
41
  inverseProjectionMatrix.copy( projectionMatrix ).invert();
@@ -42,10 +45,10 @@ class CSMFrustum {
42
45
  // 2 --- 1
43
46
  // clip space spans from [-1, 1]
44
47
 
45
- this.vertices.near[ 0 ].set( 1, 1, - 1 );
46
- this.vertices.near[ 1 ].set( 1, - 1, - 1 );
47
- this.vertices.near[ 2 ].set( - 1, - 1, - 1 );
48
- this.vertices.near[ 3 ].set( - 1, 1, - 1 );
48
+ this.vertices.near[ 0 ].set( 1, 1, zNear );
49
+ this.vertices.near[ 1 ].set( 1, - 1, zNear );
50
+ this.vertices.near[ 2 ].set( - 1, - 1, zNear );
51
+ this.vertices.near[ 3 ].set( - 1, 1, zNear );
49
52
  this.vertices.near.forEach( function ( v ) {
50
53
 
51
54
  v.applyMatrix4( inverseProjectionMatrix );
@@ -78,6 +78,8 @@ class CSMHelper extends Group {
78
78
  const cascadePlanes = this.cascadePlanes;
79
79
  const shadowLines = this.shadowLines;
80
80
 
81
+ if ( camera === null ) return;
82
+
81
83
  this.position.copy( camera.position );
82
84
  this.quaternion.copy( camera.quaternion );
83
85
  this.scale.copy( camera.scale );
@@ -0,0 +1,435 @@
1
+ import {
2
+ Vector2,
3
+ Vector3,
4
+ MathUtils,
5
+ Matrix4,
6
+ Box3,
7
+ Object3D,
8
+ WebGLCoordinateSystem
9
+ } from 'three';
10
+
11
+ import { CSMFrustum } from './CSMFrustum.js';
12
+ import { viewZToOrthographicDepth, reference, uniform, float, vec4, vec2, If, Fn, min, renderGroup, positionView, Node, NodeUpdateType, shadow } from 'three/tsl';
13
+
14
+ const _cameraToLightMatrix = new Matrix4();
15
+ const _lightSpaceFrustum = new CSMFrustum();
16
+ const _center = new Vector3();
17
+ const _bbox = new Box3();
18
+ const _uniformArray = [];
19
+ const _logArray = [];
20
+ const _lightDirection = new Vector3();
21
+ const _lightOrientationMatrix = new Matrix4();
22
+ const _lightOrientationMatrixInverse = new Matrix4();
23
+ const _up = new Vector3( 0, 1, 0 );
24
+
25
+ class LwLight extends Object3D {
26
+
27
+ constructor() {
28
+
29
+ super();
30
+
31
+ this.target = new Object3D();
32
+
33
+ }
34
+
35
+ }
36
+
37
+ class CSMShadowNode extends Node {
38
+
39
+ constructor( light, data = {} ) {
40
+
41
+ super();
42
+
43
+ this.light = light;
44
+ this.camera = null;
45
+ this.cascades = data.cascades || 3;
46
+ this.maxFar = data.maxFar || 100000;
47
+ this.mode = data.mode || 'practical';
48
+ this.lightMargin = data.lightMargin || 200;
49
+ this.customSplitsCallback = data.customSplitsCallback;
50
+
51
+ this.fade = false;
52
+
53
+ this.breaks = [];
54
+
55
+ this._cascades = [];
56
+ this.mainFrustum = null;
57
+ this.frustums = [];
58
+ this.updateBeforeType = NodeUpdateType.FRAME;
59
+
60
+ this.lights = [];
61
+
62
+ this._shadowNodes = [];
63
+
64
+ }
65
+
66
+ init( { camera, renderer } ) {
67
+
68
+ this.camera = camera;
69
+
70
+ const data = { webGL: renderer.coordinateSystem === WebGLCoordinateSystem };
71
+ this.mainFrustum = new CSMFrustum( data );
72
+
73
+ const light = this.light;
74
+ const parent = light.parent;
75
+
76
+ for ( let i = 0; i < this.cascades; i ++ ) {
77
+
78
+ const lwLight = new LwLight();
79
+ const lShadow = light.shadow.clone();
80
+ lShadow.bias = lShadow.bias * ( i + 1 );
81
+
82
+ this.lights.push( lwLight );
83
+
84
+ parent.add( lwLight );
85
+ parent.add( lwLight.target );
86
+
87
+ lwLight.shadow = lShadow;
88
+
89
+ this._shadowNodes.push( shadow( lwLight, lShadow ) );
90
+
91
+ this._cascades.push( new Vector2() );
92
+
93
+ }
94
+
95
+ this.updateFrustums();
96
+
97
+ }
98
+
99
+ initCascades() {
100
+
101
+ const camera = this.camera;
102
+ camera.updateProjectionMatrix();
103
+
104
+ this.mainFrustum.setFromProjectionMatrix( camera.projectionMatrix, this.maxFar );
105
+ this.mainFrustum.split( this.breaks, this.frustums );
106
+
107
+ }
108
+
109
+ getBreaks() {
110
+
111
+ const camera = this.camera;
112
+ const far = Math.min( camera.far, this.maxFar );
113
+
114
+ this.breaks.length = 0;
115
+
116
+ switch ( this.mode ) {
117
+
118
+ case 'uniform':
119
+ uniformSplit( this.cascades, camera.near, far, this.breaks );
120
+ break;
121
+
122
+ case 'logarithmic':
123
+ logarithmicSplit( this.cascades, camera.near, far, this.breaks );
124
+ break;
125
+
126
+ case 'practical':
127
+ practicalSplit( this.cascades, camera.near, far, 0.5, this.breaks );
128
+ break;
129
+
130
+ case 'custom':
131
+ if ( this.customSplitsCallback === undefined ) console.error( 'CSM: Custom split scheme callback not defined.' );
132
+ this.customSplitsCallback( this.cascades, camera.near, far, this.breaks );
133
+ break;
134
+
135
+ }
136
+
137
+ function uniformSplit( amount, near, far, target ) {
138
+
139
+ for ( let i = 1; i < amount; i ++ ) {
140
+
141
+ target.push( ( near + ( far - near ) * i / amount ) / far );
142
+
143
+ }
144
+
145
+ target.push( 1 );
146
+
147
+ }
148
+
149
+ function logarithmicSplit( amount, near, far, target ) {
150
+
151
+ for ( let i = 1; i < amount; i ++ ) {
152
+
153
+ target.push( ( near * ( far / near ) ** ( i / amount ) ) / far );
154
+
155
+ }
156
+
157
+ target.push( 1 );
158
+
159
+ }
160
+
161
+ function practicalSplit( amount, near, far, lambda, target ) {
162
+
163
+ _uniformArray.length = 0;
164
+ _logArray.length = 0;
165
+ logarithmicSplit( amount, near, far, _logArray );
166
+ uniformSplit( amount, near, far, _uniformArray );
167
+
168
+ for ( let i = 1; i < amount; i ++ ) {
169
+
170
+ target.push( MathUtils.lerp( _uniformArray[ i - 1 ], _logArray[ i - 1 ], lambda ) );
171
+
172
+ }
173
+
174
+ target.push( 1 );
175
+
176
+ }
177
+
178
+ }
179
+
180
+ setLightBreaks() {
181
+
182
+ for ( let i = 0, l = this.cascades; i < l; i ++ ) {
183
+
184
+ const amount = this.breaks[ i ];
185
+ const prev = this.breaks[ i - 1 ] || 0;
186
+
187
+ this._cascades[ i ].set( prev, amount );
188
+
189
+ }
190
+
191
+ }
192
+
193
+ updateShadowBounds() {
194
+
195
+ const frustums = this.frustums;
196
+
197
+ for ( let i = 0; i < frustums.length; i ++ ) {
198
+
199
+ const shadowCam = this.lights[ i ].shadow.camera;
200
+ const frustum = this.frustums[ i ];
201
+
202
+ // Get the two points that represent that furthest points on the frustum assuming
203
+ // that's either the diagonal across the far plane or the diagonal across the whole
204
+ // frustum itself.
205
+ const nearVerts = frustum.vertices.near;
206
+ const farVerts = frustum.vertices.far;
207
+ const point1 = farVerts[ 0 ];
208
+
209
+ let point2;
210
+
211
+ if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) {
212
+
213
+ point2 = farVerts[ 2 ];
214
+
215
+ } else {
216
+
217
+ point2 = nearVerts[ 2 ];
218
+
219
+ }
220
+
221
+ let squaredBBWidth = point1.distanceTo( point2 );
222
+
223
+ if ( this.fade ) {
224
+
225
+ // expand the shadow extents by the fade margin if fade is enabled.
226
+ const camera = this.camera;
227
+ const far = Math.max( camera.far, this.maxFar );
228
+ const linearDepth = frustum.vertices.far[ 0 ].z / ( far - camera.near );
229
+ const margin = 0.25 * Math.pow( linearDepth, 2.0 ) * ( far - camera.near );
230
+
231
+ squaredBBWidth += margin;
232
+
233
+ }
234
+
235
+ shadowCam.left = - squaredBBWidth / 2;
236
+ shadowCam.right = squaredBBWidth / 2;
237
+ shadowCam.top = squaredBBWidth / 2;
238
+ shadowCam.bottom = - squaredBBWidth / 2;
239
+ shadowCam.updateProjectionMatrix();
240
+
241
+ }
242
+
243
+ }
244
+
245
+ updateFrustums() {
246
+
247
+ this.getBreaks();
248
+ this.initCascades();
249
+ this.updateShadowBounds();
250
+ this.setLightBreaks();
251
+
252
+ }
253
+
254
+ setupFade() {
255
+
256
+ const cameraNear = reference( 'camera.near', 'float', this ).setGroup( renderGroup ).label( 'cameraNear' );
257
+ const cascades = reference( '_cascades', 'vec2', this ).setGroup( renderGroup ).label( 'cacades' );
258
+
259
+ const shadowFar = uniform( 'float' ).setGroup( renderGroup ).label( 'shadowFar' )
260
+ .onRenderUpdate( () => Math.min( this.maxFar, this.camera.far ) );
261
+
262
+ const linearDepth = viewZToOrthographicDepth( positionView.z, cameraNear, shadowFar ).toVar( 'linearDepth' );
263
+ const lastCascade = this.cascades - 1;
264
+
265
+ return Fn( () => {
266
+
267
+ const ret = vec4( 1, 1, 1, 1 ).toVar( 'shadowValue' );
268
+
269
+ const cascade = vec2().toVar( 'cascade' );
270
+ const cascadeCenter = float().toVar( 'cascadeCenter' );
271
+
272
+ const margin = float().toVar( 'margin' );
273
+
274
+ const csmX = float().toVar( 'csmX' );
275
+ const csmY = float().toVar( 'csmY' );
276
+
277
+ for ( let i = 0; i < this.cascades; i ++ ) {
278
+
279
+ const isLastCascade = i === lastCascade;
280
+
281
+ cascade.assign( cascades.element( i ) );
282
+
283
+ cascadeCenter.assign( cascade.x.add( cascade.y ).div( 2.0 ) );
284
+
285
+ const closestEdge = linearDepth.lessThan( cascadeCenter ).select( cascade.x, cascade.y );
286
+
287
+ margin.assign( float( 0.25 ).mul( closestEdge.pow( 2.0 ) ) );
288
+
289
+ csmX.assign( cascade.x.sub( margin.div( 2.0 ) ) );
290
+
291
+ if ( isLastCascade ) {
292
+
293
+ csmY.assign( cascade.y );
294
+
295
+ } else {
296
+
297
+ csmY.assign( cascade.y.add( margin.div( 2.0 ) ) );
298
+
299
+ }
300
+
301
+ const inRange = linearDepth.greaterThanEqual( csmX ).and( linearDepth.lessThanEqual( csmY ) );
302
+
303
+ If( inRange, () => {
304
+
305
+ const dist = min( linearDepth.sub( csmX ), csmY.sub( linearDepth ) ).toVar();
306
+
307
+ let ratio = dist.div( margin ).clamp( 0.0, 1.0 );
308
+
309
+ if ( i === 0 ) {
310
+
311
+ // dont fade at nearest edge
312
+ ratio = linearDepth.greaterThan( cascadeCenter ).select( ratio, 1 );
313
+
314
+ }
315
+
316
+ ret.subAssign( this._shadowNodes[ i ].oneMinus().mul( ratio ) );
317
+
318
+ } );
319
+
320
+ }
321
+
322
+ return ret;
323
+
324
+ } )();
325
+
326
+ }
327
+
328
+ setupStandard() {
329
+
330
+ const cameraNear = reference( 'camera.near', 'float', this ).setGroup( renderGroup ).label( 'cameraNear' );
331
+ const cascades = reference( '_cascades', 'vec2', this ).setGroup( renderGroup ).label( 'cacades' );
332
+
333
+ const shadowFar = uniform( 'float' ).setGroup( renderGroup ).label( 'shadowFar' )
334
+ .onRenderUpdate( () => Math.min( this.maxFar, this.camera.far ) );
335
+
336
+ const linearDepth = viewZToOrthographicDepth( positionView.z, cameraNear, shadowFar ).toVar( 'linearDepth' );
337
+
338
+ return Fn( () => {
339
+
340
+ const ret = vec4( 1, 1, 1, 1 ).toVar( 'shadowValue' );
341
+ const cascade = vec2().toVar( 'cascade' );
342
+
343
+ for ( let i = 0; i < this.cascades; i ++ ) {
344
+
345
+ cascade.assign( cascades.element( i ) );
346
+
347
+ If( linearDepth.greaterThanEqual( cascade.x ).and( linearDepth.lessThanEqual( cascade.y ) ), () => {
348
+
349
+ ret.assign( this._shadowNodes[ i ] );
350
+
351
+ } );
352
+
353
+ }
354
+
355
+ return ret;
356
+
357
+ } )();
358
+
359
+ }
360
+
361
+ setup( builder ) {
362
+
363
+ if ( this.camera === null ) this.init( builder );
364
+
365
+ return this.fade === true ? this.setupFade() : this.setupStandard();
366
+
367
+ }
368
+
369
+ updateBefore( /*builder*/ ) {
370
+
371
+ const light = this.light;
372
+ const camera = this.camera;
373
+ const frustums = this.frustums;
374
+
375
+ _lightDirection.subVectors( light.target.position, light.position ).normalize();
376
+
377
+ // for each frustum we need to find its min-max box aligned with the light orientation
378
+ // the position in _lightOrientationMatrix does not matter, as we transform there and back
379
+ _lightOrientationMatrix.lookAt( light.position, light.target.position, _up );
380
+ _lightOrientationMatrixInverse.copy( _lightOrientationMatrix ).invert();
381
+
382
+ for ( let i = 0; i < frustums.length; i ++ ) {
383
+
384
+ const lwLight = this.lights[ i ];
385
+ const shadow = lwLight.shadow;
386
+ const shadowCam = shadow.camera;
387
+ const texelWidth = ( shadowCam.right - shadowCam.left ) / shadow.mapSize.width;
388
+ const texelHeight = ( shadowCam.top - shadowCam.bottom ) / shadow.mapSize.height;
389
+
390
+ _cameraToLightMatrix.multiplyMatrices( _lightOrientationMatrixInverse, camera.matrixWorld );
391
+ frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum );
392
+
393
+ const nearVerts = _lightSpaceFrustum.vertices.near;
394
+ const farVerts = _lightSpaceFrustum.vertices.far;
395
+
396
+ _bbox.makeEmpty();
397
+
398
+ for ( let j = 0; j < 4; j ++ ) {
399
+
400
+ _bbox.expandByPoint( nearVerts[ j ] );
401
+ _bbox.expandByPoint( farVerts[ j ] );
402
+
403
+ }
404
+
405
+ _bbox.getCenter( _center );
406
+ _center.z = _bbox.max.z + this.lightMargin;
407
+ _center.x = Math.floor( _center.x / texelWidth ) * texelWidth;
408
+ _center.y = Math.floor( _center.y / texelHeight ) * texelHeight;
409
+ _center.applyMatrix4( _lightOrientationMatrix );
410
+
411
+ lwLight.position.copy( _center );
412
+ lwLight.target.position.copy( _center );
413
+ lwLight.target.position.add( _lightDirection );
414
+
415
+ }
416
+
417
+ }
418
+
419
+ dispose() {
420
+
421
+ for ( let i = 0; i < this.lights.length; i ++ ) {
422
+
423
+ const light = this.lights[ i ];
424
+ const parent = light.parent;
425
+
426
+ parent.remove( light.target );
427
+ parent.remove( light );
428
+
429
+ }
430
+
431
+ }
432
+
433
+ }
434
+
435
+ export { CSMShadowNode };
@@ -26,14 +26,17 @@ class NURBSCurve extends Curve {
26
26
 
27
27
  super();
28
28
 
29
+ const knotsLength = knots ? knots.length - 1 : 0;
30
+ const pointsLength = controlPoints ? controlPoints.length : 0;
31
+
29
32
  this.degree = degree;
30
33
  this.knots = knots;
31
34
  this.controlPoints = [];
32
35
  // Used by periodic NURBS to remove hidden spans
33
36
  this.startKnot = startKnot || 0;
34
- this.endKnot = endKnot || ( this.knots.length - 1 );
37
+ this.endKnot = endKnot || knotsLength;
35
38
 
36
- for ( let i = 0; i < controlPoints.length; ++ i ) {
39
+ for ( let i = 0; i < pointsLength; ++ i ) {
37
40
 
38
41
  // ensure Vector4 for control points
39
42
  const point = controlPoints[ i ];
@@ -75,6 +78,34 @@ class NURBSCurve extends Curve {
75
78
 
76
79
  }
77
80
 
81
+ toJSON() {
82
+
83
+ const data = super.toJSON();
84
+
85
+ data.degree = this.degree;
86
+ data.knots = [ ...this.knots ];
87
+ data.controlPoints = this.controlPoints.map( p => p.toArray() );
88
+ data.startKnot = this.startKnot;
89
+ data.endKnot = this.endKnot;
90
+
91
+ return data;
92
+
93
+ }
94
+
95
+ fromJSON( json ) {
96
+
97
+ super.fromJSON( json );
98
+
99
+ this.degree = json.degree;
100
+ this.knots = [ ...json.knots ];
101
+ this.controlPoints = json.controlPoints.map( p => new Vector4( p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] ) );
102
+ this.startKnot = json.startKnot;
103
+ this.endKnot = json.endKnot;
104
+
105
+ return this;
106
+
107
+ }
108
+
78
109
  }
79
110
 
80
- export { NURBSCurve };
111
+ export { NURBSCurve };