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 +124 -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.ts +501 -9
- package/package.json +1 -1
- package/src/BatchedRenderer.ts +34 -1
- package/src/ParticleSystem.ts +465 -13
- package/src/QuarksLoader.ts +50 -2
- package/src/QuarksUtil.ts +97 -1
- package/src/SpriteBatch.ts +101 -10
- package/src/TrailBatch.ts +132 -20
- package/src/VFXBatch.ts +465 -4
- package/src/index.ts +38 -2
- package/src/shaders/chunks/surface.ts +268 -0
- package/src/shaders/local_particle_physics_vert.glsl.ts +15 -0
- package/src/shaders/local_particle_physics_vert.wgsl.ts +15 -0
- package/src/shaders/particle_frag.glsl.ts +6 -11
- package/src/shaders/particle_frag.wgsl.ts +6 -11
- package/src/shaders/particle_physics_frag.glsl.ts +13 -15
- package/src/shaders/particle_physics_frag.wgsl.ts +13 -15
- package/src/shaders/particle_vert.glsl.ts +7 -0
- package/src/shaders/particle_vert.wgsl.ts +7 -0
- package/src/shaders/stretched_bb_particle_vert.glsl.ts +27 -7
- package/src/shaders/stretched_bb_particle_vert.wgsl.ts +32 -9
- package/src/shaders/trail_frag.glsl.ts +6 -7
- package/src/shaders/trail_frag.wgsl.ts +6 -7
- package/src/shaders/trail_vert.glsl.ts +8 -0
- package/src/shaders/trail_vert.wgsl.ts +8 -0
package/src/TrailBatch.ts
CHANGED
|
@@ -19,6 +19,8 @@ export class TrailBatch extends VFXBatch {
|
|
|
19
19
|
private previousBuffer!: Float32Array;
|
|
20
20
|
private nextBuffer!: Float32Array;
|
|
21
21
|
private uvBuffer!: Float32Array;
|
|
22
|
+
/** UV channel 1: along the trail and across it, without the sheet's cell; only when a texture reads it. */
|
|
23
|
+
private uv1Buffer: Float32Array | null = null;
|
|
22
24
|
private sideBuffer!: Float32Array;
|
|
23
25
|
private widthBuffer!: Float32Array;
|
|
24
26
|
private colorBuffer!: Float32Array;
|
|
@@ -52,6 +54,7 @@ export class TrailBatch extends VFXBatch {
|
|
|
52
54
|
this.previousBuffer = new Float32Array(this.maxParticles * 6);
|
|
53
55
|
this.nextBuffer = new Float32Array(this.maxParticles * 6);
|
|
54
56
|
this.uvBuffer = new Float32Array(this.maxParticles * 4);
|
|
57
|
+
this.uv1Buffer = this.usesUV1() ? new Float32Array(this.maxParticles * 4) : null;
|
|
55
58
|
this.sideBuffer = new Float32Array(this.maxParticles * 2);
|
|
56
59
|
this.widthBuffer = new Float32Array(this.maxParticles * 2);
|
|
57
60
|
this.colorBuffer = new Float32Array(this.maxParticles * 8);
|
|
@@ -86,6 +89,9 @@ export class TrailBatch extends VFXBatch {
|
|
|
86
89
|
// Set standard vertex data with full buffer capacity (updatable)
|
|
87
90
|
this.mesh.setVerticesData(VertexBuffer.PositionKind, this.positionBuffer, true);
|
|
88
91
|
this.mesh.setVerticesData(VertexBuffer.UVKind, this.uvBuffer, true);
|
|
92
|
+
if (this.uv1Buffer) {
|
|
93
|
+
this.mesh.setVerticesData(VertexBuffer.UV2Kind, this.uv1Buffer, true);
|
|
94
|
+
}
|
|
89
95
|
this.mesh.setVerticesData(VertexBuffer.ColorKind, this.colorBuffer, true, 4);
|
|
90
96
|
// The whole array, not just the dummy triangle: this call is what sizes
|
|
91
97
|
// the GPU index buffer, and updateIndices later writes into it without
|
|
@@ -139,6 +145,7 @@ export class TrailBatch extends VFXBatch {
|
|
|
139
145
|
if (this.settings.texture) {
|
|
140
146
|
defines.push('USE_MAP');
|
|
141
147
|
}
|
|
148
|
+
defines.push(...this.surfaceDefines());
|
|
142
149
|
|
|
143
150
|
const shaderLanguage = shaderLanguageFor(this.scene.getEngine());
|
|
144
151
|
registerShaders(
|
|
@@ -149,6 +156,9 @@ export class TrailBatch extends VFXBatch {
|
|
|
149
156
|
);
|
|
150
157
|
|
|
151
158
|
const attributes = ['position', 'previous', 'next', 'side', 'width', 'uv', 'color'];
|
|
159
|
+
if (this.uv1Buffer) {
|
|
160
|
+
attributes.push('uv2');
|
|
161
|
+
}
|
|
152
162
|
const uniforms = [
|
|
153
163
|
'world',
|
|
154
164
|
'view',
|
|
@@ -164,6 +174,7 @@ export class TrailBatch extends VFXBatch {
|
|
|
164
174
|
if (this.settings.texture) {
|
|
165
175
|
samplers.push('map');
|
|
166
176
|
}
|
|
177
|
+
this.surfaceUniforms(uniforms, samplers);
|
|
167
178
|
|
|
168
179
|
const mat = new ShaderMaterial(
|
|
169
180
|
shaderName,
|
|
@@ -200,6 +211,7 @@ export class TrailBatch extends VFXBatch {
|
|
|
200
211
|
});
|
|
201
212
|
|
|
202
213
|
this.bindFog(mat);
|
|
214
|
+
this.bindSurface(mat);
|
|
203
215
|
mat.backFaceCulling = false;
|
|
204
216
|
|
|
205
217
|
if (this.settings.materialTransparent) {
|
|
@@ -228,6 +240,30 @@ export class TrailBatch extends VFXBatch {
|
|
|
228
240
|
* frame costs a matrix compose per system; checking the transform cache
|
|
229
241
|
* first makes a still emitter free.
|
|
230
242
|
*/
|
|
243
|
+
/**
|
|
244
|
+
* Writes a swept ribbon's vertex pair at `pi`: the sample at (x, y, z)
|
|
245
|
+
* pushed `half` widths along its side (sx, sy, sz) one way for the first
|
|
246
|
+
* vertex and the other way for the second.
|
|
247
|
+
*/
|
|
248
|
+
private writeSweptPair(
|
|
249
|
+
pi: number,
|
|
250
|
+
x: number,
|
|
251
|
+
y: number,
|
|
252
|
+
z: number,
|
|
253
|
+
sx: number,
|
|
254
|
+
sy: number,
|
|
255
|
+
sz: number,
|
|
256
|
+
half: number
|
|
257
|
+
): void {
|
|
258
|
+
const positions = this.positionBuffer;
|
|
259
|
+
positions[pi] = x + sx * half;
|
|
260
|
+
positions[pi + 1] = y + sy * half;
|
|
261
|
+
positions[pi + 2] = z + sz * half;
|
|
262
|
+
positions[pi + 3] = x - sx * half;
|
|
263
|
+
positions[pi + 4] = y - sy * half;
|
|
264
|
+
positions[pi + 5] = z - sz * half;
|
|
265
|
+
}
|
|
266
|
+
|
|
231
267
|
private static ensureWorldMatrix(system: IParticleSystem): void {
|
|
232
268
|
const emitter = system.emitter as {
|
|
233
269
|
computeWorldMatrix?: (force: boolean) => void;
|
|
@@ -293,10 +329,15 @@ export class TrailBatch extends VFXBatch {
|
|
|
293
329
|
// rather than by the particle's velocity, so it is left alone.
|
|
294
330
|
const trailSettings = system.rendererEmitterSettings as TrailSettings;
|
|
295
331
|
const uvFromHead = Boolean(trailSettings.uvFromHead);
|
|
332
|
+
const uv1 = this.uv1Buffer;
|
|
296
333
|
const colorFromParticle = Boolean(trailSettings.colorFromParticle);
|
|
297
334
|
// Recorded samples already sit in world space; the live tip still comes
|
|
298
335
|
// from the particle's own (local) position.
|
|
299
336
|
const samplesInWorld = systemWorldSpace || Boolean(trailSettings.recordWorldSpace);
|
|
337
|
+
// A swept trail spans each sample's recorded side instead of facing
|
|
338
|
+
// the camera: its vertices are laid out here, and a zero width
|
|
339
|
+
// keeps the shader from pushing them.
|
|
340
|
+
const sideAxis = trailSettings.sideAxis;
|
|
300
341
|
const residual = trailSettings.followLocalOrigin ? 0 : (system.simulationResidual ?? 0);
|
|
301
342
|
// Measured from the step the particle just took, not from its
|
|
302
343
|
// velocity: a trail pulled along by an orbit or by a plugin's own
|
|
@@ -312,6 +353,8 @@ export class TrailBatch extends VFXBatch {
|
|
|
312
353
|
const historyCapacity = particle.historyCapacity;
|
|
313
354
|
const historyPositions = particle.historyPositions;
|
|
314
355
|
const historySizes = particle.historySizes;
|
|
356
|
+
const historySides = particle.historySides;
|
|
357
|
+
const swept = sideAxis !== undefined && historySides.length === historyCapacity * 3;
|
|
315
358
|
// Every sample takes its color from one place: its own recorded slot, or
|
|
316
359
|
// the particle's current row in the store.
|
|
317
360
|
const colors = colorFromParticle ? particle.store.color : particle.historyColors;
|
|
@@ -391,12 +434,27 @@ export class TrailBatch extends VFXBatch {
|
|
|
391
434
|
const currentColorW = colors[currentColorIndex + 3];
|
|
392
435
|
|
|
393
436
|
const pi = index * 3;
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
437
|
+
if (swept) {
|
|
438
|
+
const si = currentSlot * 3;
|
|
439
|
+
let sx = historySides[si];
|
|
440
|
+
let sy = historySides[si + 1];
|
|
441
|
+
let sz = historySides[si + 2];
|
|
442
|
+
if (!samplesInWorld) {
|
|
443
|
+
const tx = m00 * sx + m10 * sy + m20 * sz;
|
|
444
|
+
const ty = m01 * sx + m11 * sy + m21 * sz;
|
|
445
|
+
sz = m02 * sx + m12 * sy + m22 * sz;
|
|
446
|
+
sx = tx;
|
|
447
|
+
sy = ty;
|
|
448
|
+
}
|
|
449
|
+
this.writeSweptPair(pi, currentX, currentY, currentZ, sx, sy, sz, currentSize * 0.5);
|
|
450
|
+
} else {
|
|
451
|
+
this.positionBuffer[pi] = currentX;
|
|
452
|
+
this.positionBuffer[pi + 1] = currentY;
|
|
453
|
+
this.positionBuffer[pi + 2] = currentZ;
|
|
454
|
+
this.positionBuffer[pi + 3] = currentX;
|
|
455
|
+
this.positionBuffer[pi + 4] = currentY;
|
|
456
|
+
this.positionBuffer[pi + 5] = currentZ;
|
|
457
|
+
}
|
|
400
458
|
|
|
401
459
|
this.previousBuffer[pi] = previousX;
|
|
402
460
|
this.previousBuffer[pi + 1] = previousY;
|
|
@@ -412,7 +470,10 @@ export class TrailBatch extends VFXBatch {
|
|
|
412
470
|
this.nextBuffer[pi + 4] = nextY;
|
|
413
471
|
this.nextBuffer[pi + 5] = nextZ;
|
|
414
472
|
|
|
415
|
-
if (
|
|
473
|
+
if (swept) {
|
|
474
|
+
this.widthBuffer[index] = 0;
|
|
475
|
+
this.widthBuffer[index + 1] = 0;
|
|
476
|
+
} else if (systemWorldSpace || particle.parentMatrix) {
|
|
416
477
|
this.widthBuffer[index] = currentSize;
|
|
417
478
|
this.widthBuffer[index + 1] = currentSize;
|
|
418
479
|
} else {
|
|
@@ -427,6 +488,13 @@ export class TrailBatch extends VFXBatch {
|
|
|
427
488
|
this.uvBuffer[ui + 1] = (vTileCount - row - 1) * tileHeight;
|
|
428
489
|
this.uvBuffer[ui + 2] = u;
|
|
429
490
|
this.uvBuffer[ui + 3] = (vTileCount - row) * tileHeight;
|
|
491
|
+
if (uv1) {
|
|
492
|
+
const u1 = uvFromHead ? 1 - along : along;
|
|
493
|
+
uv1[ui] = u1;
|
|
494
|
+
uv1[ui + 1] = 0;
|
|
495
|
+
uv1[ui + 2] = u1;
|
|
496
|
+
uv1[ui + 3] = 1;
|
|
497
|
+
}
|
|
430
498
|
|
|
431
499
|
const cci = index * 4;
|
|
432
500
|
this.colorBuffer[cci] = currentColorX;
|
|
@@ -467,9 +535,12 @@ export class TrailBatch extends VFXBatch {
|
|
|
467
535
|
let tipY = position.y + (position.y - previousHead.y) * stepFraction;
|
|
468
536
|
let tipZ = position.z + (position.z - previousHead.z) * stepFraction;
|
|
469
537
|
const headIndex = index - 2;
|
|
470
|
-
|
|
471
|
-
const
|
|
472
|
-
const
|
|
538
|
+
// The pair's midpoint: a swept pair lies to either side of its sample.
|
|
539
|
+
const headX = (this.positionBuffer[headIndex * 3] + this.positionBuffer[headIndex * 3 + 3]) * 0.5;
|
|
540
|
+
const headY =
|
|
541
|
+
(this.positionBuffer[headIndex * 3 + 1] + this.positionBuffer[headIndex * 3 + 4]) * 0.5;
|
|
542
|
+
const headZ =
|
|
543
|
+
(this.positionBuffer[headIndex * 3 + 2] + this.positionBuffer[headIndex * 3 + 5]) * 0.5;
|
|
473
544
|
|
|
474
545
|
if (!systemWorldSpace) {
|
|
475
546
|
const w = 1 / (m03 * tipX + m13 * tipY + m23 * tipZ + m33);
|
|
@@ -481,12 +552,30 @@ export class TrailBatch extends VFXBatch {
|
|
|
481
552
|
}
|
|
482
553
|
|
|
483
554
|
const tipPi = index * 3;
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
555
|
+
const tipSize = particle.size.x;
|
|
556
|
+
if (swept) {
|
|
557
|
+
// The side as the emitter holds it now.
|
|
558
|
+
const ax = sideAxis!.x;
|
|
559
|
+
const ay = sideAxis!.y;
|
|
560
|
+
const az = sideAxis!.z;
|
|
561
|
+
this.writeSweptPair(
|
|
562
|
+
tipPi,
|
|
563
|
+
tipX,
|
|
564
|
+
tipY,
|
|
565
|
+
tipZ,
|
|
566
|
+
m00 * ax + m10 * ay + m20 * az,
|
|
567
|
+
m01 * ax + m11 * ay + m21 * az,
|
|
568
|
+
m02 * ax + m12 * ay + m22 * az,
|
|
569
|
+
tipSize * 0.5
|
|
570
|
+
);
|
|
571
|
+
} else {
|
|
572
|
+
this.positionBuffer[tipPi] = tipX;
|
|
573
|
+
this.positionBuffer[tipPi + 1] = tipY;
|
|
574
|
+
this.positionBuffer[tipPi + 2] = tipZ;
|
|
575
|
+
this.positionBuffer[tipPi + 3] = tipX;
|
|
576
|
+
this.positionBuffer[tipPi + 4] = tipY;
|
|
577
|
+
this.positionBuffer[tipPi + 5] = tipZ;
|
|
578
|
+
}
|
|
490
579
|
|
|
491
580
|
this.previousBuffer[tipPi] = headX;
|
|
492
581
|
this.previousBuffer[tipPi + 1] = headY;
|
|
@@ -513,8 +602,10 @@ export class TrailBatch extends VFXBatch {
|
|
|
513
602
|
this.nextBuffer[headPi + 4] = tipY;
|
|
514
603
|
this.nextBuffer[headPi + 5] = tipZ;
|
|
515
604
|
|
|
516
|
-
|
|
517
|
-
|
|
605
|
+
if (swept) {
|
|
606
|
+
this.widthBuffer[index] = 0;
|
|
607
|
+
this.widthBuffer[index + 1] = 0;
|
|
608
|
+
} else if (systemWorldSpace || particle.parentMatrix) {
|
|
518
609
|
this.widthBuffer[index] = tipSize;
|
|
519
610
|
this.widthBuffer[index + 1] = tipSize;
|
|
520
611
|
} else {
|
|
@@ -528,6 +619,13 @@ export class TrailBatch extends VFXBatch {
|
|
|
528
619
|
this.uvBuffer[tipUi + 1] = (vTileCount - row - 1) * tileHeight;
|
|
529
620
|
this.uvBuffer[tipUi + 2] = tipU;
|
|
530
621
|
this.uvBuffer[tipUi + 3] = (vTileCount - row) * tileHeight;
|
|
622
|
+
if (uv1) {
|
|
623
|
+
const tipU1 = uvFromHead ? 0 : 1;
|
|
624
|
+
uv1[tipUi] = tipU1;
|
|
625
|
+
uv1[tipUi + 1] = 0;
|
|
626
|
+
uv1[tipUi + 2] = tipU1;
|
|
627
|
+
uv1[tipUi + 3] = 1;
|
|
628
|
+
}
|
|
531
629
|
|
|
532
630
|
const tipColor = particle.color;
|
|
533
631
|
const tipCi = index * 4;
|
|
@@ -552,6 +650,17 @@ export class TrailBatch extends VFXBatch {
|
|
|
552
650
|
index += 2;
|
|
553
651
|
}
|
|
554
652
|
}
|
|
653
|
+
const tint = (system as ParticleSystem).tint;
|
|
654
|
+
if (tint !== undefined) {
|
|
655
|
+
// As SpriteBatch does: the system's tint over its ribbons' vertices.
|
|
656
|
+
const colors = this.colorBuffer;
|
|
657
|
+
for (let o = firstVertex * 4, end = index * 4; o < end; o += 4) {
|
|
658
|
+
colors[o] *= tint.x;
|
|
659
|
+
colors[o + 1] *= tint.y;
|
|
660
|
+
colors[o + 2] *= tint.z;
|
|
661
|
+
colors[o + 3] *= tint.w;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
555
664
|
this.measureSystemBounds(system as ParticleSystem, firstVertex, index);
|
|
556
665
|
}
|
|
557
666
|
|
|
@@ -575,8 +684,8 @@ export class TrailBatch extends VFXBatch {
|
|
|
575
684
|
let maxX = -Infinity;
|
|
576
685
|
let maxY = -Infinity;
|
|
577
686
|
let maxZ = -Infinity;
|
|
578
|
-
//
|
|
579
|
-
for (let o = fromVertex * 3, end = toVertex * 3; o < end; o +=
|
|
687
|
+
// Both of each pair: a swept ribbon's edges lie apart, a facing one's coincide.
|
|
688
|
+
for (let o = fromVertex * 3, end = toVertex * 3; o < end; o += 3) {
|
|
580
689
|
const x = positions[o];
|
|
581
690
|
const y = positions[o + 1];
|
|
582
691
|
const z = positions[o + 2];
|
|
@@ -611,6 +720,9 @@ export class TrailBatch extends VFXBatch {
|
|
|
611
720
|
// the high-water mark of every system in the batch.
|
|
612
721
|
this.mesh.updateVerticesData(VertexBuffer.PositionKind, this.positionBuffer.subarray(0, index * 3));
|
|
613
722
|
this.mesh.updateVerticesData(VertexBuffer.UVKind, this.uvBuffer.subarray(0, index * 2));
|
|
723
|
+
if (this.uv1Buffer) {
|
|
724
|
+
this.mesh.updateVerticesData(VertexBuffer.UV2Kind, this.uv1Buffer.subarray(0, index * 2));
|
|
725
|
+
}
|
|
614
726
|
// Straight to the GPU buffer. Going through `mesh.updateIndices` with a
|
|
615
727
|
// range whose length changes every frame makes Babylon copy the
|
|
616
728
|
// indices, rebuild the sub mesh and recompute its bounds from the
|