@fps-games/vfx 0.1.1 → 0.3.3

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 (250) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +41 -0
  3. package/dist/effects/coin-burst/index.js +6 -2
  4. package/dist/effects/comet-trail-flame/index.js +3 -1
  5. package/dist/effects/debris-smoke/index.js +1 -0
  6. package/dist/effects/electric-arc/index.js +1 -0
  7. package/dist/effects/energy-shield/index.js +1 -0
  8. package/dist/effects/explosion/index.js +3 -2
  9. package/dist/effects/hit-flash/index.js +12 -4
  10. package/dist/effects/laser-beam/index.js +14 -2
  11. package/dist/effects/lumber_vehicle_upgrade_aura/index.js +1 -0
  12. package/dist/effects/monster-hit/index.js +2 -1
  13. package/dist/effects/player-upgrade/index.js +5 -3
  14. package/dist/effects/pulse-laser-volley/index.js +14 -4
  15. package/dist/effects/thruster-flame/index.js +3 -1
  16. package/dist/effects/treasure-attention/index.d.ts +54 -0
  17. package/dist/effects/treasure-attention/index.js +535 -0
  18. package/dist/effects/ufo-thread-flame/index.js +1 -0
  19. package/dist/effects/vehicle-upgrade/index.js +4 -1
  20. package/dist/effects/weapon-trail/index.js +8 -3
  21. package/dist/effects/wood_crusher_sawdust/index.d.ts +4 -0
  22. package/dist/effects/wood_cutter_sawdust/index.d.ts +4 -0
  23. package/dist/index.js +85 -17
  24. package/dist/types.d.ts +80 -0
  25. package/index.json +19 -1
  26. package/package.json +9 -4
  27. package/packages/effects/treasure-attention/vfx-params.json +49 -0
  28. package/tooling/vfx-cli.mjs +8 -1
  29. package/docs/AUTHORING_EFFECTS.md +0 -297
  30. package/docs/VFX_LIBRARY_ARCHITECTURE_chatgpt.md +0 -1580
  31. package/docs/VFX_LIBRARY_EXECUTION_PLAN.md +0 -229
  32. package/docs/VFX_LIBRARY_PLAN.md +0 -546
  33. package/docs/vfx-ab/RESULTS.md +0 -35
  34. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/after.png +0 -0
  35. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/before.png +0 -0
  36. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/after.png +0 -0
  37. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/before.png +0 -0
  38. package/docs/vfx-integration_chatgpt.md +0 -462
  39. package/docs/weapon-trail-visualization.html +0 -241
  40. package/packages/EffectPackageService.ts +0 -240
  41. package/packages/SceneVfxService.ts +0 -96
  42. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/runtime/simpleMeshEffect.v1.js +0 -333
  43. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.frag.glsl +0 -25
  44. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.vert.glsl +0 -11
  45. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/textures/effect_jianbian.png +0 -0
  46. package/packages/build.mesh.yellow_build_upgrade_indicator/effect.json +0 -927
  47. package/packages/build.mesh.yellow_build_upgrade_indicator/media/contact-sheet.png +0 -0
  48. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.gif +0 -0
  49. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.mp4 +0 -0
  50. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.webm +0 -0
  51. package/packages/build.mesh.yellow_build_upgrade_indicator/media/thumbnail.png +0 -0
  52. package/packages/build.mesh.yellow_build_upgrade_indicator/metadata/description.json +0 -197
  53. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-effect.original.json +0 -895
  54. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-normalized-vfx-to-babylon-report.json +0 -241
  55. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-overrides.json +0 -542
  56. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-tuning-report.json +0 -69
  57. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/asset-map.json +0 -125
  58. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/lineage.json +0 -44
  59. package/packages/build.particle.golden_upgrade_starburst/assets/runtime/particleEmitter.v1.js +0 -210
  60. package/packages/build.particle.golden_upgrade_starburst/assets/textures/effect_guangdian.png +0 -0
  61. package/packages/build.particle.golden_upgrade_starburst/effect.json +0 -880
  62. package/packages/build.particle.golden_upgrade_starburst/media/contact-sheet.png +0 -0
  63. package/packages/build.particle.golden_upgrade_starburst/media/preview.gif +0 -0
  64. package/packages/build.particle.golden_upgrade_starburst/media/preview.mp4 +0 -0
  65. package/packages/build.particle.golden_upgrade_starburst/media/preview.webm +0 -0
  66. package/packages/build.particle.golden_upgrade_starburst/media/thumbnail.png +0 -0
  67. package/packages/build.particle.golden_upgrade_starburst/metadata/description.json +0 -161
  68. package/packages/build.particle.golden_upgrade_starburst/provenance/03-effect.original.json +0 -762
  69. package/packages/build.particle.golden_upgrade_starburst/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  70. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-overrides.json +0 -436
  71. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-tuning-report.json +0 -40
  72. package/packages/build.particle.golden_upgrade_starburst/provenance/asset-map.json +0 -115
  73. package/packages/build.particle.golden_upgrade_starburst/provenance/lineage.json +0 -40
  74. package/packages/build.particle.orange_upgrade_transform_sparks/assets/runtime/particleEmitter.v1.js +0 -210
  75. package/packages/build.particle.orange_upgrade_transform_sparks/assets/textures/b5b27ab1-e740-4398-b407-848fc2b2c897.png +0 -0
  76. package/packages/build.particle.orange_upgrade_transform_sparks/effect.json +0 -887
  77. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.gif +0 -0
  78. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.mp4 +0 -0
  79. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.webm +0 -0
  80. package/packages/build.particle.orange_upgrade_transform_sparks/media/thumbnail.png +0 -0
  81. package/packages/build.particle.orange_upgrade_transform_sparks/metadata/description.json +0 -179
  82. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-effect.original.json +0 -859
  83. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  84. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-overrides.json +0 -478
  85. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-tuning-report.json +0 -40
  86. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/asset-map.json +0 -114
  87. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/lineage.json +0 -41
  88. package/packages/build.particle.wood_chip_dust_burst/assets/runtime/particleEmitter.v1.js +0 -210
  89. package/packages/build.particle.wood_chip_dust_burst/assets/textures/effect_yanwu4.png +0 -0
  90. package/packages/build.particle.wood_chip_dust_burst/assets/textures/suipian3.png +0 -0
  91. package/packages/build.particle.wood_chip_dust_burst/effect.json +0 -1400
  92. package/packages/build.particle.wood_chip_dust_burst/media/contact-sheet.png +0 -0
  93. package/packages/build.particle.wood_chip_dust_burst/media/preview.gif +0 -0
  94. package/packages/build.particle.wood_chip_dust_burst/media/preview.mp4 +0 -0
  95. package/packages/build.particle.wood_chip_dust_burst/media/preview.webm +0 -0
  96. package/packages/build.particle.wood_chip_dust_burst/media/thumbnail.png +0 -0
  97. package/packages/build.particle.wood_chip_dust_burst/metadata/description.json +0 -173
  98. package/packages/build.particle.wood_chip_dust_burst/provenance/03-effect.original.json +0 -1277
  99. package/packages/build.particle.wood_chip_dust_burst/provenance/03-normalized-vfx-to-babylon-report.json +0 -329
  100. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-overrides.json +0 -749
  101. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-tuning-report.json +0 -60
  102. package/packages/build.particle.wood_chip_dust_burst/provenance/asset-map.json +0 -146
  103. package/packages/build.particle.wood_chip_dust_burst/provenance/lineage.json +0 -69
  104. package/packages/effects/building-upgrade/effect.json +0 -6
  105. package/packages/effects/building-upgrade/index.ts +0 -387
  106. package/packages/effects/character-entrance/effect.json +0 -6
  107. package/packages/effects/character-entrance/index.ts +0 -308
  108. package/packages/effects/coin-burst/index.ts +0 -43
  109. package/packages/effects/comet-trail-flame/assets/textures/trail_5x4.webp +0 -0
  110. package/packages/effects/comet-trail-flame/index.ts +0 -106
  111. package/packages/effects/conveyor-upgrade/effect.json +0 -6
  112. package/packages/effects/conveyor-upgrade/index.ts +0 -401
  113. package/packages/effects/debris-smoke/assets/models/rock_debris.glb +0 -0
  114. package/packages/effects/debris-smoke/assets/textures/smoke22.webp +0 -0
  115. package/packages/effects/debris-smoke/index.ts +0 -101
  116. package/packages/effects/door_open_gold_flakes/assets/runtime/goldFlakes.v1.js +0 -397
  117. package/packages/effects/door_open_gold_flakes/door_open_gold_flakes.json +0 -498
  118. package/packages/effects/door_open_gold_flakes/index.ts +0 -11
  119. package/packages/effects/electric-arc/assets/textures/spark_4x4.webp +0 -0
  120. package/packages/effects/electric-arc/index.ts +0 -62
  121. package/packages/effects/energy-shield/effect.json +0 -7
  122. package/packages/effects/energy-shield/index.ts +0 -431
  123. package/packages/effects/explosion/assets/textures/baozha29.webp +0 -0
  124. package/packages/effects/explosion/assets/textures/glow01.webp +0 -0
  125. package/packages/effects/explosion/assets/textures/lizi01.webp +0 -0
  126. package/packages/effects/explosion/assets/textures/xulie_lizibaozha02_5x5.webp +0 -0
  127. package/packages/effects/explosion/index.ts +0 -114
  128. package/packages/effects/ground-tile-upgrade/effect.json +0 -6
  129. package/packages/effects/ground-tile-upgrade/index.ts +0 -410
  130. package/packages/effects/hit-flash/index.ts +0 -69
  131. package/packages/effects/laser-beam/assets/textures/laser_glow.webp +0 -0
  132. package/packages/effects/laser-beam/assets/textures/laser_noise.webp +0 -0
  133. package/packages/effects/laser-beam/index.ts +0 -6
  134. package/packages/effects/laser-beam-factory.ts +0 -135
  135. package/packages/effects/lumber-cart-suction/effect.json +0 -6
  136. package/packages/effects/lumber-cart-suction/index.ts +0 -399
  137. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb +0 -0
  138. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/.active +0 -1
  139. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/1781589063890_upload.glb +0 -0
  140. package/packages/effects/lumber-debris-scatter/assets/runtime/solidParticleScatter.v1.js +0 -236
  141. package/packages/effects/lumber-debris-scatter/effect.json +0 -228
  142. package/packages/effects/lumber-debris-scatter/index.ts +0 -780
  143. package/packages/effects/lumber_vehicle_gear_spin/assets/runtime/gearSpin.v1.js +0 -202
  144. package/packages/effects/lumber_vehicle_gear_spin/index.ts +0 -11
  145. package/packages/effects/lumber_vehicle_gear_spin/lumber_vehicle_gear_spin.json +0 -338
  146. package/packages/effects/lumber_vehicle_upgrade_aura/assets/runtime/upgradeAura.v1.js +0 -353
  147. package/packages/effects/lumber_vehicle_upgrade_aura/index.ts +0 -11
  148. package/packages/effects/lumber_vehicle_upgrade_aura/lumber_vehicle_upgrade_aura.json +0 -365
  149. package/packages/effects/lumber_vehicle_wood_chips/assets/runtime/solidParticleScatter.v1.js +0 -310
  150. package/packages/effects/lumber_vehicle_wood_chips/index.ts +0 -11
  151. package/packages/effects/lumber_vehicle_wood_chips/lumber_vehicle_wood_chips.json +0 -335
  152. package/packages/effects/monster-hit/index.ts +0 -128
  153. package/packages/effects/player-upgrade/effect.json +0 -6
  154. package/packages/effects/player-upgrade/index.ts +0 -635
  155. package/packages/effects/pulse-laser-volley/assets/textures/bolt_guangshu.webp +0 -0
  156. package/packages/effects/pulse-laser-volley/index.ts +0 -204
  157. package/packages/effects/resource-collect-sparkles/effect.json +0 -6
  158. package/packages/effects/resource-collect-sparkles/index.ts +0 -254
  159. package/packages/effects/run-footstep-dust/assets/runtime/runFootstepDust.v1.js +0 -215
  160. package/packages/effects/run-footstep-dust/effect.json +0 -183
  161. package/packages/effects/run-footstep-dust/index.ts +0 -377
  162. package/packages/effects/space-shared.ts +0 -120
  163. package/packages/effects/thruster-flame/index.ts +0 -305
  164. package/packages/effects/tree-chop-dust/assets/textures/tree_chop_dust_atlas.png +0 -0
  165. package/packages/effects/tree-chop-dust/effect.json +0 -8
  166. package/packages/effects/tree-chop-dust/index.ts +0 -202
  167. package/packages/effects/tree-leaf-chop-burst/assets/runtime/particleEmitter.v1.js +0 -303
  168. package/packages/effects/tree-leaf-chop-burst/assets/textures/tree_leaf_chop_burst_leaf_atlas.png +0 -0
  169. package/packages/effects/tree-leaf-chop-burst/effect.json +0 -498
  170. package/packages/effects/tree-leaf-chop-burst/index.ts +0 -294
  171. package/packages/effects/tree_chop_dust_burst/assets/runtime/particleEmitter.v1.js +0 -318
  172. package/packages/effects/tree_chop_dust_burst/assets/textures/tree_chop_dust_burst_dust.png +0 -0
  173. package/packages/effects/tree_chop_dust_burst/index.ts +0 -13
  174. package/packages/effects/tree_chop_dust_burst/tree_chop_dust_burst.json +0 -412
  175. package/packages/effects/ufo-thread-flame/assets/textures/flame_flow.webp +0 -0
  176. package/packages/effects/ufo-thread-flame/assets/textures/flame_spike.webp +0 -0
  177. package/packages/effects/ufo-thread-flame/index.ts +0 -152
  178. package/packages/effects/vehicle-exhaust-smoke/assets/textures/vehicle_exhaust_smoke_atlas.png +0 -0
  179. package/packages/effects/vehicle-exhaust-smoke/effect.json +0 -8
  180. package/packages/effects/vehicle-exhaust-smoke/index.ts +0 -298
  181. package/packages/effects/vehicle-upgrade/effect.json +0 -6
  182. package/packages/effects/vehicle-upgrade/index.ts +0 -401
  183. package/packages/effects/weapon-trail/assets/textures/trail_wedge.png +0 -0
  184. package/packages/effects/weapon-trail/index.ts +0 -313
  185. package/packages/effects/wood-crusher-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  186. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  187. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  188. package/packages/effects/wood-crusher-sawdust/index.ts +0 -43
  189. package/packages/effects/wood-crusher-sawdust/wood_crusher_sawdust.json +0 -592
  190. package/packages/effects/wood-cutter-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  191. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  192. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  193. package/packages/effects/wood-cutter-sawdust/index.ts +0 -43
  194. package/packages/effects/wood-cutter-sawdust/wood_cutter_sawdust.json +0 -592
  195. package/packages/effects/wood-sawdust-effect-factory.ts +0 -194
  196. package/packages/effects/wood_crusher_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  197. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  198. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  199. package/packages/effects/wood_crusher_sawdust/index.ts +0 -29
  200. package/packages/effects/wood_crusher_sawdust/wood_crusher_sawdust.json +0 -592
  201. package/packages/effects/wood_cutter_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  202. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  203. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  204. package/packages/effects/wood_cutter_sawdust/index.ts +0 -29
  205. package/packages/effects/wood_cutter_sawdust/wood_cutter_sawdust.json +0 -592
  206. package/packages/effects/wood_peel_material_test/assets/runtime/woodPeelMaterialTest.v1.js +0 -196
  207. package/packages/effects/wood_peel_material_test/index.ts +0 -11
  208. package/packages/effects/wood_peel_material_test/wood_peel_material_test.json +0 -136
  209. package/packages/env.particle.forest_edge_fog/assets/runtime/particleEmitter.v1.js +0 -210
  210. package/packages/env.particle.forest_edge_fog/assets/textures/f12a23c4-b924-4322-a260-3d982428f1e8.png +0 -0
  211. package/packages/env.particle.forest_edge_fog/assets/textures/yuan.png +0 -0
  212. package/packages/env.particle.forest_edge_fog/effect.json +0 -854
  213. package/packages/env.particle.forest_edge_fog/media/preview.gif +0 -0
  214. package/packages/env.particle.forest_edge_fog/media/preview.mp4 +0 -0
  215. package/packages/env.particle.forest_edge_fog/media/preview.webm +0 -0
  216. package/packages/env.particle.forest_edge_fog/media/thumbnail.png +0 -0
  217. package/packages/env.particle.forest_edge_fog/metadata/description.json +0 -148
  218. package/packages/env.particle.forest_edge_fog/provenance/03-effect.original.json +0 -827
  219. package/packages/env.particle.forest_edge_fog/provenance/03-normalized-vfx-to-babylon-report.json +0 -196
  220. package/packages/env.particle.forest_edge_fog/provenance/04-preview-overrides.json +0 -432
  221. package/packages/env.particle.forest_edge_fog/provenance/04-preview-tuning-report.json +0 -28
  222. package/packages/env.particle.forest_edge_fog/provenance/asset-map.json +0 -124
  223. package/packages/env.particle.forest_edge_fog/provenance/lineage.json +0 -41
  224. package/packages/generation.ts +0 -14
  225. package/packages/index.ts +0 -14
  226. package/packages/legacy-particle-runtime.ts +0 -113
  227. package/packages/manifestRuntimePackage.ts +0 -519
  228. package/packages/registry.ts +0 -85
  229. package/packages/rendering.ts +0 -13
  230. package/packages/resource.particle.viscous_oil_suction/assets/runtime/top_disk_suction/particleEmitter.v1.js +0 -424
  231. package/packages/resource.particle.viscous_oil_suction/assets/textures/Glow ad.png +0 -0
  232. package/packages/resource.particle.viscous_oil_suction/effect.json +0 -1254
  233. package/packages/resource.particle.viscous_oil_suction/media/preview.gif +0 -0
  234. package/packages/resource.particle.viscous_oil_suction/media/preview.mp4 +0 -0
  235. package/packages/resource.particle.viscous_oil_suction/media/preview.webm +0 -0
  236. package/packages/resource.particle.viscous_oil_suction/media/thumbnail.png +0 -0
  237. package/packages/resource.particle.viscous_oil_suction/metadata/description.json +0 -122
  238. package/packages/resource.particle.viscous_oil_suction/provenance/03-effect.original.json +0 -1051
  239. package/packages/resource.particle.viscous_oil_suction/provenance/03-normalized-vfx-to-babylon-report.json +0 -200
  240. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-overrides.json +0 -581
  241. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-tuning-report.json +0 -28
  242. package/packages/resource.particle.viscous_oil_suction/provenance/asset-map.json +0 -111
  243. package/packages/resource.particle.viscous_oil_suction/provenance/lineage.json +0 -45
  244. package/packages/types.ts +0 -107
  245. package/tooling/check-dist-runtime.mjs +0 -166
  246. package/tooling/generate-index.mjs +0 -55
  247. package/tooling/test-guardrails.mjs +0 -157
  248. package/tooling/validate-boundary.mjs +0 -92
  249. package/tooling/validate-effects.mjs +0 -304
  250. package/tooling/validate.mjs +0 -53
