babylon.quarks 0.24.0 → 0.25.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.
@@ -1182,6 +1182,14 @@ interface IParticleSystem {
1182
1182
  * @type {number}
1183
1183
  */
1184
1184
  simulationStep?: number;
1185
+ /**
1186
+ * What world-space forces and speed limits are multiplied by: the
1187
+ * emitter's world scale when the system scales its motion with it (a
1188
+ * world-space system in `'hierarchy'` scaling mode), 1 or undefined
1189
+ * otherwise.
1190
+ * @type {number}
1191
+ */
1192
+ motionScale?: number;
1185
1193
  /**
1186
1194
  * Whether this system only emits through another system, which is when its
1187
1195
  * particles carry their own parent transform.
@@ -2114,17 +2122,67 @@ declare class ForceOverLife implements Behavior {
2114
2122
  }
2115
2123
 
2116
2124
  /**
2117
- * apply tile number of particle texture by particles' life.
2125
+ * How {@link FrameOverLife} plays the sheet, beyond sampling `frame` over the
2126
+ * particle's life. Every field is optional, and leaving them all out keeps the
2127
+ * plain life-fraction behaviour.
2128
+ */
2129
+ interface FrameOverLifeOptions {
2130
+ /**
2131
+ * Frames per second. Above zero the sheet plays by the particle's age in
2132
+ * seconds instead of its life fraction, Unity's "FPS" time mode: `frame`
2133
+ * then gives the first frame of the segment, and the frame advances by one
2134
+ * every `1 / fps` seconds. Needs {@link frameCount}.
2135
+ */
2136
+ fps?: number;
2137
+ /**
2138
+ * Life mode only: how many times `frame` plays over the particle's life
2139
+ * (Unity's "Cycles"). Default 1.
2140
+ */
2141
+ cycles?: number;
2142
+ /**
2143
+ * Frames in the segment that plays, from the first frame. In FPS mode the
2144
+ * frame wraps (or holds, see {@link loop}) at it, counted from `frame`;
2145
+ * in life mode the curve plus a {@link startFrame} offset wraps into
2146
+ * `[0, frameCount)`, so the curve should start at frame 0. 0, the default,
2147
+ * means no segment.
2148
+ */
2149
+ frameCount?: number;
2150
+ /** FPS mode: wrap back to the first frame of the segment (default) or hold its last. */
2151
+ loop?: boolean;
2152
+ /**
2153
+ * Per-particle frame offset, sampled once at birth: an `IntervalValue(0, n)`
2154
+ * starts each particle on a random frame (Unity's "Start Frame"). Default none.
2155
+ */
2156
+ startFrame?: ValueGenerator;
2157
+ }
2158
+ /**
2159
+ * Sets the particle's texture tile (`uvTile`) over its life.
2160
+ *
2161
+ * By default `frame` is sampled at the particle's life fraction. The
2162
+ * {@link FrameOverLifeOptions} add the rest of Unity's texture sheet
2163
+ * animation: playing at a fixed frame rate, several cycles per life, a frame
2164
+ * segment that loops or holds, and a random start frame.
2118
2165
  */
2119
2166
  declare class FrameOverLife implements Behavior {
2120
2167
  type: string;
2121
2168
  private _frame;
2122
- constructor(frame: FunctionValueGenerator | ValueGenerator);
2169
+ fps: number;
2170
+ cycles: number;
2171
+ frameCount: number;
2172
+ loop: boolean;
2173
+ startFrame?: ValueGenerator;
2174
+ constructor(frame: FunctionValueGenerator | ValueGenerator, options?: FrameOverLifeOptions);
2123
2175
  get frame(): FunctionValueGenerator | ValueGenerator;
2124
2176
  set frame(frame: FunctionValueGenerator | ValueGenerator);
2177
+ /** True when no option is in play and the frame is just `frame` at the life fraction. */
2178
+ isPlain(): boolean;
2125
2179
  initialize(particle: Particle): void;
2126
2180
  update(particle: Particle, delta: number): void;
2127
2181
  updateAll(particles: Array<Particle>, count: number, delta: number): void;
2182
+ /** The tile for `particle` at `age` seconds, `t` being that age over its life. */
2183
+ frameAt(particle: Particle, age: number, t: number): number;
2184
+ private offset;
2185
+ private static wrap;
2128
2186
  private sampleFrame;
2129
2187
  frameUpdate(delta: number): void;
2130
2188
  toJSON(): any;
@@ -2188,7 +2246,11 @@ declare class LimitSpeedOverLife implements Behavior {
2188
2246
  speed: FunctionValueGenerator;
2189
2247
  dampen: number;
2190
2248
  type: string;
2191
- initialize(particle: Particle): void;
2249
+ /** Learned in {@link initialize}; its motion scale multiplies the limit of a world-space system. */
2250
+ ps?: IParticleSystem;
2251
+ initialize(particle: Particle, particleSystem?: IParticleSystem): void;
2252
+ /** What the limit is multiplied by: the system's motion scale in world space, else 1. */
2253
+ motionScale(): number;
2192
2254
  constructor(speed: FunctionValueGenerator, dampen: number);
2193
2255
  update(particle: Particle, delta: number): void;
2194
2256
  updateAll(particles: Array<Particle>, count: number, delta: number): void;
@@ -3262,7 +3324,14 @@ declare enum RenderMode {
3262
3324
  Mesh = 2,
3263
3325
  Trail = 3,
3264
3326
  HorizontalBillBoard = 4,
3265
- VerticalBillBoard = 5
3327
+ VerticalBillBoard = 5,
3328
+ /**
3329
+ * A quad laid from each particle to the system's {@link ParticleSystem.beamEnd}
3330
+ * and turned about its length to face the camera (a line renderer): U runs
3331
+ * from the particle (0) to the end (1), V across, the particle's size is
3332
+ * the width. Lightning, tethers, lasers.
3333
+ */
3334
+ Beam = 6
3266
3335
  }
3267
3336
  /**
3268
3337
  * How mesh particles are lit.
@@ -3314,6 +3383,36 @@ interface MeshRim {
3314
3383
  declare function normalizeMeshRim(rim: Partial<MeshRim> | null | undefined): MeshRim | undefined;
3315
3384
  /** True when both describe the same rim (or both none). */
3316
3385
  declare function meshRimEqual(a: MeshRim | undefined, b: MeshRim | undefined): boolean;
3386
+ /**
3387
+ * Alpha erosion: the particle's alpha decides how much of its shape is left
3388
+ * instead of how transparent it is, so `ColorOverLife` fading alpha out
3389
+ * dissolves (noise mask) or wipes (gradient mask) the shape away. See
3390
+ * {@link VFXBatchSettings.erosion}.
3391
+ */
3392
+ interface ParticleErosion {
3393
+ /**
3394
+ * Mask whose red channel orders what goes first, sampled with the
3395
+ * particle's UV (the quad, mesh or trail UV, unscrolled). Null: the map's
3396
+ * own alpha, so a soft shape shrinks from its edges.
3397
+ */
3398
+ mask: BaseTexture | null;
3399
+ /** Width of the soft transition at the cut, in mask units. Default 0.05. */
3400
+ softness: number;
3401
+ /** Width of the glowing band above the cut, in mask units; 0 (default) draws none. */
3402
+ edgeWidth: number;
3403
+ /** Colour added in the edge band, linear RGB, may exceed 1. Default `[1, 1, 1]`. */
3404
+ edgeColor: [number, number, number];
3405
+ /** Mask UV scroll, UV units per second. Default `[0, 0]`. */
3406
+ maskScroll: [number, number];
3407
+ }
3408
+ /** A complete erosion from a partial one, every field defaulted, or undefined when `erosion` is unset. */
3409
+ declare function normalizeErosion(erosion: Partial<ParticleErosion> | null | undefined): ParticleErosion | undefined;
3410
+ /** True when both describe the same erosion (or both none). */
3411
+ declare function erosionEqual(a: ParticleErosion | undefined, b: ParticleErosion | undefined): boolean;
3412
+ /** A UV scroll speed, or undefined when unset or zero. */
3413
+ declare function normalizeUVScroll(scroll: ArrayLike<number> | null | undefined): [number, number] | undefined;
3414
+ /** True when both scroll the same way (or both not at all). */
3415
+ declare function uvScrollEqual(a: [number, number] | undefined, b: [number, number] | undefined): boolean;
3317
3416
  interface StoredBatchSettings {
3318
3417
  instancingGeometry: Float32Array;
3319
3418
  instancingIndices: Uint32Array | Uint16Array;
@@ -3354,6 +3453,12 @@ interface StoredBatchSettings {
3354
3453
  lighting?: MeshLighting;
3355
3454
  /** Mesh particle rim, see {@link VFXBatchSettings.rim}. */
3356
3455
  rim?: MeshRim;
3456
+ /** Map UV scroll, see {@link VFXBatchSettings.uvScroll}. */
3457
+ uvScroll?: [number, number];
3458
+ /** Colour ramp for the map, see {@link VFXBatchSettings.gradientMap}. */
3459
+ gradientMap: BaseTexture | null;
3460
+ /** Alpha erosion, see {@link VFXBatchSettings.erosion}. */
3461
+ erosion?: ParticleErosion;
3357
3462
  }
3358
3463
  declare abstract class VFXBatch {
3359
3464
  mesh: Mesh;
@@ -3391,6 +3496,17 @@ declare abstract class VFXBatch {
3391
3496
  protected static readonly FOG_UNIFORMS: string[];
3392
3497
  protected fogDefines(): string[];
3393
3498
  protected bindFog(material: ShaderMaterial): void;
3499
+ /**
3500
+ * Seconds of renderer time, set by the renderer before each fill; what UV
3501
+ * and erosion mask scrolling advance by.
3502
+ */
3503
+ time: number;
3504
+ /** Defines of the texture effects (see `shaders/chunks/surface.ts`) this batch uses. */
3505
+ protected surfaceDefines(): string[];
3506
+ /** Adds the uniforms and samplers of the texture effects this batch uses. */
3507
+ protected surfaceUniforms(uniforms: string[], samplers: string[]): void;
3508
+ /** Sets the texture effects' textures and constants, and advances their scrolling on every bind. */
3509
+ protected bindSurface(material: ShaderMaterial): void;
3394
3510
  addSystem(system: IParticleSystem): void;
3395
3511
  removeSystem(system: IParticleSystem): void;
3396
3512
  /**
@@ -3488,6 +3604,22 @@ interface VFXBatchSettings {
3488
3604
  lighting?: MeshLighting;
3489
3605
  /** Rim (Fresnel) term on mesh particles; unset draws none. See {@link MeshRim}. */
3490
3606
  rim?: MeshRim;
3607
+ /**
3608
+ * Scrolls the map's UV by this many UV units per second, `[u, v]`, on the
3609
+ * renderer's clock. The texture should wrap; scrolling one tile of a sheet
3610
+ * runs into its neighbours. Unset or zero: no scroll. Systems that differ
3611
+ * are batched apart.
3612
+ */
3613
+ uvScroll?: [number, number];
3614
+ /**
3615
+ * Colour ramp the map is recoloured through: the map's red channel picks
3616
+ * a colour along U of this texture, and its alpha multiplies the map's. The
3617
+ * particle colour still tints the result. Unset: none. Systems that differ
3618
+ * are batched apart.
3619
+ */
3620
+ gradientMap?: BaseTexture | null;
3621
+ /** Alpha erosion (dissolve / wipe), see {@link ParticleErosion}. Unset: none. Systems that differ are batched apart. */
3622
+ erosion?: ParticleErosion;
3491
3623
  }
3492
3624
  interface AdaptivePerformanceOptions {
3493
3625
  targetFrameMs: number;
@@ -3503,6 +3635,8 @@ interface AdaptivePerformanceState extends AdaptivePerformanceOptions {
3503
3635
  }
3504
3636
  declare class BatchedRenderer extends TransformNode {
3505
3637
  batches: Array<VFXBatch>;
3638
+ /** Seconds this renderer has been updated for; the clock UV and erosion scrolling run on. */
3639
+ private elapsed;
3506
3640
  systemToBatchIndex: Map<IParticleSystem, number>;
3507
3641
  depthTexture: BaseTexture | null;
3508
3642
  /** Systems in insertion order — iterated every frame, unlike the map. */
@@ -3778,6 +3912,35 @@ interface BurstParameters {
3778
3912
  * culled either; its parent decides.
3779
3913
  */
3780
3914
  type CullingMode = 'always' | 'pause' | 'pauseAndCatchUp';
3915
+ /**
3916
+ * What the emitter's world scale does to a world-space system (Unity's
3917
+ * Scaling Mode, as far as it differs here). A local-space system lives in its
3918
+ * emitter's space, so its scale reaches everything either way.
3919
+ *
3920
+ * - `'shape'` (default): the scale sizes the emission shape and the
3921
+ * particles; speeds, forces and speed limits stay in world units, so a
3922
+ * scaled-down effect moves as far as the full-size one.
3923
+ * - `'hierarchy'`: the scale also multiplies start speeds (per axis),
3924
+ * `ForceOverLife` and `LimitSpeedOverLife` (by the mean of the axes), so the
3925
+ * whole effect, motion included, scales like a model would.
3926
+ */
3927
+ type ScalingMode = 'shape' | 'hierarchy';
3928
+ /**
3929
+ * Where a {@link RenderMode.Beam} system's quads end: a point in world space,
3930
+ * or anything with a world position, such as a Babylon `TransformNode`, read
3931
+ * every frame.
3932
+ */
3933
+ type BeamEnd = {
3934
+ x: number;
3935
+ y: number;
3936
+ z: number;
3937
+ } | {
3938
+ getAbsolutePosition(): {
3939
+ x: number;
3940
+ y: number;
3941
+ z: number;
3942
+ };
3943
+ };
3781
3944
  interface ParticleSystemParameters {
3782
3945
  autoDestroy?: boolean;
3783
3946
  looping?: boolean;
@@ -3830,10 +3993,18 @@ interface ParticleSystemParameters {
3830
3993
  lighting?: MeshLighting;
3831
3994
  /** Rim (Fresnel) term on mesh particles, see {@link ParticleSystem.rim}. Default none. */
3832
3995
  rim?: Partial<MeshRim>;
3996
+ /** Map UV scroll in UV units per second, see {@link ParticleSystem.uvScroll}. Default none. */
3997
+ uvScroll?: [number, number];
3998
+ /** Colour ramp for the map, see {@link ParticleSystem.gradientMap}. Default none. */
3999
+ gradientMap?: BaseTexture | null;
4000
+ /** Alpha erosion, see {@link ParticleSystem.erosion}. Default none. */
4001
+ erosion?: Partial<ParticleErosion>;
3833
4002
  /** Multiplier on the time the system is advanced by, see {@link ParticleSystem.playbackSpeed}. Default 1. */
3834
4003
  playbackSpeed?: number;
3835
4004
  /** What the system does while off screen, see {@link CullingMode}. Default `'always'`. */
3836
4005
  cullingMode?: CullingMode;
4006
+ /** What the emitter's scale does to a world-space system, see {@link ScalingMode}. Default `'shape'`. */
4007
+ scalingMode?: ScalingMode;
3837
4008
  /** Seed for this system's own random generator, see {@link ParticleSystem.seed}. Default none. */
3838
4009
  seed?: number;
3839
4010
  /** Draw order within the batch, see {@link ParticleSystem.sortMode}. Default `'none'`. */
@@ -3887,6 +4058,8 @@ interface ParticleSystemJSONParameters {
3887
4058
  playbackSpeed?: number;
3888
4059
  /** Written only when not `'always'`. */
3889
4060
  cullingMode?: CullingMode;
4061
+ /** Written only when not `'shape'`. */
4062
+ scalingMode?: ScalingMode;
3890
4063
  /** Written only when set. */
3891
4064
  seed?: number;
3892
4065
  /** Written only when not `'none'`. */
@@ -4090,6 +4263,43 @@ declare class ParticleSystem implements IParticleSystem {
4090
4263
  */
4091
4264
  get rim(): MeshRim | undefined;
4092
4265
  set rim(rim: Partial<MeshRim> | undefined);
4266
+ /**
4267
+ * Scrolls the map's UV by `[u, v]` UV units per second on the renderer's
4268
+ * clock: flowing energy, lava, a smear running along a mesh. The texture
4269
+ * should wrap. Undefined (the default) or zero does not scroll. Assign a
4270
+ * new array to change it. Saved with the material in the effect JSON.
4271
+ */
4272
+ get uvScroll(): [number, number] | undefined;
4273
+ set uvScroll(scroll: [number, number] | undefined);
4274
+ /**
4275
+ * Colour ramp the map is recoloured through (a gradient map): the map's
4276
+ * red channel picks a colour along U of this texture, whose alpha
4277
+ * multiplies the map's; the particle colour still tints the result. One
4278
+ * greyscale texture then serves every palette. Null (the default): none.
4279
+ * Saved with the material in the effect JSON.
4280
+ */
4281
+ get gradientMap(): BaseTexture | null;
4282
+ set gradientMap(texture: BaseTexture | null);
4283
+ /**
4284
+ * Alpha erosion, see {@link ParticleErosion}: the particle's alpha decides
4285
+ * how much of the shape is left rather than how transparent it is, so a
4286
+ * `ColorOverLife` alpha curve dissolves the shape through a noise mask or
4287
+ * wipes it through a gradient one — and an effect told to stop can fade
4288
+ * out that way. Undefined (the default): alpha is plain transparency.
4289
+ * Fields left out take their defaults; assign a new object to change it.
4290
+ * Saved with the material in the effect JSON.
4291
+ */
4292
+ get erosion(): ParticleErosion | undefined;
4293
+ set erosion(erosion: Partial<ParticleErosion> | undefined);
4294
+ /**
4295
+ * The emitter's world scale per axis, measured with {@link motionScale}
4296
+ * before every step; what `'hierarchy'` multiplies start speeds by. Taken
4297
+ * from the system's own emitter rather than the emission matrix, whose
4298
+ * columns carry a parent particle's velocity for a sub emitter.
4299
+ */
4300
+ private readonly hierarchyScale;
4301
+ /** The mean world scale of the emitter for a world-space `'hierarchy'` system, else 1. */
4302
+ private measureMotionScale;
4093
4303
  /** `lighting` if it is one of the modes, else the default. */
4094
4304
  private static validLighting;
4095
4305
  private static validSortMode;
@@ -4128,8 +4338,24 @@ declare class ParticleSystem implements IParticleSystem {
4128
4338
  * renderer. 1 by default; saved in the effect JSON only when it differs.
4129
4339
  */
4130
4340
  playbackSpeed: number;
4341
+ /**
4342
+ * Runtime multiplier on how many particles the system emits: bursts,
4343
+ * emission over time and over distance alike. Unlike
4344
+ * {@link setQualityFactor}, which only ever thins an effect, it may go
4345
+ * above 1 to make a stronger version of the same effect. The two multiply.
4346
+ * 1 by default; not saved in the effect JSON.
4347
+ */
4348
+ emissionMultiplier: number;
4131
4349
  /** What this system does while off screen, see {@link CullingMode}. `'always'` by default. */
4132
4350
  cullingMode: CullingMode;
4351
+ /** What the emitter's world scale does to a world-space system, see {@link ScalingMode}. `'shape'` by default. */
4352
+ scalingMode: ScalingMode;
4353
+ /**
4354
+ * What world-space forces and speed limits are multiplied by this step:
4355
+ * the mean of the emitter's world scale axes in `'hierarchy'` mode, 1
4356
+ * otherwise. Updated before every simulation step.
4357
+ */
4358
+ motionScale: number;
4133
4359
  /**
4134
4360
  * Whether each particle starts turned along the direction its shape sends
4135
4361
  * it (Unity's Align To Direction): a mesh particle's +Z is pointed along
@@ -4195,6 +4421,8 @@ declare class ParticleSystem implements IParticleSystem {
4195
4421
  play(): void;
4196
4422
  stop(): void;
4197
4423
  setQualityFactor(qualityFactor: number): void;
4424
+ /** Quality factor times {@link emissionMultiplier}: what emission counts are scaled by. */
4425
+ private emissionFactor;
4198
4426
  /**
4199
4427
  * Appends one particle to the pool, giving it the next row of the store.
4200
4428
  *
@@ -4245,6 +4473,18 @@ declare class ParticleSystem implements IParticleSystem {
4245
4473
  * frame behind the display.
4246
4474
  */
4247
4475
  getWorldBounds(min: Vector3, max: Vector3): boolean;
4476
+ /**
4477
+ * Where a {@link RenderMode.Beam} system's quads end, see {@link BeamEnd}.
4478
+ * Unset (the default), a beam has no length and draws nothing. Not saved
4479
+ * in the effect JSON: it is where this instance is aimed at runtime.
4480
+ */
4481
+ beamEnd?: BeamEnd;
4482
+ private readonly beamEndScratch;
4483
+ /** The world position of {@link beamEnd} into `out`; false when it is unset. */
4484
+ getBeamEnd(out: Vector3): boolean;
4485
+ /** The largest axis of the emitter's world scale. */
4486
+ private emitterMaxScale;
4487
+ private measureWorldBounds;
4248
4488
  /**
4249
4489
  * Records bounds a renderer measured in world space, for systems whose
4250
4490
  * drawn extent the store does not hold (trail ribbons).
@@ -4587,6 +4827,22 @@ declare class QuarksUtil {
4587
4827
  * Nodes that are neither transform nodes nor emitters are skipped.
4588
4828
  */
4589
4829
  static instantiate(root: TransformNode, name?: string): TransformNode;
4830
+ /**
4831
+ * Seconds until the effect under `root` is over when it plays from the
4832
+ * start: for each system its start delay, its duration and its longest
4833
+ * particle life, divided by its playback speed; a sub emitter target goes
4834
+ * on emitting for its own duration after the last of its parents' particles
4835
+ * and ends a particle life after that, wherever it sits in the scene.
4836
+ * Infinity when a system loops, since such an effect only ends on
4837
+ * {@link endEmit}, or when one is frozen at playback speed 0.
4838
+ *
4839
+ * Random values count at their maximum, so this is an upper bound; curves
4840
+ * are sampled. Particles cut short by collisions or culling only make the
4841
+ * real effect shorter.
4842
+ */
4843
+ static getDuration(root: Node): number;
4844
+ /** The largest value `generator` gives: exact for constants and intervals, sampled otherwise. */
4845
+ private static maxOf;
4590
4846
  private static traverseNode;
4591
4847
  }
4592
4848
 
@@ -4688,7 +4944,17 @@ declare class SpriteBatch extends VFXBatch {
4688
4944
  * optimised code on every frame.
4689
4945
  */
4690
4946
  private syncStretchedSpeedFactor;
4691
- /** The quads that take a pivot and flip: every billboard kind, stretched included, but not meshes. */
4947
+ /** Stretched billboards and beams: drawn along a per-instance vector, by the stretched shader. */
4948
+ private static drawsAlongVelocity;
4949
+ private readonly beamEnd_;
4950
+ /**
4951
+ * Writes, for the `count` instances from `first`, the world vector from
4952
+ * each one's drawn position to the system's beam end into the velocity
4953
+ * buffer, which the stretched shader under `BEAM` lays the quad along. A
4954
+ * beam without an end gets no length.
4955
+ */
4956
+ private writeBeams;
4957
+ /** The quads that take a pivot and flip: every billboard kind, stretched included, but not meshes or beams. */
4692
4958
  private static takesPivotAndFlip;
4693
4959
  /**
4694
4960
  * Negates the size of each flipped particle along the axes it flips on,
@@ -4816,5 +5082,5 @@ declare class TrailBatch extends VFXBatch {
4816
5082
  dispose(): void;
4817
5083
  }
4818
5084
 
4819
- export { ApplyCollision, ApplyForce, ApplySequences, AxisAngleGenerator, BatchedParticleRenderer, BatchedRenderer, BehaviorFromJSON, BehaviorTypes, Bezier, BoxEmitFrom, BoxEmitter, ChangeEmitDirection, CircleEmitter, ColorBySpeed, ColorGeneratorFromJSON, ColorOverLife, ColorRange, ConeEmitter, ConstantColor, ConstantValue, DEG2RAD, DonutEmitter, EdgeEmitter, EffectPool, EmitSubParticleSystem, EmitterFromJSON, EmitterMode, EmitterShapes, Euler, EulerGenerator, ForceOverLife, FrameOverLife, GeneratorFromJSON, Gradient, GravityForce, GridEmitter, HemisphereEmitter, InheritVelocity, IntervalValue, LimitSpeedOverLife, MathUtils, Matrix3, Matrix4, MeshSurfaceEmitter, MeshSurfaceEmitterPlugin, NodeParticle, Noise, OrbitOverLife, ParticleEmitter, ParticleMeshPhysicsMaterial, ParticleMeshStandardMaterial, ParticleStore, ParticleSystem, PiecewiseBezier, PiecewiseFunction, Plugins, PointEmitter, QuarksLoader, QuarksPrefab, QuarksUtil, Quaternion, QuaternionView, RAD2DEG, RandomColor, RandomColorBetweenGradient, RandomQuatGenerator, RecordState, RectangleEmitter, RenderMode, Rotation3DOverLife, RotationBySpeed, RotationGeneratorFromJSON, RotationOverLife, SequencerFromJSON, ShapeTransform, SizeBySpeed, SizeOverLife, SpeedOverLife, SphereEmitter, SpriteBatch, SpriteParticle, SubEmitterInheritMask, SubParticleEmitMode, TextureSequencer, TrailBatch, TrailParticle, TurbulenceField, VFXBatch, ValueGeneratorFromJSON, Vector2, Vector3, Vector3Function, Vector3GeneratorFromJSON, Vector3View, Vector4, Vector4View, VelocityOverLife, WebGLCoordinateSystem, WebGPUCoordinateSystem, WidthOverLength, cacheEnvAtlas, ceilPowerOfTwo, clamp, createEnvAtlasFromFaceUrls, createSeededRandom, cubeFaceUrls, damp, defaultMeshLighting, degToRad, denormalize, ensureEnvAtlasFromCube, euclideanModulo, floorPowerOfTwo, generateUUID, getCachedEnvAtlas, getPhysicsResolver, getRandomSource, getRegisteredShaderChunks, getShaderChunk, getValueFromEmitterMode, inverseLerp, isPowerOfTwo, lerp, loadPlugin, _default$7 as localParticlePhysicsVertShader, _default$6 as localParticleVertShader, mapLinear, meshRimEqual, normalize, normalizeMeshRim, _default$5 as particleFragShader, _default$4 as particlePhysicsFragShader, _default$3 as particleVertShader, pingpong, planBehaviorFusion, radToDeg, randFloat, randFloatSpread, randInt, random, registerShaderChunks, seededRandom, setPhysicsResolver, setQuaternionFromProperEuler, setRandomSource, smootherstep, smoothstep, _default$2 as stretchedBillboardVertShader, subEmitterInheritMask, _default$1 as trailFragShader, _default as trailVertShader, unloadPlugin, withRandomSource };
4820
- export type { AdaptivePerformanceOptions, AdaptivePerformanceState, AnimationData, BabylonMetaData, BabylonParticleMaterialParameters, Behavior, BehaviorPlugin, BillBoardSettings, BoxEmitterParameters, BurstParameters, BurstParametersJSON, CircleEmitterParameters, ColorGenerator, ConeEmitterParameters, Constructable, CullingMode, DonutEmitterParameters, EdgeEmitterParameters, EffectPoolOptions, EmissionState, EmitterShape, EmitterShapePlugin, EulerOrder, FieldType, FunctionColorGenerator, FunctionJSON, FunctionValueGenerator, FusedPass, FusionStep, GeneratorMemory, GridEmitterParameters, HemisphereEmitterParameters, IAnimationData, IEmitter, IParticle, IParticleSystem, IPrefab, InheritVelocityMode, JsonMetaData, MeshLighting, MeshLightingSettings, MeshRim, MeshSettings, ParameterPair, ParameterType, Particle, ParticleSystemEvent, ParticleSystemEventType, ParticleSystemJSONParameters, ParticleSystemParameters, Plugin, QuarksBatchLoadOptions, QuarksJSONLoadEntry, QuarksLoaderOptions, QuarksResourceKind, QuarksResourceResolver, QuarksTimelineClip, RandomSource, RectangleEmitterParameters, RendererEmitterSettings, Resource, RotationGenerator, Sequencer, SerializationOptions, ShapeJSON, ShapeTransformJSON, SortMode, SphereEmitterParameters, StoredBatchSettings, StretchedBillBoardSettings, SubEmitterInheritance, TrailSettings, VFXBatchSettings, ValueGenerator, Vector3Generator, VelocityOverLifeSpace };
5085
+ export { ApplyCollision, ApplyForce, ApplySequences, AxisAngleGenerator, BatchedParticleRenderer, BatchedRenderer, BehaviorFromJSON, BehaviorTypes, Bezier, BoxEmitFrom, BoxEmitter, ChangeEmitDirection, CircleEmitter, ColorBySpeed, ColorGeneratorFromJSON, ColorOverLife, ColorRange, ConeEmitter, ConstantColor, ConstantValue, DEG2RAD, DonutEmitter, EdgeEmitter, EffectPool, EmitSubParticleSystem, EmitterFromJSON, EmitterMode, EmitterShapes, Euler, EulerGenerator, ForceOverLife, FrameOverLife, GeneratorFromJSON, Gradient, GravityForce, GridEmitter, HemisphereEmitter, InheritVelocity, IntervalValue, LimitSpeedOverLife, MathUtils, Matrix3, Matrix4, MeshSurfaceEmitter, MeshSurfaceEmitterPlugin, NodeParticle, Noise, OrbitOverLife, ParticleEmitter, ParticleMeshPhysicsMaterial, ParticleMeshStandardMaterial, ParticleStore, ParticleSystem, PiecewiseBezier, PiecewiseFunction, Plugins, PointEmitter, QuarksLoader, QuarksPrefab, QuarksUtil, Quaternion, QuaternionView, RAD2DEG, RandomColor, RandomColorBetweenGradient, RandomQuatGenerator, RecordState, RectangleEmitter, RenderMode, Rotation3DOverLife, RotationBySpeed, RotationGeneratorFromJSON, RotationOverLife, SequencerFromJSON, ShapeTransform, SizeBySpeed, SizeOverLife, SpeedOverLife, SphereEmitter, SpriteBatch, SpriteParticle, SubEmitterInheritMask, SubParticleEmitMode, TextureSequencer, TrailBatch, TrailParticle, TurbulenceField, VFXBatch, ValueGeneratorFromJSON, Vector2, Vector3, Vector3Function, Vector3GeneratorFromJSON, Vector3View, Vector4, Vector4View, VelocityOverLife, WebGLCoordinateSystem, WebGPUCoordinateSystem, WidthOverLength, cacheEnvAtlas, ceilPowerOfTwo, clamp, createEnvAtlasFromFaceUrls, createSeededRandom, cubeFaceUrls, damp, defaultMeshLighting, degToRad, denormalize, ensureEnvAtlasFromCube, erosionEqual, euclideanModulo, floorPowerOfTwo, generateUUID, getCachedEnvAtlas, getPhysicsResolver, getRandomSource, getRegisteredShaderChunks, getShaderChunk, getValueFromEmitterMode, inverseLerp, isPowerOfTwo, lerp, loadPlugin, _default$7 as localParticlePhysicsVertShader, _default$6 as localParticleVertShader, mapLinear, meshRimEqual, normalize, normalizeErosion, normalizeMeshRim, normalizeUVScroll, _default$5 as particleFragShader, _default$4 as particlePhysicsFragShader, _default$3 as particleVertShader, pingpong, planBehaviorFusion, radToDeg, randFloat, randFloatSpread, randInt, random, registerShaderChunks, seededRandom, setPhysicsResolver, setQuaternionFromProperEuler, setRandomSource, smootherstep, smoothstep, _default$2 as stretchedBillboardVertShader, subEmitterInheritMask, _default$1 as trailFragShader, _default as trailVertShader, unloadPlugin, uvScrollEqual, withRandomSource };
5086
+ export type { AdaptivePerformanceOptions, AdaptivePerformanceState, AnimationData, BabylonMetaData, BabylonParticleMaterialParameters, BeamEnd, Behavior, BehaviorPlugin, BillBoardSettings, BoxEmitterParameters, BurstParameters, BurstParametersJSON, CircleEmitterParameters, ColorGenerator, ConeEmitterParameters, Constructable, CullingMode, DonutEmitterParameters, EdgeEmitterParameters, EffectPoolOptions, EmissionState, EmitterShape, EmitterShapePlugin, EulerOrder, FieldType, FrameOverLifeOptions, FunctionColorGenerator, FunctionJSON, FunctionValueGenerator, FusedPass, FusionStep, GeneratorMemory, GridEmitterParameters, HemisphereEmitterParameters, IAnimationData, IEmitter, IParticle, IParticleSystem, IPrefab, InheritVelocityMode, JsonMetaData, MeshLighting, MeshLightingSettings, MeshRim, MeshSettings, ParameterPair, ParameterType, Particle, ParticleErosion, ParticleSystemEvent, ParticleSystemEventType, ParticleSystemJSONParameters, ParticleSystemParameters, Plugin, QuarksBatchLoadOptions, QuarksJSONLoadEntry, QuarksLoaderOptions, QuarksResourceKind, QuarksResourceResolver, QuarksTimelineClip, RandomSource, RectangleEmitterParameters, RendererEmitterSettings, Resource, RotationGenerator, ScalingMode, Sequencer, SerializationOptions, ShapeJSON, ShapeTransformJSON, SortMode, SphereEmitterParameters, StoredBatchSettings, StretchedBillBoardSettings, SubEmitterInheritance, TrailSettings, VFXBatchSettings, ValueGenerator, Vector3Generator, VelocityOverLifeSpace };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babylon.quarks",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "A High-Performance Particle System for Babylon.js",
5
5
  "type": "module",
6
6
  "types": "./dist/types/index.d.ts",
@@ -11,13 +11,16 @@ import {SpriteBatch} from './SpriteBatch';
11
11
  import {TrailBatch} from './TrailBatch';
12
12
  import {
13
13
  defaultMeshLighting,
14
+ erosionEqual,
14
15
  MeshLighting,
15
16
  MeshLightingSettings,
16
17
  MeshRim,
17
18
  meshRimEqual,
19
+ ParticleErosion,
18
20
  RenderMode,
19
21
  SortMode,
20
22
  StoredBatchSettings,
23
+ uvScrollEqual,
21
24
  VFXBatch,
22
25
  } from './VFXBatch';
23
26
 
@@ -100,6 +103,22 @@ export interface VFXBatchSettings {
100
103
  lighting?: MeshLighting;
101
104
  /** Rim (Fresnel) term on mesh particles; unset draws none. See {@link MeshRim}. */
102
105
  rim?: MeshRim;
106
+ /**
107
+ * Scrolls the map's UV by this many UV units per second, `[u, v]`, on the
108
+ * renderer's clock. The texture should wrap; scrolling one tile of a sheet
109
+ * runs into its neighbours. Unset or zero: no scroll. Systems that differ
110
+ * are batched apart.
111
+ */
112
+ uvScroll?: [number, number];
113
+ /**
114
+ * Colour ramp the map is recoloured through: the map's red channel picks
115
+ * a colour along U of this texture, and its alpha multiplies the map's. The
116
+ * particle colour still tints the result. Unset: none. Systems that differ
117
+ * are batched apart.
118
+ */
119
+ gradientMap?: BaseTexture | null;
120
+ /** Alpha erosion (dissolve / wipe), see {@link ParticleErosion}. Unset: none. Systems that differ are batched apart. */
121
+ erosion?: ParticleErosion;
103
122
  }
104
123
 
105
124
  export interface AdaptivePerformanceOptions {
@@ -139,6 +158,8 @@ export interface AdaptivePerformanceState extends AdaptivePerformanceOptions {
139
158
 
140
159
  export class BatchedRenderer extends TransformNode {
141
160
  batches: Array<VFXBatch> = [];
161
+ /** Seconds this renderer has been updated for; the clock UV and erosion scrolling run on. */
162
+ private elapsed = 0;
142
163
  systemToBatchIndex: Map<IParticleSystem, number> = new Map<IParticleSystem, number>();
143
164
  depthTexture: BaseTexture | null = null;
144
165
  /** Systems in insertion order — iterated every frame, unlike the map. */
@@ -311,7 +332,10 @@ export class BatchedRenderer extends TransformNode {
311
332
  a.minParticleSize === (b.minParticleSize ?? 0) &&
312
333
  a.maxParticleSize === (b.maxParticleSize ?? Infinity) &&
313
334
  (a.lighting ?? 'fixed') === (b.lighting ?? 'fixed') &&
314
- meshRimEqual(a.rim, b.rim)
335
+ meshRimEqual(a.rim, b.rim) &&
336
+ uvScrollEqual(a.uvScroll, b.uvScroll) &&
337
+ a.gradientMap === (b.gradientMap ?? null) &&
338
+ erosionEqual(a.erosion, b.erosion)
315
339
  );
316
340
  }
317
341
 
@@ -350,6 +374,7 @@ export class BatchedRenderer extends TransformNode {
350
374
  case RenderMode.VerticalBillBoard:
351
375
  case RenderMode.HorizontalBillBoard:
352
376
  case RenderMode.StretchedBillBoard:
377
+ case RenderMode.Beam:
353
378
  batch = new SpriteBatch(settings, scene);
354
379
  break;
355
380
  default:
@@ -543,6 +568,7 @@ export class BatchedRenderer extends TransformNode {
543
568
  }
544
569
 
545
570
  update(delta: number) {
571
+ this.elapsed += delta;
546
572
  const adaptiveState = this.adaptivePerformanceState;
547
573
  const frameStart = adaptiveState.enabled ? performance.now() : 0;
548
574
  if (adaptiveState.enabled) {
@@ -602,6 +628,7 @@ export class BatchedRenderer extends TransformNode {
602
628
  const emptyFrames = this.batchEmptyFrames;
603
629
  for (let i = 0; i < this.batches.length; i++) {
604
630
  const batch = this.batches[i];
631
+ batch.time = this.elapsed;
605
632
  if (batch.systems.size > 0) {
606
633
  emptyFrames[i] = 0;
607
634
  batch.update();