13 KiB
网页粒子系统 · 阶段四
阶段定位:修改器模块第一阶段定版
完成日期:2026-08-28
工程目录:/Users/tianmokeji/Desktop/SpineParticle
技术栈:Vue 3 + TypeScript + Pinia + PixiJS 7 + Vite
一、阶段结论
阶段四围绕粒子系统的外部运动影响完成开发,已经实现并接入实时预览的修改器包括:
- 移动噪声;
- 重力;
- 风力;
- 全局力场;
- 吸附。
本阶段同时统一了场景初始状态和随机种子语义:打开项目时默认创建一个粒子系统,仅展开“场景对象”模块,其他模块保持折叠;所有修改器默认关闭。随机种子移动到场景对象模块,作为粒子系统全局随机入口,相同种子能够复现随机初始属性、资源选择和修改器采样结果。
阶段四结束后,项目已经具备“基础发射参数 + 外观资源 + 生命周期属性 + 多种运动修改器 + 画布辅助交互”的完整实时编辑链路。
二、初始状态与全局随机种子
2.1 默认场景状态
- 场景中默认创建一个名为
ParticleSystem1的粒子系统; - “场景对象”模块默认展开;
- 发射、形状、粒子属性、外观资源、修改器和导出等模块默认折叠;
- 移动噪声、重力、风力、力场和吸附默认关闭;
- 原有粒子属性、外观资源和时间轴功能保持不变。
2.2 随机种子
随机种子从“粒子属性”移动到“场景对象”,其影响范围扩展为整个粒子系统:
- 初始生命周期、速度、缩放和旋转的随机采样;
- 图片资源的随机选择;
- 重力和风力的粒子级随机强度;
- 移动噪声的粒子相位;
- 曲线吸附的弯曲方向。
包括 0 在内的任意整数种子都使用确定性随机序列。重新模拟相同配置时,可以获得一致的粒子结果。
三、移动噪声
移动噪声用于在不破坏基础物理轨迹的前提下,为粒子增加连续的视觉偏移。
| 参数 | 默认值 | 作用 |
|---|---|---|
| 强度 | 30 | 控制噪声影响比例,范围 0~100% |
| 波动范围 | 100 | 控制粒子偏离原轨迹的最大范围 |
| 时间流速 | 1 | 控制噪声随时间变化的速度 |
实现规则:
- 噪声只作用于最终渲染位置,粒子的基础
x/y和速度仍由物理系统维护; - 每个粒子使用由全局种子和粒子池编号推导的独立相位;
- 出生时减去初始噪声采样,保证粒子仍从原发射点出现;
- 使用连续正弦变化避免逐帧随机产生的跳动;
- 反复关闭、开启且参数和种子相同时,轨迹保持可复现。
四、重力
重力支持固定强度、粒子级随机强度、方向和生命周期曲线。
4.1 默认值与方向
| 参数 | 默认值 |
|---|---|
| 模式 | 固定 |
| 重力强度 | 980 |
| 方向 | -90° |
| 生命周期曲线 | 全程 1 |
方向使用数学角度:
0°:向右;-90°:向屏幕下方;- 正强度沿设定方向作用;
- 负强度使作用方向反转。
4.2 固定与随机
- 固定模式下,全部粒子使用当前固定强度;
- 随机模式下,每个粒子出生时在
min~max中独立采样; - 随机结果受全局随机种子控制;
- 已出生粒子的随机强度保持不变。
4.3 生命周期内重力
生命周期曲线的横轴为归一化生命时间 0~1,纵轴为重力倍率 0~1。最终重力为:
最终重力 = 粒子重力强度 × 生命周期曲线倍率
曲线支持关键点编辑和恢复默认水平曲线。
五、风力
风力复用重力的模式结构和生命周期曲线,但使用独立配置。
| 参数 | 默认值 |
|---|---|
| 模式 | 固定 |
| 风力强度 | 100 |
| 方向 | 0°,水平向右 |
| 生命周期曲线 | 全程 1 |
风力同样支持:
- 固定强度;
- 每个粒子独立的随机强度范围;
0°向右、-90°向下的数学角度规则;- 负强度反转方向;
- 生命周期
0~1倍率曲线; - 全局随机种子复现。
六、全局力场
力场以场景全局坐标定义,不跟随粒子系统自身的位移、旋转和缩放。
6.1 参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| 中心 X/Y | 0 / 0 | 场景全局数学坐标 |
| 力场强度 | 10 | 正数吸引,负数排斥 |
| 力场半径 | 100 | 力场作用范围 |
| 衰减模式 | 线性衰减 | 边缘强度为 0 |
6.2 衰减模式
- 恒定:半径范围内力度不变;
- 线性衰减:中心最强,接近边缘时线性下降为 0;
- 距离反比:距离中心越近力度越强,并设置中心上限以避免数值爆炸。
6.3 坐标与物理计算
每帧先将粒子从发射器局部坐标转换为场景全局数学坐标,计算力场加速度,再将加速度转换回粒子系统局部坐标。因此:
- 力场中心始终位于固定的场景位置;
- 粒子系统经过位移、旋转或非等比缩放后,力场方向仍正确;
- 正强度始终把粒子拉向中心;
- 负强度始终把粒子推离中心。
6.4 画布交互
- 开启后在画布显示力场作用圆和中心标记;
- 正吸力使用蓝色,负斥力使用红色;
- 按住圆内任意位置即可拖动力场中心;
- 拖动结果实时同步到面板中心 X/Y;
- 圆形辅助线使用全局坐标,不应用粒子系统根变换。
七、吸附
吸附用于在延迟结束后,把粒子从当时所在位置移动到指定全局点;粒子进入吸附完成半径后立即死亡。
7.1 默认参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| 吸附点 X | 200 | 场景全局数学坐标 |
| 吸附点 Y | 0 | 场景全局数学坐标 |
| 吸附半径 | 20 | 进入范围即视为完成并死亡 |
| 吸附时长 | 0.5 秒 | 从当前点移动到吸附点的时间 |
| 延迟时间 | 0.1 秒 | 延迟结束后开始受吸附影响 |
| 延迟方式 | 单粒子生命 | 每个粒子按出生时间独立计时 |
| 吸附方式 | 曲线 | 使用确定性的二次曲线路径 |
吸附模块默认关闭。
7.2 延迟方式
| 模式 | 行为 |
|---|---|
| 统一时间 | 从吸附开关开启时统一计时;延迟结束后,当前及之后的粒子立即具备吸附条件 |
| 单粒子生命 | 每个粒子从出生开始独立计时,达到延迟时间后才开始吸附 |
7.3 吸附路径
- 直线:从吸附开始时的位置匀速插值到吸附点;
- 曲线:使用二次贝塞尔曲线移动,曲线弯曲方向由全局种子和粒子编号确定;
- 吸附开始时记录粒子的实际当前位置,不会跳回出生点;
- 拖动画布上的吸附点时,正在吸附的粒子会继续朝新的目标位置移动。
7.4 死亡规则
粒子在以下任一条件先满足时死亡:
- 进入吸附半径;
- 吸附路径进度达到终点;
- 粒子自身生命周期耗尽。
生命周期判断优先于吸附计算,因此吸附不会延长粒子原本的生命。吸附半径可设为 0,此时目标表示一个点,粒子到达中心后死亡。
7.5 画布交互
- 开启后在画布显示红色吸附圆和中心十字;
- 半径为
0时显示红色中心点; - 可按住吸附圆拖动全局位置;
- 半径为
0时仍保留约 12 像素的鼠标命中区域,便于拖动; - 拖动结果实时同步到面板吸附点 X/Y;
- 吸附圆与力场圆重叠时,红色吸附圆优先接收拖动。
八、修改器执行顺序
当前单帧主要执行顺序为:
- 扣除粒子自身生命周期,生命耗尽则立即销毁;
- 计算重力;
- 计算风力;
- 计算全局力场;
- 应用阻尼;
- 积分基础位置;
- 判断吸附延迟并覆盖吸附路径位置;
- 计算移动噪声的渲染偏移;
- 更新缩放、旋转、透明度、颜色和混合模式;
- 生成实时状态或录制帧。
吸附开始后位置由吸附路径控制,并清除原速度,避免外力积累造成终点抖动。移动噪声仍属于渲染偏移,不改变吸附和物理系统维护的基础坐标。
九、核心实现文件
| 文件 | 本阶段职责 |
|---|---|
src/core/particleEmitter.ts |
修改器配置、默认值、配置补齐、随机采样、重力/风力/力场/吸附/噪声计算 |
src/views/ParticlePanel.vue |
修改器开关、参数控件、模式选择与生命周期曲线 |
src/views/Stage.vue |
全局力场和吸附范围绘制、画布拖动、坐标换算及实时预览 |
src/store/particleStore.ts |
默认粒子系统和编辑器状态的承载 |
为兼容热更新对象和旧配置,ensureEmitterConfig() 会自动补齐新增字段。旧版重力、二维风力和力场参数也保留迁移处理。
十、验证结果
本阶段已完成以下检查:
- 相同种子下移动噪声重复开启可得到一致结果;
- 重力方向
0°向右、-90°向下; - 重力和风力固定/随机模式能正确切换;
- 生命周期倍率曲线已参与重力和风力计算;
- 力场三种衰减模式可切换且配置实时生效;
- 力场圆画布拖动与面板坐标同步;
- 吸附默认参数、延迟模式、路径模式、死亡优先级均已接入运行逻辑;
npm run build通过;git diff --check通过。
Vite 仍会提示主包体积超过 500 kB,该提示不影响当前功能运行。
十一、当前边界与已知风险
- 拖尾尚未实现:当前只有配置开关,没有轨迹采样和渲染逻辑。
- 碰撞尚未实现:界面仍标记为预留,未定义碰撞体和反弹规则。
- 路径跟随尚未实现:界面仍标记为预留,尚未建立路径编辑和粒子约束。
- 修改器组合缺少系统测试:重力、风力、力场、吸附和噪声同时开启时,需要补充参数极值和稳定性测试。
- 吸附曲线暂为自动弧线:当前不能由用户编辑控制点,也没有自定义吸附曲线编辑器。
- 辅助圆没有独立显示开关:开启力场或吸附后,选中系统时始终显示对应辅助范围。
- 工程保存/加载尚未完成:新增修改器字段目前依赖内存配置和默认值,尚未形成正式版本化工程格式。
- 缺少自动化单元测试:当前主要依赖类型检查、生产构建和人工交互验证。
十二、下一步开发建议
优先级 P0:修改器模块收尾
建议按以下顺序继续,避免同时扩散多个高成本功能:
- 拖尾:确定每粒子采样点上限、宽度/颜色/透明度生命周期和对象池;
- 碰撞:先支持全局直线、矩形和圆形碰撞体,再扩展反弹、摩擦和死亡;
- 路径跟随:复用吸附的全局坐标与曲线求值,增加可编辑路径控制点;
- 增加修改器总开关、辅助线显示开关和单项重置。
优先级 P1:工程保存与加载
- 定义
ProjectSchema和schemaVersion; - 将 Pixi 运行时对象与可序列化参数分离;
- 保存全部修改器开关、模式、曲线和全局坐标;
- 为阶段三、阶段四配置建立明确迁移函数;
- 支持工程 JSON 或包含资源的 ZIP 工程包。
优先级 P2:修改器组合测试
- 为全局/局部坐标转换增加单元测试;
- 验证旋转、负缩放、非等比缩放下的力场和吸附;
- 测试极短生命周期、零延迟、零半径和极短吸附时长;
- 测试正负极值、帧率波动和大粒子数量;
- 固化相同种子的轨迹快照,防止随机语义回归。
优先级 P3:交互与可视化
- 力场和吸附中心增加悬停、选中和拖动反馈;
- 为圆形辅助线增加半径拖拽手柄;
- 在画布标注半径、强度方向和中心坐标;
- 增加修改器辅助线显隐入口;
- 处理力场、吸附点、根变换 Gizmo 重叠时的明确选中规则。
优先级 P4:性能与导出准备
- 避免每帧重复查找资源配置;
- 为多个全局力场或碰撞体预留空间索引;
- 明确修改器结果在固定帧录制中的采样精度;
- 验证吸附死亡对粒子骨骼池和导出帧的影响;
- 对 400 粒子上限进行组合修改器性能压测。
十三、阶段四验收标准
阶段四可视为完成,当以下条件持续满足:
- 默认场景和模块折叠状态符合约定;
- 所有已实现修改器默认关闭;
- 移动噪声受全局随机种子控制且可复现;
- 重力和风力的固定、随机、方向与生命周期曲线真实生效;
- 力场使用全局坐标并支持吸力、斥力、三种衰减和画布拖动;
- 吸附支持全局点、完成半径、时长、两种延迟方式、两种路径和画布拖动;
- 粒子进入吸附范围或自身生命周期结束时能够正确销毁;
- 阶段三已经完成的粒子属性与外观资源功能没有发生回归;
- TypeScript 类型检查和生产构建保持通过。