@@ -1,431 +0,0 @@
1
- import { Constants } from '@babylonjs/core/Engines/constants';
2
- import { GlowLayer } from '@babylonjs/core/Layers/glowLayer';
3
- import { Effect } from '@babylonjs/core/Materials/effect';
4
- import { ShaderMaterial } from '@babylonjs/core/Materials/shaderMaterial';
5
- import { Color3 } from '@babylonjs/core/Maths/math.color';
6
- import { Vector3 } from '@babylonjs/core/Maths/math.vector';
7
- import type { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
8
- import { Mesh } from '@babylonjs/core/Meshes/mesh';
9
- import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder';
10
- import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
11
- import type { Scene } from '@babylonjs/core/scene';
12
- import { VFX_RENDERING_GROUP_ID } from '../../rendering';
13
- import type { VfxColorValue, VfxEffectHandle, VfxEffectPackage, VfxParamValues } from '../../types';
14
-
15
- export interface EnergyShieldParams extends VfxParamValues {
16
- radius: number;
17
- verticalScale: number;
18
- color: VfxColorValue;
19
- opacity: number;
20
- fresnelPower: number;
21
- fresnelStrength: number;
22
- rimIntensity: number;
23
- surfaceIntensity: number;
24
- noiseScale: number;
25
- noiseEdgeWidth: number;
26
- noiseEdgeIntensity: number;
27
- noiseEdgeSmoothness: number;
28
- flowScale: number;
29
- flowSpeed: number;
30
- flowIntensity: number;
31
- marbleContrast: number;
32
- bloomIntensity: number;
33
- bloomKernelSize: number;
34
- segments: number;
35
- }
36
-
37
- export interface CreateEnergyShieldOptions {
38
- root?: TransformNode;
39
- target?: TransformNode | AbstractMesh;
40
- position?: Vector3;
41
- params?: Partial<EnergyShieldParams>;
42
- renderingGroupId?: number;
43
- disposeRoot?: boolean;
44
- }
45
-
46
- export interface EnergyShieldHandle extends VfxEffectHandle {
47
- shield: Mesh;
48
- material: ShaderMaterial;
49
- glowLayer: GlowLayer | null;
50
- update(params: Partial<EnergyShieldParams>): void;
51
- }
52
-
53
- const SHADER_NAME = 'vfxEnergyShield';
54
-
55
- const DEFAULT_PARAMS: EnergyShieldParams = {
56
- radius: 3.18,
57
- verticalScale: 1.02,
58
- color: { r: 0.34902, g: 0.568627, b: 0.968627 },
59
- opacity: 0.2,
60
- fresnelPower: 1.8,
61
- fresnelStrength: 0.66,
62
- rimIntensity: 0.4,
63
- surfaceIntensity: 0.3,
64
- noiseScale: 1,
65
- noiseEdgeWidth: 0.1,
66
- noiseEdgeIntensity: 0.42,
67
- noiseEdgeSmoothness: 0.5,
68
- flowScale: 0.36,
69
- flowSpeed: 0.25,
70
- flowIntensity: 1.15,
71
- marbleContrast: 0.67,
72
- bloomIntensity: 0.45,
73
- bloomKernelSize: 36,
74
- segments: 64,
75
- };
76
-
77
- const VERTEX_SHADER = `
78
- precision highp float;
79
-
80
- attribute vec3 position;
81
- attribute vec3 normal;
82
-
83
- uniform mat4 world;
84
- uniform mat4 worldViewProjection;
85
-
86
- varying vec3 vObjPos;
87
- varying vec3 vWorldPos;
88
- varying vec3 vNormalW;
89
-
90
- void main(void) {
91
- vObjPos = position;
92
- vec4 worldPos = world * vec4(position, 1.0);
93
- vWorldPos = worldPos.xyz;
94
- vNormalW = normalize(mat3(world) * normal);
95
- gl_Position = worldViewProjection * vec4(position, 1.0);
96
- }
97
- `;
98
-
99
- const FRAGMENT_SHADER = `
100
- precision highp float;
101
-
102
- uniform float uTime;
103
- uniform vec3 cameraPosition;
104
- uniform vec3 uColor;
105
- uniform float uOpacity;
106
- uniform float uFresnelPower;
107
- uniform float uFresnelStrength;
108
- uniform float uRimIntensity;
109
- uniform float uSurfaceIntensity;
110
- uniform float uNoiseScale;
111
- uniform float uNoiseEdgeWidth;
112
- uniform float uNoiseEdgeIntensity;
113
- uniform float uNoiseEdgeSmoothness;
114
- uniform float uFlowScale;
115
- uniform float uFlowSpeed;
116
- uniform float uFlowIntensity;
117
- uniform float uMarbleContrast;
118
-
119
- varying vec3 vObjPos;
120
- varying vec3 vWorldPos;
121
- varying vec3 vNormalW;
122
-
123
- vec3 mod289v3(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
124
- vec4 mod289v4(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
125
- vec4 permute(vec4 x) { return mod289v4(((x * 34.0) + 1.0) * x); }
126
- vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
127
-
128
- float saturate(float v) { return clamp(v, 0.0, 1.0); }
129
-
130
- float snoise(vec3 v) {
131
- const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
132
- const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
133
- vec3 i = floor(v + dot(v, C.yyy));
134
- vec3 x0 = v - i + dot(i, C.xxx);
135
- vec3 g = step(x0.yzx, x0.xyz);
136
- vec3 l = 1.0 - g;
137
- vec3 i1 = min(g.xyz, l.zxy);
138
- vec3 i2 = max(g.xyz, l.zxy);
139
- vec3 x1 = x0 - i1 + C.xxx;
140
- vec3 x2 = x0 - i2 + C.yyy;
141
- vec3 x3 = x0 - D.yyy;
142
- i = mod289v3(i);
143
- vec4 p = permute(permute(permute(
144
- i.z + vec4(0.0, i1.z, i2.z, 1.0))
145
- + i.y + vec4(0.0, i1.y, i2.y, 1.0))
146
- + i.x + vec4(0.0, i1.x, i2.x, 1.0));
147
- float n_ = 0.142857142857;
148
- vec3 ns = n_ * D.wyz - D.xzx;
149
- vec4 j = p - 49.0 * floor(p * ns.z * ns.z);
150
- vec4 x_ = floor(j * ns.z);
151
- vec4 y_ = floor(j - 7.0 * x_);
152
- vec4 x = x_ * ns.x + ns.yyyy;
153
- vec4 y = y_ * ns.x + ns.yyyy;
154
- vec4 h = 1.0 - abs(x) - abs(y);
155
- vec4 b0 = vec4(x.xy, y.xy);
156
- vec4 b1 = vec4(x.zw, y.zw);
157
- vec4 s0 = floor(b0) * 2.0 + 1.0;
158
- vec4 s1 = floor(b1) * 2.0 + 1.0;
159
- vec4 sh = -step(h, vec4(0.0));
160
- vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
161
- vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
162
- vec3 p0 = vec3(a0.xy, h.x);
163
- vec3 p1 = vec3(a0.zw, h.y);
164
- vec3 p2 = vec3(a1.xy, h.z);
165
- vec3 p3 = vec3(a1.zw, h.w);
166
- vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
167
- p0 *= norm.x;
168
- p1 *= norm.y;
169
- p2 *= norm.z;
170
- p3 *= norm.w;
171
- vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
172
- m = m * m;
173
- return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
174
- }
175
-
176
- float fbm(vec3 p) {
177
- float total = 0.0;
178
- float amp = 0.55;
179
- total += snoise(p) * amp;
180
- p = p * 2.03 + vec3(17.1, 3.7, 9.2);
181
- amp *= 0.52;
182
- total += snoise(p) * amp;
183
- p = p * 2.11 + vec3(4.3, 13.9, 6.4);
184
- amp *= 0.5;
185
- total += snoise(p) * amp;
186
- return total;
187
- }
188
-
189
- void main(void) {
190
- vec3 normalW = normalize(vNormalW);
191
- vec3 viewDir = normalize(cameraPosition - vWorldPos);
192
- float ndv = saturate(dot(normalW, viewDir));
193
- float fresnel = pow(1.0 - ndv, max(0.05, uFresnelPower)) * uFresnelStrength;
194
-
195
- float t = uTime * uFlowSpeed;
196
- vec3 spherePos = normalize(vObjPos + vec3(0.0001)) * max(0.05, uNoiseScale);
197
- vec3 flowA = spherePos * uFlowScale + vec3(t, t * 0.62, t * 0.38);
198
- vec3 flowB = spherePos * (uFlowScale * 1.91) + vec3(-t * 0.46, t * 0.82, -t * 0.27);
199
- float n1 = fbm(flowA);
200
- float n2 = fbm(flowB);
201
- float cloud = saturate((n1 * 0.58 + n2 * 0.42) * 0.5 + 0.5);
202
-
203
- float veinInput = spherePos.y * 0.92 + n1 * 1.65 + n2 * 0.74 + t * 0.13;
204
- float ribbon = abs(sin(veinInput * 3.14159265));
205
- float marble = pow(1.0 - ribbon, max(0.25, uMarbleContrast));
206
- float nebula = saturate(mix(cloud, marble, 0.58) * uFlowIntensity * 0.34);
207
-
208
- float edgeWidth = max(0.01, uNoiseEdgeWidth);
209
- float edgeSoft = max(0.01, uNoiseEdgeSmoothness) * 0.22;
210
- float noiseEdge = smoothstep(1.0 - edgeWidth - edgeSoft, 1.0 - edgeWidth * 0.22, nebula);
211
-
212
- vec3 deepBlue = uColor * (0.12 + 0.42 * cloud);
213
- vec3 marbleBlue = uColor * (0.34 + 0.9 * marble) * uSurfaceIntensity;
214
- vec3 rimBlue = uColor * fresnel * uRimIntensity;
215
- vec3 edgeBlue = uColor * noiseEdge * uNoiseEdgeIntensity;
216
- vec3 color = min((deepBlue + marbleBlue + rimBlue + edgeBlue) * 0.72, vec3(1.12));
217
-
218
- float alpha = uOpacity * (0.16 + 0.34 * cloud + 0.24 * marble);
219
- alpha += fresnel * uOpacity * 0.58;
220
- alpha += noiseEdge * uNoiseEdgeIntensity * 0.05;
221
-
222
- gl_FragColor = vec4(color, saturate(alpha));
223
- }
224
- `;
225
-
226
- export const energyShieldEffectPackage: VfxEffectPackage<EnergyShieldParams> = {
227
- id: 'energy-shield',
228
- nameZh: '半球玻璃罩',
229
- defaultParams: DEFAULT_PARAMS,
230
- debugAnchor: 'player',
231
- manifest: {
232
- id: 'energy-shield',
233
- nameZh: '半球玻璃罩',
234
- source: 'https://github.com/cortiz2894/flow-shield-effect',
235
- },
236
- debugParams: [
237
- { key: 'radius', label: '玻璃罩半径', kind: 'scale', min: 0.4, max: 10, step: 0.01 },
238
- { key: 'verticalScale', label: '纵向缩放', kind: 'scale', min: 0.5, max: 1.8, step: 0.01 },
239
- { key: 'color', label: '主体颜色', kind: 'color' },
240
- { key: 'opacity', label: '透明度', kind: 'opacity', min: 0.02, max: 1, step: 0.01 },
241
- { key: 'fresnelPower', label: '边缘曲线', kind: 'number', min: 0.2, max: 6, step: 0.01 },
242
- { key: 'fresnelStrength', label: '边缘强度', kind: 'number', min: 0, max: 6, step: 0.01 },
243
- { key: 'rimIntensity', label: '轮廓亮度', kind: 'number', min: 0, max: 4, step: 0.01 },
244
- { key: 'surfaceIntensity', label: '表面亮度', kind: 'number', min: 0, max: 3, step: 0.01 },
245
- { key: 'noiseScale', label: '噪声缩放', kind: 'number', min: 0.2, max: 5, step: 0.01 },
246
- { key: 'noiseEdgeWidth', label: '噪声亮边宽度', kind: 'number', min: 0.01, max: 0.5, step: 0.01 },
247
- { key: 'noiseEdgeIntensity', label: '噪声亮边强度', kind: 'number', min: 0, max: 4, step: 0.01 },
248
- { key: 'noiseEdgeSmoothness', label: '噪声亮边柔和度', kind: 'number', min: 0.02, max: 1, step: 0.01 },
249
- { key: 'flowScale', label: '纹路密度', kind: 'number', min: 0, max: 3, step: 0.01 },
250
- { key: 'flowSpeed', label: '流动速度', kind: 'number', min: 0, max: 5, step: 0.01 },
251
- { key: 'flowIntensity', label: '流动强度', kind: 'number', min: 0, max: 8, step: 0.01 },
252
- { key: 'marbleContrast', label: '纹路锐度', kind: 'number', min: 0.25, max: 4, step: 0.01 },
253
- { key: 'bloomIntensity', label: 'Bloom 强度', kind: 'number', min: 0, max: 4, step: 0.01 },
254
- { key: 'bloomKernelSize', label: 'Bloom 半径', kind: 'number', min: 8, max: 128, step: 1 },
255
- ],
256
- create({ scene, root, position, renderingGroupId, params }) {
257
- return createEnergyShield(scene, { root, position, renderingGroupId, params });
258
- },
259
- };
260
-
261
- export default energyShieldEffectPackage;
262
-
263
- export function createEnergyShield(scene: Scene, options: CreateEnergyShieldOptions = {}): EnergyShieldHandle {
264
- registerShaders();
265
-
266
- let params = mergeParams(options.params);
267
- const root = options.root ?? new TransformNode('vfx_energyShield_root', scene);
268
- const disposeRoot = options.disposeRoot ?? true;
269
- if (options.target) {
270
- root.parent = options.target;
271
- root.position.set(0, 0, 0);
272
- } else {
273
- root.position.copyFrom(options.position ?? Vector3.ZeroReadOnly);
274
- }
275
-
276
- const shield = MeshBuilder.CreateSphere(
277
- 'vfx_energyShield_hemisphere',
278
- {
279
- diameter: 2,
280
- segments: Math.max(16, Math.round(params.segments)),
281
- slice: 0.5,
282
- updatable: false,
283
- },
284
- scene,
285
- );
286
- shield.parent = root;
287
- shield.isPickable = false;
288
- shield.alwaysSelectAsActiveMesh = true;
289
- shield.renderingGroupId = options.renderingGroupId ?? VFX_RENDERING_GROUP_ID;
290
- shield.alphaIndex = 20;
291
-
292
- const material = createShieldMaterial(scene);
293
- shield.material = material;
294
-
295
- let glowLayer: GlowLayer | null = null;
296
- if (params.bloomIntensity > 0) {
297
- glowLayer = new GlowLayer(`vfx_energyShield_glow_${shield.uniqueId}`, scene, {
298
- blurKernelSize: params.bloomKernelSize,
299
- mainTextureRatio: 0.35,
300
- });
301
- glowLayer.intensity = params.bloomIntensity;
302
- glowLayer.addIncludedOnlyMesh(shield);
303
- glowLayer.referenceMeshToUseItsOwnMaterial(shield);
304
- }
305
-
306
- applyParams(material, shield, glowLayer, params);
307
-
308
- let elapsed = 0;
309
- const observer = scene.onBeforeRenderObservable.add(() => {
310
- elapsed += Math.min(scene.getEngine().getDeltaTime() / 1000, 0.05);
311
- material.setFloat('uTime', elapsed);
312
- });
313
-
314
- let disposed = false;
315
- const dispose = (): void => {
316
- if (disposed) return;
317
- disposed = true;
318
- scene.onBeforeRenderObservable.remove(observer);
319
- glowLayer?.dispose();
320
- shield.dispose(false, false);
321
- material.dispose();
322
- if (disposeRoot) root.dispose();
323
- };
324
-
325
- return {
326
- root,
327
- shield,
328
- material,
329
- glowLayer,
330
- update(partial: Partial<EnergyShieldParams>) {
331
- params = mergeParams(partial, params);
332
- applyParams(material, shield, glowLayer, params);
333
- if (!glowLayer && params.bloomIntensity > 0) {
334
- glowLayer = new GlowLayer(`vfx_energyShield_glow_${shield.uniqueId}`, scene, {
335
- blurKernelSize: params.bloomKernelSize,
336
- mainTextureRatio: 0.35,
337
- });
338
- glowLayer.addIncludedOnlyMesh(shield);
339
- glowLayer.referenceMeshToUseItsOwnMaterial(shield);
340
- glowLayer.intensity = params.bloomIntensity;
341
- applyParams(material, shield, glowLayer, params);
342
- this.glowLayer = glowLayer;
343
- }
344
- },
345
- dispose,
346
- };
347
- }
348
-
349
- function createShieldMaterial(scene: Scene): ShaderMaterial {
350
- const material = new ShaderMaterial(
351
- 'vfx_energyShield_material',
352
- scene,
353
- { vertex: SHADER_NAME, fragment: SHADER_NAME },
354
- {
355
- attributes: ['position', 'normal'],
356
- uniforms: [
357
- 'world',
358
- 'worldViewProjection',
359
- 'cameraPosition',
360
- 'uTime',
361
- 'uColor',
362
- 'uOpacity',
363
- 'uFresnelPower',
364
- 'uFresnelStrength',
365
- 'uRimIntensity',
366
- 'uSurfaceIntensity',
367
- 'uNoiseScale',
368
- 'uNoiseEdgeWidth',
369
- 'uNoiseEdgeIntensity',
370
- 'uNoiseEdgeSmoothness',
371
- 'uFlowScale',
372
- 'uFlowSpeed',
373
- 'uFlowIntensity',
374
- 'uMarbleContrast',
375
- ],
376
- needAlphaBlending: true,
377
- },
378
- );
379
- material.alphaMode = Constants.ALPHA_COMBINE;
380
- material.backFaceCulling = false;
381
- material.disableDepthWrite = true;
382
- material.fogEnabled = false;
383
- return material;
384
- }
385
-
386
- function applyParams(
387
- material: ShaderMaterial,
388
- shield: Mesh,
389
- glowLayer: GlowLayer | null,
390
- params: EnergyShieldParams,
391
- ): void {
392
- shield.scaling.set(params.radius, params.radius * params.verticalScale, params.radius);
393
- material.setColor3('uColor', toColor3(params.color));
394
- material.setFloat('uOpacity', params.opacity);
395
- material.setFloat('uFresnelPower', params.fresnelPower);
396
- material.setFloat('uFresnelStrength', params.fresnelStrength);
397
- material.setFloat('uRimIntensity', params.rimIntensity);
398
- material.setFloat('uSurfaceIntensity', params.surfaceIntensity);
399
- material.setFloat('uNoiseScale', params.noiseScale);
400
- material.setFloat('uNoiseEdgeWidth', params.noiseEdgeWidth);
401
- material.setFloat('uNoiseEdgeIntensity', params.noiseEdgeIntensity);
402
- material.setFloat('uNoiseEdgeSmoothness', params.noiseEdgeSmoothness);
403
- material.setFloat('uFlowScale', params.flowScale);
404
- material.setFloat('uFlowSpeed', params.flowSpeed);
405
- material.setFloat('uFlowIntensity', params.flowIntensity);
406
- material.setFloat('uMarbleContrast', params.marbleContrast);
407
- if (glowLayer) {
408
- glowLayer.intensity = params.bloomIntensity;
409
- glowLayer.blurKernelSize = params.bloomKernelSize;
410
- }
411
- }
412
-
413
- function mergeParams(
414
- patch: Partial<EnergyShieldParams> | undefined,
415
- base: EnergyShieldParams = DEFAULT_PARAMS,
416
- ): EnergyShieldParams {
417
- return {
418
- ...base,
419
- ...patch,
420
- color: patch?.color ? { ...patch.color } : { ...base.color },
421
- };
422
- }
423
-
424
- function toColor3(color: VfxColorValue): Color3 {
425
- return new Color3(color.r, color.g, color.b);
426
- }
427
-
428
- function registerShaders(): void {
429
- Effect.ShadersStore[`${SHADER_NAME}VertexShader`] = VERTEX_SHADER;
430
- Effect.ShadersStore[`${SHADER_NAME}FragmentShader`] = FRAGMENT_SHADER;
431
- }
@@ -1,114 +0,0 @@
1
- // 爆炸(组合:闪光/光晕 #6 + 序列帧火花 #7 + 火花点 #9)。一次性爆点,参数分三段独立调。
2
- // 闪光段:2 billboard 面片 sqrt 缩放+淡出;序列帧段:5x5 火花 ADD;火花点段:lizi ADD 下落火星。
3
- import { Mesh } from '@babylonjs/core/Meshes/mesh';
4
- import { CreatePlane } from '@babylonjs/core/Meshes/Builders/planeBuilder';
5
- import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
6
- import { Texture } from '@babylonjs/core/Materials/Textures/texture';
7
- import { ParticleSystem } from '@babylonjs/core/Particles/particleSystem';
8
- import { Color3, Color4 } from '@babylonjs/core/Maths/math.color';
9
- import { Vector3 } from '@babylonjs/core/Maths/math.vector';
10
- import { Constants } from '@babylonjs/core/Engines/constants';
11
- import type { Scene } from '@babylonjs/core/scene';
12
- import type { Observer } from '@babylonjs/core/Misc/observable';
13
- import type { VfxEffectPackage, VfxParamValues } from '../../types';
14
- import { makeBurstPS } from '../space-shared';
15
- import baozhaUrl from './assets/textures/baozha29.webp?url';
16
- import glowUrl from './assets/textures/glow01.webp?url';
17
- import bombUrl from './assets/textures/xulie_lizibaozha02_5x5.webp?url';
18
- import liziUrl from './assets/textures/lizi01.webp?url';
19
-
20
- interface ExplosionParams extends VfxParamValues {
21
- // 段1 闪光/光晕
22
- flashRadius: number; flashBrightness: number;
23
- // 段2 序列帧火花
24
- sparksCount: number; sparksSize: number;
25
- // 段3 火花点
26
- embersCount: number; embersPower: number;
27
- }
28
-
29
- const DEFAULT_PARAMS: ExplosionParams = {
30
- flashRadius: 1.8, flashBrightness: 1.0,
31
- sparksCount: 4, sparksSize: 1,
32
- embersCount: 24, embersPower: 14,
33
- };
34
-
35
- interface Flash { mesh: Mesh; mat: StandardMaterial; from: number; to: number; life: number; maxLife: number; }
36
-
37
- export const explosionEffectPackage: VfxEffectPackage<ExplosionParams> = {
38
- id: 'explosion',
39
- nameZh: '爆炸',
40
- debugAnchor: 'playerRight',
41
- defaultParams: DEFAULT_PARAMS,
42
- debugParams: [
43
- // 段1 · 闪光/光晕
44
- { key: 'flashRadius', label: '闪光·半径', kind: 'scale', min: 0.5, max: 5, step: 0.1 },
45
- { key: 'flashBrightness', label: '闪光·亮度', kind: 'number', min: 0.2, max: 3, step: 0.05 },
46
- // 段2 · 序列帧火花
47
- { key: 'sparksCount', label: '序列帧·数量', kind: 'number', min: 0, max: 30, step: 1 },
48
- { key: 'sparksSize', label: '序列帧·尺寸', kind: 'scale', min: 0.2, max: 3, step: 0.05 },
49
- // 段3 · 火花点
50
- { key: 'embersCount', label: '火花点·数量', kind: 'number', min: 0, max: 80, step: 1 },
51
- { key: 'embersPower', label: '火花点·速度', kind: 'number', min: 2, max: 30, step: 0.5 },
52
- ],
53
-
54
- create({ scene, root, position, params }) {
55
- root.position.copyFrom(position);
56
-
57
- // ── 段1 闪光/光晕 ──────────────────────────────────────────────────────────
58
- const r = params.flashRadius, b = params.flashBrightness;
59
- const flashes: Flash[] = [];
60
- function flashPlane(url: string, from: number, to: number, maxLife: number, color: Color3, alphaFromRGB: boolean): void {
61
- const m = CreatePlane('vfx_exp_flash', { size: 1 }, scene);
62
- m.billboardMode = Mesh.BILLBOARDMODE_ALL; m.position.copyFrom(position); m.isPickable = false;
63
- const tex = new Texture(url, scene); tex.hasAlpha = true; if (alphaFromRGB) tex.getAlphaFromRGB = true;
64
- const mat = new StandardMaterial('vfx_exp_flashMat', scene);
65
- mat.emissiveTexture = tex; mat.opacityTexture = tex; mat.emissiveColor = color.scale(b);
66
- mat.disableLighting = true; mat.alphaMode = Constants.ALPHA_ADD;
67
- m.material = mat; m.scaling.setAll(from);
68
- flashes.push({ mesh: m, mat, from, to, life: 0, maxLife });
69
- }
70
- flashPlane(baozhaUrl, r * 1.5, r * 5.2, 0.4, new Color3(1.6, 1.2, 0.8), true);
71
- flashPlane(glowUrl, r * 2, r * 7, 0.3, new Color3(1.2, 0.75, 0.35), false);
72
-
73
- // ── 段2 序列帧火花 ─────────────────────────────────────────────────────────
74
- const sparksPs = makeBurstPS('vfx_exp_sparks', scene, bombUrl, {
75
- cap: 120, sheet: [75, 75, 25], size: [4.5, 7], life: [0.55, 0.7], power: [0, 0.6], gravity: new Vector3(0, 0, 0),
76
- blend: ParticleSystem.BLENDMODE_ADD, c1: new Color4(1, 0.95, 0.85, 1), c2: new Color4(1, 0.8, 0.55, 1), cd: new Color4(1, 0.5, 0.2, 0),
77
- });
78
- sparksPs.minSize *= params.sparksSize; sparksPs.maxSize *= params.sparksSize;
79
- (sparksPs.emitter as Vector3).copyFrom(position);
80
- sparksPs.manualEmitCount += Math.round(params.sparksCount);
81
-
82
- // ── 段3 火花点 ─────────────────────────────────────────────────────────────
83
- const embersPs = makeBurstPS('vfx_exp_embers', scene, liziUrl, {
84
- cap: 120, size: [0.25, 0.7], life: [0.3, 0.8], power: [params.embersPower * 0.43, params.embersPower], gravity: new Vector3(0, -9, 0),
85
- blend: ParticleSystem.BLENDMODE_ADD, c1: new Color4(1, 0.85, 0.5, 1), c2: new Color4(1, 0.6, 0.25, 1), cd: new Color4(0.8, 0.3, 0.1, 0),
86
- });
87
- (embersPs.emitter as Vector3).copyFrom(position);
88
- embersPs.manualEmitCount += Math.round(params.embersCount);
89
-
90
- // 闪光 tween 每帧
91
- const observer = scene.onBeforeRenderObservable.add(() => {
92
- const dt = Math.min(scene.getEngine().getDeltaTime() / 1000, 0.05);
93
- for (let i = flashes.length - 1; i >= 0; i--) {
94
- const f = flashes[i]; f.life += dt; const k = Math.min(1, f.life / f.maxLife);
95
- f.mesh.scaling.setAll(f.from + (f.to - f.from) * Math.sqrt(k));
96
- f.mat.alpha = 1 - k;
97
- if (k >= 1) { f.mesh.dispose(); f.mat.dispose(); flashes.splice(i, 1); }
98
- }
99
- });
100
-
101
- let disposed = false;
102
- const disposeTimer = window.setTimeout(() => disposeAll(), 1400);
103
- function disposeAll(): void {
104
- if (disposed) return; disposed = true;
105
- window.clearTimeout(disposeTimer);
106
- scene.onBeforeRenderObservable.remove(observer as Observer<Scene>);
107
- for (const f of flashes) { f.mesh.dispose(); f.mat.dispose(); }
108
- flashes.length = 0;
109
- sparksPs.dispose(); embersPs.dispose();
110
- root.dispose();
111
- }
112
- return { root, dispose() { disposeAll(); } };
113
- },
114
- };
@@ -1,6 +0,0 @@
1
- {
2
- "id": "ground-tile-upgrade",
3
- "nameZh": "地块升级光效",
4
- "source": "runtime-generated",
5
- "assets": []
6
- }