three-low-poly 0.9.22 → 0.9.24

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.
package/dist/index.d.ts CHANGED
@@ -2,13 +2,15 @@ import { BoxGeometry } from 'three';
2
2
  import { BufferGeometry } from 'three';
3
3
  import { Camera } from 'three';
4
4
  import { Color } from 'three';
5
+ import { ColorRepresentation } from 'three';
5
6
  import { DataTexture } from 'three';
7
+ import { DirectionalLight } from 'three';
6
8
  import { ExtrudeGeometry } from 'three';
7
9
  import { Group } from 'three';
8
10
  import { InstancedMesh } from 'three';
9
- import { Light } from 'three';
10
11
  import { Material } from 'three';
11
12
  import { Mesh } from 'three';
13
+ import { MeshBasicMaterial } from 'three';
12
14
  import { MeshLambertMaterial } from 'three';
13
15
  import { MeshPhongMaterial } from 'three';
14
16
  import { MeshPhysicalMaterial } from 'three';
@@ -16,9 +18,13 @@ import { MeshStandardMaterial } from 'three';
16
18
  import { Object3D } from 'three';
17
19
  import { ParametricGeometry } from 'three-stdlib';
18
20
  import { PerspectiveCamera } from 'three';
21
+ import { PlaneGeometry } from 'three';
22
+ import { PointLight } from 'three';
23
+ import { Points } from 'three';
19
24
  import { ShaderMaterial } from 'three';
20
25
  import { Shape } from 'three';
21
26
  import { SphereGeometry } from 'three';
27
+ import * as THREE from 'three';
22
28
  import { Uniform } from 'three';
23
29
  import { Vector2 } from 'three';
24
30
  import { Vector3 } from 'three';
@@ -390,6 +396,31 @@ export declare class BifurcatedStaircaseGeometry extends BufferGeometry {
390
396
  constructor(stepWidth?: number, stepHeight?: number, stepDepth?: number, numStepsCentral?: number, numStepsBranch?: number, branchAngle?: number);
391
397
  }
392
398
 
399
+ declare interface BloomTransitionOptions extends SceneTransitionFXOptions {
400
+ maxBloom?: number;
401
+ }
402
+
403
+ declare interface BlurTransitionOptions extends SceneTransitionFXOptions {
404
+ maxBlur?: number;
405
+ kernelSize?: number;
406
+ }
407
+
408
+ export declare const blurTransitionShader: {
409
+ uniforms: {
410
+ tDiffuse: {
411
+ value: null;
412
+ };
413
+ kernelSize: {
414
+ value: number;
415
+ };
416
+ resolution: {
417
+ value: null;
418
+ };
419
+ };
420
+ vertexShader: string;
421
+ fragmentShader: string;
422
+ };
423
+
393
424
  export declare class Bone extends Mesh<BoneGeometry, MeshStandardMaterial> {
394
425
  constructor();
395
426
  }
@@ -472,31 +503,31 @@ export declare enum BoxSide {
472
503
  BACK = "back"
473
504
  }
474
505
 
