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