babylon.quarks 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/dist/babylon.quarks.cjs +1 -1
  3. package/dist/babylon.quarks.cjs.map +1 -1
  4. package/dist/babylon.quarks.esm.js +1 -1
  5. package/dist/babylon.quarks.esm.js.map +1 -1
  6. package/dist/babylon.quarks.umd.min.js +1 -1
  7. package/dist/babylon.quarks.umd.min.js.map +1 -1
  8. package/dist/types/index.d.ts +529 -20
  9. package/package.json +2 -2
  10. package/src/BatchedRenderer.ts +146 -2
  11. package/src/EffectPool.ts +165 -0
  12. package/src/MeshSurfaceEmitter.ts +4 -4
  13. package/src/ParticleEmitter.ts +2 -1
  14. package/src/ParticleSystem.ts +592 -15
  15. package/src/QuarksUtil.ts +55 -7
  16. package/src/SpriteBatch.ts +127 -3
  17. package/src/TrailBatch.ts +49 -12
  18. package/src/VFXBatch.ts +154 -3
  19. package/src/index.ts +4 -1
  20. package/src/instanceSort.ts +121 -0
  21. package/src/shaders/chunks/fog.ts +127 -0
  22. package/src/shaders/local_particle_physics_vert.glsl.ts +4 -0
  23. package/src/shaders/local_particle_physics_vert.wgsl.ts +4 -0
  24. package/src/shaders/particle_frag.glsl.ts +4 -0
  25. package/src/shaders/particle_frag.wgsl.ts +4 -0
  26. package/src/shaders/particle_physics_frag.glsl.ts +4 -0
  27. package/src/shaders/particle_physics_frag.wgsl.ts +4 -0
  28. package/src/shaders/particle_vert.glsl.ts +23 -4
  29. package/src/shaders/particle_vert.wgsl.ts +23 -4
  30. package/src/shaders/stretched_bb_particle_vert.glsl.ts +17 -0
  31. package/src/shaders/stretched_bb_particle_vert.wgsl.ts +18 -1
  32. package/src/shaders/trail_frag.glsl.ts +4 -0
  33. package/src/shaders/trail_frag.wgsl.ts +4 -0
  34. package/src/shaders/trail_vert.glsl.ts +4 -0
  35. package/src/shaders/trail_vert.wgsl.ts +4 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,107 @@ All notable changes to the `babylon.quarks` package are documented here.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5
5
  and the project follows the `quarks.core` 0.x version line.
6
6
 
