@fps-games/vfx 0.3.2 → 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 (231) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +5 -4
  3. package/tooling/vfx-cli.mjs +8 -1
  4. package/docs/AUTHORING_EFFECTS.md +0 -297
  5. package/docs/INTEGRATION.md +0 -194
  6. package/docs/VFX_LIBRARY_ARCHITECTURE_chatgpt.md +0 -1580
  7. package/docs/VFX_LIBRARY_EXECUTION_PLAN.md +0 -229
  8. package/docs/VFX_LIBRARY_PLAN.md +0 -546
  9. package/docs/hit-flash-red-method.md +0 -155
  10. package/docs/treasure_attention_fx_babylonjs_guide.md +0 -901
  11. package/docs/vfx-ab/RESULTS.md +0 -35
  12. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/after.png +0 -0
  13. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/before.png +0 -0
  14. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/after.png +0 -0
  15. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/before.png +0 -0
  16. package/docs/vfx-integration_chatgpt.md +0 -462
  17. package/docs/vfx-placement-design.md +0 -164
  18. package/docs/weapon-trail-visualization.html +0 -241
  19. package/packages/EffectPackageService.ts +0 -346
  20. package/packages/SceneVfxService.ts +0 -96
  21. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/runtime/simpleMeshEffect.v1.js +0 -333
  22. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.frag.glsl +0 -25
  23. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.vert.glsl +0 -11
  24. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/textures/effect_jianbian.png +0 -0
  25. package/packages/build.mesh.yellow_build_upgrade_indicator/effect.json +0 -927
  26. package/packages/build.mesh.yellow_build_upgrade_indicator/media/contact-sheet.png +0 -0
  27. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.gif +0 -0
  28. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.mp4 +0 -0
  29. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.webm +0 -0
  30. package/packages/build.mesh.yellow_build_upgrade_indicator/media/thumbnail.png +0 -0
  31. package/packages/build.mesh.yellow_build_upgrade_indicator/metadata/description.json +0 -197
  32. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-effect.original.json +0 -895
  33. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-normalized-vfx-to-babylon-report.json +0 -241
  34. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-overrides.json +0 -542
  35. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-tuning-report.json +0 -69
  36. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/asset-map.json +0 -125
  37. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/lineage.json +0 -44
  38. package/packages/build.particle.golden_upgrade_starburst/assets/runtime/particleEmitter.v1.js +0 -210
  39. package/packages/build.particle.golden_upgrade_starburst/assets/textures/effect_guangdian.png +0 -0
  40. package/packages/build.particle.golden_upgrade_starburst/effect.json +0 -880
  41. package/packages/build.particle.golden_upgrade_starburst/media/contact-sheet.png +0 -0
  42. package/packages/build.particle.golden_upgrade_starburst/media/preview.gif +0 -0
  43. package/packages/build.particle.golden_upgrade_starburst/media/preview.mp4 +0 -0
  44. package/packages/build.particle.golden_upgrade_starburst/media/preview.webm +0 -0
  45. package/packages/build.particle.golden_upgrade_starburst/media/thumbnail.png +0 -0
  46. package/packages/build.particle.golden_upgrade_starburst/metadata/description.json +0 -161
  47. package/packages/build.particle.golden_upgrade_starburst/provenance/03-effect.original.json +0 -762
  48. package/packages/build.particle.golden_upgrade_starburst/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  49. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-overrides.json +0 -436
  50. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-tuning-report.json +0 -40
  51. package/packages/build.particle.golden_upgrade_starburst/provenance/asset-map.json +0 -115
  52. package/packages/build.particle.golden_upgrade_starburst/provenance/lineage.json +0 -40
  53. package/packages/build.particle.orange_upgrade_transform_sparks/assets/runtime/particleEmitter.v1.js +0 -210
  54. package/packages/build.particle.orange_upgrade_transform_sparks/assets/textures/b5b27ab1-e740-4398-b407-848fc2b2c897.png +0 -0
  55. package/packages/build.particle.orange_upgrade_transform_sparks/effect.json +0 -887
  56. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.gif +0 -0
  57. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.mp4 +0 -0
  58. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.webm +0 -0
  59. package/packages/build.particle.orange_upgrade_transform_sparks/media/thumbnail.png +0 -0
  60. package/packages/build.particle.orange_upgrade_transform_sparks/metadata/description.json +0 -179
  61. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-effect.original.json +0 -859
  62. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  63. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-overrides.json +0 -478
  64. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-tuning-report.json +0 -40
  65. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/asset-map.json +0 -114
  66. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/lineage.json +0 -41
  67. package/packages/build.particle.wood_chip_dust_burst/assets/runtime/particleEmitter.v1.js +0 -210
  68. package/packages/build.particle.wood_chip_dust_burst/assets/textures/effect_yanwu4.png +0 -0
  69. package/packages/build.particle.wood_chip_dust_burst/assets/textures/suipian3.png +0 -0
  70. package/packages/build.particle.wood_chip_dust_burst/effect.json +0 -1400
  71. package/packages/build.particle.wood_chip_dust_burst/media/contact-sheet.png +0 -0
  72. package/packages/build.particle.wood_chip_dust_burst/media/preview.gif +0 -0
  73. package/packages/build.particle.wood_chip_dust_burst/media/preview.mp4 +0 -0
  74. package/packages/build.particle.wood_chip_dust_burst/media/preview.webm +0 -0
  75. package/packages/build.particle.wood_chip_dust_burst/media/thumbnail.png +0 -0
  76. package/packages/build.particle.wood_chip_dust_burst/metadata/description.json +0 -173
  77. package/packages/build.particle.wood_chip_dust_burst/provenance/03-effect.original.json +0 -1277
  78. package/packages/build.particle.wood_chip_dust_burst/provenance/03-normalized-vfx-to-babylon-report.json +0 -329
  79. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-overrides.json +0 -749
  80. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-tuning-report.json +0 -60
  81. package/packages/build.particle.wood_chip_dust_burst/provenance/asset-map.json +0 -146
  82. package/packages/build.particle.wood_chip_dust_burst/provenance/lineage.json +0 -69
  83. package/packages/effects/building-upgrade/effect.json +0 -6
  84. package/packages/effects/building-upgrade/index.ts +0 -387
  85. package/packages/effects/character-entrance/effect.json +0 -6
  86. package/packages/effects/character-entrance/index.ts +0 -308
  87. package/packages/effects/coin-burst/index.ts +0 -48
  88. package/packages/effects/comet-trail-flame/assets/textures/trail_5x4.webp +0 -0
  89. package/packages/effects/comet-trail-flame/index.ts +0 -107
  90. package/packages/effects/conveyor-upgrade/effect.json +0 -6
  91. package/packages/effects/conveyor-upgrade/index.ts +0 -401
  92. package/packages/effects/debris-smoke/assets/models/rock_debris.glb +0 -0
  93. package/packages/effects/debris-smoke/assets/textures/smoke22.webp +0 -0
  94. package/packages/effects/debris-smoke/index.ts +0 -102
  95. package/packages/effects/door_open_gold_flakes/assets/runtime/goldFlakes.v1.js +0 -397
  96. package/packages/effects/door_open_gold_flakes/door_open_gold_flakes.json +0 -498
  97. package/packages/effects/door_open_gold_flakes/index.ts +0 -11
  98. package/packages/effects/electric-arc/assets/textures/spark_4x4.webp +0 -0
  99. package/packages/effects/electric-arc/index.ts +0 -63
  100. package/packages/effects/energy-shield/effect.json +0 -7
  101. package/packages/effects/energy-shield/index.ts +0 -432
  102. package/packages/effects/explosion/assets/textures/baozha29.webp +0 -0
  103. package/packages/effects/explosion/assets/textures/glow01.webp +0 -0
  104. package/packages/effects/explosion/assets/textures/lizi01.webp +0 -0
  105. package/packages/effects/explosion/assets/textures/xulie_lizibaozha02_5x5.webp +0 -0
  106. package/packages/effects/explosion/index.ts +0 -115
  107. package/packages/effects/ground-tile-upgrade/effect.json +0 -6
  108. package/packages/effects/ground-tile-upgrade/index.ts +0 -410
  109. package/packages/effects/hit-flash/index.ts +0 -77
  110. package/packages/effects/laser-beam/assets/textures/laser_glow.webp +0 -0
  111. package/packages/effects/laser-beam/assets/textures/laser_noise.webp +0 -0
  112. package/packages/effects/laser-beam/index.ts +0 -6
  113. package/packages/effects/laser-beam-factory.ts +0 -146
  114. package/packages/effects/lumber-cart-suction/effect.json +0 -6
  115. package/packages/effects/lumber-cart-suction/index.ts +0 -399
  116. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb +0 -0
  117. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/.active +0 -1
  118. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/1781589063890_upload.glb +0 -0
  119. package/packages/effects/lumber-debris-scatter/assets/runtime/solidParticleScatter.v1.js +0 -236
  120. package/packages/effects/lumber-debris-scatter/effect.json +0 -228
  121. package/packages/effects/lumber-debris-scatter/index.ts +0 -780
  122. package/packages/effects/lumber_vehicle_gear_spin/assets/runtime/gearSpin.v1.js +0 -202
  123. package/packages/effects/lumber_vehicle_gear_spin/index.ts +0 -11
  124. package/packages/effects/lumber_vehicle_gear_spin/lumber_vehicle_gear_spin.json +0 -338
  125. package/packages/effects/lumber_vehicle_upgrade_aura/assets/runtime/upgradeAura.v1.js +0 -353
  126. package/packages/effects/lumber_vehicle_upgrade_aura/index.ts +0 -13
  127. package/packages/effects/lumber_vehicle_upgrade_aura/lumber_vehicle_upgrade_aura.json +0 -365
  128. package/packages/effects/lumber_vehicle_wood_chips/assets/runtime/solidParticleScatter.v1.js +0 -310
  129. package/packages/effects/lumber_vehicle_wood_chips/index.ts +0 -11
  130. package/packages/effects/lumber_vehicle_wood_chips/lumber_vehicle_wood_chips.json +0 -335
  131. package/packages/effects/monster-hit/index.ts +0 -129
  132. package/packages/effects/player-upgrade/effect.json +0 -6
  133. package/packages/effects/player-upgrade/index.ts +0 -640
  134. package/packages/effects/pulse-laser-volley/assets/textures/bolt_guangshu.webp +0 -0
  135. package/packages/effects/pulse-laser-volley/index.ts +0 -215
  136. package/packages/effects/resource-collect-sparkles/effect.json +0 -6
  137. package/packages/effects/resource-collect-sparkles/index.ts +0 -254
  138. package/packages/effects/run-footstep-dust/assets/runtime/runFootstepDust.v1.js +0 -215
  139. package/packages/effects/run-footstep-dust/effect.json +0 -183
  140. package/packages/effects/run-footstep-dust/index.ts +0 -377
  141. package/packages/effects/space-shared.ts +0 -120
  142. package/packages/effects/thruster-flame/index.ts +0 -306
  143. package/packages/effects/treasure-attention/effect.json +0 -7
  144. package/packages/effects/treasure-attention/index.ts +0 -630
  145. package/packages/effects/tree-chop-dust/assets/textures/tree_chop_dust_atlas.png +0 -0
  146. package/packages/effects/tree-chop-dust/effect.json +0 -8
  147. package/packages/effects/tree-chop-dust/index.ts +0 -202
  148. package/packages/effects/tree-leaf-chop-burst/assets/runtime/particleEmitter.v1.js +0 -303
  149. package/packages/effects/tree-leaf-chop-burst/assets/textures/tree_leaf_chop_burst_leaf_atlas.png +0 -0
  150. package/packages/effects/tree-leaf-chop-burst/effect.json +0 -498
  151. package/packages/effects/tree-leaf-chop-burst/index.ts +0 -294
  152. package/packages/effects/tree_chop_dust_burst/assets/runtime/particleEmitter.v1.js +0 -318
  153. package/packages/effects/tree_chop_dust_burst/assets/textures/tree_chop_dust_burst_dust.png +0 -0
  154. package/packages/effects/tree_chop_dust_burst/index.ts +0 -13
  155. package/packages/effects/tree_chop_dust_burst/tree_chop_dust_burst.json +0 -412
  156. package/packages/effects/ufo-thread-flame/assets/textures/flame_flow.webp +0 -0
  157. package/packages/effects/ufo-thread-flame/assets/textures/flame_spike.webp +0 -0
  158. package/packages/effects/ufo-thread-flame/index.ts +0 -153
  159. package/packages/effects/vehicle-exhaust-smoke/assets/textures/vehicle_exhaust_smoke_atlas.png +0 -0
  160. package/packages/effects/vehicle-exhaust-smoke/effect.json +0 -8
  161. package/packages/effects/vehicle-exhaust-smoke/index.ts +0 -298
  162. package/packages/effects/vehicle-upgrade/effect.json +0 -6
  163. package/packages/effects/vehicle-upgrade/index.ts +0 -404
  164. package/packages/effects/weapon-trail/assets/textures/trail_wedge.png +0 -0
  165. package/packages/effects/weapon-trail/index.ts +0 -317
  166. package/packages/effects/wood-crusher-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  167. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  168. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  169. package/packages/effects/wood-crusher-sawdust/index.ts +0 -43
  170. package/packages/effects/wood-crusher-sawdust/wood_crusher_sawdust.json +0 -592
  171. package/packages/effects/wood-cutter-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  172. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  173. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  174. package/packages/effects/wood-cutter-sawdust/index.ts +0 -43
  175. package/packages/effects/wood-cutter-sawdust/wood_cutter_sawdust.json +0 -592
  176. package/packages/effects/wood-sawdust-effect-factory.ts +0 -194
  177. package/packages/effects/wood_crusher_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  178. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  179. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  180. package/packages/effects/wood_crusher_sawdust/index.ts +0 -29
  181. package/packages/effects/wood_crusher_sawdust/wood_crusher_sawdust.json +0 -592
  182. package/packages/effects/wood_cutter_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  183. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  184. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  185. package/packages/effects/wood_cutter_sawdust/index.ts +0 -29
  186. package/packages/effects/wood_cutter_sawdust/wood_cutter_sawdust.json +0 -592
  187. package/packages/effects/wood_peel_material_test/assets/runtime/woodPeelMaterialTest.v1.js +0 -196
  188. package/packages/effects/wood_peel_material_test/index.ts +0 -11
  189. package/packages/effects/wood_peel_material_test/wood_peel_material_test.json +0 -136
  190. package/packages/env.particle.forest_edge_fog/assets/runtime/particleEmitter.v1.js +0 -210
  191. package/packages/env.particle.forest_edge_fog/assets/textures/f12a23c4-b924-4322-a260-3d982428f1e8.png +0 -0
  192. package/packages/env.particle.forest_edge_fog/assets/textures/yuan.png +0 -0
  193. package/packages/env.particle.forest_edge_fog/effect.json +0 -854
  194. package/packages/env.particle.forest_edge_fog/media/preview.gif +0 -0
  195. package/packages/env.particle.forest_edge_fog/media/preview.mp4 +0 -0
  196. package/packages/env.particle.forest_edge_fog/media/preview.webm +0 -0
  197. package/packages/env.particle.forest_edge_fog/media/thumbnail.png +0 -0
  198. package/packages/env.particle.forest_edge_fog/metadata/description.json +0 -148
  199. package/packages/env.particle.forest_edge_fog/provenance/03-effect.original.json +0 -827
  200. package/packages/env.particle.forest_edge_fog/provenance/03-normalized-vfx-to-babylon-report.json +0 -196
  201. package/packages/env.particle.forest_edge_fog/provenance/04-preview-overrides.json +0 -432
  202. package/packages/env.particle.forest_edge_fog/provenance/04-preview-tuning-report.json +0 -28
  203. package/packages/env.particle.forest_edge_fog/provenance/asset-map.json +0 -124
  204. package/packages/env.particle.forest_edge_fog/provenance/lineage.json +0 -41
  205. package/packages/generation.ts +0 -14
  206. package/packages/index.ts +0 -14
  207. package/packages/legacy-particle-runtime.ts +0 -113
  208. package/packages/manifestRuntimePackage.ts +0 -519
  209. package/packages/registry.ts +0 -85
  210. package/packages/rendering.ts +0 -13
  211. package/packages/resource.particle.viscous_oil_suction/assets/runtime/top_disk_suction/particleEmitter.v1.js +0 -424
  212. package/packages/resource.particle.viscous_oil_suction/assets/textures/Glow ad.png +0 -0
  213. package/packages/resource.particle.viscous_oil_suction/effect.json +0 -1254
  214. package/packages/resource.particle.viscous_oil_suction/media/preview.gif +0 -0
  215. package/packages/resource.particle.viscous_oil_suction/media/preview.mp4 +0 -0
  216. package/packages/resource.particle.viscous_oil_suction/media/preview.webm +0 -0
  217. package/packages/resource.particle.viscous_oil_suction/media/thumbnail.png +0 -0
  218. package/packages/resource.particle.viscous_oil_suction/metadata/description.json +0 -122
  219. package/packages/resource.particle.viscous_oil_suction/provenance/03-effect.original.json +0 -1051
  220. package/packages/resource.particle.viscous_oil_suction/provenance/03-normalized-vfx-to-babylon-report.json +0 -200
  221. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-overrides.json +0 -581
  222. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-tuning-report.json +0 -28
  223. package/packages/resource.particle.viscous_oil_suction/provenance/asset-map.json +0 -111
  224. package/packages/resource.particle.viscous_oil_suction/provenance/lineage.json +0 -45
  225. package/packages/types.ts +0 -195
  226. package/tooling/check-dist-runtime.mjs +0 -166
  227. package/tooling/generate-index.mjs +0 -55
  228. package/tooling/test-guardrails.mjs +0 -157
  229. package/tooling/validate-boundary.mjs +0 -92
  230. package/tooling/validate-effects.mjs +0 -304
  231. package/tooling/validate.mjs +0 -53
