关于 particles-vfx
面向 Godot 4.3+ 开发者的粒子与 VFX 技能,覆盖 2D、3D 粒子系统的配置、常见效果制作和性能排查。
主要功能
- 01比较 GPU 与 CPU 粒子节点
- 02设置发射材质与粒子行为
- 03制作火焰、爆炸和尘土效果
- 04配置轨迹、子发射器与碰撞
- 05排查粒子效果与性能问题
适用场景
- 01为游戏制作持续火焰效果
- 02触发爆炸或冲击粒子
- 03为粒子添加轨迹或子发射效果
- 04降低低端设备上的粒子开销
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jame581/ godotprompter --skill particles-vfx安装后在 Claude Code 中输入/particles-vfx确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/attractors-and-collision.mdflipbook-animation.mdperformance-and-pitfalls.mdprocess-material-basics.mdsubemitters.mdtrails.mdvfx-recipes.md详细介绍
Godot 4.3+ 中的粒子系统
所有示例均面向 Godot 4.3+,不使用已弃用的 API。先展示 GDScript,再展示 C#。
**相关技能:**自定义粒子着色器请参阅 shader-basics,影响粒子的光照和环境请参阅 3d-essentials,2D 渲染上下文请参阅 2d-essentials,由代码驱动的 VFX 时序请参阅 tween-animation,粒子性能调优请参阅 godot-optimization。
1. 核心概念
GPU 粒子与 CPU 粒子
| 节点 | 处理方式 | 功能 | 适用场景 |
|---|---|---|---|
GPUParticles2D | GPU | 功能全面,支持大量粒子和拖尾 | 大多数 2D 效果 |
GPUParticles3D | GPU | 功能全面,支持吸引器和碰撞 | 大多数 3D 效果 |
CPUParticles2D | CPU | 功能较简单,不支持拖尾/吸引器 | 低端设备、少量粒子 |
CPUParticles3D | CPU | 功能较简单,不支持拖尾/吸引器 | 低端设备、少量粒子 |
**经验法则:**默认使用 GPU 粒子。仅在面向低端设备或 Web 时切换到 CPU 粒子。这两个节点都不会向脚本公开单个粒子的位置,因此若要在粒子位置生成对象,需要自行实现模拟。
你可以在编辑器中转换 GPU 和 CPU 粒子:选择节点 → 工具栏 → 转换为 CPUParticles2D/3D(或反向转换)。
粒子系统架构
GPUParticles2D/3D
├── Process Material (ParticleProcessMaterial) ← physics, emission, color
├── Draw Pass 1 (Mesh) ← what each particle looks like
└── (Optional) Draw Pass 2-4 ← additional meshes
最简设置
- 添加一个 GPUParticles2D(或 3D)节点
- 在检查器 → Process Material → 新建 ParticleProcessMaterial
- 设置 Amount(粒子数量)
- 配置发射、方向、速度和重力
- (2D)设置粒子外观的 Texture
- (3D)设置 Draw Pass 1 网格(公告板使用 QuadMesh,或使用自定义网格)
2. 关键节点属性
GPUParticles2D/3D 属性
| 属性 | 类型 | 描述 |
|---|---|---|
emitting | bool | 开始/停止发射 |
amount | int | 同时存活的粒子总数 |
lifetime | float | 每个粒子的存活秒数 |
one_shot | bool | 发射一次后停止 |
preprocess | float | 在首帧前模拟的秒数 |
speed_scale | float | 粒子物理的时间倍率 |
explosiveness | float | 0.0 = 在整个生命周期内分散发射,1.0 = 一次性全部发射 |
fixed_fps | int | 锁定粒子更新速率(0 = 与渲染 FPS 一致) |
local_coords | bool | 粒子随节点移动(true)或留在世界空间中(false) |
draw_order | enum | Index、Lifetime 或 Reverse Lifetime |
amount_ratio | float | 要发射的粒子比例(0.0–1.0) |
单次发射与持续发射
# Continuous emitter (fire, smoke, ambient dust)
$GPUParticles2D.one_shot = false
$GPUParticles2D.emitting = true
# One-shot burst (explosion, impact splash)
$GPUParticles2D.one_shot = true
$GPUParticles2D.emitting = false # arm it
# Later, trigger:
$GPUParticles2D.restart()
$GPUParticles2D.emitting = true
// Continuous
var particles = GetNode<GpuParticles2D>("GPUParticles2D");
particles.OneShot = false;
particles.Emitting = true;
// One-shot burst
particles.OneShot = true;
particles.Emitting = false;
// Trigger:
particles.Restart();
particles.Emitting = true;
本地公告板对齐(Godot 4.7+)
GPUParticles3D 新增了 TRANSFORM_ALIGN_LOCAL_BILLBOARD(= 4):每个粒子的 Z 轴朝向摄像机,同时保留指定轴——通过 transform_align_axis 选择 X 轴或 Y 轴。对于公告板粒子,transform_align_channel_filter 用于选择要读取哪个自定义通道来计算粒子的角度。ParticleProcessMaterial 可将此功能与各轴的旋转速度配合使用:启用 use_rotation_velocity_3d,然后设置 rotation_velocity_3d_min/max(Vector3,沿粒子的本地轴)以及可选的 rotation_velocity_3d_curve(随生命周期变化的各轴曲线)。
# 3D only — billboard toward the camera while keeping the Y axis fixed.
# Assumes a ParticleProcessMaterial is assigned (section 1 setup).
$GPUParticles3D.transform_align = GPUParticles3D.TRANSFORM_ALIGN_LOCAL_BILLBOARD
$GPUParticles3D.transform_align_axis = RenderingServer.PARTICLES_ALIGN_AXIS_Y
var mat: ParticleProcessMaterial = $GPUParticles3D.process_material
mat.use_rotation_velocity_3d = true
mat.rotation_velocity_3d_min = Vector3(-2.0, 0.0, 0.0)
mat.rotation_velocity_3d_max = Vector3(2.0, 0.0, 0.0)
// Assumes a ParticleProcessMaterial is assigned (section 1 setup).
var particles = GetNode<GpuParticles3D>("GPUParticles3D");
particles.TransformAlign = GpuParticles3D.TransformAlignEnum.LocalBillboard;
particles.TransformAlignAxis = RenderingServer.ParticlesTransformAlignAxis.Y;
var mat = (ParticleProcessMaterial)particles.ProcessMaterial;
mat.UseRotationVelocity3D = true;
mat.RotationVelocity3DMin = new Vector3(-2.0f, 0.0f, 0.0f);
mat.RotationVelocity3DMax = new Vector3(2.0f, 0.0f, 0.0f);
3. ParticleProcessMaterial — 核心属性
材质控制每个粒子的行为:发射形状(Point / Sphere / Box / Ring / Points / Directed Points)、方向 + 扩散 + 初始速度、重力、生命周期内的缩放和颜色(通过 scale_curve / color_ramp)、阻尼、径向 / 切向加速度以及角速度。
请参阅 references/process-material-basics.md,了解发射形状表格,以及每组属性对应的 GDScript 和 C# 代码片段。
按轴设置 3D 缩放和旋转(Godot 4.7+)
可以按轴随机设置缩放和初始朝向,而非统一设置。use_scale_3d 会启用 scale_3d_min/max(每个粒子的随机 Vector3 缩放);use_rotation_3d 会启用 rotation_3d_min/max(Vector3,单位为度——仅适用于 3D)。
mat.use_scale_3d = true
mat.scale_3d_min = Vector3(0.5, 1.0, 0.5)
mat.scale_3d_max = Vector3(1.0, 2.0, 1.0)
mat.use_rotation_3d = true # 3D only
mat.rotation_3d_min = Vector3(0.0, -180.0, 0.0) # degrees
mat.rotation_3d_max = Vector3(0.0, 180.0, 0.0)
mat.UseScale3D = true;
mat.Scale3DMin = new Vector3(0.5f, 1.0f, 0.5f);
mat.Scale3DMax = new Vector3(1.0f, 2.0f, 1.0f);
mat.UseRotation3D = true; // 3D only
mat.Rotation3DMin = new Vector3(0.0f, -180.0f, 0.0f); // degrees
mat.Rotation3DMax = new Vector3(0.0f, 180.0f, 0.0f);
继承发射器缩放(Godot 4.7+)
particle_flag_inherit_emitter_scale(默认值为 false):如果设为 true,粒子会继承发射器节点的缩放。当 local_coords 为 true 时,此设置无效,因为处于本地空间的粒子本来就会受到发射器缩放的影响。
mat.particle_flag_inherit_emitter_scale = true
mat.ParticleFlagInheritEmitterScale = true;
4. 常见 VFX 配方
大多数项目都会用到的配方:火焰(2D,循环发射,搭配暖色渐变 + 缩小)、爆炸喷发(单次发射,高数量、短生命周期)、灰尘 / 脚步扬尘(单次发射,先放大 + 快速淡出)。
请参阅 references/vfx-recipes.md,查看可直接使用的 GDScript 配置代码,以及这三种效果推荐的
ParticleProcessMaterial设置。
5. 拖尾(仅限 Forward+ 和 Mobile)
在 GPUParticles2D/3D 上设置 trail_enabled = true,并指定一个 Mesh(RibbonTrailMesh 或 TubeTrailMesh)。Compatibility 渲染器不支持拖尾。
请参阅 references/trails.md,了解设置步骤和拖尾网格类型对比。
6. 子发射器
粒子可以使另一个粒子系统以固定频率发射,也可以在碰撞时、死亡时或(Godot 4.4+)出生时发射。通过 ParticleProcessMaterial.sub_emitter_mode 和父粒子节点上的 sub_emitter 属性进行配置。
请参阅 references/subemitters.md,了解触发模式、场景设置、GDScript 和 C#(v1.6.0 功能一致性)以及限制。
注意: 将
sub_emitter_keep_velocity = true(默认值为false)时,子发射粒子会在生成时继承父粒子的速度。Godot 4.7 中此行为未发生变化:在 4.7 稳定版发布前,已修复导致继承失效的 4.7 开发版回归问题(GH-118062),因此无需从 4.6 迁移任何内容。
7. 吸引器和碰撞(3D)
GPUParticlesAttractor*3D(Box / Sphere / Vector Field)会将粒子拉向某个区域。GPUParticlesCollision*3D(Box / Sphere / SDF / HeightField)可使粒子与几何体发生碰撞并反弹。Compatibility 支持 Box / Sphere 吸引器和 Box / Sphere / HeightField 碰撞器;Vector Field 吸引器和 SDF 碰撞器需要 Forward+ 或 Mobile。2D 没有吸引器节点,但当设置了 collision_mode 时,GPUParticles2D 会与 LightOccluder2D 节点发生碰撞。
请参阅 references/attractors-and-collision.md,了解每种吸引器和碰撞类型的完整设置方法。
8. 湍流
在 ParticleProcessMaterial 上设置 turbulence_enabled = true,并调整 turbulence_noise_strength(通常为 0.5–2.0)、turbulence_noise_scale(值越大,漩涡越大、越平滑)和 turbulence_noise_speed(让噪声场动起来)。这是为烟雾、火焰和灰尘增添「生命感」的低成本效果。
9. 翻页动画(2D)
通过 ParticleProcessMaterial.AnimSpeedMin/Max 为粒子添加精灵表动画,并通过 CanvasItemMaterial.ParticlesAnimHFrames/VFrames 设置精灵表布局。粒子会在生命周期内逐帧循环播放。
请参阅 references/flipbook-animation.md,了解完整设置方法,以及 GDScript 和 C#(v1.6.0 功能一致性)示例。
10. 性能与常见问题
最显著的优化方法都很直接:将 amount 设为满足视觉效果所需的最小值;对于环境效果,将 fixed_fps 保持为默认值 30(0 表示每帧更新);始终为 2D 粒子设置 visibility_rect;并将 amount_ratio 作为画质滑块提供给用户。Godot 4.7+ 新增了 request_particles_process(),可用于跳转到暂停时间线中的指定位置。
大多数“粒子异常”报告都由已知的 11 种原因之一导致:粒子不可见(没有纹理或绘制通道网格)、粒子消失(lifetime 太短)、单次发射不再触发(上次爆发的粒子完成前,emitting = true 会被忽略;restart() 则会立即重新触发)、方向错误(2D 中 Y 轴方向相反),或基础 color 太暗,导致 color_ramp 的颜色被其相乘而变暗。
完整性能表、4.7+ 时间线跳转 API、动态画质缩放(GDScript + C#),以及完整的问题现象/原因/解决方法表:references/performance-and-pitfalls.md
11. 实现检查清单
- 粒子的
amount设为满足视觉效果所需的最小值 -
lifetime与视觉效果持续时间相符——不要过短或过长 - 对爆发效果(爆炸、撞击)启用
one_shot - 对始终可见的环境效果(火焰、烟雾、灰尘)设置
preprocess - 发射形状与来源几何形状相符(爆炸使用球体,区域效果使用盒体)
- 将
color_ramp的 alpha 在末尾渐变至 0,避免粒子突然消失 - 使用
scale_curve在粒子生命周期内缩小粒子,使其自然淡出 - 正确设置
local_coords——附着效果设为true,世界空间效果设为false - 在单次发射粒子的
lifetime结束后,再加上适当余量,使用queue_free清理粒子 - 设置
visibility_rect(2D),防止粒子过早被剔除 - 动态画质缩放使用
amount_ratio,提供玩家可调整的画质设置 - 在低端设备上禁用性能开销较大的功能(湍流、拖尾)