@fps-games/vfx 0.3.2 → 0.3.4

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 (234) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -5
  3. package/dist/effects/treasure-attention/index.d.ts +1 -1
  4. package/package.json +6 -5
  5. package/tooling/vfx-cli.mjs +31 -22
  6. package/tooling/vfx-package-resolution.mjs +8 -8
  7. package/docs/AUTHORING_EFFECTS.md +0 -297
  8. package/docs/INTEGRATION.md +0 -194
  9. package/docs/VFX_LIBRARY_ARCHITECTURE_chatgpt.md +0 -1580
  10. package/docs/VFX_LIBRARY_EXECUTION_PLAN.md +0 -229
  11. package/docs/VFX_LIBRARY_PLAN.md +0 -546
  12. package/docs/hit-flash-red-method.md +0 -155
  13. package/docs/treasure_attention_fx_babylonjs_guide.md +0 -901
  14. package/docs/vfx-ab/RESULTS.md +0 -35
  15. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/after.png +0 -0
  16. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/before.png +0 -0
  17. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/after.png +0 -0
  18. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/before.png +0 -0
  19. package/docs/vfx-integration_chatgpt.md +0 -462
  20. package/docs/vfx-placement-design.md +0 -164
  21. package/docs/weapon-trail-visualization.html +0 -241
  22. package/packages/EffectPackageService.ts +0 -346
  23. package/packages/SceneVfxService.ts +0 -96
  24. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/runtime/simpleMeshEffect.v1.js +0 -333
  25. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.frag.glsl +0 -25
  26. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.vert.glsl +0 -11
  27. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/textures/effect_jianbian.png +0 -0
  28. package/packages/build.mesh.yellow_build_upgrade_indicator/effect.json +0 -927
  29. package/packages/build.mesh.yellow_build_upgrade_indicator/media/contact-sheet.png +0 -0
  30. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.gif +0 -0
  31. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.mp4 +0 -0
  32. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.webm +0 -0
  33. package/packages/build.mesh.yellow_build_upgrade_indicator/media/thumbnail.png +0 -0
  34. package/packages/build.mesh.yellow_build_upgrade_indicator/metadata/description.json +0 -197
  35. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-effect.original.json +0 -895
  36. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-normalized-vfx-to-babylon-report.json +0 -241
  37. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-overrides.json +0 -542
  38. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-tuning-report.json +0 -69
  39. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/asset-map.json +0 -125
  40. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/lineage.json +0 -44
  41. package/packages/build.particle.golden_upgrade_starburst/assets/runtime/particleEmitter.v1.js +0 -210
  42. package/packages/build.particle.golden_upgrade_starburst/assets/textures/effect_guangdian.png +0 -0
  43. package/packages/build.particle.golden_upgrade_starburst/effect.json +0 -880
  44. package/packages/build.particle.golden_upgrade_starburst/media/contact-sheet.png +0 -0
  45. package/packages/build.particle.golden_upgrade_starburst/media/preview.gif +0 -0
  46. package/packages/build.particle.golden_upgrade_starburst/media/preview.mp4 +0 -0
  47. package/packages/build.particle.golden_upgrade_starburst/media/preview.webm +0 -0
  48. package/packages/build.particle.golden_upgrade_starburst/media/thumbnail.png +0 -0
  49. package/packages/build.particle.golden_upgrade_starburst/metadata/description.json +0 -161
  50. package/packages/build.particle.golden_upgrade_starburst/provenance/03-effect.original.json +0 -762
  51. package/packages/build.particle.golden_upgrade_starburst/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  52. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-overrides.json +0 -436
  53. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-tuning-report.json +0 -40
  54. package/packages/build.particle.golden_upgrade_starburst/provenance/asset-map.json +0 -115
  55. package/packages/build.particle.golden_upgrade_starburst/provenance/lineage.json +0 -40
  56. package/packages/build.particle.orange_upgrade_transform_sparks/assets/runtime/particleEmitter.v1.js +0 -210
  57. package/packages/build.particle.orange_upgrade_transform_sparks/assets/textures/b5b27ab1-e740-4398-b407-848fc2b2c897.png +0 -0
  58. package/packages/build.particle.orange_upgrade_transform_sparks/effect.json +0 -887
  59. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.gif +0 -0
  60. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.mp4 +0 -0
  61. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.webm +0 -0
  62. package/packages/build.particle.orange_upgrade_transform_sparks/media/thumbnail.png +0 -0
  63. package/packages/build.particle.orange_upgrade_transform_sparks/metadata/description.json +0 -179
  64. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-effect.original.json +0 -859
  65. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  66. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-overrides.json +0 -478
  67. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-tuning-report.json +0 -40
  68. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/asset-map.json +0 -114
  69. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/lineage.json +0 -41
  70. package/packages/build.particle.wood_chip_dust_burst/assets/runtime/particleEmitter.v1.js +0 -210
  71. package/packages/build.particle.wood_chip_dust_burst/assets/textures/effect_yanwu4.png +0 -0
  72. package/packages/build.particle.wood_chip_dust_burst/assets/textures/suipian3.png +0 -0
  73. package/packages/build.particle.wood_chip_dust_burst/effect.json +0 -1400
  74. package/packages/build.particle.wood_chip_dust_burst/media/contact-sheet.png +0 -0
  75. package/packages/build.particle.wood_chip_dust_burst/media/preview.gif +0 -0
  76. package/packages/build.particle.wood_chip_dust_burst/media/preview.mp4 +0 -0
  77. package/packages/build.particle.wood_chip_dust_burst/media/preview.webm +0 -0
  78. package/packages/build.particle.wood_chip_dust_burst/media/thumbnail.png +0 -0
  79. package/packages/build.particle.wood_chip_dust_burst/metadata/description.json +0 -173
  80. package/packages/build.particle.wood_chip_dust_burst/provenance/03-effect.original.json +0 -1277
  81. package/packages/build.particle.wood_chip_dust_burst/provenance/03-normalized-vfx-to-babylon-report.json +0 -329
  82. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-overrides.json +0 -749
  83. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-tuning-report.json +0 -60
  84. package/packages/build.particle.wood_chip_dust_burst/provenance/asset-map.json +0 -146
  85. package/packages/build.particle.wood_chip_dust_burst/provenance/lineage.json +0 -69
  86. package/packages/effects/building-upgrade/effect.json +0 -6
  87. package/packages/effects/building-upgrade/index.ts +0 -387
  88. package/packages/effects/character-entrance/effect.json +0 -6
  89. package/packages/effects/character-entrance/index.ts +0 -308
  90. package/packages/effects/coin-burst/index.ts +0 -48
  91. package/packages/effects/comet-trail-flame/assets/textures/trail_5x4.webp +0 -0
  92. package/packages/effects/comet-trail-flame/index.ts +0 -107
  93. package/packages/effects/conveyor-upgrade/effect.json +0 -6
  94. package/packages/effects/conveyor-upgrade/index.ts +0 -401
  95. package/packages/effects/debris-smoke/assets/models/rock_debris.glb +0 -0
  96. package/packages/effects/debris-smoke/assets/textures/smoke22.webp +0 -0
  97. package/packages/effects/debris-smoke/index.ts +0 -102
  98. package/packages/effects/door_open_gold_flakes/assets/runtime/goldFlakes.v1.js +0 -397
  99. package/packages/effects/door_open_gold_flakes/door_open_gold_flakes.json +0 -498
  100. package/packages/effects/door_open_gold_flakes/index.ts +0 -11
  101. package/packages/effects/electric-arc/assets/textures/spark_4x4.webp +0 -0
  102. package/packages/effects/electric-arc/index.ts +0 -63
  103. package/packages/effects/energy-shield/effect.json +0 -7
  104. package/packages/effects/energy-shield/index.ts +0 -432
  105. package/packages/effects/explosion/assets/textures/baozha29.webp +0 -0
  106. package/packages/effects/explosion/assets/textures/glow01.webp +0 -0
  107. package/packages/effects/explosion/assets/textures/lizi01.webp +0 -0
  108. package/packages/effects/explosion/assets/textures/xulie_lizibaozha02_5x5.webp +0 -0
  109. package/packages/effects/explosion/index.ts +0 -115
  110. package/packages/effects/ground-tile-upgrade/effect.json +0 -6
  111. package/packages/effects/ground-tile-upgrade/index.ts +0 -410
  112. package/packages/effects/hit-flash/index.ts +0 -77
  113. package/packages/effects/laser-beam/assets/textures/laser_glow.webp +0 -0
  114. package/packages/effects/laser-beam/assets/textures/laser_noise.webp +0 -0
  115. package/packages/effects/laser-beam/index.ts +0 -6
  116. package/packages/effects/laser-beam-factory.ts +0 -146
  117. package/packages/effects/lumber-cart-suction/effect.json +0 -6
  118. package/packages/effects/lumber-cart-suction/index.ts +0 -399
  119. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb +0 -0
  120. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/.active +0 -1
  121. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/1781589063890_upload.glb +0 -0
  122. package/packages/effects/lumber-debris-scatter/assets/runtime/solidParticleScatter.v1.js +0 -236
  123. package/packages/effects/lumber-debris-scatter/effect.json +0 -228
  124. package/packages/effects/lumber-debris-scatter/index.ts +0 -780
  125. package/packages/effects/lumber_vehicle_gear_spin/assets/runtime/gearSpin.v1.js +0 -202
  126. package/packages/effects/lumber_vehicle_gear_spin/index.ts +0 -11
  127. package/packages/effects/lumber_vehicle_gear_spin/lumber_vehicle_gear_spin.json +0 -338
  128. package/packages/effects/lumber_vehicle_upgrade_aura/assets/runtime/upgradeAura.v1.js +0 -353
  129. package/packages/effects/lumber_vehicle_upgrade_aura/index.ts +0 -13
  130. package/packages/effects/lumber_vehicle_upgrade_aura/lumber_vehicle_upgrade_aura.json +0 -365
  131. package/packages/effects/lumber_vehicle_wood_chips/assets/runtime/solidParticleScatter.v1.js +0 -310
  132. package/packages/effects/lumber_vehicle_wood_chips/index.ts +0 -11
  133. package/packages/effects/lumber_vehicle_wood_chips/lumber_vehicle_wood_chips.json +0 -335
  134. package/packages/effects/monster-hit/index.ts +0 -129
  135. package/packages/effects/player-upgrade/effect.json +0 -6
  136. package/packages/effects/player-upgrade/index.ts +0 -640
  137. package/packages/effects/pulse-laser-volley/assets/textures/bolt_guangshu.webp +0 -0
  138. package/packages/effects/pulse-laser-volley/index.ts +0 -215
  139. package/packages/effects/resource-collect-sparkles/effect.json +0 -6
  140. package/packages/effects/resource-collect-sparkles/index.ts +0 -254
  141. package/packages/effects/run-footstep-dust/assets/runtime/runFootstepDust.v1.js +0 -215
  142. package/packages/effects/run-footstep-dust/effect.json +0 -183
  143. package/packages/effects/run-footstep-dust/index.ts +0 -377
  144. package/packages/effects/space-shared.ts +0 -120
  145. package/packages/effects/thruster-flame/index.ts +0 -306
  146. package/packages/effects/treasure-attention/effect.json +0 -7
  147. package/packages/effects/treasure-attention/index.ts +0 -630
  148. package/packages/effects/tree-chop-dust/assets/textures/tree_chop_dust_atlas.png +0 -0
  149. package/packages/effects/tree-chop-dust/effect.json +0 -8
  150. package/packages/effects/tree-chop-dust/index.ts +0 -202
  151. package/packages/effects/tree-leaf-chop-burst/assets/runtime/particleEmitter.v1.js +0 -303
  152. package/packages/effects/tree-leaf-chop-burst/assets/textures/tree_leaf_chop_burst_leaf_atlas.png +0 -0
  153. package/packages/effects/tree-leaf-chop-burst/effect.json +0 -498
  154. package/packages/effects/tree-leaf-chop-burst/index.ts +0 -294
  155. package/packages/effects/tree_chop_dust_burst/assets/runtime/particleEmitter.v1.js +0 -318
  156. package/packages/effects/tree_chop_dust_burst/assets/textures/tree_chop_dust_burst_dust.png +0 -0
  157. package/packages/effects/tree_chop_dust_burst/index.ts +0 -13
  158. package/packages/effects/tree_chop_dust_burst/tree_chop_dust_burst.json +0 -412
  159. package/packages/effects/ufo-thread-flame/assets/textures/flame_flow.webp +0 -0
  160. package/packages/effects/ufo-thread-flame/assets/textures/flame_spike.webp +0 -0
  161. package/packages/effects/ufo-thread-flame/index.ts +0 -153
  162. package/packages/effects/vehicle-exhaust-smoke/assets/textures/vehicle_exhaust_smoke_atlas.png +0 -0
  163. package/packages/effects/vehicle-exhaust-smoke/effect.json +0 -8
  164. package/packages/effects/vehicle-exhaust-smoke/index.ts +0 -298
  165. package/packages/effects/vehicle-upgrade/effect.json +0 -6
  166. package/packages/effects/vehicle-upgrade/index.ts +0 -404
  167. package/packages/effects/weapon-trail/assets/textures/trail_wedge.png +0 -0
  168. package/packages/effects/weapon-trail/index.ts +0 -317
  169. package/packages/effects/wood-crusher-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  170. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  171. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  172. package/packages/effects/wood-crusher-sawdust/index.ts +0 -43
  173. package/packages/effects/wood-crusher-sawdust/wood_crusher_sawdust.json +0 -592
  174. package/packages/effects/wood-cutter-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  175. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  176. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  177. package/packages/effects/wood-cutter-sawdust/index.ts +0 -43
  178. package/packages/effects/wood-cutter-sawdust/wood_cutter_sawdust.json +0 -592
  179. package/packages/effects/wood-sawdust-effect-factory.ts +0 -194
  180. package/packages/effects/wood_crusher_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  181. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  182. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  183. package/packages/effects/wood_crusher_sawdust/index.ts +0 -29
  184. package/packages/effects/wood_crusher_sawdust/wood_crusher_sawdust.json +0 -592
  185. package/packages/effects/wood_cutter_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  186. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  187. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  188. package/packages/effects/wood_cutter_sawdust/index.ts +0 -29
  189. package/packages/effects/wood_cutter_sawdust/wood_cutter_sawdust.json +0 -592
  190. package/packages/effects/wood_peel_material_test/assets/runtime/woodPeelMaterialTest.v1.js +0 -196
  191. package/packages/effects/wood_peel_material_test/index.ts +0 -11
  192. package/packages/effects/wood_peel_material_test/wood_peel_material_test.json +0 -136
  193. package/packages/env.particle.forest_edge_fog/assets/runtime/particleEmitter.v1.js +0 -210
  194. package/packages/env.particle.forest_edge_fog/assets/textures/f12a23c4-b924-4322-a260-3d982428f1e8.png +0 -0
  195. package/packages/env.particle.forest_edge_fog/assets/textures/yuan.png +0 -0
  196. package/packages/env.particle.forest_edge_fog/effect.json +0 -854
  197. package/packages/env.particle.forest_edge_fog/media/preview.gif +0 -0
  198. package/packages/env.particle.forest_edge_fog/media/preview.mp4 +0 -0
  199. package/packages/env.particle.forest_edge_fog/media/preview.webm +0 -0
  200. package/packages/env.particle.forest_edge_fog/media/thumbnail.png +0 -0
  201. package/packages/env.particle.forest_edge_fog/metadata/description.json +0 -148
  202. package/packages/env.particle.forest_edge_fog/provenance/03-effect.original.json +0 -827
  203. package/packages/env.particle.forest_edge_fog/provenance/03-normalized-vfx-to-babylon-report.json +0 -196
  204. package/packages/env.particle.forest_edge_fog/provenance/04-preview-overrides.json +0 -432
  205. package/packages/env.particle.forest_edge_fog/provenance/04-preview-tuning-report.json +0 -28
  206. package/packages/env.particle.forest_edge_fog/provenance/asset-map.json +0 -124
  207. package/packages/env.particle.forest_edge_fog/provenance/lineage.json +0 -41
  208. package/packages/generation.ts +0 -14
  209. package/packages/index.ts +0 -14
  210. package/packages/legacy-particle-runtime.ts +0 -113
  211. package/packages/manifestRuntimePackage.ts +0 -519
  212. package/packages/registry.ts +0 -85
  213. package/packages/rendering.ts +0 -13
  214. package/packages/resource.particle.viscous_oil_suction/assets/runtime/top_disk_suction/particleEmitter.v1.js +0 -424
  215. package/packages/resource.particle.viscous_oil_suction/assets/textures/Glow ad.png +0 -0
  216. package/packages/resource.particle.viscous_oil_suction/effect.json +0 -1254
  217. package/packages/resource.particle.viscous_oil_suction/media/preview.gif +0 -0
  218. package/packages/resource.particle.viscous_oil_suction/media/preview.mp4 +0 -0
  219. package/packages/resource.particle.viscous_oil_suction/media/preview.webm +0 -0
  220. package/packages/resource.particle.viscous_oil_suction/media/thumbnail.png +0 -0
  221. package/packages/resource.particle.viscous_oil_suction/metadata/description.json +0 -122
  222. package/packages/resource.particle.viscous_oil_suction/provenance/03-effect.original.json +0 -1051
  223. package/packages/resource.particle.viscous_oil_suction/provenance/03-normalized-vfx-to-babylon-report.json +0 -200
  224. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-overrides.json +0 -581
  225. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-tuning-report.json +0 -28
  226. package/packages/resource.particle.viscous_oil_suction/provenance/asset-map.json +0 -111
  227. package/packages/resource.particle.viscous_oil_suction/provenance/lineage.json +0 -45
  228. package/packages/types.ts +0 -195
  229. package/tooling/check-dist-runtime.mjs +0 -166
  230. package/tooling/generate-index.mjs +0 -55
  231. package/tooling/test-guardrails.mjs +0 -157
  232. package/tooling/validate-boundary.mjs +0 -92
  233. package/tooling/validate-effects.mjs +0 -304
  234. package/tooling/validate.mjs +0 -53
