> **本文回答**：fx 的 12 点预设 + 5 线预设 —— 各自效果、适合场景、选型指南。

## 一、12 点预设

所有点预设签名：`fx.addPoint(name, opts) → handle`。

| # | 预设 | 视觉 | 典型用途 |
|---|---|---|---|
| 1 | `fire` | 火焰（动态噪声 + 暖色） | 故障点 / 燃烧告警 |
| 2 | `pulseRing` | 脉冲光环（持续扩散） | 监控告警 / 活动节点 |
| 3 | `halo` | 柔光光晕（静态发光） | 重要位置突出 / hover 提示 |
| 4 | `radarSweep` | 雷达扫描（扇形旋转） | 扫描范围 / 动态指示 |
| 5 | `smoke` | 烟雾（柔和粒子） | 工厂 / 事故现场 |
| 6 | `lightning` | 闪电（分叉动画） | 瞬时告警 / 一次性触发 |
| 7 | `meteor` | 流星（拖尾扩散） | 动态飞入点 / 粒子爆炸 |
| 8 | `vortex` | 漩涡（旋转几何） | 动态压制 / 风暴中心 |
| 9 | `shield` | 护盾（几何网格） | 防护范围 / 隔离区 |
| 10 | `firework` | 烟花（一次性爆炸） | 庆祝 / 警报一次 |
| 11 | `crosshair` | 十字锁定（描边瞄准） | 战术锁定关键目标 |
| 12 | `shadertoy` | ⚠️ 1.0.1 经 `addPoint` 用时**忽略 `fragmentShader`，渲染的是 fire 着色器** | 自定义 GLSL 请改用 `fx.addShadertoy`（见 [shadertoy](#四shadertoy-入口)） |

## 二、通用字段

```js
fx.addPoint('halo', {
  cad: [100, 200],         // 或 lngLat / mercator
  size: 80,                // 尺寸（默认 'map' 单位）
  sizeUnits: 'map',        // 'map' 跟随缩放 / 'pixels' 屏幕恒定
  color: [1, 0.5, 0, 1],   // RGBA 0~1
  params: [0, 1, 1, 0.5],  // [kind, p1, p2, p3]：槽 0 会被强制覆盖为预设 kind，只需关心 1..3
  bucket: 'above',         // 'below' / 'above' / 'topmost'
  visible: true,
  triggerOnce: false,      // 一次性
  ttl: 2000                // 一次性的生命周期（ms）
});
```

`params[0]` 是预设 kind——实现里会被**强制覆盖**为所选预设的 kind 值，传什么都被忽略；`params[1..3]` 才是可调参数（含义随预设变化）。注意 `params` 若传**必须恰好是长度 4 的 vec4**（`SymbolFxImage.setParams`/preset 校验长度，不对直接 throw）。

## 三、5 线预设

签名：`fx.addLine(name, opts) → handle`。

| # | 预设 | 视觉 | 典型用途 |
|---|---|---|---|
| 1 | `flowLine` | 流光管线（光沿线跑） | 管道 / 链路流向 |
| 2 | `meteor` | 流星线（头亮尾淡） | 态势飞线 / 攻击路径 |
| 3 | `lightning` | 闪电线（分叉抖动） | 瞬时告警路径 |
| 4 | `arrowFlow` | 箭头流动（带方向） | 有向图 / 数据流 |
| 5 | `dashFlow` | 虚线流动 | 非实体线 / 提示 |

```js
fx.addLine('flowLine', {
  path: { cad: [[x1, y1], [x2, y2], [x3, y3]] },  // FxPathInput：cad / lngLat / mercator 三选一
  width: 4,          // 线宽（widthUnits 默认 'pixels'）
  color: [0, 1, 1, 1],
  bucket: 'above'
});
```

## 四、Shadertoy 入口

3 个自定义入口：

```js
// 三者都是单参数 opts 对象
fx.addShadertoy({ cad: [x, y], fragmentShader: 'void mainImage(...)...', size: 120 });
fx.addShadertoyLine({ path: { cad: [[x1,y1],[x2,y2]] }, fragmentShader: '...', width: 6 });
fx.addShadertoyFullscreen({ fragmentShader: '...' });   // 全屏 NDC 覆盖，不绑坐标
```

支持 5 种 `alphaMode`：`premul / opaque / additive / luma / colorKey`，用于和底图混合。

详见 vjmapext 的 fx shadertoy 文档（MCP `mapext/docs/fx/shadertoy.md`，入口 `https://vjmap.com/server/aimcp/mcp?products=mapext`）。

## 五、一次性触发

```js
fx.addPoint('lightning', {
  cad: [x, y], size: 60,
  triggerOnce: true,
  ttl: 800          // 800ms 后自动移除
});
```

内建 `lightning` 和 `firework` 是"瞬发即灭"型；`triggerOnce: true` 跑完自动清理。

## 六、选型指南

### 数量

| 数量 | 推荐 |
|---|---|
| < 100 | 任何预设都 OK |
| 100~1000 | 全部 standard / 部分 lite |
| 1000~10000 | lite + 精选 2~3 个预设 |
| > 10000 | `fx.symbolImage` 走 symbol 图层 |

### 场景

| 场景 | 推荐预设 |
|---|---|
| 动态告警 | `pulseRing` / `halo` / `fire` |
| 瞬时事件 | `lightning` / `firework`（triggerOnce） |
| 流向 | `flowLine` / `arrowFlow` / `meteor` line |
| 范围 | `shield` / `radarSweep` |
| 锁定 | `crosshair` |
| 高级自定义 | `fx.addShadertoy`（不是 `addPoint('shadertoy')`） |

## 七、CAD 实体绑定 FX

```js
const circle = new vjmapext.CircleEnt([100, 200], 50);
mapcadLayer.addEntity(circle);

fx.bindToEntity(circle, 'pulseRing', {
  color: [1, 0, 0, 1],
  size: 60
});

// 实体动 → FX 跟随；实体删 → FX 自动清理
```

## 八、关掉不用的预设省 GPU

```js
// 清空某预设在默认 'above' 桶的全部实例（replaceAllPoints 传空数组）
fx.replaceAllPoints('fire', []);
// 或整个 FX 层清空（所有预设所有 bucket）：fx.removeAll()
```

预设首次使用时编译 shader / 创建 buffer；不再用时可清零回收。**没有 `removeAllOfPreset`**——按预设清空用 `replaceAllPoints(preset, [])`，按句柄删单个用 `fx.remove(handle)`。

⚠️ `replaceAllPoints` 的限制（1.0.1）：
- **只动默认 `above` 桶**：`below`/`topmost` 里的同预设实例不清；新列表里每项的 `bucket` 也被忽略，一律加进 `above`。
- 不走 `addPoint` 的语法糖：`triggerOnce`/`ttl` 自动移除、lightning 的 `strikeEvery` 都不生效。
- 它会重置该预设的槽位分配器——之前拿到的该预设句柄（含 `bindToEntity` 绑定的）全部失效，甚至可能与新点串号；有实体绑定的预设别用它整批替换。

## 九、色彩搭配建议

| 语义 | 色值（RGBA 0~1） |
|---|---|
| 告警红 | `[1, 0, 0, 1]` |
| 警告橙 | `[1, 0.5, 0, 1]` |
| 信息蓝 | `[0, 0.7, 1, 1]` |
| 成功绿 | `[0, 1, 0.3, 1]` |
| 高亮金 | `[1, 0.85, 0, 1]` |

alpha 0.8~0.9 对光晕类效果自然；完全不透明会掩盖底图。

## 十、常见坑

1. **params[0] 传了自定义值**：无害但无效——实现会强制覆盖为预设 kind；要调效果改 p1/p2/p3（各预设含义不同）。
2. **颜色传 0~255**：FX 要 0~1；传错没错误但色很淡。
3. **sizeUnits 用 `pixels` 但 size 太大**：屏占比大 → GPU 贵；用 map 跟随缩放。
4. **所有预设都 cinematic**：卡；按重要度选档。
5. **triggerOnce 但没 ttl**：内建 lightning/firework 有默认 ttl；自定义没有 ttl 永不清理。
6. **`addLine` 的坐标要包在 `opts.path` 里**：`addLine('flowLine', { cad: [[x1,y1],[x2,y2]] })`（把 cad 写在 opts 顶层）会抛 `Cannot read properties of undefined (reading 'lngLat')`——校验器读的是 `opts.path.cad`。正确形态 `addLine('flowLine', { path: { cad: [[...]] } })`。
7. **校验报错是无条件的，并非只在 dev 抛出**：`fx.addPoint('not-a-preset', {cad})` 抛 `[FX] unknown point preset`，缺坐标（`cad`/`lngLat`/`mercator` 三选一都不给）、`size<=0`、非法 `bucket`、`params` 非 vec4 同样**总是抛错**——`addPoint/addLine/addPoints` 的 `validatePointOptions/validateLineOptions` 在调用链上不被环境门控。真正被 `if(ht)`（`typeof process==="undefined" || NODE_ENV!=="production"`）包裹的只是 `addShadertoy/addShadertoyLine/addShadertoyFullscreen/setShadertoyUniforms` 里的 `mainImage` 正则、`resolution` 等**额外**校验——而浏览器里 `process` 未定义使 `ht` 恒为 true，这些校验在 vite 产物中实际也总是执行。

## 相关

- FX 总览 → [fx-overview](fx-overview.md)
- 运行时调优 → [fx-quality](fx-quality.md)
- 大量点 → [large-markers](../../../vjmap/references/perf/large-markers.md)
