Вопрос

Я разрабатываю свой собственный движок системы частиц, это для учебных целей, на самом деле я не хочу использовать существующий движок.

Прямо сейчас я сгенерировал красивые частицы, но я хочу доработать движок, чтобы упростить работу с ними.

Я размышлял о классе "Система частиц".,

этот класс будет содержать следующие ссылки:

Список частиц:Список частиц, составляющих систему.

Системный излучатель:Системный излучатель для частиц, класс Излучателя должен быть способен выполнять несколько методов излучения частиц, таких как, например, излучение из линий, точек, случайное излучение из многоугольника.Также этот класс должен выполнять контроль выбросов, например, излучать в направлении точки, от точки, в направлении и времени для излучения.

Контроллер частиц:Управляет, например, вращением вокруг точки, переменными размерами частиц, переменным цветом частиц, областями вокруг системы, на которые частицы реагируют по-разному, обнаружением столкновений (с другими объектами или внутри частиц, если это необходимо).

Средство визуализации частиц:Отвечает за создание этой системы, переменные типы наложения, текстуры частиц, такие типы частиц, как треугольники, круги, пользовательские...

Эти четыре элемента составили бы класс particle system.Для некоторых FX может потребоваться более одной системы частиц, например, FX Fire может использовать одну систему для огня, одну систему для дыма и одну систему для искр.

Это то, что я имею в виду, но мне действительно хотелось бы знать, хорош ли этот подход к дизайну, или вы видите, что я чего-то не хватает или мог / должен сделать что-то другое.Я не думал о каком-нибудь простом способе "сохранить" FX, как, например, о том, что было бы лучшим способом сообщить моему движку "нарисовать огонь", "нарисовать взрыв", "нарисовать фонтан" и т.д., Возможно, хорошей идеей было бы сохранить информацию о FX в XML-файлах и т.д..

Мнения действительно приветствуются, и, как я уже говорил ранее, я действительно хочу создать это, вместо того чтобы использовать другой движок, из соображений обучения.

Это было полезно?

Решение

Эта настройка должна быть прекрасной.Я надеюсь, вы думаете о том, какие данные составят частицу, которая будет находиться в классе particle.Вы захотите иметь только самое необходимое, поэтому вам нужно будет читать / записывать как можно меньше памяти при запуске системы.

Что касается того, чтобы сделать его управляемым данными, это должно быть довольно прямолинейно.Я бы предложил использовать xml и двоичный формат для загрузки.таким образом, вы можете легко настраивать материал во время разработки (и не имея инструмента).Как только у вас будет инструмент или вы закончите настройку, я бы преобразовал xml в двоичный файл для быстрой загрузки.

Вам также может понадобиться класс manager, который обрабатывает создание и обновление этих систем частиц.Это также позволило бы вам использовать другие функциональные возможности, которые имеют отношение ко всем вашим системам.Некоторыми примерами этого является ограничение количества систем частиц, которыми можно управлять по соображениям производительности, или наличие плоскости столкновения, которую должны учитывать все системы.

Вы упомянули, что это для образовательных целей, и в этом отношении эти вещи довольно придирчивы (но важны, если вы собираетесь использовать это в игре с большим количеством частиц).

Я предполагаю, что для рендеринга используется API, такой как DirectX или OpenGL.В этом отношении я бы хотел, чтобы все эффекты частиц использовали один и тот же пул памяти для вашей информации о вершинах.Это значительно повышает скорость рендеринга.Я бы также отслеживал границы области, на которую влияет система частиц, для использования при отборе усеченного конуса (AABB или Circle).

Огромная часть обновления системы частиц заключается в том, как атрибуты переходят от одного значения к другому.Чем более динамичной вы сможете сделать интерполяцию значений, тем лучше будут выглядеть ваши эффекты.Простая линейная интерполяция могла бы быть достаточно хорошей, но, возможно, лучше иметь динамический график, который используется для интерполяции значений.Например, вместо того, чтобы переходить от 0 к 255 синему цвету за секунду, может быть круто перейти от 0 к 128 за 0,2 секунды, затем к 128-255 за 0,8 секунды.Добавление этого значительно расширит возможности того, как будут выглядеть ваши эффекты.

Кроме того, я думаю, у тебя есть довольно хорошее представление о том, что ты хочешь делать.Ваше упоминание о рендеринге различных типов частиц говорит мне о том, что вы правильно об этом думаете.Я видел, как люди создают движки частиц, просто сосредоточившись на рендеринге квадрата с рекламным щитом.Наличие возможности создавать 3d-геометрию действительно делает вещи великолепными.Возможно, вы также захотите подумать о том (если вы еще этого не сделали), чтобы ваша система могла принимать информацию о модели и динамически разделять ее на отдельные частицы, которые будут испускаться.На самом деле взрыв модели выглядит значительно лучше, чем отображение какой-либо частицы взрыва и исчезновение объекта или перевод его в поврежденное состояние.

