babylon.quarks 0.28.0 → 0.29.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 +160 -0
- package/dist/babylon.quarks.cjs +1 -1
- package/dist/babylon.quarks.cjs.map +1 -1
- package/dist/babylon.quarks.esm.js +1 -1
- package/dist/babylon.quarks.esm.js.map +1 -1
- package/dist/babylon.quarks.umd.min.js +1 -1
- package/dist/babylon.quarks.umd.min.js.map +1 -1
- package/dist/types/index.d.cts +602 -190
- package/dist/types/index.d.ts +602 -190
- package/package.json +1 -1
- package/src/BatchedRenderer.ts +13 -1
- package/src/EffectPool.ts +5 -4
- package/src/ParticleEmitter.ts +89 -24
- package/src/ParticleSystem.ts +213 -30
- package/src/QuarksLoader.ts +9 -0
- package/src/QuarksSerializer.ts +1 -1
- package/src/QuarksUtil.ts +24 -2
- package/src/SpriteBatch.ts +3 -0
- package/src/TrailBatch.ts +8 -1
- package/src/VFXBatch.ts +112 -0
- package/src/batchKey.ts +2 -0
- package/src/batchSettings.ts +2 -0
- package/src/index.ts +2 -0
- package/src/shaderProgram.ts +103 -0
- package/src/shaderVariants.ts +102 -5
- package/src/shaders/chunks/blend.ts +15 -7
- package/src/shaders/chunks/imageProcessing.ts +143 -0
- package/src/shaders/particle_frag.glsl.ts +2 -0
- package/src/shaders/particle_frag.wgsl.ts +2 -0
- package/src/shaders/particle_physics_frag.glsl.ts +2 -0
- package/src/shaders/particle_physics_frag.wgsl.ts +2 -0
- package/src/shaders/trail_frag.glsl.ts +2 -0
- package/src/shaders/trail_frag.wgsl.ts +2 -0
- package/src/system/EmissionController.ts +21 -16
- package/src/system/ParticleSpawner.ts +96 -19
- package/src/system/integrate.ts +61 -4
- package/src/system/normalize.ts +28 -1
- package/src/system/settingsSchema.ts +25 -7
- package/src/system/types.ts +83 -14
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,166 @@ 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.29.0] — 2026-10-24
|
|
8
|
+
|
|
9
|
+
Phase 7 of the road to 1.0: what still behaves differently from Unity is brought in line before
|
|
10
|
+
the API and the look of effects are frozen. Cones tilt and fill like Unity's and emit from their
|
|
11
|
+
volume, Scaling Mode has Unity's Local, Hierarchy and Shape, curves can be random between two,
|
|
12
|
+
Limit Velocity has Separate Axes, a system has a Stop Action and a Ring Buffer Mode, and the
|
|
13
|
+
particles take the scene's image processing as Babylon's own materials do.
|
|
14
|
+
|
|
15
|
+
### Upgrading from 0.28
|
|
16
|
+
|
|
17
|
+
Effects in a scene without image processing, at scale 1 and without cones, look as before. Check
|
|
18
|
+
these, in this order:
|
|
19
|
+
|
|
20
|
+
1. **Scenes with image processing** (tone mapping, exposure, contrast, a vignette or grading, also
|
|
21
|
+
when set up by `createDefaultEnvironment()` or a `DefaultRenderingPipeline`): the particles now
|
|
22
|
+
take it. Re-tune colours that were authored to look right without it, or set
|
|
23
|
+
`applyImageProcessing: false` on a system to keep the old look.
|
|
24
|
+
2. **Scaled emitters or scaled parents:** the default Scaling Mode is now `'local'`. Set
|
|
25
|
+
`scalingMode: 'hierarchy'` where a parent's scale should reach the effect. Files saved before
|
|
26
|
+
0.29 read as `'hierarchy'` and keep their look; save them again to write format 2.
|
|
27
|
+
3. **Cones:** particles between the centre and the rim lean out more (Unity's tilt). Re-tune an
|
|
28
|
+
effect that relied on the narrower middle.
|
|
29
|
+
4. **`autoDestroy`** still works but is deprecated: use `stopAction: 'destroy'`. Files are
|
|
30
|
+
written with `stopAction`, which a 0.28 runtime does not read.
|
|
31
|
+
5. **TypeScript:** narrow `LimitSpeedOverLife.speed` before calling `genValue` on it
|
|
32
|
+
(`!(speed instanceof Vector3Function)`); a custom behavior reading `emitter.matrixWorld` gets
|
|
33
|
+
the matrix with the Scaling Mode's scale.
|
|
34
|
+
6. **Files are format 2.** babylon.quarks 0.28 warns about them and reads their systems with its
|
|
35
|
+
own Scaling Mode. Install `babylon.quarks-editor` 0.29 with `babylon.quarks` 0.29, and export
|
|
36
|
+
from the Unity exporter 0.29 for this runtime.
|
|
37
|
+
|
|
38
|
+
### Breaking
|
|
39
|
+
|
|
40
|
+
- `autoDestroy` gives way to `stopAction` (`'none'`, `'disable'` or `'destroy'`, Unity's Stop
|
|
41
|
+
Action). Files are written with `stopAction` and no longer with `autoDestroy`; reading
|
|
42
|
+
`autoDestroy: true` from an older file, or passing it to the constructor, still gives
|
|
43
|
+
`'destroy'`, and the `autoDestroy` property and `QuarksUtil.setAutoDestroy` remain as deprecated
|
|
44
|
+
aliases. An older runtime does not read `stopAction`.
|
|
45
|
+
- `LimitSpeedOverLife.speed` is typed `FunctionValueGenerator | ValueGenerator | Vector3Function`
|
|
46
|
+
(it was `FunctionValueGenerator`), for Separate Axes and constant limits. Code that reads it
|
|
47
|
+
with `genValue(memory, t)` narrows it first: `!(speed instanceof Vector3Function)`.
|
|
48
|
+
- **Cone particles between the centre and the rim tilt by `atan(r · tan(angle))`**, as Unity's
|
|
49
|
+
Cone, instead of `angle · r`. Each particle follows the cone's side line through its start
|
|
50
|
+
point, so the cone's far end is a disc of radius `radius + length · tan(angle)` filled as evenly
|
|
51
|
+
as its base. The rim and the centre are unchanged; particles in between lean out more than
|
|
52
|
+
before. Re-tune a cone effect that relied on the old, narrower middle. Cones in three.quarks
|
|
53
|
+
files tilt the new way too, so they lean out further in the middle than in three.quarks.
|
|
54
|
+
- **Scaling Mode works as Unity's, in world and local space, and defaults to `'local'`.** The
|
|
55
|
+
emitter's scale now reaches the shape, the particles' size and their motion in every mode except
|
|
56
|
+
where the mode leaves it out: `'local'` (new, the default) uses only the emitter's own `scaling`
|
|
57
|
+
and leaves its parents' out; `'hierarchy'` uses the whole world scale, as before; `'shape'` now
|
|
58
|
+
scales only the emission shape, leaving the particles' size and speed alone (it used to scale
|
|
59
|
+
their size too). Before, a local-space system took its emitter's whole world scale whatever the
|
|
60
|
+
mode. An effect whose emitter or its parents are scaled looks different unless it was
|
|
61
|
+
`'hierarchy'`: set `scalingMode: 'hierarchy'` to keep a parent's scale on it, or leave it at
|
|
62
|
+
`'local'` to keep the effect its own size under a scaled parent. Effects at scale 1 are
|
|
63
|
+
unchanged.
|
|
64
|
+
- **Files from before this release keep their look:** the format goes to 2, and a system in a
|
|
65
|
+
file of format 1 or without `quarksFormat` (older babylon.quarks, three.quarks, the Unity
|
|
66
|
+
exporter before 0.29) reads as `'hierarchy'`, which gives it the emitter's whole world scale
|
|
67
|
+
as before (except a world-space system's speed, which now scales too). Save it again to keep
|
|
68
|
+
that, or set the mode you want. A 0.28 loader warns about a format 2 file and reads its
|
|
69
|
+
systems as its own default.
|
|
70
|
+
- **`ParticleEmitter.matrixWorld` (`IEmitter.matrixWorld`) is the matrix the system simulates
|
|
71
|
+
and draws in:** the world matrix with each axis's length set by the mode. A custom behavior
|
|
72
|
+
that reads it gets that scale. `ParticleEmitter.shapeScale` is what `'shape'` gives the shape.
|
|
73
|
+
- **Negative scales mirror the start velocity as they mirror the position,** in every mode; a
|
|
74
|
+
world-space `'hierarchy'` system used to mirror the position only.
|
|
75
|
+
- **A sub emission's speed** takes its parent particle's frame, as its size did: it no longer
|
|
76
|
+
scales with the sub emitter's own scale in `'hierarchy'`.
|
|
77
|
+
- **The scene's image processing applies to the particles by default**, as it does to Babylon's
|
|
78
|
+
own `ParticleSystem` and its standard and PBR materials. A scene whose
|
|
79
|
+
`imageProcessingConfiguration` does nothing (Babylon's default) looks the same as before. One
|
|
80
|
+
that tone maps, sets exposure or contrast, grades, vignettes or dithers now does it to the
|
|
81
|
+
particles too, so they sit in the frame like the meshes around them. Under a
|
|
82
|
+
`DefaultRenderingPipeline` with image processing on (`applyByPostProcess`), the particles now
|
|
83
|
+
leave their colour in linear space for the post process, as Babylon's materials do; before they
|
|
84
|
+
were gamma-corrected twice and looked washed out. Set `applyImageProcessing: false` on a system
|
|
85
|
+
to keep the old look. Check effects in scenes set up by any of these, which turn image
|
|
86
|
+
processing on or hand it to a post process without saying so: `scene.createDefaultEnvironment()`
|
|
87
|
+
(tone mapping, exposure and contrast), a `DefaultRenderingPipeline` with
|
|
88
|
+
`imageProcessingEnabled` (its default), a `PrePassRenderer` (SSAO2, SSR, motion blur) and a
|
|
89
|
+
`ReflectionProbe` rendering in linear space.
|
|
90
|
+
Tone mapping clamps HDR particle colours, and a contrast below 1 or colour curves lift black,
|
|
91
|
+
which an additive particle then adds.
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- **Scene image processing** (`ParticleSystem.applyImageProcessing`, default true; JSON writes it
|
|
96
|
+
only when false): the scene's `imageProcessingConfiguration` (exposure, contrast, tone mapping,
|
|
97
|
+
vignette, colour curves, colour grading, dithering) is compiled into every render mode, in GLSL
|
|
98
|
+
and WGSL, through Babylon's own includes, bound on every draw, and switched in place, on
|
|
99
|
+
the same material, when the configuration changes what the shader needs. A post process that applies it gets the colour in
|
|
100
|
+
linear space. It runs on the straight colour after fog and before the blend resolve, so alpha
|
|
101
|
+
stays coverage; particles that multiply the frame (`ALPHA_MULTIPLY`) are a factor rather than
|
|
102
|
+
light and are not tone mapped. Systems that differ are batched apart. On WebGPU, a 2D colour
|
|
103
|
+
grading texture works through a WGSL port of Babylon's slice sampler, which Babylon's own WGSL
|
|
104
|
+
include lacks. The Image Processing demo compares a flame with and without it.
|
|
105
|
+
|
|
106
|
+
- **Cone Emit from Volume and Length** (Unity's Cone Volume): `ConeEmitter.emitFrom`
|
|
107
|
+
(`ConeEmitFrom.Base`, the default, or `ConeEmitFrom.Volume`) and `ConeEmitter.length` (5 by
|
|
108
|
+
default, as in Unity). In Volume, particles start anywhere on their side line from the base up
|
|
109
|
+
to `length` along z. The Unity exporter writes Cone Volume with its Length instead of warning,
|
|
110
|
+
and the editor's Shape module and wireframe show both.
|
|
111
|
+
- **Random Between Two Curves** (Unity's MinMaxCurve mode of the same name): `RandomBetweenCurves`
|
|
112
|
+
holds two `PiecewiseBezier` curves and rolls each particle a mix between them, kept for its
|
|
113
|
+
life, so every particle follows its own curve within the band. It goes wherever a curve does
|
|
114
|
+
(start values over the system's cycle, emission rates, every over-lifetime and by-speed
|
|
115
|
+
behavior, Noise) and reads and writes as `{type: 'RandomBetweenCurves', curve1, curve2}`. Where
|
|
116
|
+
a system-level setting takes it (emission over time or distance, a burst's count, a shape's
|
|
117
|
+
speed, Noise's scroll speed) the mix is rolled once per play, as a random range is there, rather
|
|
118
|
+
than at each emission step as in Unity. A bound that is missing or not a curve warns and reads as
|
|
119
|
+
a flat 0 curve. The Unity exporter writes it instead of the upper curve, and the editor offers it
|
|
120
|
+
in its value fields and in every module that edits a curve over life.
|
|
121
|
+
- **Grid sampling** (Niagara's Grid Location by particle index): `GridEmitter.sampling`
|
|
122
|
+
(`GridSampling.Random`, the default, or `GridSampling.Sequential`). Sequential fills the cells in
|
|
123
|
+
turn, row by row from −x, −y, so a burst of `row × column` particles puts one in every cell; a
|
|
124
|
+
restart starts over at the first cell. The editor's Shape module offers it.
|
|
125
|
+
- **Separate Axes for Limit Velocity over Lifetime** (Unity's option of the same name):
|
|
126
|
+
`LimitSpeedOverLife.speed` takes a `Vector3Function`, a limit per axis, and the new
|
|
127
|
+
`LimitSpeedOverLife.space` (`'local'`, the default, or `'world'`) says which axes they are
|
|
128
|
+
measured along. Each component of the velocity is limited on its own and keeps its sign; a world
|
|
129
|
+
limit is scaled by the system's `motionScale` in a world-space system. `space` is written only
|
|
130
|
+
when not `'local'`. One limit for the speed works as before. The editor's Limit Speed, Size over
|
|
131
|
+
Lifetime and Size by Speed modules get a Separate Axes switch, and the new Limit Velocity Axes
|
|
132
|
+
demo compares the two.
|
|
133
|
+
- **Stop Action** (Unity's option of the same name): `ParticleSystem.stopAction` says what a
|
|
134
|
+
finished system does: nothing (`'none'`, the default), disable its emitter node (`'disable'`,
|
|
135
|
+
once per finish), or dispose itself (`'destroy'`). Unity's Callback is the `finished` event,
|
|
136
|
+
which fires whatever the action. `ignoreStopAction`, runtime only, skips it for tools that replay
|
|
137
|
+
an effect; `EffectPool` and the editor set it, so pooled and previewed effects keep their
|
|
138
|
+
authored stop action. `QuarksUtil.setStopAction` sets it on a whole effect. As in Unity, the
|
|
139
|
+
action waits until the systems the system emits into have no particles left, and a sub emitter
|
|
140
|
+
target takes none of its own. `ParticleSystem.isAlive(withSubEmitters = true)` is Unity's
|
|
141
|
+
`IsAlive`. quarks.core's `IParticleSystem` gains `stopAction` (`autoDestroy` is deprecated),
|
|
142
|
+
`ringBufferActive`, and `hasPendingEmission(state?)` for a sub emission's state.
|
|
143
|
+
- **Ring Buffer Mode** (Unity's option of the same name): with `maxParticles`, a full system's
|
|
144
|
+
new particles replace the oldest instead of being dropped. `ringBufferMode: 'pauseUntilReplaced'`
|
|
145
|
+
freezes a particle at the end of its life until then (footprints, decals);
|
|
146
|
+
`'loopUntilReplaced'` replays the part of its life `ringBufferLoopRange` names (0 to 1 by
|
|
147
|
+
default); a range of no length holds the particle at that point. Particles of a ring buffer
|
|
148
|
+
never die by age, so the system keeps them, fires no Death sub emitter for them and never
|
|
149
|
+
finishes. Lowering `maxParticles` drops the oldest over the new limit. Every render mode but
|
|
150
|
+
Trail, whose particles always die. The Ring Buffer demo shows both.
|
|
151
|
+
- `EmitterFrame.fromSimulation`, the inverse of `toSimulation`, for behaviors that measure a
|
|
152
|
+
vector in their own space.
|
|
153
|
+
|
|
154
|
+
### Fixed
|
|
155
|
+
|
|
156
|
+
- A **Death sub emitter** fired for the particles that died on a non-looping system's last step
|
|
157
|
+
queued its burst and never emitted it: the system counted itself finished first. A system now
|
|
158
|
+
finishes once the emissions its sub emitters run have nothing left to emit, so `finished` fires
|
|
159
|
+
after those bursts.
|
|
160
|
+
- A local-space force, orbit or per-axis speed limit under an emitter scaled to 0 on an axis read
|
|
161
|
+
a NaN rotation from it, and turned the velocity into NaN (forces) or stopped limiting
|
|
162
|
+
(limits). `EmitterFrame` rebuilds the rotation from the axes that remain.
|
|
163
|
+
- **Noise** rolls a random Frequency, Strength, Position or Rotation amount, or Remap (a range or
|
|
164
|
+
two curves) into every particle. Only the first particle got its own value; the others read a
|
|
165
|
+
missing one and their position became NaN.
|
|
166
|
+
|
|
7
167
|
## [0.28.0] — 2026-10-23
|
|
8
168
|
|
|
9
169
|
The release after phase 6 of the audit and the 0.28 cleanup: alpha means coverage in every blend
|