7
+ ## [0.24.0] — 2026-10-20
8
+
9
+ ### Added
10
+
11
+ - `ParticleSystem.renderingGroupId` (constructor option, JSON `renderingGroupId`, written only when
12
+ not 0): the Babylon rendering group the batch mesh draws in. Systems with different groups are
13
+ batched apart.
14
+ - `ParticleSystem.applyFog` (constructor option, JSON `applyFog`, written only when false): the
15
+ scene's fog now reaches the particles in every render mode, in GLSL and WGSL, the way it reaches
16
+ any other mesh. Additive blending fades toward black instead of the fog colour. Fog is bound from
17
+ the scene on every draw, so enabling or disabling it at runtime needs no recompile.
18
+ - `ParticleSystem.playbackSpeed` (constructor option, JSON `playbackSpeed`, written only when
19
+ not 1): a multiplier on the time the system is advanced by — Unity's Simulation Speed. The
20
+ Unity exporter writes it from Main → Simulation Speed.
21
+ - quarks.core `ApplySequences` is registered in `BehaviorTypes`, so an effect using it serialises
22
+ and loads like any other behavior.
23
+ - Bounds and culling. Every system measures the world bounds of what it draws
24
+ (`ParticleSystem.getWorldBounds`), from the store columns for sprites and meshes and from the
25
+ ribbons for trails; batch meshes carry the union, so Babylon's frustum culling skips the draw of
26
+ a batch no camera sees and transparent sorting has real bounds to work with. Measured in full
27
+ every few steps and carried, padded for the motion since, in between: no measurable cost on the
28
+ profiling scenarios.
29
+ - `ParticleSystem.cullingMode` (constructor option, JSON `cullingMode`, written only when not
30
+ `'always'`): Unity's Culling Mode. `'pause'` freezes a system while no active camera sees its
31
+ bounds; `'pauseAndCatchUp'` also replays the missed time (up to 2 s) when it comes back, within
32
+ `BatchedRenderer.catchUpBudgetMs` (2 ms per frame, shared by all systems; what does not fit is
33
+ dropped). Culled systems are neither simulated nor filled into their batch. Empty systems and sub
34
+ emitter targets are never culled; `BatchedRenderer.cullingEnabled = false` turns the test off.
35
+ With 400 systems in a ring around the camera and three quarters of them out of view, a frame goes
36
+ from 9.6 ms to 1.6 ms. The Unity exporter writes Pause and Pause And Catch-up.
37
+ - Deterministic randomness. Every roll the simulation makes now goes through quarks.core's
38
+ `random()`, whose source is replaceable: `setRandomSource(createSeededRandom(seed))` makes a whole
39
+ scene reproducible, `withRandomSource` scopes it, and `getRandomSource` reads it back. The noise
40
+ generators are seeded by slot, so a Noise behavior looks the same on every run. UUIDs keep using
41
+ `Math.random`.
42
+ - `ParticleSystem.seed` (constructor option, JSON `seed`, written only when set): the system rolls
43
+ on its own generator started from the seed while it steps, and restarts it on `restart()`, so the
44
+ effect plays out identically every time; systems it emits into roll on it too. The editor has a
45
+ "Fixed seed" field; the Unity exporter writes Main → Random Seed when Auto Random Seed is off.
46
+ - `EffectPool`: a pool of copies of one effect for things played many times over. `acquire(position,
47
+ parent)` takes an idle copy (or makes one, up to `maxSize`), places it and plays it; a copy whose
48
+ systems have all finished returns to the pool by itself; `stop(copy)` ends a looping copy's
49
+ emission and lets it die out first; `release(copy)` takes it back at once; `prewarm` makes copies
50
+ up front. Idle copies stay disabled in the renderer's batches, so acquiring allocates nothing.
51
+ - `QuarksUtil.instantiate(root)`: a deep copy of an effect tree, with sub emitter links pointing at
52
+ the copied emitters.
53
+ - `ParticleSystem.sortMode` (constructor option, JSON `sortMode`, written only when not `'none'`):
54
+ Unity's Sort Mode. `'distance'` draws the particles of the batch farthest from the active camera
55
+ first, so nearer alpha-blended particles cover farther ones; `'oldestInFront'` and
56
+ `'youngestInFront'` order by age. The order is a radix sort over the whole batch after each fill
57
+ (about 2.5 ms per 50k particles), so systems with different modes are batched apart; trails are
58
+ not sorted. The editor's Renderer module and the Unity exporter carry it (Distance and Depth both
59
+ map to `'distance'`).
60
+ - `ParticleSystem.minParticleSize` / `maxParticleSize` (constructor options, JSON, written only when
61
+ set): Unity's Min / Max Particle Size, the smallest and largest size a billboard or stretched
62
+ particle is drawn at as a fraction of the viewport height, clamped in the vertex shader (GLSL and
63
+ WGSL). Meshes and trails ignore them. The editor's Renderer module has them under "Limit screen
64
+ size"; the exporter writes Unity's values, its default maximum of 0.5 included.
65
+ - `ParticleSystem.alignToDirection` (constructor option, JSON `alignToDirection`, written only when
66
+ true): Unity's Align To Direction. A mesh particle's +Z is turned along the direction its shape
67
+ sends it; a billboard's top is turned toward it in the emitter's XY plane. The start rotation is
68
+ applied on top; a particle with no speed is left alone. Shape module checkbox in the editor; the
69
+ exporter writes Shape → Align To Direction.
70
+ - quarks.core `Noise` gains `scrollSpeed` (Unity's Scroll Speed: the field moves past the particles,
71
+ sampled once per frame, reset with the behavior) and `remap` (Unity's Remap: a curve read at the
72
+ raw noise mapped from [-1, 1] to [0, 1], whose value replaces it). Both in JSON, the editor's Noise
73
+ module and the exporter.
74
+ - quarks.core `VelocityOverLife` gains `radial` (Unity's Radial: speed away from the orbit centre)
75
+ and `orbitalOffset` (Unity's Orbital Offset: where the orbital speeds turn around, relative to
76
+ the emitter). In JSON, the editor's Velocity module and the exporter.
77
+ - quarks.core `EmitSubParticleSystem` gains `inherit` (Unity's sub emitter Inherit): `'color'` and
78
+ `'size'` multiply the sub particles' start values by the parent's current ones, `'rotation'` adds
79
+ the parent's, `'lifetime'` scales theirs by the parent's remaining lifetime fraction. The mask
80
+ travels in the emission state, so a host that emits into a system by hand can set it too. In
81
+ JSON, the editor's Sub Emitters module (four checkboxes) and the exporter.
82
+ - `BatchedRenderer.simulationBudgetMs` (unlimited by default): once a frame's simulation has taken
83
+ this long, the systems still to be advanced run one step instead of catching up on the long
84
+ frame, and the time the skipped steps would have covered is dropped — so a frame that already ran
85
+ long cannot make the next one longer still.
86
+
87
+ ### Changed
88
+
89
+ - Developed and tested against `@babylonjs/core` 9.31.0 (was 9.6.2); the peer range stays
90
+ `>=9.0.0`. The examples and the editor's dev dependencies follow.
91
+ - `ParticleSystem.isFinished()` is true for a looping system whose emission was ended with
92
+ `endEmit()` once its particles are gone, and for a sub emitter target whenever it is empty,
93
+ looping or not; `finished` fires accordingly. `QuarksUtil.isEffectFinished` follows, so an effect
94
+ with looping systems is finished after `endEmit` rather than never.
95
+
96
+ ### Fixed
97
+
98
+ - quarks.core `ApplySequences` threw on update while it had no sequences yet (an editor adds the
99
+ behavior before its first sequence); it now leaves the particles alone until one is appended.
100
+ - `ParticleSystem.clone()` left cloned `EmitSubParticleSystem` behaviors transforming by the
101
+ original system's emitter; they now follow the clone. `ParticleEmitter.clone()` no longer
102
+ disables the clone itself when only an ancestor of the original was disabled.
103
+ - `renderOrder` now reaches the batch mesh as `alphaIndex`, so it orders the batch among the
104
+ scene's transparent meshes instead of only keying the batching; it used to have no effect on
105
+ what was drawn first. `layerMask` likewise now reaches the batch mesh — cameras with a
106
+ non-matching mask used to draw the particles anyway.
107
+
7
108
  ## [0.23.0] — 2026-10-18
8
109
 
9
110
  ### Changed