Частицы — GPUParticles3D и CPUParticles3D
ParticleProcessMaterial, эмиттеры, sub-emitters, collision.
В Godot два узла для частиц с похожим API:
- GPUParticles3D — на GPU, до миллионов частиц.
- CPUParticles3D — на CPU, fallback для слабого железа и веба.
| Параметр | GPUParticles3D | CPUParticles3D |
|---|---|---|
| Где вычисляется | GPU (compute) | CPU |
| Максимум частиц | Миллионы | ~10 000 |
| Compatibility-рендер | Работают с оговорками (требуется compute) | Работают везде |
| Web-цель | Ограниченно (зависит от WebGL) | Работают |
| Per-particle GDScript-доступ | Нет | Да |
Грубое правило: GPU где можно, CPU где обязательно.
ParticleProcessMaterial
Главное отличие от Unity Particle System: поведение частиц задаётся не в инспекторе узла, а в
отдельном ресурсе ParticleProcessMaterial. Это удобно — можно сохранить, переиспользовать,
override в инстансах.
@onready var particles: GPUParticles3D = $GPUParticles3D
func _ready() -> void:
var mat: ParticleProcessMaterial = particles.process_material
mat.initial_velocity_min = 5.0
mat.initial_velocity_max = 10.0
mat.gravity = Vector3(0, -3, 0)
Главные секции ParticleProcessMaterial:
- Direction + spread — направление выброса.
- Initial Velocity (min/max) — стартовая скорость.
- Gravity — на каждую частицу.
- Linear / Angular / Radial Accel — постоянные ускорения.
- Damping — гашение скорости.
- Color + Color Curve — цвет и кривая по жизни.
- Scale + Scale Curve — размер.
- Hue Variation, Anim Speed / Offset — для текстурных листов.
- Emission Shape —
POINT,SPHERE,BOX,POINTS,DIRECTED_POINTS,RING.
GPUParticles3D — узел
Главные свойства на самом узле:
amount— максимальное число одновременных частиц.lifetime— время жизни в секундах.one_shot— одноразовый выстрел или непрерывный.explosiveness— 0..1, насколько “залпом” вылетают (0 = равномерно, 1 = все одновременно).emitting— испускать сейчас.fixed_fps— фиксированная частота обновления (0 = с FPS).local_coords— позиции частиц локальные или мировые.
# Запуск одноразового взрыва
func boom(at: Vector3) -> void:
var explosion = explosion_scene.instantiate()
explosion.global_position = at
get_tree().current_scene.add_child(explosion)
explosion.emitting = true # включить эмиссию
# Автоудаление
func _on_finished() -> void:
queue_free()
Сигнал finished срабатывает после lifetime (для one_shot = true).
Trails (следы)
Каждая частица может оставлять trail — узкую ленту, идущую за ней:
trail_enabled = trueна узле GPUParticles3D.trail_lifetime— длина следа в секундах.- Mesh trail (если хотите кастомный mesh) — через
draw_pass_1.mesh.
Полезно для пуль-трассеров, спецэффектов магии.
Sub-emitters
GPUParticles3D могут испускать другие частицы при определённых событиях:
Explosion (GPUParticles3D — главный)
└── SubEmitter (GPUParticles3D — sub)
Виды sub-emitter activation:
- CONSTANT — постоянно от каждой родительской частицы.
- AT_END — в момент смерти родителя.
- AT_COLLISION — при касании коллайдера (требует collision_enabled).
Пример: ракета (родительская частица) — при касании земли испускает 50 искр (sub-emitter).
Collision с миром
Чтобы частицы реагировали на коллизии:
ParticleProcessMaterial.collision_mode = COLLISION_RIGID(отскакивают) илиCOLLISION_HIDE_ON_CONTACT.- Добавьте на сцену GPUParticlesCollisionSphere3D, GPUParticlesCollisionBox3D, GPUParticlesCollisionHeightField3D или GPUParticlesCollisionSDF3D — это специальные коллайдеры только для частиц, отдельные от физических.
GPU-частицы НЕ сталкиваются с обычными StaticBody3D / Collider’ами. Они используют отдельную
систему GPUParticlesCollision* узлов. Это сделано для производительности GPU-симуляции.
Visibility AABB
GPUParticles3D имеют visibility_aabb — bounding box, в пределах которого они считаются видимыми. Если AABB вне камеры — частицы не симулируются.
По умолчанию AABB маленький (вокруг эмиттера) и частицы, улетевшие далеко, могут “пропадать”. Решение: вручную задать большой AABB или нажать Generate AABB в редакторе (Godot подберёт по симуляции).
particles.visibility_aabb = AABB(Vector3(-20, -20, -20), Vector3(40, 40, 40))
ProcessMaterial vs ShaderMaterial для частиц
ParticleProcessMaterial — стандартный, покрывает 90% задач. Если нужно нестандартное поведение
(specific вихрь, attractor по сложной формуле), пишите свой ShaderMaterial с
shader_type particles:
shader_type particles;
render_mode keep_data;
uniform vec3 swirl_center;
uniform float swirl_strength;
void process() {
vec3 to_center = swirl_center - TRANSFORM[3].xyz;
float dist = length(to_center);
vec3 tangent = normalize(cross(to_center, vec3(0, 1, 0)));
VELOCITY += tangent * swirl_strength * (1.0 / max(dist, 0.5));
TRANSFORM[3].xyz += VELOCITY * DELTA;
}
Это процессинг-шейдер. Рендерится частица отдельным draw pass материалом (через
draw_pass_1 на GPUParticles3D).
CPUParticles3D — когда полезно
- Web-сборка с Compatibility-рендером — GPU-симуляция там работает не везде (особенно на WebGL без compute).
- Per-particle логика на GDScript — если хотите менять отдельные частицы в коде.
- Старое железо, где compute shader недоступен.
API почти идентично, но настройки — прямо на узле (без отдельного ProcessMaterial).
Профайлинг
GPU-частицы — одна из самых нагружающих фич. В Debugger → Profiler → Visual смотрите время
prepare/process. Если 10000+ частиц на слабом телефоне — режьте amount и lifetime.
В следующей главе — мультиплеер.