Files
SpineParticlesWeb/Document/网页粒子系统阶段四.md
T
2026-09-02 10:45:10 +08:00

343 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 网页粒子系统 · 阶段四
> 阶段定位:**修改器模块第一阶段定版**
> 完成日期: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 固定与随机
- 固定模式下,全部粒子使用当前固定强度;
- 随机模式下,每个粒子出生时在 `minmax` 中独立采样;
- 随机结果受全局随机种子控制;
- 已出生粒子的随机强度保持不变。
### 4.3 生命周期内重力
生命周期曲线的横轴为归一化生命时间 `01`,纵轴为重力倍率 `01`。最终重力为:
```text
最终重力 = 粒子重力强度 × 生命周期曲线倍率
```
曲线支持关键点编辑和恢复默认水平曲线。
---
## 五、风力
风力复用重力的模式结构和生命周期曲线,但使用独立配置。
| 参数 | 默认值 |
|---|---:|
| 模式 | 固定 |
| 风力强度 | 100 |
| 方向 | 0°,水平向右 |
| 生命周期曲线 | 全程 1 |
风力同样支持:
- 固定强度;
- 每个粒子独立的随机强度范围;
- `0°` 向右、`-90°` 向下的数学角度规则;
- 负强度反转方向;
- 生命周期 `01` 倍率曲线;
- 全局随机种子复现。
---
## 六、全局力场
力场以场景全局坐标定义,不跟随粒子系统自身的位移、旋转和缩放。
### 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 类型检查和生产构建保持通过。