Другие советы

Просто несколько идей по оптимизации простых 2D-частиц-спрайтов.

Хорошая идея - отправить все частицы в массив вершин / VBO и использовать вершинный шейдер для обновления их позиций с течением времени.Это здорово, если у вас есть простое движение, которое можно легко описать с помощью математической формулы, где x(t) и y(t) (то есть они зависят только от времени).

Еще одна отличная идея - использовать точечные спрайты вместо треугольников и квадрациклов.Это должно сократить требуемую пропускную способность конвейера до четверти.


В моем космическом симуляторе я реализовал самый тривиальный подход:частицы, отправленные в виде текстурированных квадратиков с использованием glBegin()/glEnd().Они сбрасываются в текущий "сектор" как отдельные объекты и полностью независимы с момента сброса и далее.Это самая примитивная, глупая и идиотская вещь, которую можно сделать, и она приводит к значительному снижению производительности, тем более что то, что я делаю, это перебираю объекты с помощью итератора STL vector и отправляю каждый из них последовательно.

Вам нужно подумать, сколько частиц вы хотите, и что вы хотите, чтобы они делали.* Вы хотите, чтобы они реагировали на окружающую обстановку и сталкивались?Затем вам нужно обработать обновление на процессоре и отправлять данные снова и снова.* Они просто летают вокруг самым глупым из возможных способов?Тогда вам может сойти с рук отправка всех частиц в виде VBO и TBO и обновление их в shader.

Получайте удовольствие!


Обновлено, чтобы соотноситься с комментарием № 1 от asker :-)

Что я бы сделал, так это использовал Принцип ПОЦЕЛУЯ.Это означает:класс под названием ParticleEmitter содержащий массив вершин, массив скоростей и STL vector с примерами простых коллайдеров, таких как плоскость, сфера, треугольник.Кроме того, имейте "глобальный"* STL vector с помощью коллайдеров.Затем обновите скорости в соответствии с коллайдерами.

Аналогично можно сделать с воздействующими факторами (гравитация, ветер и тому подобное).:другой вектор STL в ParticleEmitter с аффекторами и другим "глобальным" STL vector с аффекторами.

Аффекторы и коллайдеры были бы классами, которые реализовывали бы affectParticle(particle_t*).где struct particle_t { float x,y,z; float vx,vy,vz; }.Я бы сохранил это в виде структуры POD и запустил обновление в ParticleEmitter::update().

Однако, если вы запускаете это на iPhone, может ли это быть чрезмерным усложнением?Возможно, вам сойдет с рук то, что вы уже реализовали?Я понятия не имею, как мой дизайн может повлиять на результаты тестов, но для меня это звучит достаточно разумно, если вы уменьшите количество частиц, коллайдеров и аффекторов, потому что, похоже, это может масштабироваться примерно n*c+n*a.

Это всего лишь мои разрозненные мысли и то, как бы я лично их реализовал.Ваш дизайн или дизайн других людей, вероятно, был бы лучше :-)

* "Глобальный" в кавычках, потому что, вероятно, имело бы смысл использовать любое используемое вами разделение пространства.

Я реализовал такой же хороший дизайн для своего собственного движка на C ++.Вместо этого я не использовал ссылки и политики шаблонов (стратегии - прочитайте "Современное проектирование C ++" Александреску).Статический полиморфизм обеспечивает лучшую производительность.

Я хочу сделать несколько комментариев в соответствии со своим опытом.

  1. Традиционно большинство particles использует AOS (Массив Struct) для хранения атрибутов particle.Но это, возможно, не самое лучшее решение.Использование представления SOA (Структура массива) даст вам большую гибкость при добавлении атрибутов каждой системы частиц.Кроме того, вам будет намного проще повысить производительность SIMD с помощью SOA.Например, выполнить 4 частицы вместе, используя инструкции SSE.
  2. положение, в котором испускается частица, является только инициализацией одного атрибута частицы.Когда вы испускаете частицы, вам, вероятно, необходимо инициализировать другие атрибуты, такие как время жизни, скорость и т.д.Вы можете абстрагировать все эти функции как инициализаторы.Для определения местоположения у вас может быть инициализатор диска, инициализатор коробки и т.д.
  3. Некоторые современные системы частиц используют концепцию события.Система частиц может генерировать событие (напримердождь сталкивается с местностью), и другая система частиц может прослушивать и выполнять некоторые действия (напримериспускать всплеск).

Кстати, я думаю, что лучший способ - это изучить дизайн существующего приложения / промежуточного программного обеспечения, а также поэкспериментировать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top