babylon.quarks 0.23.0 → 0.24.1

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