Турбулентность частиц: движение и начальное смещение
Рабочий пример, неподвижное поле, влияние по возрасту и диагностика.
Турбулентность искривляет траектории GPU-частиц с помощью процедурного поля шума. Она подходит для дрейфующего дыма, искр и клубящейся пыли. Загружать текстуру шума не требуется; на физические тела игры это поле не действует.
Начните с видимого движущегося эмиттера
Сначала настройте GpuParticles3D: назначьте геометрию и видимый материал, включите испускание и направьте на него Camera3D. Если частиц не видно без турбулентности, начните с настройки эмиттера.
Турбулентности нужно движение, направление которого она изменит. Задайте начальную скорость, гравитацию или другой источник движения. Для понятного сравнения оставьте только начальную скорость, отключив гравитацию, аттракторы и столкновения.
Сохраните помощник в ParticleTurbulence.cs:
using Reckfell;
public static class ParticleTurbulence
{
// Static noise-field preset for a controlled motion comparison.
public static ParticleProcessMaterial Create()
{
return new ParticleProcessMaterial
{
Direction = Vector3.Up, Spread = 0,
InitialVelocityMin = 1f, InitialVelocityMax = 1f,
Gravity = Vector3.Zero,
EmissionShapeOffset = new Vector3(0.13f, 0.17f, 0),
TurbulenceEnabled = true,
TurbulenceNoiseStrength = 1f,
TurbulenceNoiseScale = 3f,
TurbulenceNoiseSpeed = Vector3.Zero,
TurbulenceNoiseSpeedRandom = 0f,
TurbulenceInfluenceMin = 1f,
TurbulenceInfluenceMax = 1f,
TurbulenceInitialDisplacementMin = 0f,
TurbulenceInitialDisplacementMax = 0f,
};
}
}Назначьте эмиттеру particles.ProcessMaterial = ParticleTurbulence.Create();. Установите Lifetime 4, FixedFps 60 и VisibilityAabb, охватывающий ожидаемое движение. Для условий выполненного примера расположите эмиттер в (0.37, 0.21, 0), используйте мировые координаты (LocalCoords = false), OneShot, Explosiveness 1 и фиксированный seed. Смещение области испускания выводит частицы из начала координат шума; это не обязательное значение для любого эффекта.
После каждого изменения перезапускайте эмиттер. При выключенном TurbulenceEnabled частицы летят вверх. При включённом пресете то же начальное движение искривляется в неподвижном поле. Траектория зависит от положения и настроек поля; турбулентность не ведёт частицу по заданной кривой.
Меняйте по одной настройке
| Настройка | Что изменяет |
|---|---|
| TurbulenceNoiseStrength | Контраст шума и детализацию направлений. Это не прямая скорость частицы и не величина силы. |
| TurbulenceNoiseScale | Пространственную детализацию поля через нелинейный регулятор. Это не расстояние в метрах; переносить сюда частоту из другой системы частиц нельзя напрямую. |
| TurbulenceNoiseSpeed | Перемещение процедурного поля во времени. Напрямую скорость частиц не задаёт. |
| TurbulenceNoiseSpeedRandom | Изменение дополнительной координаты шума во времени. Нулевого NoiseSpeed недостаточно для неподвижного поля, если этот параметр ненулевой. |
| TurbulenceInfluenceMin / Max | Диапазон влияния на направление движения отдельной частицы. Одинаковые границы убирают этот источник разброса. |
| TurbulenceInfluenceOverLife | Текстуру-множитель по нормализованному возрасту: 0 при рождении, 1 при смерти. Для настройки удобно использовать CurveTexture. |
| TurbulenceInitialDisplacementMin / Max | Однократное смещение при рождении вдоль направления, полученного из шума. Оно отделено от последующего изменения движения. |
Для неподвижного поля обнулите оба параметра: NoiseSpeed = Vector3.Zero и NoiseSpeedRandom = 0. Частицы продолжат двигаться через неподвижное поле и менять направление. Это отличается от паузы симуляции эмиттера.
Влияние умножается на текстуру возраста и ограничивается диапазоном 0–1 для изменения движения. Без текстуры множитель равен 1. Чтобы получить заведомо нулевую кривую, добавьте в Curve точки (0, 0) и (1, 0), затем назначьте её через CurveTexture. Новая текстура без заданной кривой при назначении этому материалу получает постоянное значение 1; сама по себе она не отключает влияние.
Увеличение влияния не гарантирует роста скорости. Реализация смешивает текущую скорость с направленной по полю; могут измениться и направление, и величина. Начальную скорость настраивайте отдельно.
Различайте положение рождения и движение
При нулевой начальной скорости и гравитации изменение направления турбулентностью не запускает заметное движение из состояния покоя. При этом InitialDisplacement может сместить место рождения даже с нулевыми InfluenceMin и InfluenceMax. После этого однократного смещения частица без источника движения остаётся на месте.
Учитывайте это при проверке эффекта: другое начальное положение ещё не означает ускорение. Сравните одну и ту же частицу сразу после рождения и позднее, сохранив настройки и seed.
Если результат неправильный
| Симптом | Что проверить |
|---|---|
| Частицы видны, но стоят | Начальную скорость, гравитацию или другой источник движения: турбулентность перенаправляет имеющееся движение. |
| Частицы летят прямо | TurbulenceEnabled, диапазон влияния и текстуру возраста. Нулевой множитель подавляет изменение направления. |
| Поле меняется при нулевом NoiseSpeed | Обнулите также NoiseSpeedRandom. |
| Частицы скачут при рождении | Диапазон InitialDisplacement и смещение области испускания. |
| Эффект пропадает в полёте | VisibilityAabb, камеру и время жизни: траектория может выходить за исходную область испускания. |
| Настройки меняются сразу у двух эмиттеров | Возможно, они используют один ресурс ParticleProcessMaterial. |
Пример выполнен с проверкой реальных пикселей частиц на Windows Forward+/Vulkan: выключенное, нулевое и полное влияние, нулевая кривая возраста, покой и начальное смещение. Движущийся шум, сочетания со столкновениями и аттракторами, другие рендереры требуют отдельной проверки. Измеряйте время GPU в целевой сцене: универсального безопасного количества эмиттеров с турбулентностью нет.