Создание GPU-эффекта частиц в 3D
Рабочий C#-всплеск: материалы, геометрия, запуск и причины невидимости.
GPU-эффект частиц состоит из трёх отдельных частей: источника (GpuParticles3D в C#), материала симуляции поведения и геометрии/материала для отображения каждой частицы. Одна галочка Emitting не создаёт видимую геометрию.
Создайте эффект в редакторе
- Добавьте Entity GPUParticles3D в 3D-сцену.
- В Process Material создайте
ParticleProcessMaterial. Начните с понятного Direction, небольшой начальной скорости и осмысленной Gravity; не настраивайте несколько сил одновременно. - В Draw Passes назначьте Mesh в Pass 1, например небольшую сферу для функциональной проверки. Назначьте мешу видимый материал поверхности.
- Разместите источник перед активной Camera3D. Освещаемому материалу нужен подходящий свет; unshaded-материал позволяет убрать эту переменную при проверке видимости.
- Задайте Visibility AABB, охватывающий весь эффект, включая движение и размеры мешей. Это граница отсечения видимости, не коллайдер.
- Включите эмиссию для непрерывного эффекта либо One Shot и перезапуск для всплеска.
Проверьте активный рендерер и целевое устройство. Пример ниже исполнен в Forward+/Vulkan на Windows и не подтверждает поведение каждого GPU/бэкенда. GPU-частицы не гарантируют выигрыш производительности для любого маленького эффекта.
Запустите законченный C#-эффект
Сохраните класс в C#-проекте. Он возвращает настроенный источник, не добавляя его в дерево:
using Reckfell;
public static class ParticleBurst
{
// A functional burst. Replace its geometry/material with your effect assets.
// Add to the tree, then call Restart() to trigger it.
public static GpuParticles3D Create()
{
var movement = new ParticleProcessMaterial
{
Direction = Vector3.Up,
Spread = 25f,
Gravity = Vector3.Zero,
InitialVelocityMin = 0.6f,
InitialVelocityMax = 0.6f,
};
var surface = new StandardMaterial3D
{
ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded,
AlbedoColor = new Color(1f, 0.4f, 0.1f),
};
var mesh = new SphereMesh { Radius = 0.06f, Height = 0.12f, Material = surface };
return new GpuParticles3D
{
Emitting = false,
OneShot = true,
Amount = 24,
Lifetime = 0.75,
Explosiveness = 1f,
LocalCoords = true,
UseFixedSeed = true,
Seed = 42,
ProcessMaterial = movement,
DrawPass1 = mesh,
VisibilityAabb = new Aabb(new Vector3(-2, -2, -2), new Vector3(4, 4, 4)),
};
}
}Из своей Entity вызовите var burst = ParticleBurst.Create();, затем AddChild(burst); и burst.Restart();. Разместите эту Entity в точке начала эффекта. Пример явно запускает эмиссию, использует повторяемое зерно и создаёт короткий оранжевый всплеск. Сферы — функциональная геометрия, а не готовый дым, растительность или фотореалистичный эффект. Для своей графики замените отображаемый ассет и материал.
Process Material управляет движением; материал поверхности сферы — видимым цветом и освещением. Изменение материала симуляции не заменяет назначение меша. И наоборот: меш не задаёт симуляцию гравитации или скорости.
Остановка, пауза и повторный запуск различаются
| Действие | Результат |
|---|---|
Emitting = false | Прекратить создание новых частиц. Старые могут оставаться видимыми до истечения жизни. |
SpeedScale = 0 | Приостановить обычное продвижение симуляции; геометрия может продолжать отображаться. Перемещение локального источника всё ещё перемещает видимые частицы. |
Restart() | Очистить/перезапустить цикл и включить эмиссию. Подходит для явного повторного всплеска, в том числе до завершения предыдущего. |
Дождаться Finished | Узнать о завершении one-shot-цикла. Это не универсальный сигнал завершения непрерывного источника, остановленного вручную. |
У взрывного one-shot Emitting уже может быть false, пока частицы ещё живы. Не используйте его как признак «на экране ничего не осталось». Если важно завершение, подключите Finished до запуска. Повторное присваивание Emitting true во время активного one-shot не равно Restart и в этой реализации может отменить ожидающее уведомление о завершении.
UseFixedSeed = true сохраняет заданный Seed между перегрузками Restart в примере. Restart(keepSeed: true) также сохраняет текущее зерно. Одно зерно не гарантирует одинаковую симуляцию на всех драйверах, шагах времени и сборках движка.
Ограничение времени в 1.0.0: после длительной паузы SpeedScale = 0 и возврата к 1 проверенный one-shot может выдать Finished, пока GPU-частицы ещё видны. Таймер Entity умножает накопленное время на текущий масштаб скорости; это не GPU-подтверждение истечения жизни. Не возвращайте эффект с меняющимся временем в пул только по этому сигналу. Фиксированная скорость простого one-shot исключает именно этот случай паузы/возобновления; при изменении времени отдельно проверьте политику жизненного цикла.
Выберите систему координат
При LocalCoords = true существующие частицы следуют за трансформацией источника. Это подходит для эффекта, прикреплённого к движущемуся объекту. При false уже созданные частицы находятся в мировом пространстве, а источник может двигаться дальше: например, оставлять след. Выберите пространство до запуска; переключение работающего эффекта не является автоматическим процессом визуального преобразования между пространствами.
В локальной GPU-проверке симуляция поставлена на паузу, источник перемещён, а оба случая подтверждены пикселями. Поэтому пауза системы частиц не обязана замораживать картинку на экране при движении источника или камеры.
Найдите причину невидимых частиц
| Симптом | Что проверить сначала |
|---|---|
| Частицы не появляются | ProcessMaterial, Draw Pass 1, размер меша, камеру/слои, время обновления и запуск эмиссии. |
| Симуляция есть, изображения нет | Меш и его материал поверхности: удаление DrawPass1 скрывает проверенный эффект, но не является командой остановить симуляцию. |
| Эффект пропадает у края вида | VisibilityAabb должен покрывать всю область движения: невидимая граница может отсечь частицы, которые сами находились бы в кадре. |
| Дым выглядит непрозрачными карточками | Прозрачность поверхности и alpha текстуры: Process Material не рисует поверхность. |
| Цвет симуляции не влияет на меш | Использование цвета вершин частиц материалом поверхности, например Vertex Color → Use As Albedo стандартного материала. |
| Всплеск повторно запускается неправильно | Явно вызывайте Restart; различайте завершённый цикл и значение Emitting во время ещё живых частиц. |
| Источник тащит за собой ожидаемый след | LocalCoords. |
Для оценки границ используйте инструмент генерации редактора или CaptureAabb() во время реального движения, затем проверьте крайние случаи. Снимок текущего кадра не охватывает автоматически будущие скорости, формы рождения и шлейфы. Не оставляйте гигантский AABB как постоянное исправление: он мешает полезному отсечению.
CPU-частицы используют другой путь симуляции и набор возможностей. Конвертацию проверяйте как отдельную задачу: её успех не доказывает одинаковые визуал, время и производительность. Шлейфы, столкновения, турбулентность и sub-emitters требуют собственных настроек.
Нативные проверки охватывают реальные GPU-пиксели, завершение/перезапуск всплеска, остановку эмиссии, паузу, пространства координат, границы и наличие draw pass. Здесь не заявлены красивая иллюстрация, конвертация CPU, продвинутые возможности, бюджет производительности и вся матрица экспорта/устройств. Управление временем и стоимостью разобрано в статье Свойства источника.