@@ -1,6 +0,0 @@
1
- {
2
- "id": "character-entrance",
3
- "nameZh": "人物登场光柱",
4
- "source": "runtime-generated",
5
- "assets": []
6
- }
@@ -1,308 +0,0 @@
1
- import { Color3 } from '@babylonjs/core/Maths/math.color';
2
- import { Constants } from '@babylonjs/core/Engines/constants';
3
- import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTexture';
4
- import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
5
- import { CreateCylinder } from '@babylonjs/core/Meshes/Builders/cylinderBuilder';
6
- import { CreateTorus } from '@babylonjs/core/Meshes/Builders/torusBuilder';
7
- import { Mesh } from '@babylonjs/core/Meshes/mesh';
8
- import type { Texture } from '@babylonjs/core/Materials/Textures/texture';
9
- import type { Scene } from '@babylonjs/core/scene';
10
- import type { TransformNode } from '@babylonjs/core/Meshes/transformNode';
11
- import type { VfxColorValue, VfxEffectPackage, VfxParamValues } from '../../types';
12
- import { VFX_RENDERING_GROUP_ID } from '../../rendering';
13
- import manifest from './effect.json';
14
-
15
- interface CharacterEntranceParams extends VfxParamValues {
16
- lifetime: number;
17
- scale: number;
18
- initialHeight: number;
19
- offsetX: number;
20
- offsetZ: number;
21
- color: VfxColorValue;
22
- opacity: number;
23
- radius: number;
24
- height: number;
25
- beamWidth: number;
26
- riseSpeed: number;
27
- ringOpacity: number;
28
- fadeStart: number;
29
- }
30
-
31
- const DEFAULT_PARAMS: CharacterEntranceParams = {
32
- lifetime: 2.2,
33
- scale: 1,
34
- initialHeight: 0.02,
35
- offsetX: 0,
36
- offsetZ: 0,
37
- color: { r: 0.72, g: 0.96, b: 1 },
38
- opacity: 0.82,
39
- radius: 0.58,
40
- height: 2.35,
41
- beamWidth: 0.08,
42
- riseSpeed: 0.9,
43
- ringOpacity: 0.78,
44
- fadeStart: 0.58,
45
- };
46
-
47
- export const characterEntranceEffectPackage: VfxEffectPackage<CharacterEntranceParams> = {
48
- id: 'character-entrance',
49
- nameZh: '人物登场光柱',
50
- manifest,
51
- defaultParams: DEFAULT_PARAMS,
52
- debugAnchor: 'player',
53
- debugParams: [
54
- { key: 'lifetime', label: '生命周期', kind: 'lifetime', min: 0.4, max: 6, step: 0.01 },
55
- { key: 'scale', label: '整体缩放', kind: 'scale', min: 0.1, max: 5, step: 0.01 },
56
- { key: 'color', label: '光柱颜色', kind: 'color' },
57
- { key: 'opacity', label: '透明度', kind: 'opacity', min: 0, max: 1, step: 0.01 },
58
- { key: 'radius', label: '光柱半径', kind: 'number', min: 0.05, max: 3, step: 0.01 },
59
- { key: 'height', label: '光柱高度', kind: 'number', min: 0.2, max: 8, step: 0.01 },
60
- { key: 'beamWidth', label: '杯壁厚度', kind: 'number', min: 0.005, max: 0.35, step: 0.001 },
61
- { key: 'riseSpeed', label: '流动速度', kind: 'number', min: 0, max: 5, step: 0.01 },
62
- { key: 'ringOpacity', label: '底部强度', kind: 'opacity', min: 0, max: 1, step: 0.01 },
63
- { key: 'fadeStart', label: '淡出开始', kind: 'number', min: 0.05, max: 0.95, step: 0.01 },
64
- ],
65
- create({ scene, root, position, params }) {
66
- root.position.copyFrom(position);
67
-
68
- const beam = createCupBeam(scene, root, params);
69
- let disposed = false;
70
- const disposeTimer = window.setTimeout(() => disposeAll(), Math.max(0.05, params.lifetime + 0.45) * 1000);
71
-
72
- beam.start();
73
-
74
- return {
75
- root,
76
- dispose() {
77
- disposeAll();
78
- },
79
- };
80
-
81
- function disposeAll(): void {
82
- if (disposed) return;
83
- disposed = true;
84
- window.clearTimeout(disposeTimer);
85
- beam.dispose();
86
- root.dispose();
87
- }
88
- },
89
- };
90
-
91
- function createCupBeam(scene: Scene, root: TransformNode, params: CharacterEntranceParams): { start(): void; dispose(): void } {
92
- const scale = Math.max(0.05, params.scale);
93
- const height = Math.max(0.05, params.height * scale);
94
- const radius = Math.max(0.02, params.radius * scale);
95
- const wallThickness = Math.max(0.006, params.beamWidth * scale);
96
- const shellAlpha = clamp01(params.opacity * 0.68);
97
- const flowAlpha = clamp01(params.opacity * 0.78);
98
- const rimAlpha = clamp01(params.opacity * params.ringOpacity * 1.18);
99
- const shellMaterial = createCupBeamMaterial(scene, params, 'shell', getCupBeamTexture(scene), shellAlpha);
100
- const flowTexture = getCupFlowTexture(scene);
101
- const flowMaterial = createCupBeamMaterial(scene, params, 'flow', flowTexture, flowAlpha);
102
- const rimMaterial = createCupBeamMaterial(scene, params, 'bottom-rim', getBottomRimTexture(scene), rimAlpha);
103
- const shell = createOpenCylinder(scene, 'character-entrance.cup.shell');
104
- const flow = createOpenCylinder(scene, 'character-entrance.cup.flow');
105
- const rim = CreateTorus('character-entrance.cup.bottom-rim', {
106
- diameter: radius * 2,
107
- thickness: Math.max(0.018, wallThickness * 0.9),
108
- tessellation: 64,
109
- sideOrientation: Mesh.DOUBLESIDE,
110
- }, scene);
111
- const meshes = [
112
- { mesh: shell, radius: radius + wallThickness * 1.6, material: shellMaterial, alpha: shellAlpha },
113
- { mesh: flow, radius: radius + wallThickness * 0.55, material: flowMaterial, alpha: flowAlpha },
114
- ];
115
- let age = 0;
116
- let observer: ReturnType<Scene['onBeforeRenderObservable']['add']> | null = null;
117
- let disposed = false;
118
-
119
- for (const entry of meshes) {
120
- entry.mesh.parent = root;
121
- entry.mesh.position.y = 0;
122
- entry.mesh.scaling.set(entry.radius, 0.001, entry.radius);
123
- entry.mesh.renderingGroupId = VFX_RENDERING_GROUP_ID;
124
- entry.mesh.isPickable = false;
125
- entry.mesh.material = entry.material;
126
- entry.material.alpha = 0;
127
- }
128
- rim.parent = root;
129
- rim.position.y = 0.025 * scale;
130
- rim.renderingGroupId = VFX_RENDERING_GROUP_ID;
131
- rim.isPickable = false;
132
- rim.material = rimMaterial;
133
- rimMaterial.alpha = 0;
134
-
135
- return { start, dispose };
136
-
137
- function start(): void {
138
- if (observer) return;
139
- observer = scene.onBeforeRenderObservable.add(() => {
140
- if (disposed) return;
141
- const deltaSeconds = Math.min(0.05, scene.getEngine().getDeltaTime() / 1000);
142
- age += deltaSeconds;
143
- const t = Math.min(1, age / Math.max(0.01, params.lifetime));
144
- const riseDuration = Math.max(0.1, Math.min(0.68, 0.55 / Math.max(0.2, params.riseSpeed)));
145
- const rise = easeOutCubic(Math.min(1, t / riseDuration));
146
- const fadeStart = Math.max(0.05, Math.min(0.95, params.fadeStart));
147
- const fade = Math.max(0, 1 - Math.max(0, t - fadeStart) / Math.max(0.01, 1 - fadeStart));
148
- const visibleHeight = Math.max(0.001, height * rise);
149
- const softPulse = 0.96 + Math.sin(age * 4.2) * 0.04;
150
- flowTexture.vOffset -= deltaSeconds * Math.max(0, params.riseSpeed) * 0.34;
151
-
152
- for (const entry of meshes) {
153
- entry.mesh.scaling.y = visibleHeight;
154
- entry.mesh.position.y = visibleHeight * 0.5;
155
- entry.material.alpha = entry.alpha * fade * softPulse;
156
- }
157
- rim.scaling.setAll(1 + rise * 0.06);
158
- rimMaterial.alpha = rimAlpha * fade * (0.82 + rise * 0.18);
159
- });
160
- }
161
-
162
- function dispose(): void {
163
- if (disposed) return;
164
- disposed = true;
165
- if (observer) scene.onBeforeRenderObservable.remove(observer);
166
- observer = null;
167
- shell.dispose();
168
- flow.dispose();
169
- rim.dispose();
170
- shellMaterial.dispose();
171
- flowMaterial.dispose();
172
- rimMaterial.dispose();
173
- }
174
- }
175
-
176
- function createOpenCylinder(scene: Scene, name: string): Mesh {
177
- return CreateCylinder(name, {
178
- height: 1,
179
- diameter: 2,
180
- tessellation: 96,
181
- subdivisions: 12,
182
- cap: Mesh.NO_CAP,
183
- sideOrientation: Mesh.DOUBLESIDE,
184
- }, scene);
185
- }
186
-
187
- function createCupBeamMaterial(
188
- scene: Scene,
189
- params: CharacterEntranceParams,
190
- suffix: string,
191
- texture: Texture,
192
- alpha: number,
193
- ): StandardMaterial {
194
- const material = new StandardMaterial(`character-entrance.cup.${suffix}.material`, scene);
195
- texture.hasAlpha = true;
196
- material.diffuseTexture = texture;
197
- material.opacityTexture = texture;
198
- material.useAlphaFromDiffuseTexture = true;
199
- material.emissiveColor = toColor3(params.color);
200
- material.diffuseColor = toColor3(params.color);
201
- material.alpha = alpha;
202
- material.disableLighting = true;
203
- material.backFaceCulling = false;
204
- material.alphaMode = Constants.ALPHA_ADD;
205
- return material;
206
- }
207
-
208
- function getCupBeamTexture(scene: Scene): DynamicTexture {
209
- const key = '__vfx_character_entrance_cup_beam_texture';
210
- const metadata = scene.metadata && typeof scene.metadata === 'object' ? scene.metadata as Record<string, unknown> : {};
211
- scene.metadata = metadata;
212
- const existing = metadata[key] as DynamicTexture | undefined;
213
- if (existing) return existing;
214
-
215
- const texture = new DynamicTexture('character_entrance_cup_beam_texture', { width: 128, height: 256 }, scene, true);
216
- const context = texture.getContext();
217
- const composite = context as unknown as CanvasRenderingContext2D;
218
- context.clearRect(0, 0, 128, 256);
219
- const side = context.createLinearGradient(0, 0, 128, 0);
220
- side.addColorStop(0, 'rgba(205, 250, 255, 0)');
221
- side.addColorStop(0.22, 'rgba(205, 250, 255, 0.42)');
222
- side.addColorStop(0.5, 'rgba(245, 255, 255, 0.82)');
223
- side.addColorStop(0.78, 'rgba(205, 250, 255, 0.42)');
224
- side.addColorStop(1, 'rgba(205, 250, 255, 0)');
225
- const vertical = context.createLinearGradient(0, 0, 0, 256);
226
- vertical.addColorStop(0, 'rgba(210, 250, 255, 0)');
227
- vertical.addColorStop(0.18, 'rgba(210, 250, 255, 0.1)');
228
- vertical.addColorStop(0.62, 'rgba(185, 246, 255, 0.58)');
229
- vertical.addColorStop(1, 'rgba(245, 255, 255, 0.96)');
230
- context.fillStyle = side;
231
- context.fillRect(0, 0, 128, 256);
232
- composite.globalCompositeOperation = 'source-in';
233
- context.fillStyle = vertical;
234
- context.fillRect(0, 0, 128, 256);
235
- composite.globalCompositeOperation = 'source-over';
236
- texture.hasAlpha = true;
237
- texture.update(false);
238
- return texture;
239
- }
240
-
241
- function getCupFlowTexture(scene: Scene): DynamicTexture {
242
- const key = '__vfx_character_entrance_cup_flow_texture';
243
- const metadata = scene.metadata && typeof scene.metadata === 'object' ? scene.metadata as Record<string, unknown> : {};
244
- scene.metadata = metadata;
245
- const existing = metadata[key] as DynamicTexture | undefined;
246
- if (existing) return existing;
247
-
248
- const texture = new DynamicTexture('character_entrance_cup_flow_texture', { width: 128, height: 256 }, scene, true);
249
- const context = texture.getContext();
250
- const composite = context as unknown as CanvasRenderingContext2D;
251
- context.clearRect(0, 0, 128, 256);
252
- const side = context.createLinearGradient(0, 0, 128, 0);
253
- side.addColorStop(0, 'rgba(255, 255, 255, 0)');
254
- side.addColorStop(0.28, 'rgba(255, 255, 255, 0.22)');
255
- side.addColorStop(0.5, 'rgba(255, 255, 255, 0.7)');
256
- side.addColorStop(0.72, 'rgba(255, 255, 255, 0.22)');
257
- side.addColorStop(1, 'rgba(255, 255, 255, 0)');
258
- context.fillStyle = side;
259
- context.fillRect(0, 0, 128, 256);
260
- composite.globalCompositeOperation = 'source-in';
261
- for (let y = -48; y < 304; y += 56) {
262
- const band = context.createLinearGradient(0, y, 0, y + 42);
263
- band.addColorStop(0, 'rgba(255, 255, 255, 0)');
264
- band.addColorStop(0.48, 'rgba(255, 255, 255, 0.92)');
265
- band.addColorStop(1, 'rgba(255, 255, 255, 0)');
266
- context.fillStyle = band;
267
- context.fillRect(0, y, 128, 42);
268
- }
269
- composite.globalCompositeOperation = 'source-over';
270
- texture.hasAlpha = true;
271
- texture.vScale = 1.2;
272
- texture.update(false);
273
- return texture;
274
- }
275
-
276
- function getBottomRimTexture(scene: Scene): DynamicTexture {
277
- const key = '__vfx_character_entrance_bottom_rim_texture';
278
- const metadata = scene.metadata && typeof scene.metadata === 'object' ? scene.metadata as Record<string, unknown> : {};
279
- scene.metadata = metadata;
280
- const existing = metadata[key] as DynamicTexture | undefined;
281
- if (existing) return existing;
282
-
283
- const texture = new DynamicTexture('character_entrance_bottom_rim_texture', { width: 64, height: 64 }, scene, true);
284
- const context = texture.getContext();
285
- context.clearRect(0, 0, 64, 64);
286
- const glow = context.createRadialGradient(32, 32, 8, 32, 32, 31);
287
- glow.addColorStop(0, 'rgba(245, 255, 255, 0.96)');
288
- glow.addColorStop(0.55, 'rgba(185, 246, 255, 0.68)');
289
- glow.addColorStop(1, 'rgba(150, 230, 255, 0)');
290
- context.fillStyle = glow;
291
- context.fillRect(0, 0, 64, 64);
292
- texture.hasAlpha = true;
293
- texture.update(false);
294
- return texture;
295
- }
296
-
297
- function toColor3(color: VfxColorValue): Color3 {
298
- return new Color3(clamp01(color.r), clamp01(color.g), clamp01(color.b));
299
- }
300
-
301
- function clamp01(value: number): number {
302
- return Math.min(1, Math.max(0, value));
303
- }
304
-
305
- function easeOutCubic(value: number): number {
306
- const t = clamp01(value);
307
- return 1 - Math.pow(1 - t, 3);
308
- }
@@ -1,48 +0,0 @@
1
- // 金币爆出(移植自 babylon-laser 击破掉落金币, 特效#11)。
2
- // 金色 primitive 圆柱,抛物 flyer 池(重力9/寿命1.9),一次性。无外部资产。
3
- import { CreateCylinder } from '@babylonjs/core/Meshes/Builders/cylinderBuilder';
4
- import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
5
- import { Color3 } from '@babylonjs/core/Maths/math.color';
6
- import { Vector3 } from '@babylonjs/core/Maths/math.vector';
7
- import type { VfxEffectPackage, VfxParamValues } from '../../types';
8
- import { FlyerPool } from '../space-shared';
9
-
10
- interface CoinBurstParams extends VfxParamValues { count: number; }
11
- const DEFAULT_PARAMS: CoinBurstParams = { count: 6 };
12
-
13
- export const coinBurstEffectPackage: VfxEffectPackage<CoinBurstParams> = {
14
- id: 'coin-burst',
15
- nameZh: '金币爆出',
16
- placement: 'world',
17
- debugAnchor: 'playerRight',
18
- defaultParams: DEFAULT_PARAMS,
19
- debugParams: [
20
- { key: 'count', label: '金币数量', kind: 'number', min: 0, max: 20, step: 1 },
21
- ],
22
-
23
- create({ scene, root, position, params, scale, renderingGroupId }) {
24
- root.position.copyFrom(position);
25
- // 金币是世界坐标抛物(不挂 root),root.scaling 作用不到 → 自行用 ctx.scale 缩放尺寸/抛撒/重力(G3/M6)。
26
- const s = scale ? scale.x : 1;
27
- const pool = new FlyerPool(scene);
28
- const coinMat = new StandardMaterial('vfx_coin_mat', scene);
29
- coinMat.diffuseColor = new Color3(1, 0.78, 0.1);
30
- coinMat.emissiveColor = new Color3(0.5, 0.36, 0.02);
31
- coinMat.specularColor = new Color3(1, 0.9, 0.4);
32
- for (let i = 0; i < Math.round(params.count); i++) {
33
- const c = CreateCylinder('vfx_coin', { diameter: 0.8, height: 0.12, tessellation: 18 }, scene);
34
- c.scaling.setAll(s);
35
- c.renderingGroupId = renderingGroupId ?? 0; // M7:补全分组(全库约定)
36
- c.rotation.x = Math.random() * Math.PI; c.material = coinMat;
37
- pool.spawn(c, position, new Vector3((Math.random() - 0.5) * 6 * s, (Math.random() * 6 + 4) * s, (Math.random() - 0.5) * 6 * s), 9 * s, 1.9);
38
- }
39
- let disposed = false;
40
- const disposeTimer = window.setTimeout(() => disposeAll(), 2300);
41
- function disposeAll(): void {
42
- if (disposed) return; disposed = true;
43
- window.clearTimeout(disposeTimer);
44
- pool.dispose(); coinMat.dispose(); root.dispose();
45
- }
46
- return { root, dispose() { disposeAll(); } };
47
- },
48
- };
@@ -1,107 +0,0 @@
1
- // 陨石/彗星拖尾火焰(移植自 babylon-laser TrailFlame, 特效#5)。
2
- // 十字两面片(沿 +Z 长 1,root.scaling.z=length 拉长)+ trail_5x4 序列帧(20帧5x4,全局同步播)。
3
- // 偏橙 emissive,ALPHA_COMBINE(非 ADD,不过曝)。自排除 GlowLayer。亮头在 z=0、尾端淡出。
4
- // 库版为持续型:头在 root、尾沿局部 +Z 延伸(宿主把 +Z 朝运动反方向即成拖尾)。
5
- import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
6
- import { Mesh } from '@babylonjs/core/Meshes/mesh';
7
- import { VertexData } from '@babylonjs/core/Meshes/mesh.vertexData';
8
- import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
9
- import { Texture } from '@babylonjs/core/Materials/Textures/texture';
10
- import { Color3 } from '@babylonjs/core/Maths/math.color';
11
- import { Constants } from '@babylonjs/core/Engines/constants';
12
- import type { Scene } from '@babylonjs/core/scene';
13
- import type { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
14
- import type { VfxColorValue, VfxEffectPackage, VfxParamValues } from '../../types';
15
- import trailTextureUrl from './assets/textures/trail_5x4.webp?url';
16
- import { LIFETIME_DEBUG_PARAMS, LIFETIME_DEFAULTS, scheduleLifetime } from '../space-shared';
17
-
18
- interface CometTrailFlameParams extends VfxParamValues {
19
- lifetimeMode: string; lifetime: number;
20
- width: number;
21
- length: number;
22
- fps: number;
23
- tint: VfxColorValue;
24
- }
25
-
26
- const DEFAULT_PARAMS: CometTrailFlameParams = {
27
- ...LIFETIME_DEFAULTS,
28
- width: 3.0, length: 7.0, fps: 20, tint: { r: 1.0, g: 0.62, b: 0.35 },
29
- };
30
-
31
- function createTrailPlaneGeo(name: string, width: number, axis: 'x' | 'y', scene: Scene): Mesh {
32
- const h = width / 2;
33
- const positions = axis === 'x'
34
- ? [-h, 0, 0, h, 0, 0, h, 0, 1, -h, 0, 1]
35
- : [0, -h, 0, 0, h, 0, 0, h, 1, 0, -h, 1];
36
- const normals = axis === 'x' ? [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0] : [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0];
37
- const uvs = [0, 0, 1, 0, 1, 1, 0, 1];
38
- const indices = [0, 1, 2, 0, 2, 3];
39
- const mesh = new Mesh(name, scene);
40
- const vd = new VertexData();
41
- vd.positions = positions; vd.normals = normals; vd.uvs = uvs; vd.indices = indices;
42
- vd.applyToMesh(mesh);
43
- return mesh;
44
- }
45
-
46
- function excludeFromGlow(scene: Scene, mesh: AbstractMesh): void {
47
- for (const layer of scene.effectLayers ?? []) {
48
- const add = (layer as unknown as { addExcludedMesh?: (m: AbstractMesh) => void }).addExcludedMesh;
49
- if (typeof add === 'function') add.call(layer, mesh);
50
- }
51
- }
52
-
53
- export const cometTrailFlameEffectPackage: VfxEffectPackage<CometTrailFlameParams> = {
54
- id: 'comet-trail-flame',
55
- nameZh: '拖尾火焰',
56
- placement: 'socket',
57
- debugAnchor: 'player',
58
- defaultParams: DEFAULT_PARAMS,
59
- debugParams: [
60
- ...LIFETIME_DEBUG_PARAMS,
61
- { key: 'width', label: '宽度', kind: 'scale', min: 0.3, max: 10, step: 0.1 },
62
- { key: 'length', label: '长度', kind: 'scale', min: 0.5, max: 20, step: 0.1 },
63
- { key: 'fps', label: '播放帧率', kind: 'number', min: 1, max: 60, step: 1 },
64
- { key: 'tint', label: '火焰色', kind: 'color' },
65
- ],
66
-
67
- create({ scene, root, position, rotationY, params, renderingGroupId }) {
68
- root.position.copyFrom(position);
69
- root.rotation.y = rotationY;
70
-
71
- const tex = new Texture(trailTextureUrl, scene);
72
- tex.hasAlpha = true;
73
- tex.uScale = 1 / 5; tex.vScale = 1 / 4; // 5列x4行序列帧
74
- const mat = new StandardMaterial('vfx_trail_mat', scene);
75
- mat.emissiveTexture = tex; mat.opacityTexture = tex;
76
- mat.emissiveColor = new Color3(params.tint.r, params.tint.g, params.tint.b);
77
- mat.alpha = 0.9; mat.disableLighting = true; mat.backFaceCulling = false;
78
- mat.alphaMode = Constants.ALPHA_COMBINE;
79
-
80
- const trailRoot = new TransformNode('vfx_trail_root', scene);
81
- trailRoot.parent = root;
82
- trailRoot.scaling.z = params.length;
83
- const a = createTrailPlaneGeo('vfx_trail_a', params.width, 'x', scene);
84
- const b = createTrailPlaneGeo('vfx_trail_b', params.width, 'y', scene);
85
- for (const m of [a, b]) { m.material = mat; m.isPickable = false; m.parent = trailRoot; m.renderingGroupId = renderingGroupId ?? 0; excludeFromGlow(scene, m); }
86
-
87
- let t = 0;
88
- const observer = scene.onBeforeRenderObservable.add(() => {
89
- t += Math.min(scene.getEngine().getDeltaTime() / 1000, 0.05);
90
- const f = Math.floor(t * params.fps) % 20; // 20 帧循环
91
- tex.uOffset = (f % 5) / 5;
92
- tex.vOffset = 1 - (Math.floor(f / 5) + 1) / 4; // V 翻转
93
- });
94
-
95
- let disposed = false;
96
- let ltTimer = 0;
97
- const dispose = (): void => {
98
- if (disposed) return; disposed = true;
99
- if (ltTimer) window.clearTimeout(ltTimer);
100
- scene.onBeforeRenderObservable.remove(observer);
101
- a.dispose(); b.dispose(); trailRoot.dispose();
102
- mat.dispose(); tex.dispose(); root.dispose();
103
- };
104
- ltTimer = scheduleLifetime(params, dispose);
105
- return { root, dispose };
106
- },
107
- };
@@ -1,6 +0,0 @@
1
- {
2
- "id": "conveyor-upgrade",
3
- "nameZh": "传送带升级光效",
4
- "source": "runtime-generated",
5
- "assets": []
6
- }