babylon.quarks 0.24.1 → 0.26.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,130 @@ 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.26.0] — 2026-10-21
8
+
9
+ ### Changed (breaking)
10
+
11
+ The texture effects of 0.25 are redesigned on the concepts Unity and Unreal use, so that one
12
+ model covers every texture a particle samples. Effects and code written against 0.25 need the
13
+ renames below.
14
+
15
+ - `ParticleSystem.gradientMap` is now a `ParticleGradientMap` `{ramp, channel}` instead of a bare
16
+ texture. `channel` (`'r'` default, `'g'`, `'b'`, `'a'`, `'luminance'`) picks the texel value
17
+ the ramp is looked up by, so channel-packed and coloured textures work as well as greyscale ones.
18
+ Looked up by `'a'`, the ramp's alpha replaces the map's, so a soft shape can glow at its fringe
19
+ and stay solid at its heart. JSON: `gradientMap: {ramp: <texture uuid>, channel}`.
20
+ - `ParticleSystem.uvScroll` is replaced by `mapUV`, a `TextureUV` that lays the main map (tiling,
21
+ offset, scroll, and UV channel 1). JSON: `mapUV` on the material, only the fields that differ from
22
+ the default. The `UV_SCROLL` define and `uvScrollOffset` uniform become `MAP_TRANSFORM` and
23
+ `mapTransform` (`uv * xy + zw`), with `MAP_UV1` when the map reads channel 1.
24
+ - `ParticleErosion.maskScroll` is replaced by `maskUV`, a `TextureUV`.
25
+ - Shader uniforms: `erosionParams` is a `vec2` (softness, edge width) and the mask is laid by
26
+ `erosionMaskTransform`. The gradient map adds `gradientMapChannel`.
27
+ - 0.25 JSON is not migrated: a bare-texture `gradientMap`, `uvScroll`, and `erosion.maskScroll` are
28
+ ignored on load. Re-export those effects.
29
+
30
+ ### Added
31
+
32
+ - **UV channels** (`UVChannel`: `0 | 1`), as Unity's UV channels and Niagara's ribbon UV0/UV1:
33
+ - Channel 0 is the map's UV as drawn.
34
+ - Channel 1 is the particle's own UV, which the sprite sheet never moves:
35
+ - the whole quad on billboards, stretched billboards and beams;
36
+ - along and across the trail on trails;
37
+ - the mesh's second UV set on meshes.
38
+ - A texture on channel 1 can run once across a whole trail or mesh however the map repeats or
39
+ animates. Shaders declare `vUV1` under `UV1` only when a texture reads it.
40
+ - **Second UV set on mesh particles:** `instancingUVs2` (glTF `TEXCOORD_1`, Unity's `uv2`).
41
+ - It is saved with the geometry as `uvs2` and read from three.js `uv1`/`uv2` attributes by the
42
+ loader.
43
+ - Systems batch by both UV sets.
44
+ - A mesh without a second set reads its first on channel 1. A set whose length is not two values
45
+ per vertex is left out with a one-time warning.
46
+ - `ParticleSystem.instancingUVs` and `instancingUVs2` accessors. Assigning `instancingGeometry`
47
+ with a different vertex count resets the first set to zeros and drops the second, so assign
48
+ the UVs after the geometry.
49
+ - **`TextureUV`** (`channel`, `tiling`, `offset`, `scroll`) lays a texture over the particle:
50
+ Unity's Tiling/Offset plus Unreal's Panner. `mapUV`, `erosion.maskUV` and `uvDistortion.mapUV`
51
+ take it. The offset is kept as given; only the scroll's share is wrapped.
52
+ JSON writes only the fields that differ from the default. Helpers: `normalizeTextureUV`,
53
+ `textureUVEqual`, `textureUVToJSON`.
54
+ - **`ParticleSystem.tint`** (`Vector4`, runtime only, copied by `clone()`):
55
+ - Multiplies every particle's colour and alpha as drawn, without touching the particles or
56
+ splitting batches.
57
+ - Use it for a per-instance colour or fade driven from code, like Unreal's user parameters.
58
+ With erosion, alpha is the erosion level.
59
+ - Additive and premultiplied blending ignore alpha; fade those through the colour instead.
60
+ - quarks.core `FrameOverLife` option **`random`** (FPS mode, with `frameCount`; saved in JSON only
61
+ when set):
62
+ - Every `1 / fps` seconds it shows a random frame of the segment instead of the next.
63
+ - Each particle has its own sequence.
64
+ - Like Cascade's random SubUV, for the flicker of lightning, sparks and neon.
65
+ - Mesh particle **rim mode `'fade'`** (Fresnel to opacity):
66
+ - Faces turned to the camera fade by `strength` instead of gaining a colour.
67
+ - A wall of light reads thick along its silhouette and thin across its face.
68
+ - **`ParticleSystem.uvDistortion`** (`ParticleUVDistortion`: noise `map`, `mapUV` (default
69
+ scroll `[0, 0.5]`), `strength`;
70
+ saved with the material only when set):
71
+ - A scrolling noise texture pushes the map's UV about, for heat shimmer and licking, breathing
72
+ shapes.
73
+ - Works on sprites, meshes and trails, in GLSL and WGSL.
74
+ - quarks.core **`TrailSettings.sideAxis`** (JSON `[x, y, z]`, written only when set):
75
+ - The trail is swept along that emitter axis instead of facing the camera.
76
+ - Each sample records the axis as the emitter held it, so a trail on a blade is the surface the
77
+ blade swept, like Unreal's AnimTrail.
78
+ - `TrailParticle.historySides` holds the recorded sides.
79
+
80
+ ### Fixed
81
+
82
+ - **Scrolls wrap over two repeats instead of one** in every `TextureUV`. A map with mirrored addressing no longer flips to its mirror image at every wrap.
83
+ - **Systems that share positions but not UVs batch apart.** Before, the first system's UVs drew
84
+ for both. Systems given a geometry without UVs share one fallback array per geometry, so they
85
+ still batch together.
86
+ - **Mesh systems that share positions but not normals batch apart.** Before, the first system's
87
+ normals lit both. Fallback normals are shared per geometry, and trails no longer split batches
88
+ over instanced UVs they never read.
89
+ - **Assigning `instancingGeometry` replaces stale normals and fallback UVs**: normals of a different
90
+ vertex count, and the previous geometry's fallbacks, move to the new geometry's.
91
+
92
+ ## [0.25.0] — 2026-10-20
93
+
94
+ ### Added
95
+
96
+ - `ParticleSystem.emissionMultiplier` (runtime only, default 1): scales bursts, emission over time
97
+ and over distance, and may go above 1, unlike `setQualityFactor`. The two multiply.
98
+ - `QuarksUtil.getDuration(root)`: seconds until an effect played from the start is over (start
99
+ delay, duration and longest life over playback speed; sub emitter targets a life after their
100
+ parents), or `Infinity` when a system loops.
101
+ - quarks.core `FrameOverLife` options (`fps`, `cycles`, `frameCount`, `loop`, `startFrame`, all
102
+ saved in JSON only when set): Unity's texture sheet FPS mode, several cycles per life, a looping
103
+ or holding frame segment and a per-particle random start frame. Without them the behaviour is
104
+ unchanged and stays in the fused pass.
105
+ - Texture effects on sprites, meshes and trails, GLSL and WGSL, each saved with the material in the
106
+ effect JSON only when set and batched apart when they differ:
107
+ - `ParticleSystem.uvScroll` `[u, v]`: scrolls the map in UV units per second on the renderer's clock.
108
+ - `ParticleSystem.gradientMap`: recolours the map through a ramp texture picked by its red
109
+ channel; the particle colour still tints it.
110
+ - `ParticleSystem.erosion` (`ParticleErosion`: mask, softness, edgeWidth, edgeColor, maskScroll):
111
+ alpha erosion. The particle's alpha decides how much of the shape is left instead of how
112
+ transparent it is, so a `ColorOverLife` alpha curve dissolves it through a noise mask or wipes
113
+ it through a gradient one, with an optional glowing edge.
114
+ - `RenderMode.Beam` (6) with `ParticleSystem.beamEnd` (a point or anything with a world position,
115
+ such as a `TransformNode`, read every frame; runtime only): a quad laid from each particle to
116
+ the end and turned about its length to face the camera, U along it, the size as its width. With
117
+ a sheet and `FrameOverLife` `fps` it flickers like lightning; bounds reach the end.
118
+ - `ParticleSystem.scalingMode` (`'shape'` default | `'hierarchy'`, constructor option, JSON written
119
+ only when `'hierarchy'`): in `'hierarchy'` a world-space system's start speeds scale with the
120
+ emitter's world scale, and `ForceOverLife` and `LimitSpeedOverLife` by its mean, so a scaled
121
+ effect moves in proportion. quarks.core `IParticleSystem.motionScale` carries the factor to
122
+ behaviors; `LimitSpeedOverLife` now learns its system in `initialize`.
123
+ - Example "Texture Effects" showing the texture effects and a beam.
124
+
125
+ ### Fixed
126
+
127
+ - A looping system kept firing its bursts on every loop after `endEmit()`, so it never finished.
128
+ Bursts now stop with the rest of the system's own emission; a sub emitter's bursts, which belong
129
+ to parent particles still dying, keep firing.
130
+
7
131
  ## [0.24.1] — 2026-10-20
8
132
 
9
133
  ### Changed