mcpField
P
particles-vfx

particles-vfx

github.com/jame581创意与媒体889198 次安装4 天前更新
代码仓库

关于 particles-vfx

面向 Godot 4.3+ 开发者的粒子与 VFX 技能,覆盖 2D、3D 粒子系统的配置、常见效果制作和性能排查。

主要功能

  1. 01比较 GPU 与 CPU 粒子节点
  2. 02设置发射材质与粒子行为
  3. 03制作火焰、爆炸和尘土效果
  4. 04配置轨迹、子发射器与碰撞
  5. 05排查粒子效果与性能问题

适用场景

  1. 01为游戏制作持续火焰效果
  2. 02触发爆炸或冲击粒子
  3. 03为粒子添加轨迹或子发射效果
  4. 04降低低端设备上的粒子开销

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jame581/godotprompter --skill particles-vfx

安装后在 Claude Code 中输入/particles-vfx确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
attractors-and-collision.md
flipbook-animation.md
performance-and-pitfalls.md
process-material-basics.md
subemitters.md
trails.md
vfx-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 粒子
节点处理方式功能适用场景
GPUParticles2DGPU功能全面,支持大量粒子和拖尾大多数 2D 效果
GPUParticles3DGPU功能全面,支持吸引器和碰撞大多数 3D 效果
CPUParticles2DCPU功能较简单,不支持拖尾/吸引器低端设备、少量粒子
CPUParticles3DCPU功能较简单,不支持拖尾/吸引器低端设备、少量粒子

**经验法则:**默认使用 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
最简设置
  1. 添加一个 GPUParticles2D(或 3D)节点
  2. 在检查器 → Process Material → 新建 ParticleProcessMaterial
  3. 设置 Amount(粒子数量)
  4. 配置发射、方向、速度和重力
  5. (2D)设置粒子外观的 Texture
  6. (3D)设置 Draw Pass 1 网格(公告板使用 QuadMesh,或使用自定义网格)

2. 关键节点属性

GPUParticles2D/3D 属性
属性类型描述
emittingbool开始/停止发射
amountint同时存活的粒子总数
lifetimefloat每个粒子的存活秒数
one_shotbool发射一次后停止
preprocessfloat在首帧前模拟的秒数
speed_scalefloat粒子物理的时间倍率
explosivenessfloat0.0 = 在整个生命周期内分散发射,1.0 = 一次性全部发射
fixed_fpsint锁定粒子更新速率(0 = 与渲染 FPS 一致)
local_coordsbool粒子随节点移动(true)或留在世界空间中(false)
draw_orderenumIndex、Lifetime 或 Reverse Lifetime
amount_ratiofloat要发射的粒子比例(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,提供玩家可调整的画质设置
  • 在低端设备上禁用性能开销较大的功能(湍流、拖尾)

评论

支持 Markdown