475
- export declare class BubblingEffect extends InstancedMesh {
476
- private bubblePositions;
477
- private velocities;
478
- private width;
479
- private height;
480
- private depth;
481
- constructor(options?: BubblingEffectOptions);
482
- /**
483
- * Updates the position of a specific bubble instance in the InstancedMesh.
484
- */
485
- private updateInstanceMatrix;
486
- /**
487
- * Updates bubble positions, moving them upward and resetting them
488
- * to the bottom if they reach the top.
489
- */
490
- update(): void;
506
+ /**
507
+ * Single brick geometry for low-poly aesthetic.
508
+ * Default dimensions approximate standard brick proportions (in feet scale).
509
+ */
510
+ export declare class BrickGeometry extends BufferGeometry {
511
+ constructor({ width, height, depth, }?: {
512
+ width?: number | undefined;
513
+ height?: number | undefined;
514
+ depth?: number | undefined;
515
+ });
491
516
  }
492
517
 
493
- export declare interface BubblingEffectOptions {
494
- geometry?: BufferGeometry;
518
+ export declare interface BrickWallOptions {
519
+ wallWidth?: number;
520
+ wallHeight?: number;
521
+ brickWidth?: number;
522
+ brickHeight?: number;
523
+ brickDepth?: number;
524
+ mortarGap?: number;
525
+ offsetPattern?: boolean;
526
+ brickColors?: number[];
527
+ colorVariation?: boolean;
528
+ positionVariation?: number;
529
+ rotationVariation?: number;
495
530
  material?: Material;
496
- count?: number;
497
- height?: number;
498
- width?: number;
499
- depth?: number;
500
531
  }
501
532
 
502
533
  export declare class BunsenBurner extends Group {
@@ -644,6 +675,87 @@ export declare function cameraPendulumAnimation(camera: Camera, center: Vector3,
644
675
  */
645
676
  export declare function cameraSpiralAscensionAnimation(camera: Camera, center: Vector3, radius: number, height: number, revolutions: number, duration: number, onComplete?: () => void): void;
646
677
 
678
+ /**
679
+ * CameraTransition provides smooth animated transitions between perspective and orthographic cameras.
680
+ *
681
+ * The transition works by rendering both camera views to separate render targets and blending between them.
682
+ * This provides a true, accurate transition between the two camera types.
683
+ *
684
+ * @example
685
+ * ```typescript
686
+ * const transition = new CameraTransition(
687
+ * perspectiveCamera,
688
+ * orthographicCamera,
689
+ * renderer
690
+ * );
691
+ *
692
+ * transition.transitionTo(orthographicCamera, {
693
+ * duration: 1000,
694
+ * easing: 'easeInOutCubic'
695
+ * });
696
+ * ```
697
+ */
698
+ export declare class CameraTransition {
699
+ private perspectiveCamera;
700
+ private orthographicCamera;
701
+ private renderer;
702
+ private scene;
703
+ private currentCamera;
704
+ private targetCamera;
705
+ private transitionProgress;
706
+ private transitionDuration;
707
+ private transitionStartTime;
708
+ private isTransitioning;
709
+ private easingFunction;
710
+ private renderTargetA;
711
+ private renderTargetB;
712
+ private blendScene;
713
+ private blendCamera;
714
+ private blendMaterial;
715
+ private onUpdateCallback?;
716
+ private onCompleteCallback?;
717
+ constructor(perspectiveCamera: THREE.PerspectiveCamera, orthographicCamera: THREE.OrthographicCamera, renderer: THREE.WebGLRenderer);
718
+ /**
719
+ * Start a transition to the target camera
720
+ */
721
+ transitionTo(targetCamera: THREE.PerspectiveCamera | THREE.OrthographicCamera, options?: CameraTransitionOptions): void;
722
+ /**
723
+ * Update the transition. Call this in your render loop.
724
+ */
725
+ update(scene: THREE.Scene): THREE.Camera;
726
+ /**
727
+ * Render the scene with camera transition blending
728
+ */
729
+ render(scene: THREE.Scene): void;
730
+ /**
731
+ * Get the current active camera
732
+ */
733
+ getCurrentCamera(): THREE.Camera;
734
+ /**
735
+ * Check if a transition is currently in progress
736
+ */
737
+ getIsTransitioning(): boolean;
738
+ /**
739
+ * Get the current transition progress (0-1)
740
+ */
741
+ getProgress(): number;
742
+ /**
743
+ * Resize the render targets when the renderer size changes
744
+ */
745
+ setSize(width: number, height: number): void;
746
+ /**
747
+ * Dispose of resources
748
+ */
749
+ dispose(): void;
750
+ }
751
+
752
+ export declare interface CameraTransitionOptions {
753
+ duration?: number;
754
+ easing?: EasingFunction | keyof typeof Easing;
755
+ onUpdate?: (progress: number) => void;
756
+ onComplete?: () => void;
757
+ }
758
+
647
759
  /**
648
760
  * Add a slight random wobble for intensity or realism (e.g., during an explosion).
649
761
  *
@@ -775,12 +887,6 @@ export declare function centerObjectGeometry<T extends Object3D>(object: T, targ
775
887
  */
776
888
  export declare const checkerboardTexture: (size: number) => DataTexture;
777
889
 
778
- export declare const circularEaseIn: (t: number) => number;
779
-
780
- export declare const circularEaseInOut: (t: number) => number;
781
-
782
- export declare const circularEaseOut: (t: number) => number;
783
-
784
890
  export declare const ColorPalette: {
785
891
  CADMIUM_RED: number;
786
892
  CARDINAL_RED: number;
@@ -853,9 +959,21 @@ export declare const ColorPalette: {
853
959
  TITANIUM_WHITE: number;
854
960
  };
855
961
 
856
- export declare const concave: (t: number) => number;
857
-
858
- export declare const convex: (t: number) => number;
962
+ /**
963
+ * Creates an instanced mesh brick wall with running bond pattern.
964
+ *
965
+ * @example
966
+ * ```ts
967
+ * const wall = createBrickWall({
968
+ * wallWidth: 10,
969
+ * wallHeight: 8,
970
+ * brickColors: [0x8b4513, 0xa0522d, 0x6b3410],
971
+ * colorVariation: true
972
+ * });
973
+ * scene.add(wall);
974
+ * ```
975
+ */
976
+ export declare function createBrickWall({ wallWidth, wallHeight, brickWidth, brickHeight, brickDepth, mortarGap, offsetPattern, brickColors, colorVariation, positionVariation, rotationVariation, material, }?: BrickWallOptions): InstancedMesh;
859
977
 
860
978
  /**
861
979
  * Function to create cubic Bezier curve points
@@ -1071,6 +1189,22 @@ export declare const createQuadraticCurvePoints: (start: Vector2, control: Vecto
1071
1189
  */
1072
1190
  export declare const createSigmoidCurvePoints: (start: Vector2, end: Vector2, a: number, segments?: number) => Vector2[];
1073
1191
 
1192
+ export declare const crossfadeShader: {
1193
+ uniforms: {
1194
+ tDiffuseA: {
1195
+ value: null;
1196
+ };
1197
+ tDiffuseB: {
1198
+ value: null;
1199
+ };
1200
+ mixRatio: {
1201
+ value: number;
1202
+ };
1203
+ };
1204
+ vertexShader: string;
1205
+ fragmentShader: string;
1206
+ };
1207
+
1074
1208
  export declare class CrossHeadstone extends Mesh<CrossHeadstoneGeometry, MeshStandardMaterial> {
1075
1209
  constructor({ width, height, depth, }?: CrossHeadstoneOptions);
1076
1210
  }
@@ -1085,14 +1219,6 @@ declare interface CrossHeadstoneOptions {
1085
1219
  depth?: number;
1086
1220
  }
1087
1221
 
1088
- export declare const cubicCurve: (t: number, p0: number, p1: number, p2: number, p3: number) => number;
1089
-
1090
- export declare const cubicEaseIn: (t: number) => number;
1091
-
1092
- export declare const cubicEaseInOut: (t: number) => number;
1093
-
1094
- export declare const cubicEaseOut: (t: number) => number;
1095
-
1096
1222
  /**
1097
1223
  * Cubic UV Mapping
1098
1224
  * Applies a texture by projecting UVs along each face of a cube.
@@ -1132,8 +1258,6 @@ export declare function cubicUVMappingBatch(vertices: [number, number, number][]
1132
1258
  */
1133
1259
  export declare function cylindricalUVMapping(vertices: [number, number, number][]): [number, number][];
1134
1260
 
1135
- export declare const dampedCurve: (t: number, damping?: number) => number;
1136
-
1137
1261
  export declare class DaySkybox extends Mesh {
1138
1262
  geometry: BoxGeometry;
1139
1263
  material: ShaderMaterial & {
@@ -1310,39 +1434,151 @@ export declare const displacementBrush: <T extends BufferGeometry>(geometry: T,
1310
1434
 
1311
1435
  /**
1312
1436
  * Easing functions for interpolating values over time.
1437
+ *
1438
+ * Use these functions to create smooth animations and transitions.
1439
+ * All easing functions take a value t between 0 and 1 and return an eased value between 0 and 1.
1440
+ *
1441
+ * @example
1442
+ * ```typescript
1443
+ * import { Easing } from 'three-low-poly';
1444
+ *
1445
+ * // Using with transitions (namespace)
1446
+ * cameraTransition.transitionTo(camera, {
1447
+ * duration: 1000,
1448
+ * easing: Easing.cubicInOut // Function reference
1449
+ * });
1450
+ *
1451
+ * // Or using string reference
1452
+ * cameraTransition.transitionTo(camera, {
1453
+ * duration: 1000,
1454
+ * easing: 'cubicInOut' // String reference
1455
+ * });
1456
+ *
1457
+ * // Using the function directly in custom animation
1458
+ * const progress = 0.5;
1459
+ * const easedValue = Easing.cubicInOut(progress);
1460
+ *
1461
+ * // Custom animation loop
1462
+ * const startValue = 0;
1463
+ * const endValue = 100;
1464
+ * const t = elapsedTime / duration;
1465
+ * const easedT = Easing.sineInOut(t);
1466
+ * const currentValue = startValue + (endValue - startValue) * easedT;
1467
+ * ```
1313
1468
  */
1314
1469
  export declare const Easing: {
1315
- SINE_EASE_IN: (t: number) => number;
1316
- SINE_EASE_OUT: (t: number) => number;
1317
- SINE_EASE_IN_OUT: (t: number) => number;
1318
- QUADRATIC_EASE_IN: (t: number) => number;
1319
- QUADRATIC_EASE_OUT: (t: number) => number;
1320
- QUADRATIC_EASE_IN_OUT: (t: number) => number;
1321
- CUBIC_EASE_IN: (t: number) => number;
1322
- CUBIC_EASE_OUT: (t: number) => number;
1323
- CUBIC_EASE_IN_OUT: (t: number) => number;
1324
- QUARTIC_EASE_IN: (t: number) => number;
1325
- QUARTIC_EASE_OUT: (t: number) => number;
1326
- QUARTIC_EASE_IN_OUT: (t: number) => number;
1327
- QUINTIC_EASE_IN: (t: number) => number;
1328
- QUINTIC_EASE_OUT: (t: number) => number;
1329
- QUINTIC_EASE_IN_OUT: (t: number) => number;
1330
- EXPONENTIAL_EASE_IN: (t: number) => number;
1331
- EXPONENTIAL_EASE_OUT: (t: number) => number;
1332
- EXPONENTIAL_EASE_IN_OUT: (t: number) => number;
1333
- CIRCULAR_EASE_IN: (t: number) => number;
1334
- CIRCULAR_EASE_OUT: (t: number) => number;
1335
- CIRCULAR_EASE_IN_OUT: (t: number) => number;
1336
- LINEAR: (t: number) => number;
1337
- SMOOTHSTEP: (t: number) => number;
1338
- CONCAVE: (t: number) => number;
1339
- CONVEX: (t: number) => number;
1340
- LOGARITHMIC: (t: number) => number;
1341
- SQUARE_ROOT: (t: number) => number;
1342
- INVERSE: (t: number) => number;
1343
- GAUSSIAN: (t: number) => number;
1470
+ sineIn: (t: number) => number;
1471
+ sineOut: (t: number) => number;
1472
+ sineInOut: (t: number) => number;
1473
+ quadIn: (t: number) => number;
1474
+ quadOut: (t: number) => number;
1475
+ quadInOut: (t: number) => number;
1476
+ cubicIn: (t: number) => number;
1477
+ cubicOut: (t: number) => number;
1478
+ cubicInOut: (t: number) => number;
1479
+ quartIn: (t: number) => number;
1480
+ quartOut: (t: number) => number;
1481
+ quartInOut: (t: number) => number;
1482
+ quintIn: (t: number) => number;
1483
+ quintOut: (t: number) => number;
1484
+ quintInOut: (t: number) => number;
1485
+ expoIn: (t: number) => number;
1486
+ expoOut: (t: number) => number;
1487
+ expoInOut: (t: number) => number;
1488
+ circIn: (t: number) => number;
1489
+ circOut: (t: number) => number;
1490
+ circInOut: (t: number) => number;
1491
+ linear: (t: number) => number;
1492
+ smoothstep: (t: number) => number;
1493
+ concave: (t: number) => number;
1494
+ convex: (t: number) => number;
1495
+ logarithmic: (t: number) => number;
1496
+ squareRoot: (t: number) => number;
1497
+ inverse: (t: number) => number;
1498
+ gaussian: (t: number) => number;
1344
1499
  };
1345
1500
 
1501
+ /**
1502
+ * Easing function type for interpolating values over time.
1503
+ * @param t - Progress value between 0 and 1
1504
+ * @returns Eased value between 0 and 1
1505
+ */
1506
+ export declare type EasingFunction = (t: number) => number;
1507
+
1508
+ /**
1509
+ * Carbonation bubbles rising through a bounded volume — seltzer, soda, or
1510
+ * brewing liquid. Each instance drifts upward at its own speed and respawns
1511
+ * near {@link EffervescenceEffectOptions.baseY} after reaching the top.
1512
+ *
1513
+ * Spawn positions use a square footprint (`width` × `depth`). {@link EffervescenceEffectOptions.spread}
1514
+ * pulls that box inward so round jars do not get occasional corner outliers.
1515
+ * Position and scale the effect to sit inside a jar, flask, or panel viewport.
1516
+ * Call {@link EffervescenceEffect.update} each frame with elapsed time in seconds.
1517
+ *
1518
+ * @example
1519
+ * ```typescript
1520
+ * const fizz = new EffervescenceEffect({ width: 1.2, height: 2.5, count: 30 });
1521
+ * fizz.position.set(0, 1.2, 0);
1522
+ * scene.add(fizz);
1523
+ *
1524
+ * onFrame((dt) => fizz.update(dt));
1525
+ * ```
1526
+ */
1527
+ export declare class EffervescenceEffect extends InstancedMesh {
1528
+ private readonly width;
1529
+ private readonly height;
1530
+ private readonly depth;
1531
+ private readonly baseY;
1532
+ private readonly spread;
1533
+ private readonly px;
1534
+ private readonly py;
1535
+ private readonly pz;
1536
+ private readonly speed;
1537
+ private readonly dummy;
1538
+ constructor(options?: EffervescenceEffectOptions);
1539
+ /**
1540
+ * Advance bubble positions. Pass elapsed frame time in seconds (e.g. from
1541
+ * `createScene`'s `onFrame` callback).
1542
+ */
1543
+ update(dt: number): void;
1544
+ /** Release geometry and materials held by the field. */
1545
+ dispose(): this;
1546
+ private respawn;
1547
+ private writeMatrices;
1548
+ }
1549
+
1550
+ export declare interface EffervescenceEffectOptions {
1551
+ /** Override bubble geometry. Defaults to a small `SphereGeometry`. */
1552
+ geometry?: BufferGeometry;
1553
+ /** Override the default bubble material. */
1554
+ material?: Material;
1555
+ /** Number of bubble instances. Defaults to `24`. */
1556
+ count?: number;
1557
+ /** Horizontal spread (world units). Defaults to `1.5`. */
1558
+ width?: number;
1559
+ /** Vertical column height (world units). Defaults to `3`. */
1560
+ height?: number;
1561
+ /** Depth spread (world units). Defaults to `1.5`. */
1562
+ depth?: number;
1563
+ /**
1564
+ * Horizontal spawn inset (0–1). Scales width/depth spawn area inward so a
1565
+ * square volume fits round vessels. `1` = full box; `0.88` (default) trims corners.
1566
+ */
1567
+ spread?: number;
1568
+ /** World Y where bubbles spawn when they recycle. Defaults to `0`. */
1569
+ baseY?: number;
1570
+ /** Minimum rise speed (units/s). Defaults to `0.35`. */
1571
+ speedMin?: number;
1572
+ /** Maximum rise speed (units/s). Defaults to `0.85`. */
1573
+ speedMax?: number;
1574
+ /** Bubble tint when using the default material. Defaults to `0xffffff`. */
1575
+ color?: ColorRepresentation;
1576
+ /** Default material opacity. Defaults to `0.6`. */
1577
+ opacity?: number;
1578
+ /** Default material emissive intensity. Defaults to `0`. */
1579
+ emissiveIntensity?: number;
1580
+ }
1581
+
1346
1582
  export declare class ElectricPanel extends Group {
1347
1583
  constructor();
1348
1584
  }
@@ -1352,52 +1588,55 @@ export declare class EllipticLeafGeometry extends BufferGeometry {
1352
1588
  }
1353
1589
 
1354
1590
  /**
1355
- * Emissive pulse animation, producing a flickering light effect for materials that have emissive properties.
1356
- * The emissive intensity of the material will oscillate between `minIntensity` and `maxIntensity`.
1591
+ * Smooth emissive pulse for fake LEDs animates `emissiveIntensity` on an existing
1592
+ * mesh material without adding geometry or scene lights.
1357
1593
  *
1358
- * Oscillation time = / speed
1359
- * - Low speed values (e.g., 0.5) will result in a slow pulse
1360
- * - High speed values (e.g., 10) will result in a rapid flicker
1594
+ * Pair with a prefab such as {@link PanelLight}: place the mesh, pass its material
1595
+ * here, call `update(dt)` each frame. For a bank of same-color LEDs, give each
1596
+ * instance a different `speed` so they breathe out of sync.
1361
1597
  *
1362
- * Requires `update()` frame handler with `clock.getElapsedTime()` for animation.
1363
- *
1364
- * Example usage:
1365
- * ```
1366
- * const pulseAnimation = new EmissivePulseAnimation();
1367
- * const clock = new THREE.Clock();
1598
+ * @example
1599
+ * ```ts
1600
+ * const led = new PanelLight({ emissive: 0xff0000 });
1601
+ * scene.add(led);
1602
+ *
1603
+ * const pulse = new EmissivePulseEffect({
1604
+ * material: led.material,
1605
+ * speed: 1.4,
1606
+ * minIntensity: 0.05,
1607
+ * maxIntensity: 2,
1608
+ * });
1368
1609
  *
1369
- * function animate() {
1370
- * pulseAnimation.update(clock.getElapsedTime());
1371
- * }
1372
- * ```
1610
+ * onFrame((dt) => pulse.update(dt));
1611
+ * ```
1373
1612
  */
1374
- export declare class EmissivePulseAnimation {
1613
+ export declare class EmissivePulseEffect {
1375
1614
  speed: number;
1376
- maxIntensity: number;
1377
1615
  minIntensity: number;
1378
- material: MeshStandardMaterial | MeshPhysicalMaterial | MeshLambertMaterial | MeshPhongMaterial;
1379
- constructor(options: EmissivePulseEffectOptions);
1380
- /**
1381
- * Update the emissive intensity of the material.
1382
- *
1383
- * Use Three.Clock getElapsedTime()
1384
- *
1385
- * Example:
1386
- * ```
1387
- * const clock = new THREE.Clock();
1388
- * effect.update(clock.getElapsedTime());
1389
- * ```
1390
- */
1391
- update(elapsedTime?: number): void;
1616
+ maxIntensity: number;
1617
+ readonly material: EmissivePulseMaterial;
1618
+ private elapsed;
1619
+ constructor({ material, speed, maxIntensity, minIntensity, }: EmissivePulseEffectOptions);
1620
+ /** Advance the pulse by `dt` seconds (elapsed time, not frame index). */
1621
+ update(dt: number): void;
1392
1622
  }
1393
1623
 
1394
1624
  export declare interface EmissivePulseEffectOptions {
1625
+ /** Material whose `emissiveIntensity` will oscillate. Must have emissive set. */
1626
+ material: EmissivePulseMaterial;
1627
+ /**
1628
+ * Pulse frequency in radians per second (`abs(sin(elapsed * speed))`).
1629
+ * Defaults to `2`. Primary differentiator when many LEDs share one color.
1630
+ */
1395
1631
  speed?: number;
1396
- maxIntensity?: number;
1632
+ /** Lower bound of the pulse. Defaults to `0.2`. */
1397
1633
  minIntensity?: number;
1398
- material: MeshStandardMaterial | MeshPhysicalMaterial | MeshLambertMaterial | MeshPhongMaterial;
1634
+ /** Upper bound of the pulse. Defaults to `0.8`. */
1635
+ maxIntensity?: number;
1399
1636
  }
1400
1637
 
1638
+ export declare type EmissivePulseMaterial = MeshStandardMaterial | MeshPhysicalMaterial | MeshLambertMaterial | MeshPhongMaterial;
1639
+
1401
1640
  export declare class ErlenmeyerFlask extends Mesh<ErlenmeyerFlaskGeometry, MeshPhysicalMaterial> {
1402
1641
  constructor({ flaskRadius, //
1403
1642
  neckRadius, height, neckHeight, radialSegments, }?: {
@@ -1420,40 +1659,64 @@ export declare class ErlenmeyerFlaskGeometry extends BufferGeometry {
1420
1659
  });
1421
1660
  }
1422
1661
 
1423
- export declare const exponentialCurve: (t: number, base?: number, factor?: number) => number;
1424
-
1425
- export declare const exponentialEaseIn: (t: number) => number;
1662
+ export declare const fadeShader: {
1663
+ uniforms: {
1664
+ tDiffuse: {
1665
+ value: null;
1666
+ };
1667
+ fadeAmount: {
1668
+ value: number;
1669
+ };
1670
+ fadeColor: {
1671
+ value: null;
1672
+ };
1673
+ };
1674
+ vertexShader: string;
1675
+ fragmentShader: string;
1676
+ };
1426
1677
 
1427
- export declare const exponentialEaseInOut: (t: number) => number;
1678
+ declare interface FadeTransitionOptions extends SceneTransitionOptions {
1679
+ color?: THREE.ColorRepresentation;
1680
+ }
1428
1681
 
1429
- export declare const exponentialEaseOut: (t: number) => number;
1682
+ declare interface FadeTransitionOptions_2 extends SceneTransitionFXOptions {
1683
+ color?: THREE.ColorRepresentation;
1684
+ }
1430
1685
 
1431
- export declare const fadeShader: {
1686
+ export declare const fadeTransitionSceneShader: {
1432
1687
  uniforms: {
1433
- tDiffuse: {
1688
+ tDiffuseA: {
1434
1689
  value: null;
1435
1690
  };
1436
- opacity: {
1691
+ tDiffuseB: {
1692
+ value: null;
1693
+ };
1694
+ mixRatio: {
1437
1695
  value: number;
1438
1696
  };
1697
+ fadeColor: {
1698
+ value: null;
1699
+ };
1439
1700
  };
1440
1701
  vertexShader: string;
1441
1702
  fragmentShader: string;
1442
1703
  };
1443
1704
 
1444
1705
  export declare const Falloff: {
1445
- LINEAR: (distance: number, radius: number) => number;
1446
- QUADRATIC: (distance: number, radius: number) => number;
1447
- SQUARE_ROOT: (distance: number, radius: number) => number;
1448
- LOGARITHMIC: (distance: number, radius: number) => number;
1449
- SINE: (distance: number, radius: number) => number;
1450
- EXPONENTIAL: (distance: number, radius: number) => number;
1451
- CUBIC: (distance: number, radius: number) => number;
1452
- GAUSSIAN: (distance: number, radius: number) => number;
1453
- INVERSE: (distance: number, radius: number) => number;
1454
- SMOOTHSTEP: (distance: number, radius: number) => number;
1706
+ linear: (distance: number, radius: number) => number;
1707
+ quadratic: (distance: number, radius: number) => number;
1708
+ squareRoot: (distance: number, radius: number) => number;
1709
+ logarithmic: (distance: number, radius: number) => number;
1710
+ sine: (distance: number, radius: number) => number;
1711
+ exponential: (distance: number, radius: number) => number;
1712
+ cubic: (distance: number, radius: number) => number;
1713
+ gaussian: (distance: number, radius: number) => number;
1714
+ inverse: (distance: number, radius: number) => number;
1715
+ smoothstep: (distance: number, radius: number) => number;
1455
1716
  };
1456
1717
 
1718
+ export declare type FalloffFunction = (distance: number, radius: number) => number;
1719
+
1457
1720
  export declare function findClosestColor(inputColor: number, dataset: number[]): number | null;
1458
1721
 
1459
1722
  export declare function findClosestColorChannelWise(inputColor: number, dataset: number[]): number | null;
@@ -1478,6 +1741,53 @@ export declare class Flame extends Mesh<FlameGeometry, MeshStandardMaterial> {
1478
1741
  });
1479
1742
  }
1480
1743
 
1744
+ /**
1745
+ * Calm flame flicker from detuned sines — drives optional real lights, flame
1746
+ * materials, and {@link GlowHalo} opacity in sync. Time-based (`update(dt)`).
1747
+ *
1748
+ * Use without a `light` for mass candlefields (halo + bloom only). Add a
1749
+ * `light` for hero sconces that must cast on walls and props.
1750
+ */
1751
+ export declare class FlameFlickerEffect {
1752
+ readonly seed: number;
1753
+ light?: PointLight;
1754
+ lightIntensity: number;
1755
+ flame?: MeshBasicMaterial;
1756
+ halo?: GlowHalo;
1757
+ haloOpacity: number;
1758
+ private readonly flameColor;
1759
+ private elapsed;
1760
+ constructor({ seed, light, lightIntensity, flame, flameColor, halo, haloOpacity, }?: FlameFlickerEffectOptions);
1761
+ /**
1762
+ * Flicker factor at elapsed time — lazy sum of detuned sines (~0.5–1.1).
1763
+ */
1764
+ static factor(elapsed: number, seed: number): number;
1765
+ /** Current flicker factor after the last `update`. */
1766
+ get level(): number;
1767
+ update(dt: number): void;
1768
+ /** Billboard linked halo toward the eye, if present. */
1769
+ faceCamera(eye: Vector3): void;
1770
+ }
1771
+
1772
+ export declare interface FlameFlickerEffectOptions {
1773
+ /**
1774
+ * Desyncs multiple instances. Defaults to `Math.random() * 100`.
1775
+ */
1776
+ seed?: number;
1777
+ /** Optional real light — use sparingly; casts on geometry but counts against light limits. */
1778
+ light?: PointLight;
1779
+ /** Base intensity when `light` is set. Defaults to `4`. */
1780
+ lightIntensity?: number;
1781
+ /** Optional flame core material (e.g. `MeshBasicMaterial` on a small sphere). */
1782
+ flame?: MeshBasicMaterial;
1783
+ /** Flame tint when `flame` is set. Defaults to `0xffaa44`. */
1784
+ flameColor?: ColorRepresentation;
1785
+ /** Optional {@link GlowHalo}; opacity scales with the flicker factor. */
1786
+ halo?: GlowHalo;
1787
+ /** Halo opacity multiplier at flicker peak. Defaults to `0.75`. */
1788
+ haloOpacity?: number;
1789
+ }
1790
+
1481
1791
  export declare class FlameGeometry extends ParametricGeometry {
1482
1792
  constructor({ height, radius, segmentsU, segmentsV }?: {
1483
1793
  height?: number | undefined;
@@ -1500,8 +1810,6 @@ export declare class FlorenceFlaskGeometry extends BufferGeometry {
1500
1810
  constructor();
1501
1811
  }
1502
1812
 
1503
- export declare const gaussian: (t: number) => number;
1504
-
1505
1813
  export declare class Gear extends Mesh {
1506
1814
  constructor({ sides, innerRadius, outerRadius, holeSides, holeRadius, depth }?: {
1507
1815
  sides?: number | undefined;
@@ -1534,6 +1842,91 @@ export declare class GearShape extends Shape {
1534
1842
  */
1535
1843
  export declare function getAnalogousColors(baseHue: number): [number, number, number];
1536
1844
 
1845
+ declare interface GlitchTransitionOptions extends SceneTransitionFXOptions {
1846
+ maxIntensity?: number;
1847
+ }
1848
+
1849
+ /**
1850
+ * Soft additive glow billboard — reads as light without a {@link PointLight}.
1851
+ * Pair with {@link FlameFlickerEffect} for organic pulse, or use alone for
1852
+ * cheap mass lighting (many halos + bloom, no light-count limit).
1853
+ *
1854
+ * Call `faceCamera(camera.position)` each frame so the card faces the eye.
1855
+ */
1856
+ export declare class GlowHalo extends Object3D {
1857
+ readonly mesh: Mesh<PlaneGeometry, MeshBasicMaterial>;
1858
+ private texture;
1859
+ private readonly baseColor;
1860
+ constructor({ color, size, opacity, }?: GlowHaloOptions);
1861
+ /** Billboard toward the camera (or any eye position). */
1862
+ faceCamera(eye: Vector3): void;
1863
+ /** Set halo opacity (e.g. scaled each frame by {@link FlameFlickerEffect}). */
1864
+ setOpacity(opacity: number): void;
1865
+ get opacity(): number;
1866
+ setColor(color: ColorRepresentation): void;
1867
+ dispose(): void;
1868
+ }
1869
+
1870
+ export declare interface GlowHaloOptions {
1871
+ /** Warm glow tint. Defaults to `0xffaa44`. */
1872
+ color?: ColorRepresentation;
1873
+ /** Billboard plane edge length in world units. Defaults to `1.2`. */
1874
+ size?: number;
1875
+ /** Base opacity before flicker scaling. Defaults to `0.75`. */
1876
+ opacity?: number;
1877
+ }
1878
+
1879
+ /**
1880
+ * Creeping ground mist — soft horizontal cards drifting above the floor.
1881
+ * Interior patches wrap toroidally within `area`; optional perimeter patches
1882
+ * sit on/outside the fence on edges opposite the camera. One texture, one
1883
+ * `update(dt)` — perimeter is placement logic, not a separate effect.
1884
+ */
1885
+ export declare class GroundFogEffect extends Object3D {
1886
+ private readonly patches;
1887
+ private readonly area;
1888
+ private readonly heightAt;
1889
+ private readonly texture;
1890
+ private elapsed;
1891
+ constructor({ count, area, perimeterCount, plotHalf, terrainHalf, cameraFacing, color, heightAt, }?: GroundFogEffectOptions);
1892
+ update(dt: number): void;
1893
+ dispose(): void;
1894
+ private makeInteriorPatch;
1895
+ private makePerimeterPatch;
1896
+ private makeMesh;
1897
+ }
1898
+
1899
+ export declare interface GroundFogEffectOptions {
1900
+ /** Interior mist cards scattered across the plot. Defaults to `14`. */
1901
+ count?: number;
1902
+ /** Half-extent of the interior scatter (world units). Defaults to `16`. */
1903
+ area?: number;
1904
+ /**
1905
+ * Large cards hugging the plot perimeter — softens terrain cutoffs on the
1906
+ * horizons opposite the camera. Defaults to `0` (interior only).
1907
+ */
1908
+ perimeterCount?: number;
1909
+ /** Half-extent of the inner bounded plot (fence, wall, diorama edge, etc.). Defaults to `12`. */
1910
+ plotHalf?: number;
1911
+ /** Terrain half-extent; perimeter cards spill outward toward this edge. Defaults to `16`. */
1912
+ terrainHalf?: number;
1913
+ /**
1914
+ * Horizontal direction from plot center toward the camera. Perimeter patches
1915
+ * concentrate on the opposite edges. Defaults to `{ x: 1, z: 1 }`.
1916
+ */
1917
+ cameraFacing?: {
1918
+ x: number;
1919
+ z: number;
1920
+ };
1921
+ /** Mist tint. Defaults to `#9fb0c8`. */
1922
+ color?: ColorRepresentation;
1923
+ /**
1924
+ * Sample ground height at world (x, z). Defaults to flat `y = 0`.
1925
+ * Portfolio graveyard uses undulating terrain via the same callback.
1926
+ */
1927
+ heightAt?: (x: number, z: number) => number;
1928
+ }
1929
+
1537
1930
  export declare class Heart extends Mesh {
1538
1931
  constructor({ size, width, height, tipDepth, depth }?: {
1539
1932
  size?: number | undefined;
@@ -1651,8 +2044,6 @@ export declare function hslToRgb(h: number, s: number, l: number): [number, numb
1651
2044
  */
1652
2045
  export declare function interpolateCurve(curveFunction: (t: number) => number, startRadius: number, endRadius: number, startHeight: number, endHeight: number, segments?: number, min?: number, max?: number): Vector2[];
1653
2046
 
1654
- export declare const inverse: (t: number) => number;
1655
-
1656
2047
  /**
1657
2048
  * Material indices
1658
2049
  * 0. Jar
@@ -1675,136 +2066,72 @@ export declare class Lantern extends Group {
1675
2066
  constructor(height?: number, baseWidth?: number);
1676
2067
  }
1677
2068
 
1678
- export declare class LeafEffect extends InstancedMesh {
1679
- private dummyMatrix;
1680
- private velocities;
1681
- private width;
1682
- private height;
1683
- private depth;
1684
- constructor(options?: LeafEffectOptions);
1685
- update(): void;
1686
- }
1687
-
1688
- export declare interface LeafEffectOptions {
1689
- geometry?: BufferGeometry;
1690
- material?: Material;
1691
- count?: number;
1692
- width?: number;
1693
- height?: number;
1694
- depth?: number;
1695
- }
1696
-
1697
2069
  export declare class LeverPanel extends Group {
1698
2070
  constructor();
1699
2071
  }
1700
2072
 
1701
2073
  /**
1702
- * Create a light flicker animation that will randomly change the intensity and position of a light.
1703
- * Effect resembles a flickering flame of candlelight.
1704
- *
1705
- * Example usage:
1706
- * ```
1707
- * // Create a candle
1708
- * const candle = new Candle({
1709
- * height: 1,
1710
- * flameHeight: 0.25,
1711
- * });
1712
- * scene.add(candle);
1713
- *
1714
- * // Create a point light
1715
- * const candleLight = new THREE.PointLight(0xffa500, 1, 5);
1716
- * scene.add(candleLight);
1717
- *
1718
- * // Apply the animator to the light
1719
- * const lightAnimation = new LightFlickerAnimation({
1720
- * light: candleLight,
1721
- * maxIntensity: 2.2,
1722
- * x: candle.position.x,
1723
- * y: candle.position.y + 1 + 0.125, // height + half flame height
1724
- * z: candle.position.z,
1725
- * });
1726
- * animations.push(lightAnimation);
1727
- *
1728
- * // Update the light animation in the render loop
1729
- * renderer.setAnimationLoop(() => {
1730
- * lightAnimation.update();
1731
- * });
1732
- * ```
1733
- */
1734
- export declare class LightFlickerAnimation {
1735
- private light?;
1736
- minIntensity: number;
1737
- maxIntensity: number;
1738
- x: number;
1739
- y: number;
1740
- z: number;
1741
- jitterX: number;
1742
- jitterY: number;
1743
- jitterZ: number;
1744
- constructor({ light, minIntensity, maxIntensity, x, y, z, jitterX, jitterY, jitterZ, }?: Partial<LightFlickerAnimationOptions>);
1745
- update(): void;
1746
- }
1747
-
1748
- export declare interface LightFlickerAnimationOptions {
1749
- light?: Light;
1750
- minIntensity: number;
1751
- maxIntensity: number;
1752
- x: number;
1753
- y: number;
1754
- z: number;
1755
- jitterX: number;
1756
- jitterY: number;
1757
- jitterZ: number;
1758
- }
1759
-
1760
- /**
1761
- * A lightning animation that can be used to simulate a lightning storm.
1762
- * This effect is applied to a light source.
2074
+ * Thunderstorm lightning that drives a {@link DirectionalLight} each frame.
1763
2075
  *
1764
- * Example usage:
1765
- * ```
1766
- * const lightning = new THREE.DirectionalLight(0xffffff, 0);
1767
- * scene.add(lightning);
1768
- * lightning.position.set(5, 10, -5);
2076
+ * Rather than scheduling timeouts (which need careful teardown), each strike
2077
+ * enqueues two or three decaying intensity spikes a few frames apart — the
2078
+ * characteristic stutter of real lightning. Read {@link LightningEffect.level}
2079
+ * after {@link LightningEffect.update} to sync fog, sky, rain, or emissive
2080
+ * surfaces with the flash.
1769
2081
  *
1770
- * const lightningAnimation = new LightningAnimation();
1771
- *
1772
- * setRandomInterval(() => {
1773
- * lightningEffect.triggerLightning();
1774
- * }, 250, 1250);
2082
+ * @example
2083
+ * ```typescript
2084
+ * const bolt = new DirectionalLight(0xcdd8ff, 0);
2085
+ * bolt.position.set(5, 12, -8);
2086
+ * bolt.target.position.set(0, 0, 0);
2087
+ * scene.add(bolt, bolt.target);
2088
+ *
2089
+ * const storm = new LightningEffect({ light: bolt, peak: 12, minGap: 3, maxGap: 9 });
2090
+ *
2091
+ * function animate(delta: number) {
2092
+ * storm.update(delta);
2093
+ * const flash = storm.level; // 0..~1.2
2094
+ * renderer.render(scene, camera);
2095
+ * }
1775
2096
  * ```
1776
2097
  */
1777
- export declare class LightningAnimation {
1778
- private light?;
1779
- minIntensity: number;
1780
- maxIntensity: number;
1781
- minDuration: number;
1782
- maxDuration: number;
1783
- constructor({ light, //
1784
- minIntensity, maxIntensity, minDuration, maxDuration, }?: LightningEffectOptions);
1785
- triggerLightning(): void;
1786
- update(): void;
2098
+ export declare class LightningEffect {
2099
+ /** Current flash level, 0 = dark. Read after each {@link LightningEffect.update}. */
2100
+ level: number;
2101
+ private readonly light;
2102
+ private readonly peak;
2103
+ private readonly minGap;
2104
+ private readonly maxGap;
2105
+ private readonly spikes;
2106
+ private clock;
2107
+ private nextStrike;
2108
+ constructor({ light, peak, minGap, maxGap }: LightningEffectOptions);
2109
+ /**
2110
+ * Advance the strike schedule and update the driven light intensity. Pass
2111
+ * elapsed frame time in seconds.
2112
+ */
2113
+ update(dt: number): void;
2114
+ /** Force the driven light dark, e.g. when lightning is toggled off. */
2115
+ quiet(): void;
2116
+ private strike;
1787
2117
  }
1788
2118
 
1789
- declare interface LightningEffectOptions {
1790
- light?: Light;
1791
- minIntensity?: number;
1792
- maxIntensity?: number;
1793
- minDuration?: number;
1794
- maxDuration?: number;
2119
+ export declare interface LightningEffectOptions {
2120
+ /** Directional light driven by lightning flashes. Start at intensity `0`. */
2121
+ light: DirectionalLight;
2122
+ /** Peak light intensity at full flash. Defaults to `12`. */
2123
+ peak?: number;
2124
+ /** Minimum seconds between strikes. Defaults to `3`. */
2125
+ minGap?: number;
2126
+ /** Maximum seconds between strikes. Defaults to `9`. */
2127
+ maxGap?: number;
1795
2128
  }
1796
2129
 
1797
- export declare const linear: (t: number) => number;
1798
-
1799
2130
  export declare const LineEquations: {
1800
2131
  calculateXFromSlopeIntercept: typeof calculateXFromSlopeIntercept;
1801
2132
  calculateYFromSlopeIntercept: typeof calculateYFromSlopeIntercept;
1802
2133
  };
1803
2134
 
1804
- export declare const logarithmic: (t: number) => number;
1805
-
1806
- export declare const logarithmicCurve: (t: number, base?: number, factor?: number) => number;
1807
-
1808
2135
  /**
1809
2136
  * Generates a random number skewed towards the maximum value.
1810
2137
  *
@@ -2096,8 +2423,6 @@ export declare interface PanelOptions {
2096
2423
  depth?: number;
2097
2424
  }
2098
2425
 
2099
- export declare const parabolicCurve: (t: number, a?: number, b?: number, c?: number) => number;
2100
-
2101
2426
  /**
2102
2427
  * Prismatic parallelogram, with horizontal skew (offset in X for the slant).
2103
2428
  */
@@ -2106,14 +2431,14 @@ export declare class ParallelogramBoxGeometry extends BufferGeometry {
2106
2431
  }
2107
2432
 
2108
2433
  export declare const ParametricCurve: {
2109
- CUBIC: (t: number, p0: number, p1: number, p2: number, p3: number) => number;
2110
- DAMPED: (t: number, damping?: number) => number;
2111
- EXPONENTIAL: (t: number, base?: number, factor?: number) => number;
2112
- LOGARITHMIC: (t: number, base?: number, factor?: number) => number;
2113
- PARABOLIC: (t: number, a?: number, b?: number, c?: number) => number;
2114
- QUADRATIC: (t: number, p0: number, p1: number, p2: number) => number;
2115
- SIGMOID: (t: number, a?: number) => number;
2116
- SINUSOIDAL: (t: number) => number;
2434
+ cubic: (t: number, p0: number, p1: number, p2: number, p3: number) => number;
2435
+ damped: (t: number, damping?: number) => number;
2436
+ exponential: (t: number, base?: number, factor?: number) => number;
2437
+ logarithmic: (t: number, base?: number, factor?: number) => number;
2438
+ parabolic: (t: number, a?: number, b?: number, c?: number) => number;
2439
+ quadratic: (t: number, p0: number, p1: number, p2: number) => number;
2440
+ sigmoid: (t: number, a?: number) => number;
2441
+ sinusoidal: (t: number) => number;
2117
2442
  };
2118
2443
 
2119
2444
  export declare const ParametricCurveUtils: {
@@ -2131,6 +2456,86 @@ export declare const ParametricCurveUtils: {
2131
2456
  */
2132
2457
  export declare function parseHexCode(hex: string): [number, number, number];
2133
2458
 
2459
+ /**
2460
+ * Soft, slow-drifting petals (or leaves) falling through a bounded volume —
2461
+ * cherry-blossom float rather than stiff tumble. Each instance drifts downward
2462
+ * with gentle horizontal wander and a light sinusoidal flutter.
2463
+ *
2464
+ * Call {@link PetalDriftEffect.update} each frame with elapsed time in seconds.
2465
+ *
2466
+ * @example
2467
+ * ```typescript
2468
+ * const petals = new PetalDriftEffect({
2469
+ * count: 80,
2470
+ * color: [0xffd6f0, 0xfff0f8, 0xf8c8e0],
2471
+ * flutter: 0.3,
2472
+ * });
2473
+ * scene.add(petals);
2474
+ *
2475
+ * onFrame((dt) => petals.update(dt));
2476
+ * ```
2477
+ */
2478
+ export declare class PetalDriftEffect extends InstancedMesh {
2479
+ private readonly width;
2480
+ private readonly height;
2481
+ private readonly depth;
2482
+ private readonly floorY;
2483
+ private readonly flutter;
2484
+ private readonly px;
2485
+ private readonly py;
2486
+ private readonly pz;
2487
+ private readonly fallSpeed;
2488
+ private readonly driftX;
2489
+ private readonly driftZ;
2490
+ private readonly rotX;
2491
+ private readonly rotY;
2492
+ private readonly rotZ;
2493
+ private readonly phase;
2494
+ private readonly dummy;
2495
+ private clock;
2496
+ constructor(options?: PetalDriftEffectOptions);
2497
+ /**
2498
+ * Advance petal positions and flutter. Pass elapsed frame time in seconds.
2499
+ */
2500
+ update(dt: number): void;
2501
+ /** Release geometry and materials held by the field. */
2502
+ dispose(): this;
2503
+ private respawn;
2504
+ private writeMatrices;
2505
+ }
2506
+
2507
+ export declare interface PetalDriftEffectOptions {
2508
+ /** Override petal geometry. Defaults to {@link EllipticLeafGeometry}. */
2509
+ geometry?: BufferGeometry;
2510
+ /** Override the default petal material. */
2511
+ material?: Material;
2512
+ /** Number of petal instances. Defaults to `120`. */
2513
+ count?: number;
2514
+ /** Horizontal spread (world units). Defaults to `16`. */
2515
+ width?: number;
2516
+ /** Vertical spawn span (world units). Defaults to `8`. */
2517
+ height?: number;
2518
+ /** Depth spread (world units). Defaults to `16`. */
2519
+ depth?: number;
2520
+ /** World Y where petals respawn after drifting below the floor. Defaults to `0`. */
2521
+ floorY?: number;
2522
+ /** Minimum fall speed (units/s). Defaults to `0.12`. */
2523
+ fallSpeedMin?: number;
2524
+ /** Maximum fall speed (units/s). Defaults to `0.28`. */
2525
+ fallSpeedMax?: number;
2526
+ /** Minimum horizontal drift speed (units/s). Defaults to `0.04`. */
2527
+ driftMin?: number;
2528
+ /** Maximum horizontal drift speed (units/s). Defaults to `0.14`. */
2529
+ driftMax?: number;
2530
+ /**
2531
+ * Flutter strength (radians). Subtle rotation sway as each petal falls.
2532
+ * Defaults to `0.35`.
2533
+ */
2534
+ flutter?: number;
2535
+ /** Single petal color or palette; multiple entries pick a random color per petal. */
2536
+ color?: ColorRepresentation | ColorRepresentation[];
2537
+ }
2538
+
2134
2539
  /**
2135
2540
  * Planar UV Mapping
2136
2541
  * Projects UVs onto the geometry from a single direction (like shining a projector onto a surface).
@@ -2189,26 +2594,6 @@ export declare class PotionBottleGeometry extends BufferGeometry {
2189
2594
  constructor();
2190
2595
  }
2191
2596
 
2192
- export declare const quadraticCurve: (t: number, p0: number, p1: number, p2: number) => number;
2193
-
2194
- export declare const quadraticEaseIn: (t: number) => number;
2195
-
2196
- export declare const quadraticEaseInOut: (t: number) => number;
2197
-
2198
- export declare const quadraticEaseOut: (t: number) => number;
2199
-
2200
- export declare const quarticEaseIn: (t: number) => number;
2201
-
2202
- export declare const quarticEaseInOut: (t: number) => number;
2203
-
2204
- export declare const quarticEaseOut: (t: number) => number;
2205
-
2206
- export declare const quinticEaseIn: (t: number) => number;
2207
-
2208
- export declare const quinticEaseInOut: (t: number) => number;
2209
-
2210
- export declare const quinticEaseOut: (t: number) => number;
2211
-
2212
2597
  /**
2213
2598
  * Calculate the radius to achieve a spherical cap height.
2214
2599
  * R = r / (1 - cos(thetaLength))
@@ -2221,6 +2606,110 @@ export declare const radiusFromCapHeight: (height: number, thetaLength: number)
2221
2606
  */
2222
2607
  export declare const radiusFromCapWidth: (width: number, thetaLength: number) => number;
2223
2608
 
2609
+ /**
2610
+ * Misty rainfall as instanced vertical streaks.
2611
+ *
2612
+ * Each streak is a thin, gradient-textured quad animated through a bounded
2613
+ * volume. By default streaks fall straight down with no rotation. Optional
2614
+ * {@link RainEffectOptions.windDirection} / {@link RainEffectOptions.windStrength}
2615
+ * tilt streaks **and** drift them horizontally together, so motion matches the
2616
+ * visual angle. Streak materials use `DoubleSide` so thin quads stay visible
2617
+ * from any camera angle. Scene fog dissolves distant streaks when the material's
2618
+ * `fog` flag is enabled.
2619
+ *
2620
+ * **`intensity`** (0–1) scales how many instances draw, how fast they fall, and
2621
+ * their opacity — useful for storm ramps or lightning flashes.
2622
+ *
2623
+ * @example
2624
+ * ```typescript
2625
+ * const rain = new RainEffect({ area: 12, height: 16, intensity: 0.4 });
2626
+ * scene.add(rain);
2627
+ * scene.fog = new Fog(0x0a0a12, 4, 28);
2628
+ *
2629
+ * function animate(delta: number) {
2630
+ * rain.update(delta);
2631
+ * renderer.render(scene, camera);
2632
+ * }
2633
+ * ```
2634
+ */
2635
+ export declare class RainEffect extends InstancedMesh {
2636
+ /** Rainfall strength (0–1). Adjust at runtime for storm variation. */
2637
+ intensity: number;
2638
+ private readonly maxCount;
2639
+ private readonly area;
2640
+ private readonly height;
2641
+ private readonly groundY;
2642
+ private readonly baseOpacity;
2643
+ private readonly windDirection;
2644
+ private readonly windStrength;
2645
+ private readonly fallDirection;
2646
+ private readonly streakOrientation;
2647
+ private readonly sx;
2648
+ private readonly sz;
2649
+ private readonly topY;
2650
+ private readonly len;
2651
+ private readonly speed;
2652
+ private readonly streakTexture?;
2653
+ private readonly dummy;
2654
+ private clock;
2655
+ constructor(options?: RainEffectOptions);
2656
+ /**
2657
+ * Advance streak positions and refresh instance transforms. Pass elapsed frame
2658
+ * time in seconds (e.g. from `createScene`'s `onFrame` callback).
2659
+ */
2660
+ update(dt: number): void;
2661
+ /** Release geometry, materials, and the procedural streak texture. */
2662
+ dispose(): this;
2663
+ private applyIntensity;
2664
+ private updateFallDirection;
2665
+ private writeMatrices;
2666
+ }
2667
+
2668
+ export declare interface RainEffectOptions {
2669
+ /** Override the streak quad geometry. Defaults to a thin `PlaneGeometry`. */
2670
+ geometry?: BufferGeometry;
2671
+ /** Override the default streak material. */
2672
+ material?: Material;
2673
+ /** Maximum number of streak instances. Defaults to `1400`. */
2674
+ count?: number;
2675
+ /** Horizontal half-extent of the rainfall area (square centered on the origin). Defaults to `26`. */
2676
+ area?: number;
2677
+ /** Vertical span above `groundY`. Defaults to `22`. */
2678
+ height?: number;
2679
+ /** World Y where streaks recycle. Defaults to `0`. */
2680
+ groundY?: number;
2681
+ /** Streak quad width. Defaults to `0.009`. */
2682
+ width?: number;
2683
+ /** Streak color. Defaults to `#aebfd6`. */
2684
+ color?: ColorRepresentation;
2685
+ /** Base material opacity at full intensity. Defaults to `0.16`. */
2686
+ opacity?: number;
2687
+ /** Minimum streak length. Defaults to `0.18`. */
2688
+ lengthMin?: number;
2689
+ /** Maximum streak length. Defaults to `0.42`. */
2690
+ lengthMax?: number;
2691
+ /** Minimum fall speed (units/s). Defaults to `11`. */
2692
+ speedMin?: number;
2693
+ /** Maximum fall speed (units/s). Defaults to `19`. */
2694
+ speedMax?: number;
2695
+ /**
2696
+ * Horizontal compass direction the wind blows (radians, 0 = +X, π/2 = +Z).
2697
+ * Only used when {@link RainEffectOptions.windStrength} is greater than zero.
2698
+ * Defaults to `0`.
2699
+ */
2700
+ windDirection?: number;
2701
+ /**
2702
+ * How much rain tilts and drifts from vertical, as `tan(angleFromVertical)`.
2703
+ * `0` = straight down (default). `0.15` ≈ 8.5° lean with matching horizontal drift.
2704
+ */
2705
+ windStrength?: number;
2706
+ /**
2707
+ * Rainfall strength (0–1). Scales visible instance count, fall speed, and opacity.
2708
+ * Defaults to `0.5`.
2709
+ */
2710
+ intensity?: number;
2711
+ }
2712
+
2224
2713
  /**
2225
2714
  * Generates a random number between `min` and `max`.
2226
2715
  */
@@ -2305,6 +2794,256 @@ declare interface RowOfBooksOptions<T extends Material = Material> {
2305
2794
  scaleZMax?: number;
2306
2795
  }
2307
2796
 
2797
+ /**
2798
+ * SceneTransition provides smooth animated transitions between Three.js scenes.
2799
+ *
2800
+ * Supports multiple transition types:
2801
+ * - Fade: Fade to a color (black, white, etc.) and back
2802
+ * - Crossfade: Directly blend from one scene to another
2803
+ * - Blur: Blur out the first scene and blur in the second
2804
+ *
2805
+ * @example
2806
+ * ```typescript
2807
+ * const sceneTransition = new SceneTransition(renderer);
2808
+ *
2809
+ * // Fade to black transition
2810
+ * sceneTransition.fade(sceneA, sceneB, camera, {
2811
+ * duration: 1000,
2812
+ * color: 0x000000,
2813
+ * easing: 'easeInOutCubic'
2814
+ * });
2815
+ *
2816
+ * // Direct crossfade
2817
+ * sceneTransition.crossfade(sceneA, sceneB, camera, {
2818
+ * duration: 1500
2819
+ * });
2820
+ * ```
2821
+ */
2822
+ export declare class SceneTransition {
2823
+ private renderer;
2824
+ private currentScene;
2825
+ private targetScene;
2826
+ private camera;
2827
+ private transitionProgress;
2828
+ private transitionDuration;
2829
+ private transitionStartTime;
2830
+ private isTransitioning;
2831
+ private transitionType;
2832
+ private easingFunction;
2833
+ private renderTargetA;
2834
+ private renderTargetB;
2835
+ private blendScene;
2836
+ private blendCamera;
2837
+ private fadeMaterial;
2838
+ private crossfadeMaterial;
2839
+ private fadeColor;
2840
+ private onUpdateCallback?;
2841
+ private onCompleteCallback?;
2842
+ constructor(renderer: THREE.WebGLRenderer);
2843
+ /**
2844
+ * Fade transition: Fades to a color and then fades in the new scene
2845
+ */
2846
+ fade(fromScene: THREE.Scene, toScene: THREE.Scene, camera: THREE.Camera, options?: FadeTransitionOptions): void;
2847
+ /**
2848
+ * Crossfade transition: Directly blends from one scene to another
2849
+ */
2850
+ crossfade(fromScene: THREE.Scene, toScene: THREE.Scene, camera: THREE.Camera, options?: SceneTransitionOptions): void;
2851
+ /**
2852
+ * Blur transition: Blurs out first scene, then blurs in second scene
2853
+ * Note: This uses the fade material with a neutral gray for a blur-like effect
2854
+ * For true blur, you'd need post-processing passes
2855
+ */
2856
+ blur(fromScene: THREE.Scene, toScene: THREE.Scene, camera: THREE.Camera, options?: SceneTransitionOptions): void;
2857
+ /**
2858
+ * Internal method to start a transition
2859
+ */
2860
+ private startTransition;
2861
+ /**
2862
+ * Update the transition. Call this in your render loop.
2863
+ */
2864
+ update(): void;
2865
+ /**
2866
+ * Render the scene with transition blending
2867
+ */
2868
+ render(): void;
2869
+ /**
2870
+ * Get the current active scene
2871
+ */
2872
+ getCurrentScene(): THREE.Scene | null;
2873
+ /**
2874
+ * Check if a transition is currently in progress
2875
+ */
2876
+ getIsTransitioning(): boolean;
2877
+ /**
2878
+ * Get the current transition progress (0-1)
2879
+ */
2880
+ getProgress(): number;
2881
+ /**
2882
+ * Set the current scene (useful for initialization)
2883
+ */
2884
+ setCurrentScene(scene: THREE.Scene): void;
2885
+ /**
2886
+ * Resize the render targets when the renderer size changes
2887
+ */
2888
+ setSize(width: number, height: number): void;
2889
+ /**
2890
+ * Dispose of resources
2891
+ */
2892
+ dispose(): void;
2893
+ }
2894
+
2895
+ /**
2896
+ * SceneTransitionFX provides advanced post-processing transitions between Three.js scenes.
2897
+ *
2898
+ * Uses EffectComposer for sophisticated visual effects:
2899
+ * - Bloom: Bright bloom effect that peaks at transition midpoint, washing out to white
2900
+ * - Blur: Progressive blur effect that peaks at midpoint, blurring scenes to oblivion
2901
+ * - Fade: Classic fade through a color (black, white, or custom)
2902
+ * - Glitch: Digital distortion/glitch effect with heavy artifacts
2903
+ *
2904
+ * Built-in shader passes for blur and fade are automatically created. For bloom and glitch
2905
+ * effects, you'll need to provide those passes manually.
2906
+ *
2907
+ * Note: Requires post-processing imports from three/addons
2908
+ *
2909
+ * @example
2910
+ * ```typescript
2911
+ * import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
2912
+ * import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
2913
+ * import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
2914
+ * import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
2915
+ *
2916
+ * const composer = new EffectComposer(renderer);
2917
+ * const renderPass = new RenderPass(sceneA, camera);
2918
+ * composer.addPass(renderPass);
2919
+ *
2920
+ * // Pass ShaderPass to enable built-in blur and fade effects
2921
+ * const sceneTransitionFX = new SceneTransitionFX(renderer, composer, ShaderPass);
2922
+ *
2923
+ * // Blur and fade transitions work out of the box
2924
+ * sceneTransitionFX.blur(sceneA, sceneB, camera, { duration: 2000 });
2925
+ * sceneTransitionFX.fade(sceneA, sceneB, camera, { duration: 2000, color: 0x000000 });
2926
+ *
2927
+ * // For bloom, provide the pass manually
2928
+ * const bloomPass = new UnrealBloomPass(new THREE.Vector2(width, height), 0, 0.4, 0.85);
2929
+ * bloomPass.enabled = false;
2930
+ * composer.addPass(bloomPass);
2931
+ * sceneTransitionFX.setBloomPass(bloomPass);
2932
+ * sceneTransitionFX.bloom(sceneA, sceneB, camera, { duration: 2000, maxBloom: 15.0 });
2933
+ * ```
2934
+ */
2935
+ export declare class SceneTransitionFX {
2936
+ private renderer;
2937
+ private composer;
2938
+ private currentScene;
2939
+ private targetScene;
2940
+ private camera;
2941
+ private transitionProgress;
2942
+ private transitionDuration;
2943
+ private transitionStartTime;
2944
+ private isTransitioning;
2945
+ private transitionType;
2946
+ private easingFunction;
2947
+ private renderPass;
2948
+ private bloomPass;
2949
+ private glitchPass;
2950
+ private blurPass;
2951
+ private fadePass;
2952
+ private maxBloomStrength;
2953
+ private maxBlurAmount;
2954
+ private maxGlitchIntensity;
2955
+ private fadeColor;
2956
+ private onUpdateCallback?;
2957
+ private onCompleteCallback?;
2958
+ constructor(renderer: THREE.WebGLRenderer, composer: any, ShaderPass?: any);
2959
+ /**
2960
+ * Create default shader passes for blur and fade effects
2961
+ */
2962
+ private createDefaultPasses;
2963
+ /**
2964
+ * Set the bloom pass for bloom transitions
2965
+ */
2966
+ setBloomPass(bloomPass: any): void;
2967
+ /**
2968
+ * Set the glitch pass for glitch transitions
2969
+ */
2970
+ setGlitchPass(glitchPass: any): void;
2971
+ /**
2972
+ * Set the blur pass for blur transitions
2973
+ */
2974
+ setBlurPass(blurPass: any): void;
2975
+ /**
2976
+ * Set the fade pass for fade transitions
2977
+ */
2978
+ setFadePass(fadePass: any): void;
2979
+ /**
2980
+ * Bloom transition: Bright bloom effect that peaks at transition midpoint
2981
+ */
2982
+ bloom(fromScene: THREE.Scene, toScene: THREE.Scene, camera: THREE.Camera, options?: BloomTransitionOptions): void;
2983
+ /**
2984
+ * Blur transition: Progressively blur scenes to oblivion and back
2985
+ */
2986
+ blur(fromScene: THREE.Scene, toScene: THREE.Scene, camera: THREE.Camera, options?: BlurTransitionOptions): void;
2987
+ /**
2988
+ * Fade transition: Classic fade through a color (black, white, or custom)
2989
+ */
2990
+ fade(fromScene: THREE.Scene, toScene: THREE.Scene, camera: THREE.Camera, options?: FadeTransitionOptions_2): void;
2991
+ /**
2992
+ * Glitch transition: Digital distortion effect
2993
+ */
2994
+ glitch(fromScene: THREE.Scene, toScene: THREE.Scene, camera: THREE.Camera, options?: GlitchTransitionOptions): void;
2995
+ /**
2996
+ * Internal method to start a transition
2997
+ */
2998
+ private startTransition;
2999
+ /**
3000
+ * Update the transition. Call this in your render loop.
3001
+ */
3002
+ update(): void;
3003
+ /**
3004
+ * Render using the effect composer
3005
+ */
3006
+ render(): void;
3007
+ /**
3008
+ * Get the current active scene
3009
+ */
3010
+ getCurrentScene(): THREE.Scene | null;
3011
+ /**
3012
+ * Check if a transition is currently in progress
3013
+ */
3014
+ getIsTransitioning(): boolean;
3015
+ /**
3016
+ * Get the current transition progress (0-1)
3017
+ */
3018
+ getProgress(): number;
3019
+ /**
3020
+ * Set the current scene (useful for initialization)
3021
+ */
3022
+ setCurrentScene(scene: THREE.Scene): void;
3023
+ /**
3024
+ * Resize the composer when the renderer size changes
3025
+ */
3026
+ setSize(width: number, height: number): void;
3027
+ /**
3028
+ * Dispose of resources
3029
+ */
3030
+ dispose(): void;
3031
+ }
3032
+
3033
+ export declare interface SceneTransitionFXOptions {
3034
+ duration?: number;
3035
+ easing?: EasingFunction | keyof typeof Easing;
3036
+ onUpdate?: (progress: number) => void;
3037
+ onComplete?: () => void;
3038
+ }
3039
+
3040
+ export declare interface SceneTransitionOptions {
3041
+ duration?: number;
3042
+ easing?: EasingFunction | keyof typeof Easing;
3043
+ onUpdate?: (progress: number) => void;
3044
+ onComplete?: () => void;
3045
+ }
3046
+
2308
3047
  /**
2309
3048
  * Set a random interval that will call the callback function with a random delay between minDelay and maxDelay.
2310
3049
  *
@@ -2329,21 +3068,11 @@ export declare function setRandomInterval(callback: () => void, minDelay: number
2329
3068
  */
2330
3069
  export declare function setRandomTimeout(callback: () => void, minDelay: number, maxDelay: number): NodeJS.Timeout;
2331
3070
 
2332
- export declare const sigmoidCurve: (t: number, a?: number) => number;
2333
-
2334
- export declare const sineEaseIn: (t: number) => number;
2335
-
2336
- export declare const sineEaseInOut: (t: number) => number;
2337
-
2338
- export declare const sineEaseOut: (t: number) => number;
2339
-
2340
3071
  /**
2341
3072
  * Smooths out the vertices by averaging their positions with neighboring vertices within a given radius.
2342
3073
  */
2343
3074
  export declare const smoothBrush: <T extends BufferGeometry>(geometry: T, position: Vector3, radius: number, strength: number) => void;
2344
3075
 
2345
- export declare const smoothstep: (t: number) => number;
2346
-
2347
3076
  /**
2348
3077
  * Convert spherical coordinates to Cartesian coordinates.
2349
3078
  * @param {number} radius - The radius of the sphere.
@@ -2395,8 +3124,6 @@ export declare class SquareHeadstoneGeometry extends BufferGeometry {
2395
3124
  constructor(width?: number, height?: number, depth?: number);
2396
3125
  }
2397
3126
 
2398
- export declare const squareRoot: (t: number) => number;
2399
-
2400
3127
  export declare class StaircaseGeometry extends BufferGeometry {
2401
3128
  constructor(width?: number, stepHeight?: number, stepDepth?: number, numSteps?: number);
2402
3129
  }
@@ -2432,6 +3159,121 @@ export declare class Star extends Mesh {
2432
3159
  });
2433
3160
  }
2434
3161
 
3162
+ export declare interface StarBurstShapeOptions {
3163
+ /** Burst ray count. Defaults to `4`. */
3164
+ sides?: number;
3165
+ innerRadius?: number;
3166
+ outerRadius?: number;
3167
+ /** Extrusion depth; keep small for flat starbursts. Defaults to `0.05`. */
3168
+ depth?: number;
3169
+ }
3170
+
3171
+ /**
3172
+ * Procedural star field distributed on a spherical shell — intended as an infinite sky dome.
3173
+ *
3174
+ * Stars are placed in world space around the origin. To keep the shell centered on the
3175
+ * viewer, add this object to the **scene** (not the camera) and copy the camera position
3176
+ * every frame. Parenting to the camera is not supported: Three.js does not render
3177
+ * objects attached to the active camera.
3178
+ *
3179
+ * **Styles**
3180
+ *
3181
+ * - `points` — lightweight `Points` sprites using a canvas starburst texture.
3182
+ * - `burst` — instanced 3D starbursts ({@link BurstGeometry}) that face the shell center.
3183
+ * Uses `DoubleSide` so stars remain visible when the camera sits inside the shell.
3184
+ *
3185
+ * **Sizing** — `sizeMin` / `sizeMax` are angular extents (radians at unit distance),
3186
+ * multiplied by each star's distance from the origin so stars look similar regardless
3187
+ * of shell depth (`minRadius`–`maxRadius`).
3188
+ *
3189
+ * **Rendering** — `frustumCulled` is disabled and materials use `depthWrite: false` so
3190
+ * the field draws reliably as a background layer. For per-star color variation in burst
3191
+ * mode, colors are written via `InstancedMesh.setColorAt`, not `vertexColors` on the
3192
+ * base material.
3193
+ *
3194
+ * @example
3195
+ * ```typescript
3196
+ * const stars = new StarFieldEffect({
3197
+ * style: "burst",
3198
+ * count: 2500,
3199
+ * radius: 480,
3200
+ * twinkle: true,
3201
+ * });
3202
+ *
3203
+ * scene.add(stars);
3204
+ *
3205
+ * function animate() {
3206
+ * stars.position.copy(camera.position); // sky dome follows the viewer
3207
+ * stars.update(); // no-op when twinkle is false
3208
+ * renderer.render(scene, camera);
3209
+ * }
3210
+ * ```
3211
+ *
3212
+ * Call {@link dispose} when removing the effect to free geometry, materials, and the
3213
+ * points sprite texture.
3214
+ */
3215
+ export declare class StarFieldEffect extends Object3D {
3216
+ readonly style: "points" | "burst";
3217
+ private readonly field;
3218
+ private readonly twinkle;
3219
+ private readonly baseSize;
3220
+ private readonly baseScales?;
3221
+ private readonly twinklePhases?;
3222
+ private spriteTexture?;
3223
+ private readonly dummy;
3224
+ constructor(options?: StarFieldEffectOptions);
3225
+ get drawable(): Points | InstancedMesh;
3226
+ get geometry(): BufferGeometry;
3227
+ get material(): Material | Material[];
3228
+ /** Release GPU resources held by the field (and sprite texture, if any). */
3229
+ dispose(): void;
3230
+ /**
3231
+ * Animate twinkling. No-op when `twinkle` is `false`.
3232
+ *
3233
+ * Points style modulates sprite size; burst style pulses each instance scale with
3234
+ * a per-star phase offset. Pass elapsed time in seconds (defaults to `performance.now()`).
3235
+ */
3236
+ update(elapsed?: number): void;
3237
+ private createPointsField;
3238
+ private createBurstField;
3239
+ }
3240
+
3241
+ export declare interface StarFieldEffectOptions {
3242
+ /**
3243
+ * Rendering style.
3244
+ *
3245
+ * - `points` (default) — billboard sprites with a procedural starburst texture
3246
+ * (not the default square `Points` marker).
3247
+ * - `burst` — instanced {@link BurstGeometry} meshes oriented toward the shell center.
3248
+ */
3249
+ style?: "points" | "burst";
3250
+ /** Shape parameters for both styles; `burst` uses them for geometry, `points` for the sprite. */
3251
+ burst?: StarBurstShapeOptions;
3252
+ /** Override the burst mesh geometry (`style: "burst"` only). */
3253
+ geometry?: BufferGeometry;
3254
+ /** Override the default field material. */
3255
+ material?: Material;
3256
+ /** Number of stars. Defaults to `1500`. */
3257
+ count?: number;
3258
+ /** Shell radius when `minRadius` / `maxRadius` are omitted. Defaults to `500`. */
3259
+ radius?: number;
3260
+ /** Inner shell radius. Defaults to `radius`. */
3261
+ minRadius?: number;
3262
+ /** Outer shell radius. Defaults to `radius`. */
3263
+ maxRadius?: number;
3264
+ /**
3265
+ * Minimum angular size (radians at 1 unit distance). Scaled by each star's shell distance
3266
+ * so apparent size stays consistent. Defaults to `0.008`.
3267
+ */
3268
+ sizeMin?: number;
3269
+ /** Maximum angular size. Defaults to `0.025`. */
3270
+ sizeMax?: number;
3271
+ /** Single color or palette; multiple entries pick a random color per star. */
3272
+ color?: ColorRepresentation | ColorRepresentation[];
3273
+ /** Enable pulsing brightness; call {@link StarFieldEffect.update} each frame when `true`. */
3274
+ twinkle?: boolean;
3275
+ }
3276
+
2435
3277
  /**
2436
3278
  * Extrude geometry of Star Shape.
2437
3279
  */
@@ -2484,8 +3326,22 @@ export declare class TestTubeGeometry extends BufferGeometry {
2484
3326
  constructor(radiusTop?: number, radiusBottom?: number, height?: number, segments?: number, openEnded?: boolean);
2485
3327
  }
2486
3328
 
3329
+ /**
3330
+ * Wooden rack with instanced test tubes and emissive liquid fills.
3331
+ *
3332
+ * Glass shells use `DoubleSide` and `depthWrite: false`; liquid draws first
3333
+ * (`renderOrder` 1), glass second (`renderOrder` 2) so fills stay visible at
3334
+ * most camera angles.
3335
+ */
2487
3336
  export declare class TestTubeRack extends Group {
2488
- constructor(count?: number, colors?: number[]);
3337
+ constructor(count?: number, colors?: ColorRepresentation[]);
3338
+ }
3339
+
3340
+ export declare interface TestTubeRackOptions {
3341
+ /** Number of tubes. Defaults to `3`. */
3342
+ count?: number;
3343
+ /** Liquid color per tube; cycles when fewer entries than tubes. */
3344
+ colors?: ColorRepresentation[];
2489
3345
  }
2490
3346
 
2491
3347
  /**
@@ -2592,6 +3448,88 @@ export declare class WineBottleGeometry extends BufferGeometry {
2592
3448
  });
2593
3449
  }
2594
3450
 
3451
+ /**
3452
+ * Will-o'-the-wisps drifting through a bounded volume — eerie green orbs that
3453
+ * bob around spawn points with a pulsing point light. Ported from the portfolio
3454
+ * graveyard scene.
3455
+ *
3456
+ * @example
3457
+ * ```ts
3458
+ * const wisps = new WispEffect({ count: 3 });
3459
+ * scene.add(wisps);
3460
+ * onFrame((dt) => wisps.update(dt));
3461
+ * ```
3462
+ */
3463
+ export declare class WispEffect extends Object3D {
3464
+ private readonly wisps;
3465
+ private readonly orbGeometry;
3466
+ private readonly orbMaterial;
3467
+ private readonly halfWidth;
3468
+ private readonly depth;
3469
+ private readonly heightMin;
3470
+ private readonly heightMax;
3471
+ private readonly driftX;
3472
+ private readonly driftY;
3473
+ private readonly driftZ;
3474
+ private readonly speedMin;
3475
+ private readonly speedMax;
3476
+ private readonly castLight;
3477
+ private readonly lightDistance;
3478
+ private readonly lightDecay;
3479
+ private readonly lightIntensity;
3480
+ private readonly lightPulseAmplitude;
3481
+ private readonly lightPulseSpeed;
3482
+ private elapsed;
3483
+ constructor({ count, width, depth, heightMin, heightMax, color, orbRadius, driftX, driftY, driftZ, speedMin, speedMax, castLight, lightDistance, lightDecay, lightIntensity, lightPulseAmplitude, lightPulseSpeed, }?: WispEffectOptions);
3484
+ update(dt: number): void;
3485
+ dispose(): void;
3486
+ }
3487
+
3488
+ export declare interface WispEffectOptions {
3489
+ /** Number of drifting wisps. Defaults to `3`. */
3490
+ count?: number;
3491
+ /** Horizontal spawn extent (world units, centered on the effect). Defaults to `16`. */
3492
+ width?: number;
3493
+ /** Depth spawn maximum (world units, from z = 0). Defaults to `8`. */
3494
+ depth?: number;
3495
+ /** Minimum spawn height. Defaults to `1`. */
3496
+ heightMin?: number;
3497
+ /** Maximum spawn height. Defaults to `2`. */
3498
+ heightMax?: number;
3499
+ /** Wisp tint. Defaults to `0x6dffb0` (portfolio graveyard). */
3500
+ color?: ColorRepresentation;
3501
+ /** Orb radius. Defaults to `0.08`. */
3502
+ orbRadius?: number;
3503
+ /** Horizontal drift radius (X). Defaults to `1.6`. */
3504
+ driftX?: number;
3505
+ /** Vertical drift radius (Y). Defaults to `0.3`. */
3506
+ driftY?: number;
3507
+ /** Depth drift radius (Z). Defaults to `1.6`. */
3508
+ driftZ?: number;
3509
+ /** Minimum motion speed multiplier. Defaults to `0.3`. */
3510
+ speedMin?: number;
3511
+ /** Maximum motion speed multiplier. Defaults to `0.7`. */
3512
+ speedMax?: number;
3513
+ /**
3514
+ * Attach a {@link PointLight} per wisp (keep `count` low).
3515
+ * Defaults to `true` to match the portfolio graveyard.
3516
+ */
3517
+ castLight?: boolean;
3518
+ /** Point light distance when `castLight`. Defaults to `6`. */
3519
+ lightDistance?: number;
3520
+ /** Point light decay when `castLight`. Defaults to `2`. */
3521
+ lightDecay?: number;
3522
+ /**
3523
+ * Light intensity = `lightIntensity + sin(t * lightPulseSpeed) * lightPulseAmplitude`.
3524
+ * Defaults to `2.5`.
3525
+ */
3526
+ lightIntensity?: number;
3527
+ /** Defaults to `1.2`. */
3528
+ lightPulseAmplitude?: number;
3529
+ /** Defaults to `3`. */
3530
+ lightPulseSpeed?: number;
3531
+ }
3532
+
2595
3533
  export declare class WroughtIronBar extends Mesh<WroughtIronBarGeometry, MeshStandardMaterial> {
2596
3534
  constructor({ barHeight, //
2597
3535
  barRadius, spikeHeight, spikeRadius, spikeScaleZ, radialSegments, }?: {