@fps-games/vfx 0.3.13 → 0.3.15
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.
|
@@ -26,6 +26,8 @@ const DEFAULT_PARAMS = {
|
|
|
26
26
|
scale: 1.15,
|
|
27
27
|
initialHeight: 0,
|
|
28
28
|
color: { r: 0.82, g: 0.95, b: 1 },
|
|
29
|
+
lineColor: { r: 0.82, g: 0.95, b: 1 },
|
|
30
|
+
particleColor: { r: 0.82, g: 0.95, b: 1 },
|
|
29
31
|
opacity: 1,
|
|
30
32
|
intensity: 1,
|
|
31
33
|
forwardOffset: 0,
|
|
@@ -43,12 +45,12 @@ const DEFAULT_PARAMS = {
|
|
|
43
45
|
lineOpacity: 1,
|
|
44
46
|
lineSpread: 1,
|
|
45
47
|
lineTwist: 0,
|
|
46
|
-
particleCount:
|
|
47
|
-
particleSize: 0.
|
|
48
|
+
particleCount: 22,
|
|
49
|
+
particleSize: 0.06,
|
|
48
50
|
particleSpeed: 2.15,
|
|
49
51
|
particleDrift: 0,
|
|
50
52
|
particleOuterOffset: 0,
|
|
51
|
-
particleOpacity: 0.
|
|
53
|
+
particleOpacity: 0.85,
|
|
52
54
|
directionX: 0,
|
|
53
55
|
directionZ: -1
|
|
54
56
|
};
|
|
@@ -68,7 +70,8 @@ const magnetSuctionEffectPackage = {
|
|
|
68
70
|
{ key: "lifetime", label: "自定义时长", kind: "lifetime", min: 0.1, max: 30, step: 0.01 },
|
|
69
71
|
{ key: "scale", label: "整体缩放", kind: "scale", min: 0.05, max: 6, step: 0.01 },
|
|
70
72
|
{ key: "initialHeight", label: "局部高度", kind: "number", min: -2, max: 4, step: 0.01 },
|
|
71
|
-
{ key: "
|
|
73
|
+
{ key: "lineColor", label: "线条颜色", kind: "color" },
|
|
74
|
+
{ key: "particleColor", label: "圆点颜色", kind: "color" },
|
|
72
75
|
{ key: "opacity", label: "整体透明度", kind: "opacity", min: 0, max: 1, step: 0.01 },
|
|
73
76
|
{ key: "intensity", label: "强度", kind: "opacity", min: 0, max: 1, step: 0.01 },
|
|
74
77
|
{ key: "forwardOffset", label: "入口前偏移", kind: "number", min: -2, max: 4, step: 0.01 },
|
|
@@ -193,10 +196,11 @@ function createSuctionMesh(scene, root, params, material, renderingGroupId) {
|
|
|
193
196
|
function writeGeometry() {
|
|
194
197
|
const basis = createSuctionBasis(params);
|
|
195
198
|
const cameraBasis = createCameraBasis(scene, root, basis);
|
|
196
|
-
const
|
|
199
|
+
const lineColor = toColor3(params.lineColor ?? params.color);
|
|
200
|
+
const particleColor = toColor3(params.particleColor ?? params.color);
|
|
197
201
|
const alphaScale = clamp01(params.opacity) * Math.max(0, params.intensity);
|
|
198
202
|
let vertexIndex = 0;
|
|
199
|
-
const putVertex = (position, alpha, brightness = 1) => {
|
|
203
|
+
const putVertex = (position, color, alpha, brightness = 1) => {
|
|
200
204
|
const positionOffset = vertexIndex * 3;
|
|
201
205
|
const colorOffset = vertexIndex * 4;
|
|
202
206
|
positions[positionOffset] = position.x;
|
|
@@ -216,20 +220,21 @@ function createSuctionMesh(scene, root, params, material, renderingGroupId) {
|
|
|
216
220
|
const tail = suctionPosition(tailD, line.u, line.v, basis);
|
|
217
221
|
const shrink = Math.max(lateralScale(headD, basis), 0.18);
|
|
218
222
|
const half = cameraBasis.ribbonSide.scale(line.width * shrink * 0.5);
|
|
219
|
-
putVertex(tail.subtract(half), alpha, line.brightness);
|
|
220
|
-
putVertex(tail.add(half), alpha * 0.92, line.brightness);
|
|
221
|
-
putVertex(head, alpha * 0.22, line.brightness);
|
|
223
|
+
putVertex(tail.subtract(half), lineColor, alpha, line.brightness);
|
|
224
|
+
putVertex(tail.add(half), lineColor, alpha * 0.92, line.brightness);
|
|
225
|
+
putVertex(head, lineColor, alpha * 0.22, line.brightness);
|
|
222
226
|
}
|
|
223
227
|
for (const particle of particles) {
|
|
224
|
-
const
|
|
228
|
+
const fade = lineFade(particle.d, basis);
|
|
229
|
+
const alpha = Math.sqrt(fade) * params.particleOpacity * particle.alphaMul;
|
|
225
230
|
const center = suctionPosition(particle.d, particle.u, particle.v, basis);
|
|
226
|
-
const shrink = Math.max(lateralScale(particle.d, basis), 0.
|
|
231
|
+
const shrink = Math.max(lateralScale(particle.d, basis), 0.48);
|
|
227
232
|
const right = cameraBasis.particleRight.scale(particle.size * shrink);
|
|
228
233
|
const up = cameraBasis.particleUp.scale(particle.size * shrink * 0.7);
|
|
229
|
-
putVertex(center.subtract(right).subtractInPlace(up), alpha, particle.brightness);
|
|
230
|
-
putVertex(center.add(right).subtractInPlace(up), alpha, particle.brightness);
|
|
231
|
-
putVertex(center.add(right).addInPlace(up), alpha * 0.8, particle.brightness);
|
|
232
|
-
putVertex(center.subtract(right).addInPlace(up), alpha * 0.8, particle.brightness);
|
|
234
|
+
putVertex(center.subtract(right).subtractInPlace(up), particleColor, alpha, particle.brightness);
|
|
235
|
+
putVertex(center.add(right).subtractInPlace(up), particleColor, alpha, particle.brightness);
|
|
236
|
+
putVertex(center.add(right).addInPlace(up), particleColor, alpha * 0.8, particle.brightness);
|
|
237
|
+
putVertex(center.subtract(right).addInPlace(up), particleColor, alpha * 0.8, particle.brightness);
|
|
233
238
|
}
|
|
234
239
|
mesh.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
|
|
235
240
|
mesh.updateVerticesData(VertexBuffer.ColorKind, colors, false, false);
|
|
@@ -3,12 +3,10 @@ import { Vector3 } from "@babylonjs/core/Maths/math.vector";
|
|
|
3
3
|
import { Constants } from "@babylonjs/core/Engines/constants";
|
|
4
4
|
import { DynamicTexture } from "@babylonjs/core/Materials/Textures/dynamicTexture";
|
|
5
5
|
import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial";
|
|
6
|
-
import { CreateCylinder } from "@babylonjs/core/Meshes/Builders/cylinderBuilder";
|
|
7
6
|
import { CreateDisc } from "@babylonjs/core/Meshes/Builders/discBuilder";
|
|
8
7
|
import { CreatePlane } from "@babylonjs/core/Meshes/Builders/planeBuilder";
|
|
9
|
-
import { CreateTorus } from "@babylonjs/core/Meshes/Builders/torusBuilder";
|
|
10
8
|
import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem";
|
|
11
|
-
import { c as configureVfxParticleSystem
|
|
9
|
+
import { c as configureVfxParticleSystem } from "../../chunks/rendering-CV3nhygX.js";
|
|
12
10
|
const id = "player-upgrade";
|
|
13
11
|
const nameZh = "人物升级光效";
|
|
14
12
|
const source = "runtime-generated";
|
|
@@ -22,6 +20,7 @@ const manifest = {
|
|
|
22
20
|
const strandTextureByScene = /* @__PURE__ */ new WeakMap();
|
|
23
21
|
const glowTextureByScene = /* @__PURE__ */ new WeakMap();
|
|
24
22
|
const haloTextureByScene = /* @__PURE__ */ new WeakMap();
|
|
23
|
+
const ringTextureByScene = /* @__PURE__ */ new WeakMap();
|
|
25
24
|
const DEFAULT_PARAMS = {
|
|
26
25
|
lifetime: 2.4,
|
|
27
26
|
scale: 1,
|
|
@@ -73,13 +72,13 @@ const playerUpgradeEffectPackage = {
|
|
|
73
72
|
{ key: "glowHeight", label: "光柱高度", kind: "number", min: 0.2, max: 5, step: 0.01 },
|
|
74
73
|
{ key: "glowWidth", label: "光柱宽度", kind: "number", min: 0.1, max: 4, step: 0.01 }
|
|
75
74
|
],
|
|
76
|
-
create({ scene, root, position, params }) {
|
|
75
|
+
create({ scene, root, position, params, renderingGroupId, scale }) {
|
|
77
76
|
markVfxRoot(root);
|
|
78
77
|
root.position.copyFrom(position);
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const rings = createExpandingRings(scene, root, params);
|
|
82
|
-
const glowAura = createGlowAura(scene, root, params);
|
|
78
|
+
const groupId = renderingGroupId ?? 0;
|
|
79
|
+
const strands = createStrandSystem(scene, root, params, groupId, scale);
|
|
80
|
+
const rings = createExpandingRings(scene, root, params, groupId);
|
|
81
|
+
const glowAura = createGlowAura(scene, root, params, groupId);
|
|
83
82
|
let disposed = false;
|
|
84
83
|
const disposeTimer = window.setTimeout(() => disposeAll(), getDisposeDelaySeconds(params) * 1e3);
|
|
85
84
|
strands.start();
|
|
@@ -95,7 +94,6 @@ const playerUpgradeEffectPackage = {
|
|
|
95
94
|
window.clearTimeout(disposeTimer);
|
|
96
95
|
strands.stop();
|
|
97
96
|
strands.dispose(false);
|
|
98
|
-
strandMeshes.dispose();
|
|
99
97
|
rings.dispose();
|
|
100
98
|
glowAura.dispose();
|
|
101
99
|
cleanupPlanarShadowArtifacts(scene);
|
|
@@ -133,7 +131,7 @@ function cleanupPlanarShadowArtifacts(scene) {
|
|
|
133
131
|
}
|
|
134
132
|
}
|
|
135
133
|
}
|
|
136
|
-
function createGlowAura(scene, root, params) {
|
|
134
|
+
function createGlowAura(scene, root, params, renderingGroupId) {
|
|
137
135
|
const effectScale = Math.max(0.05, params.scale);
|
|
138
136
|
const color = params.color;
|
|
139
137
|
const glowHeight = Math.max(0.1, params.glowHeight) * effectScale;
|
|
@@ -148,7 +146,7 @@ function createGlowAura(scene, root, params) {
|
|
|
148
146
|
mesh.position.y = glowHeight * 0.48;
|
|
149
147
|
mesh.rotation.y = index * Math.PI / 3;
|
|
150
148
|
mesh.scaling.set(glowWidth, glowHeight, 1);
|
|
151
|
-
mesh.renderingGroupId =
|
|
149
|
+
mesh.renderingGroupId = renderingGroupId;
|
|
152
150
|
const material = new StandardMaterial(`player-upgrade.soft-glow-column-material.${index}`, scene);
|
|
153
151
|
configureTexturedGlowMaterial(material, color, getGlowTexture(scene), 2.8);
|
|
154
152
|
material.alpha = 0;
|
|
@@ -162,7 +160,7 @@ function createGlowAura(scene, root, params) {
|
|
|
162
160
|
halo.position.y = 0.025 * effectScale;
|
|
163
161
|
halo.rotation.x = Math.PI / 2;
|
|
164
162
|
halo.scaling.set(glowWidth * 1.12, glowWidth * 1.12, 1);
|
|
165
|
-
halo.renderingGroupId =
|
|
163
|
+
halo.renderingGroupId = renderingGroupId;
|
|
166
164
|
const haloMaterial = new StandardMaterial("player-upgrade.ground-halo-material", scene);
|
|
167
165
|
configureTexturedGlowMaterial(haloMaterial, color, getHaloTexture(scene), 2.4);
|
|
168
166
|
haloMaterial.alpha = 0;
|
|
@@ -198,19 +196,23 @@ function createGlowAura(scene, root, params) {
|
|
|
198
196
|
}
|
|
199
197
|
return { dispose };
|
|
200
198
|
}
|
|
201
|
-
function createStrandSystem(scene, root, params) {
|
|
199
|
+
function createStrandSystem(scene, root, params, renderingGroupId, spawnScale) {
|
|
202
200
|
const effectScale = Math.max(0.05, params.scale);
|
|
201
|
+
const spawnHorizontalScale = getHorizontalScale(spawnScale);
|
|
202
|
+
const spawnVerticalScale = Math.max(0.01, Math.abs(spawnScale.y));
|
|
203
203
|
const count = Math.max(0, Math.round(params.strandCount));
|
|
204
204
|
const color = params.color;
|
|
205
205
|
const bright = brighten(color, 0.72);
|
|
206
|
-
const strandLength = Math.max(0.05, params.strandLength) * effectScale;
|
|
206
|
+
const strandLength = Math.max(0.05, params.strandLength) * effectScale * spawnVerticalScale;
|
|
207
207
|
const strandRadius = Math.max(0, params.strandRadius) * effectScale;
|
|
208
|
-
const strandWidth = Math.max(1e-3, params.strandWidth) * effectScale;
|
|
208
|
+
const strandWidth = Math.max(1e-3, params.strandWidth) * effectScale * spawnHorizontalScale;
|
|
209
209
|
const system = new ParticleSystem("player-upgrade.gold-strands", Math.max(1, count), scene);
|
|
210
210
|
configureVfxParticleSystem(system);
|
|
211
|
+
system.renderingGroupId = renderingGroupId;
|
|
211
212
|
system.particleTexture = getStrandTexture(scene);
|
|
212
213
|
system.particleTexture.hasAlpha = true;
|
|
213
214
|
system.emitter = root;
|
|
215
|
+
system.isLocal = true;
|
|
214
216
|
system.manualEmitCount = count;
|
|
215
217
|
system.emitRate = count * 60;
|
|
216
218
|
system.targetStopDuration = 0.05;
|
|
@@ -224,9 +226,9 @@ function createStrandSystem(scene, root, params) {
|
|
|
224
226
|
system.maxScaleX = strandWidth * 1.8;
|
|
225
227
|
system.minScaleY = 1;
|
|
226
228
|
system.maxScaleY = 1.6;
|
|
227
|
-
system.minEmitPower = Math.max(0.01, params.riseSpeed * effectScale * 0.55);
|
|
228
|
-
system.maxEmitPower = Math.max(system.minEmitPower, params.riseSpeed * effectScale * 1.28);
|
|
229
|
-
system.gravity = new Vector3(0, 0.34 * effectScale, 0);
|
|
229
|
+
system.minEmitPower = Math.max(0.01, params.riseSpeed * effectScale * spawnVerticalScale * 0.55);
|
|
230
|
+
system.maxEmitPower = Math.max(system.minEmitPower, params.riseSpeed * effectScale * spawnVerticalScale * 1.28);
|
|
231
|
+
system.gravity = new Vector3(0, 0.34 * effectScale * spawnVerticalScale, 0);
|
|
230
232
|
system.updateSpeed = 1 / 60;
|
|
231
233
|
system.color1 = toColor4(color, params.opacity * 0.72);
|
|
232
234
|
system.color2 = toColor4(bright, params.opacity);
|
|
@@ -267,102 +269,28 @@ function createStrandSystem(scene, root, params) {
|
|
|
267
269
|
};
|
|
268
270
|
return system;
|
|
269
271
|
}
|
|
270
|
-
function
|
|
271
|
-
const effectScale = Math.max(0.05, params.scale);
|
|
272
|
-
const count = Math.min(90, Math.max(0, Math.round(params.strandCount * 0.62)));
|
|
273
|
-
const color = params.color;
|
|
274
|
-
const radius = Math.max(0.04, params.strandRadius * effectScale);
|
|
275
|
-
const strandLength = Math.max(0.05, params.strandLength * effectScale);
|
|
276
|
-
const riseHeight = Math.max(0.1, params.strandHeight * effectScale);
|
|
277
|
-
const width = Math.max(5e-3, params.strandWidth * effectScale * 1.25);
|
|
278
|
-
const speedScale = Math.max(0.2, params.riseSpeed / DEFAULT_PARAMS.riseSpeed);
|
|
279
|
-
const duration = Math.max(0.22, params.lifetime * 0.72 / speedScale);
|
|
280
|
-
const states = [];
|
|
281
|
-
for (let index = 0; index < count; index += 1) {
|
|
282
|
-
const angle = sequence01(index, 0) * Math.PI * 2;
|
|
283
|
-
const localRadius = radius * lerp(0.42, 1.08, sequence01(index, 1));
|
|
284
|
-
const mesh = CreateCylinder(
|
|
285
|
-
`player-upgrade.gold-strand-mesh.${index}`,
|
|
286
|
-
{ height: 1, diameter: width, tessellation: 6 },
|
|
287
|
-
scene
|
|
288
|
-
);
|
|
289
|
-
prepareVfxMesh(mesh);
|
|
290
|
-
mesh.parent = root;
|
|
291
|
-
mesh.position.x = Math.cos(angle) * localRadius;
|
|
292
|
-
mesh.position.z = Math.sin(angle) * localRadius;
|
|
293
|
-
mesh.position.y = 0;
|
|
294
|
-
mesh.renderingGroupId = VFX_RENDERING_GROUP_ID;
|
|
295
|
-
mesh.isVisible = false;
|
|
296
|
-
const material = new StandardMaterial(`player-upgrade.gold-strand-mesh-material.${index}`, scene);
|
|
297
|
-
configureGlowMaterial(material, color, 2.8);
|
|
298
|
-
material.alpha = 0;
|
|
299
|
-
mesh.material = material;
|
|
300
|
-
states.push({
|
|
301
|
-
mesh,
|
|
302
|
-
material,
|
|
303
|
-
height: strandLength * lerp(0.68, 1.18, sequence01(index, 2)),
|
|
304
|
-
startDelay: sequence01(index, 3) * Math.min(0.34, params.lifetime * 0.18),
|
|
305
|
-
duration: duration * lerp(0.78, 1.12, sequence01(index, 4))
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
let age = 0;
|
|
309
|
-
let disposed = false;
|
|
310
|
-
const observer = scene.onBeforeRenderObservable.add(() => {
|
|
311
|
-
if (disposed) return;
|
|
312
|
-
const deltaSeconds = Math.min(0.05, scene.getEngine().getDeltaTime() / 1e3);
|
|
313
|
-
age += deltaSeconds;
|
|
314
|
-
for (const state of states) {
|
|
315
|
-
const localAge = age - state.startDelay;
|
|
316
|
-
if (localAge < 0 || localAge > state.duration) {
|
|
317
|
-
state.mesh.isVisible = false;
|
|
318
|
-
state.material.alpha = 0;
|
|
319
|
-
continue;
|
|
320
|
-
}
|
|
321
|
-
const t = Math.min(1, localAge / state.duration);
|
|
322
|
-
const grow = Math.min(1, t / 0.32);
|
|
323
|
-
const fadeOut = Math.max(0, 1 - Math.max(0, t - 0.66) / 0.34);
|
|
324
|
-
const alpha = params.opacity * fadeOut * Math.min(1, t / 0.12);
|
|
325
|
-
const currentHeight = state.height * grow;
|
|
326
|
-
state.mesh.isVisible = alpha > 0.01;
|
|
327
|
-
state.mesh.scaling.set(1, currentHeight, 1);
|
|
328
|
-
state.mesh.position.y = currentHeight * 0.5 + riseHeight * easeOutCubic(t);
|
|
329
|
-
state.material.alpha = Math.min(1, alpha * 1.35);
|
|
330
|
-
}
|
|
331
|
-
if (age >= params.lifetime + 0.45) dispose();
|
|
332
|
-
});
|
|
333
|
-
function dispose() {
|
|
334
|
-
if (disposed) return;
|
|
335
|
-
disposed = true;
|
|
336
|
-
scene.onBeforeRenderObservable.remove(observer);
|
|
337
|
-
for (const state of states) {
|
|
338
|
-
state.mesh.dispose();
|
|
339
|
-
state.material.dispose();
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return { dispose };
|
|
343
|
-
}
|
|
344
|
-
function createExpandingRings(scene, root, params) {
|
|
272
|
+
function createExpandingRings(scene, root, params, renderingGroupId) {
|
|
345
273
|
const effectScale = Math.max(0.05, params.scale);
|
|
346
274
|
const ringCount = Math.max(0, Math.round(params.ringCount));
|
|
347
275
|
const ringDuration = Math.max(0.18, Math.min(0.9, params.lifetime * 0.38));
|
|
348
276
|
const minRadius = 0.14 * effectScale;
|
|
349
277
|
const maxRadius = Math.max(minRadius + 0.01, params.ringMaxRadius * effectScale);
|
|
350
|
-
const thickness = Math.max(2e-3, params.ringThickness * effectScale);
|
|
351
278
|
const color = params.color;
|
|
352
279
|
const states = [];
|
|
353
280
|
for (let index = 0; index < ringCount; index += 1) {
|
|
354
|
-
const mesh =
|
|
281
|
+
const mesh = CreatePlane(
|
|
355
282
|
`player-upgrade.expanding-ring.${index}`,
|
|
356
|
-
{
|
|
283
|
+
{ size: 2 },
|
|
357
284
|
scene
|
|
358
285
|
);
|
|
359
286
|
prepareVfxMesh(mesh);
|
|
360
287
|
mesh.parent = root;
|
|
361
288
|
mesh.position.y = 0.03 * effectScale + index * 0.012 * effectScale;
|
|
362
|
-
mesh.
|
|
289
|
+
mesh.rotation.x = Math.PI / 2;
|
|
290
|
+
mesh.renderingGroupId = renderingGroupId;
|
|
363
291
|
mesh.isVisible = false;
|
|
364
292
|
const material = new StandardMaterial(`player-upgrade.ring-material.${index}`, scene);
|
|
365
|
-
|
|
293
|
+
configureTexturedGlowMaterial(material, color, getRingTexture(scene), 2.4);
|
|
366
294
|
material.alpha = 0;
|
|
367
295
|
mesh.material = material;
|
|
368
296
|
states.push({
|
|
@@ -390,7 +318,7 @@ function createExpandingRings(scene, root, params) {
|
|
|
390
318
|
const radius = lerp(minRadius, maxRadius, eased);
|
|
391
319
|
const alpha = params.ringOpacity * (1 - t) * Math.min(1, t / 0.12);
|
|
392
320
|
state.mesh.isVisible = alpha > 0.01;
|
|
393
|
-
state.mesh.scaling.set(radius, radius,
|
|
321
|
+
state.mesh.scaling.set(radius, radius, 1);
|
|
394
322
|
const ringColor = brighten(color, 0.1 + 0.08 * (1 - t));
|
|
395
323
|
state.material.diffuseColor = toColor3(ringColor);
|
|
396
324
|
state.material.emissiveColor = toGlowColor3(ringColor, 3.4);
|
|
@@ -477,6 +405,45 @@ function getHaloTexture(scene) {
|
|
|
477
405
|
haloTextureByScene.set(scene, texture);
|
|
478
406
|
return texture;
|
|
479
407
|
}
|
|
408
|
+
function getRingTexture(scene) {
|
|
409
|
+
const existing = ringTextureByScene.get(scene);
|
|
410
|
+
if (existing) return existing;
|
|
411
|
+
const size = 256;
|
|
412
|
+
const texture = new DynamicTexture("player_upgrade_expanding_ring_texture", { width: size, height: size }, scene, true);
|
|
413
|
+
const context = texture.getContext();
|
|
414
|
+
const canvasContext = context;
|
|
415
|
+
context.clearRect(0, 0, size, size);
|
|
416
|
+
const center = size / 2;
|
|
417
|
+
const radius = size * 0.39;
|
|
418
|
+
const strokeWidth = size * 0.105;
|
|
419
|
+
canvasContext.lineCap = "round";
|
|
420
|
+
canvasContext.lineJoin = "round";
|
|
421
|
+
const outerGlow = context.createRadialGradient(center, center, radius - strokeWidth * 1.1, center, center, radius + strokeWidth * 1.8);
|
|
422
|
+
outerGlow.addColorStop(0, "rgba(255,255,255,0)");
|
|
423
|
+
outerGlow.addColorStop(0.38, "rgba(255,255,255,0.28)");
|
|
424
|
+
outerGlow.addColorStop(0.58, "rgba(255,255,255,0.34)");
|
|
425
|
+
outerGlow.addColorStop(1, "rgba(255,255,255,0)");
|
|
426
|
+
context.strokeStyle = outerGlow;
|
|
427
|
+
context.lineWidth = strokeWidth * 2.6;
|
|
428
|
+
context.beginPath();
|
|
429
|
+
context.arc(center, center, radius, 0, Math.PI * 2);
|
|
430
|
+
context.stroke();
|
|
431
|
+
const core = context.createRadialGradient(center, center, radius - strokeWidth * 0.85, center, center, radius + strokeWidth * 0.85);
|
|
432
|
+
core.addColorStop(0, "rgba(255,255,255,0)");
|
|
433
|
+
core.addColorStop(0.42, "rgba(255,255,255,0.72)");
|
|
434
|
+
core.addColorStop(0.5, "rgba(255,255,255,1)");
|
|
435
|
+
core.addColorStop(0.62, "rgba(255,255,255,0.62)");
|
|
436
|
+
core.addColorStop(1, "rgba(255,255,255,0)");
|
|
437
|
+
context.strokeStyle = core;
|
|
438
|
+
context.lineWidth = strokeWidth;
|
|
439
|
+
context.beginPath();
|
|
440
|
+
context.arc(center, center, radius, 0, Math.PI * 2);
|
|
441
|
+
context.stroke();
|
|
442
|
+
texture.hasAlpha = true;
|
|
443
|
+
texture.update(false);
|
|
444
|
+
ringTextureByScene.set(scene, texture);
|
|
445
|
+
return texture;
|
|
446
|
+
}
|
|
480
447
|
function getDisposeDelaySeconds(params) {
|
|
481
448
|
const ringDuration = Math.max(0.18, Math.min(0.9, params.lifetime * 0.38));
|
|
482
449
|
return Math.max(0.2, params.lifetime) + getLastRingEndTime(params, ringDuration) + 0.35;
|
|
@@ -484,6 +451,9 @@ function getDisposeDelaySeconds(params) {
|
|
|
484
451
|
function getLastRingEndTime(params, ringDuration) {
|
|
485
452
|
return Math.max(0, Math.round(params.ringCount) - 1) * Math.max(0.02, params.ringInterval) + ringDuration;
|
|
486
453
|
}
|
|
454
|
+
function getHorizontalScale(scale) {
|
|
455
|
+
return Math.max(0.01, (Math.abs(scale.x) + Math.abs(scale.z)) * 0.5);
|
|
456
|
+
}
|
|
487
457
|
function toColor4(color, alpha) {
|
|
488
458
|
return new Color4(clamp01(color.r), clamp01(color.g), clamp01(color.b), clamp01(alpha));
|
|
489
459
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fps-games/vfx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared VFX library for Playable projects: engine-injected effect packages + runtime. Project-pure (no imports of host project code).",
|
|
6
6
|
"publishConfig": {
|