@@ -1,196 +0,0 @@
1
- export const runtimeContract = {
2
- id: "woodPeelMaterialTest/v1",
3
- engine: "babylon",
4
- exports: ["createWoodPeelMaterialTestRuntime"],
5
- };
6
-
7
- const PREVIEW_ROOT_NAME = "vfx_wood_peel_material_test_preview_root";
8
-
9
- function clamp01(value) {
10
- const n = Number(value);
11
- if (!Number.isFinite(n)) return 0;
12
- return Math.min(1, Math.max(0, n));
13
- }
14
-
15
- function readNumber(value, fallback) {
16
- const n = Number(value);
17
- return Number.isFinite(n) ? n : fallback;
18
- }
19
-
20
- function readColor(BABYLON, value, fallback) {
21
- if (typeof value === "string" && /^#[0-9a-f]{6}$/i.test(value)) {
22
- return BABYLON.Color3.FromHexString(value);
23
- }
24
- if (value && typeof value === "object") {
25
- const r = Number(value.r);
26
- const g = Number(value.g);
27
- const b = Number(value.b);
28
- if (Number.isFinite(r) && Number.isFinite(g) && Number.isFinite(b)) {
29
- return new BABYLON.Color3(r, g, b);
30
- }
31
- }
32
- return fallback.clone();
33
- }
34
-
35
- function createWoodPeelPbrBlendPlugin(BABYLON, material, options) {
36
- class WoodPeelPbrBlendPlugin extends BABYLON.MaterialPluginBase {
37
- constructor() {
38
- super(material, "WoodPeelPbrBlend", 210, { WOODPEEL_PBR_BLEND: false }, true, true);
39
- this.peelProgress = clamp01(options.peelProgress);
40
- }
41
-
42
- isReadyForSubMesh() {
43
- return true;
44
- }
45
-
46
- prepareDefines(defines) {
47
- defines.WOODPEEL_PBR_BLEND = true;
48
- }
49
-
50
- bindForSubMesh(uniformBuffer) {
51
- uniformBuffer.updateFloat2("woodPeelProgressBlend", this.peelProgress, Math.max(0.001, options.blendWidth));
52
- uniformBuffer.updateVector3("woodPeelAxis", options.axis);
53
- uniformBuffer.updateVector3("woodPeelAxisCenter", options.axisCenter);
54
- uniformBuffer.updateFloat("woodPeelLogLength", options.logLength);
55
- uniformBuffer.updateColor3("woodPeelBarkColor", options.barkColor);
56
- uniformBuffer.updateColor3("woodPeelPeeledColor", options.peeledColor);
57
- }
58
-
59
- getUniforms() {
60
- return {
61
- ubo: [
62
- { name: "woodPeelProgressBlend", size: 2, type: "vec2" },
63
- { name: "woodPeelAxis", size: 3, type: "vec3" },
64
- { name: "woodPeelAxisCenter", size: 3, type: "vec3" },
65
- { name: "woodPeelLogLength", size: 1, type: "float" },
66
- { name: "woodPeelBarkColor", size: 3, type: "vec3" },
67
- { name: "woodPeelPeeledColor", size: 3, type: "vec3" },
68
- ],
69
- };
70
- }
71
-
72
- getCustomCode(shaderType) {
73
- if (shaderType === "vertex") {
74
- return {
75
- CUSTOM_VERTEX_DEFINITIONS: `
76
- varying vec3 vWoodPeelLocalPosition;
77
- `,
78
- CUSTOM_VERTEX_UPDATE_POSITION: `
79
- vWoodPeelLocalPosition = positionUpdated;
80
- `,
81
- };
82
- }
83
- if (shaderType !== "fragment") return null;
84
- return {
85
- CUSTOM_FRAGMENT_DEFINITIONS: `
86
- varying vec3 vWoodPeelLocalPosition;
87
- `,
88
- CUSTOM_FRAGMENT_UPDATE_ALBEDO: `
89
- float woodPeelAxisDistance = dot(vWoodPeelLocalPosition - woodPeelAxisCenter, normalize(woodPeelAxis));
90
- float woodPeelNormalizedAxis = clamp((woodPeelAxisDistance / max(woodPeelLogLength, 0.0001)) + 0.5, 0.0, 1.0);
91
- float woodPeelWidth = max(woodPeelProgressBlend.y, 0.001);
92
- float woodPeelHead = mix(-woodPeelWidth, 1.0 + woodPeelWidth, clamp(woodPeelProgressBlend.x, 0.0, 1.0));
93
- float woodPeelPeeled = 1.0 - smoothstep(woodPeelHead - woodPeelWidth, woodPeelHead, woodPeelNormalizedAxis);
94
- vec3 woodPeelBark = toLinearSpace(woodPeelBarkColor);
95
- vec3 woodPeelPeeledWood = toLinearSpace(woodPeelPeeledColor);
96
- surfaceAlbedo = mix(woodPeelBark, woodPeelPeeledWood, woodPeelPeeled);
97
- `,
98
- };
99
- }
100
- }
101
-
102
- return new WoodPeelPbrBlendPlugin();
103
- }
104
-
105
- function createMaterial(BABYLON, scene, emitter, height, rootPosition) {
106
- const material = new BABYLON.PBRMaterial(
107
- "vfx_wood_peel_material_test_mat",
108
- scene
109
- );
110
- material.albedoColor = BABYLON.Color3.White();
111
- material.metallic = 0;
112
- material.roughness = 0.82;
113
- material.environmentIntensity = 1;
114
- material.usePhysicalLightFalloff = false;
115
- const plugin = createWoodPeelPbrBlendPlugin(BABYLON, material, {
116
- peelProgress: emitter.peelProgress,
117
- blendWidth: Math.max(0.001, readNumber(emitter.blendWidth, 0.08)),
118
- axis: new BABYLON.Vector3(0, 1, 0),
119
- axisCenter: new BABYLON.Vector3(rootPosition.x, rootPosition.y + height * 0.5, rootPosition.z),
120
- logLength: height,
121
- barkColor: readColor(BABYLON, emitter.barkColor, new BABYLON.Color3(0.76, 0.34, 0.13)),
122
- peeledColor: readColor(BABYLON, emitter.peeledColor, new BABYLON.Color3(0.98, 0.79, 0.43)),
123
- });
124
- return { material, plugin };
125
- }
126
-
127
- export async function createWoodPeelMaterialTestRuntime({ BABYLON, scene, emitter }) {
128
- const previous = scene.getTransformNodeByName(PREVIEW_ROOT_NAME);
129
- if (previous) previous.dispose(false, true);
130
-
131
- const height = Math.max(0.2, readNumber(emitter.height, 1.55));
132
- const diameter = Math.max(0.05, readNumber(emitter.diameter, 0.42));
133
- const origin = emitter.origin && typeof emitter.origin === "object"
134
- ? emitter.origin
135
- : { x: 0, y: 0, z: 0 };
136
-
137
- const root = new BABYLON.TransformNode(PREVIEW_ROOT_NAME, scene);
138
- root.position.set(
139
- readNumber(origin.x, 0),
140
- readNumber(origin.y, 0.02),
141
- readNumber(origin.z, 0)
142
- );
143
-
144
- const materialHandle = createMaterial(BABYLON, scene, emitter, height, root.position);
145
- const material = materialHandle.material;
146
-
147
- const log = BABYLON.MeshBuilder.CreateCylinder(
148
- "vfx_wood_peel_material_test_log",
149
- {
150
- height,
151
- diameter,
152
- tessellation: 48,
153
- subdivisions: 12,
154
- cap: BABYLON.Mesh.CAP_ALL,
155
- },
156
- scene
157
- );
158
- log.parent = root;
159
- log.position.y = height * 0.5;
160
- log.material = material;
161
-
162
- const base = BABYLON.MeshBuilder.CreateDisc(
163
- "vfx_wood_peel_material_test_floor_marker",
164
- {
165
- radius: diameter * 0.62,
166
- tessellation: 48,
167
- },
168
- scene
169
- );
170
- base.parent = root;
171
- base.rotation.x = Math.PI * 0.5;
172
- base.position.y = 0.006;
173
-
174
- const markerMaterial = new BABYLON.StandardMaterial("vfx_wood_peel_material_test_floor_marker_mat", scene);
175
- markerMaterial.diffuseColor = new BABYLON.Color3(0.08, 0.12, 0.12);
176
- markerMaterial.emissiveColor = new BABYLON.Color3(0.02, 0.055, 0.045);
177
- markerMaterial.alpha = 0.38;
178
- markerMaterial.backFaceCulling = false;
179
- markerMaterial.transparencyMode = BABYLON.Material.MATERIAL_ALPHABLEND;
180
- base.material = markerMaterial;
181
-
182
- return {
183
- start() {},
184
- stop() {
185
- root.setEnabled(false);
186
- },
187
- dispose() {
188
- root.dispose(false, true);
189
- material.dispose();
190
- markerMaterial.dispose();
191
- },
192
- isStarted() {
193
- return root.isEnabled();
194
- },
195
- };
196
- }
@@ -1,11 +0,0 @@
1
- import manifest from './wood_peel_material_test.json';
2
- import runtimeUrl from './assets/runtime/woodPeelMaterialTest.v1.js?url';
3
- import { createManifestRuntimeEffectPackage } from '../../manifestRuntimePackage';
4
-
5
- export const woodPeelMaterialTestEffectPackage = createManifestRuntimeEffectPackage({
6
- id: 'wood_peel_material_test',
7
- manifest,
8
- assetUrls: {
9
- 'assets/runtime/woodPeelMaterialTest.v1.js': runtimeUrl,
10
- },
11
- });
@@ -1,136 +0,0 @@
1
- {
2
- "schemaVersion": "vfx-effect-package/1.0",
3
- "id": "build.material.wood_peel_material_test",
4
- "name": {
5
- "zh": "木材剥皮材质测试",
6
- "en": "Wood Peel Material Test"
7
- },
8
- "assets": {
9
- "textures": [],
10
- "materials": [],
11
- "meshes": [],
12
- "shaders": [],
13
- "sounds": [],
14
- "scripts": [
15
- {
16
- "kind": "script",
17
- "id": "wood_peel_material_test_v1",
18
- "packagePath": "assets/runtime/woodPeelMaterialTest.v1.js",
19
- "runtimeId": "woodPeelMaterialTest/v1",
20
- "engine": "babylon",
21
- "moduleFormat": "esm",
22
- "exports": [
23
- "createWoodPeelMaterialTestRuntime",
24
- "runtimeContract"
25
- ],
26
- "mimeType": "text/javascript"
27
- }
28
- ],
29
- "raw": []
30
- },
31
- "emitters": [
32
- {
33
- "name": "wood_peel_material_test_main",
34
- "enabled": true,
35
- "type": "WoodPeelMaterialTest",
36
- "height": 1.55,
37
- "diameter": 0.42,
38
- "peelProgress": 0,
39
- "blendWidth": 0.08,
40
- "barkColor": {
41
- "r": 0.76,
42
- "g": 0.34,
43
- "b": 0.13,
44
- "a": 1
45
- },
46
- "peeledColor": {
47
- "r": 0.98,
48
- "g": 0.79,
49
- "b": 0.43,
50
- "a": 1
51
- },
52
- "runtime": {
53
- "adapter": "woodPeelMaterialTest/v1",
54
- "disposeOnComplete": false
55
- }
56
- }
57
- ],
58
- "runtime": {
59
- "driver": "woodPeelMaterialTest",
60
- "adapters": [
61
- {
62
- "id": "woodPeelMaterialTest/v1",
63
- "engine": "babylon",
64
- "entry": "assets/runtime/woodPeelMaterialTest.v1.js",
65
- "moduleFormat": "esm",
66
- "exports": [
67
- "createWoodPeelMaterialTestRuntime",
68
- "runtimeContract"
69
- ]
70
- }
71
- ]
72
- },
73
- "debug": {
74
- "playAnchor": "playerRight",
75
- "livePreview": true
76
- },
77
- "tunableParams": [
78
- {
79
- "key": "wood_peel_material_test.peelProgress",
80
- "labelZh": "剥皮进度",
81
- "type": "number",
82
- "default": 0,
83
- "min": 0,
84
- "max": 1,
85
- "step": 0.01,
86
- "target": {
87
- "emitter": "wood_peel_material_test_main",
88
- "property": "peelProgress",
89
- "operator": "set"
90
- }
91
- },
92
- {
93
- "key": "wood_peel_material_test.blendWidth",
94
- "labelZh": "柔边",
95
- "type": "number",
96
- "default": 0.08,
97
- "min": 0.001,
98
- "max": 0.35,
99
- "step": 0.005,
100
- "target": {
101
- "emitter": "wood_peel_material_test_main",
102
- "property": "blendWidth",
103
- "operator": "set"
104
- }
105
- },
106
- {
107
- "key": "wood_peel_material_test.barkColor",
108
- "labelZh": "带皮颜色",
109
- "type": "color",
110
- "default": "#c25721",
111
- "target": {
112
- "emitter": "wood_peel_material_test_main",
113
- "property": "barkColor",
114
- "operator": "set"
115
- }
116
- },
117
- {
118
- "key": "wood_peel_material_test.peeledColor",
119
- "labelZh": "去皮颜色",
120
- "type": "color",
121
- "default": "#fac96d",
122
- "target": {
123
- "emitter": "wood_peel_material_test_main",
124
- "property": "peeledColor",
125
- "operator": "set"
126
- }
127
- }
128
- ],
129
- "review": {
130
- "status": "draft",
131
- "artistNotes": [
132
- "Runtime-only material preview for testing a 0-1 bottom-to-top bark peeling parameter.",
133
- "This package does not change gameplay logic or scene.json static layout."
134
- ]
135
- }
136
- }
@@ -1,210 +0,0 @@
1
- export const runtimeId = "particleEmitter/v1";
2
-
3
- export const runtimeContract = {
4
- runtimeId,
5
- kind: "particleEmitter",
6
- emitterFields: {
7
- capacity: "Maximum Babylon particle capacity.",
8
- particleTexturePath: "Package-relative particle texture path used to load the Babylon ParticleSystem.particleTexture.",
9
- blendMode: "Babylon particle blend mode label: ADD, STANDARD, MULTIPLY, or ONEONE.",
10
- shape: "Emitter shape definition generated by the Cocos conversion stage.",
11
- renderColor: "Converted particle color inputs: one base color plus RGB/alpha intensity before writing Babylon color1/color2/colorDead.",
12
- alphaKeys: "Color alpha gradients sampled over normalized particle lifetime.",
13
- sizeKeys: "Size gradients sampled over normalized particle lifetime.",
14
- },
15
- runtimeBindings: {
16
- "ParticleSystem.particleTexture": "Texture loaded from emitter.particleTexturePath through urlForPackagePath.",
17
- "ParticleSystem.blendMode": "Mapped from emitter.blendMode.",
18
- "ParticleSystem.manualEmitCount": "emitter.manualEmitCount when emitRate is 0.",
19
- "ParticleSystem.emitRate": "emitter.emitRate for sustained emitters.",
20
- "ParticleSystem.shape": "Mapped from emitter.shape.type and shape parameters.",
21
- "ParticleSystem.colorGradient": "emitter.alphaKeys applied to the final ParticleSystem.color1.",
22
- "ParticleSystem.sizeGradient": "emitter.sizeKeys multiplied by emitter.maxSize.",
23
- },
24
- };
25
-
26
- const BABYLON_PARTICLE_UPDATE_SPEED_UNIT = 0.01;
27
-
28
- function num(value, fallback = 0) {
29
- const next = Number(value);
30
- return Number.isFinite(next) ? next : fallback;
31
- }
32
-
33
- function readColor(BABYLON, value, fallback = new BABYLON.Color4(1, 1, 1, 1)) {
34
- if (!value) return fallback;
35
- return new BABYLON.Color4(num(value.r, fallback.r), num(value.g, fallback.g), num(value.b, fallback.b), num(value.a, fallback.a));
36
- }
37
-
38
- function applyRenderColorIntensity(BABYLON, color, renderColor = {}) {
39
- const colorIntensity = Math.max(0, num(renderColor.colorIntensity, 1));
40
- const alphaIntensity = Math.max(0, num(renderColor.alphaIntensity, colorIntensity));
41
- return new BABYLON.Color4(
42
- color.r * colorIntensity,
43
- color.g * colorIntensity,
44
- color.b * colorIntensity,
45
- Math.min(1, color.a * alphaIntensity)
46
- );
47
- }
48
-
49
- function particleColors(BABYLON, emitter) {
50
- const renderColor = emitter.renderColor;
51
- const baseColor = readColor(BABYLON, renderColor?.color, new BABYLON.Color4(1, 1, 1, 1));
52
- const color1 = applyRenderColorIntensity(BABYLON, baseColor, renderColor);
53
- return {
54
- color1,
55
- color2: color1,
56
- colorDead: new BABYLON.Color4(color1.r, color1.g, color1.b, 0),
57
- };
58
- }
59
-
60
- function readVec(BABYLON, value, fallback = new BABYLON.Vector3(0, 0, 0)) {
61
- if (!value) return fallback;
62
- return new BABYLON.Vector3(num(value.x, fallback.x), num(value.y, fallback.y), num(value.z, fallback.z));
63
- }
64
-
65
- function blendMode(BABYLON, value) {
66
- if (value === "STANDARD") return BABYLON.ParticleSystem.BLENDMODE_STANDARD;
67
- if (value === "MULTIPLY") return BABYLON.ParticleSystem.BLENDMODE_MULTIPLY;
68
- if (value === "ONEONE") return BABYLON.ParticleSystem.BLENDMODE_ONEONE;
69
- return BABYLON.ParticleSystem.BLENDMODE_ADD;
70
- }
71
-
72
- function billboardMode(BABYLON, value) {
73
- if (!value || BABYLON.ParticleSystem[value] === undefined) return undefined;
74
- return BABYLON.ParticleSystem[value];
75
- }
76
-
77
- function applyCocosConeEmitFunctions(BABYLON, system, radius, angle, radiusRange) {
78
- const safeRadius = Math.max(0, radius);
79
- const innerSq = (safeRadius * Math.max(0, 1 - radiusRange)) ** 2;
80
- const outerSq = safeRadius * safeRadius;
81
- const halfAngle = Math.min(Math.PI, Math.max(0, angle));
82
- const cosAngle = Math.cos(halfAngle);
83
-
84
- system.startPositionFunction = (worldMatrix, positionToUpdate, _particle, isLocal) => {
85
- const s = Math.random() * Math.PI * 2;
86
- const r2 = innerSq + Math.random() * (outerSq - innerSq);
87
- const r = Math.sqrt(Math.max(0, r2));
88
- const lx = r * Math.cos(s);
89
- const lz = r * Math.sin(s);
90
- if (isLocal) positionToUpdate.set(lx, 0, lz);
91
- else BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(lx, 0, lz, worldMatrix, positionToUpdate);
92
- };
93
-
94
- system.startDirectionFunction = (worldMatrix, directionToUpdate, _particle, isLocal) => {
95
- const phi = Math.random() * Math.PI * 2;
96
- const cosTheta = 1 - Math.random() * (1 - cosAngle);
97
- const sinTheta = Math.sqrt(Math.max(0, 1 - cosTheta * cosTheta));
98
- const dx = sinTheta * Math.cos(phi);
99
- const dy = cosTheta;
100
- const dz = sinTheta * Math.sin(phi);
101
- if (isLocal) directionToUpdate.set(dx, dy, dz);
102
- else BABYLON.Vector3.TransformNormalFromFloatsToRef(dx, dy, dz, worldMatrix, directionToUpdate);
103
- };
104
- }
105
-
106
- function applyEmitterShape(BABYLON, system, emitter) {
107
- const shape = emitter.shape || {};
108
- const type = shape.type;
109
- const radius = num(shape.radius, 1);
110
- const radiusRange = Math.min(1, Math.max(0, num(shape.radiusRange, 1)));
111
- const angle = num(shape.angle, Math.PI / 4);
112
- const direction1 = readVec(BABYLON, shape.direction1, new BABYLON.Vector3(0, 1, 0));
113
- const direction2 = readVec(BABYLON, shape.direction2, new BABYLON.Vector3(0, 1, 0));
114
- const boxMin = readVec(BABYLON, shape.minEmitBox, new BABYLON.Vector3(-radius * 0.5, -radius * 0.5, -radius * 0.5));
115
- const boxMax = readVec(BABYLON, shape.maxEmitBox, new BABYLON.Vector3(radius * 0.5, radius * 0.5, radius * 0.5));
116
-
117
- if (type === "Box") {
118
- system.createBoxEmitter(direction1, direction2, boxMin, boxMax);
119
- } else if (type === "SphereDirected") {
120
- system.createDirectedSphereEmitter(radius, direction1, direction2);
121
- } else if (type === "Sphere") {
122
- system.createSphereEmitter(radius, radiusRange);
123
- } else if (type === "Hemisphere") {
124
- system.createHemisphericEmitter(radius, radiusRange);
125
- } else if (type === "Cone") {
126
- const dirSpread = direction1.subtract(direction2).lengthSquared();
127
- if (dirSpread < 1e-4) {
128
- system.createConeEmitter(Math.max(0.001, radius), angle);
129
- applyCocosConeEmitFunctions(BABYLON, system, radius, angle, radiusRange);
130
- } else {
131
- system.createDirectedConeEmitter(Math.max(0.001, radius), angle, direction1, direction2);
132
- }
133
- }
134
- }
135
-
136
- function addGradients(BABYLON, system, emitter, color1) {
137
- for (const key of emitter.alphaKeys || []) {
138
- const time = Math.min(1, Math.max(0, num(key.time, 0)));
139
- const alpha = Math.min(1, Math.max(0, num(key.alpha, 1)));
140
- system.addColorGradient?.(time, new BABYLON.Color4(color1.r, color1.g, color1.b, Math.min(1, color1.a * alpha)));
141
- }
142
- for (const key of emitter.sizeKeys || []) {
143
- const time = Math.min(1, Math.max(0, num(key.time, 0)));
144
- const size = Math.max(0.001, num(key.size, 1) * num(emitter.maxSize, 1));
145
- system.addSizeGradient?.(time, size);
146
- }
147
- }
148
-
149
- function playbackSpeed(emitter) {
150
- return Math.max(0.001, num(emitter.updateSpeed, BABYLON_PARTICLE_UPDATE_SPEED_UNIT) / BABYLON_PARTICLE_UPDATE_SPEED_UNIT);
151
- }
152
-
153
- function runtimeDuration(emitter) {
154
- return Math.max(0.1, num(emitter.runtime?.stopAfterSeconds, 3) / playbackSpeed(emitter));
155
- }
156
-
157
- export async function createParticleEmitterRuntime({ BABYLON, scene, emitter, index = 0, urlForPackagePath, shouldStart = false }) {
158
- if (!BABYLON) throw new Error("createParticleEmitterRuntime requires BABYLON.");
159
- if (!scene) throw new Error("createParticleEmitterRuntime requires scene.");
160
- if (!emitter) throw new Error("createParticleEmitterRuntime requires emitter.");
161
-
162
- const capacity = Math.max(1, Math.round(num(emitter.capacity, 100)));
163
- const system = new BABYLON.ParticleSystem(`particle-emitter-${emitter.name || index}`, capacity, scene);
164
- const textureUrl = urlForPackagePath ? urlForPackagePath(emitter.particleTexturePath) : emitter.particleTexturePath;
165
- system.particleTexture = new BABYLON.Texture(textureUrl, scene);
166
- system.particleTexture.hasAlpha = true;
167
- system.emitter = BABYLON.Vector3.Zero();
168
- system.blendMode = blendMode(BABYLON, emitter.blendMode);
169
- system.isLocal = emitter.isLocal === true;
170
- system.minSize = Math.max(0.001, num(emitter.minSize, 1));
171
- system.maxSize = Math.max(system.minSize, num(emitter.maxSize, system.minSize));
172
- system.minScaleX = Math.max(0.001, num(emitter.minScaleX, 1));
173
- system.maxScaleX = Math.max(system.minScaleX, num(emitter.maxScaleX, system.minScaleX));
174
- system.minScaleY = Math.max(0.001, num(emitter.minScaleY, 1));
175
- system.maxScaleY = Math.max(system.minScaleY, num(emitter.maxScaleY, system.minScaleY));
176
- system.minLifeTime = Math.max(0.02, num(emitter.minLifeTime, 0.55));
177
- system.maxLifeTime = Math.max(system.minLifeTime, num(emitter.maxLifeTime, system.minLifeTime));
178
- system.minEmitPower = Math.max(0, num(emitter.minEmitPower, 1));
179
- system.maxEmitPower = Math.max(system.minEmitPower, num(emitter.maxEmitPower, system.minEmitPower));
180
- system.updateSpeed = Math.max(0.00001, num(emitter.updateSpeed, BABYLON_PARTICLE_UPDATE_SPEED_UNIT));
181
- system.gravity = readVec(BABYLON, emitter.gravity, new BABYLON.Vector3(0, -6, 0));
182
- system.emitRate = Math.max(0, num(emitter.emitRate, 0));
183
- if (system.emitRate <= 0) system.manualEmitCount = Math.max(0, Math.round(num(emitter.manualEmitCount, 0)));
184
-
185
- const colors = particleColors(BABYLON, emitter);
186
- system.color1 = colors.color1;
187
- system.color2 = colors.color2;
188
- system.colorDead = colors.colorDead;
189
- system.minInitialRotation = num(emitter.minInitialRotation, 0);
190
- system.maxInitialRotation = num(emitter.maxInitialRotation, system.minInitialRotation);
191
- system.minAngularSpeed = num(emitter.minAngularSpeed, 0);
192
- system.maxAngularSpeed = num(emitter.maxAngularSpeed, system.minAngularSpeed);
193
-
194
- const nextBillboardMode = billboardMode(BABYLON, emitter.billboardMode);
195
- if (nextBillboardMode !== undefined) system.billboardMode = nextBillboardMode;
196
-
197
- applyEmitterShape(BABYLON, system, emitter);
198
- addGradients(BABYLON, system, emitter, system.color1);
199
-
200
- const preview = {
201
- start: () => system.start(),
202
- stop: () => system.stop(),
203
- dispose: () => system.dispose(),
204
- isStarted: () => system.isStarted(),
205
- duration: runtimeDuration(emitter),
206
- system,
207
- };
208
- if (shouldStart) preview.start();
209
- return preview;
210
- }