Самый быстрый способ создать простой эффект частиц


12

Я ищу самый быстрый способ создать по-настоящему простой эффект частиц, который будет чертовски спамить в игре ...

По сути, моя игра выглядит как игра vectrex, состоящая в основном из линий ... Я хочу сделать несколько небольших взрывов, которые будут действительно распространены.

Есть что-то более быстрое, чем просто перемещение по некоторым точкам и рендеринг с помощью GL_Point?


+1 только для справки Vectrex. В начале 80-х я провел несколько забавных часов на Scramble and Tempest в детстве. Без этого я бы, наверное, сегодня не стал разработчиком игр.
Kylotan

Да, Буря потрясающая: D
спидер

Как я говорю, что ни один не является правильным?
спидер

Ответы:


13

Там действительно нет необходимости хранить память для каждой частицы и анимировать каждую частицу в отдельности. Вы можете сделать это процедурно, восстанавливая положение частицы во время рисования, используя классическое физическое уравнение. s = ut + 1 / 2.at ^ 2

Простой пример (без постоянного ускорения частиц):


void drawExplosion(ExplosionParameters& s)
{
  Random rng;
  rng.seed(s.startSeed);
  glBegin(GL_POINTS);
  for (int i = 0; i < s.numParticles; i++)
  {
    vec3 vel = rng.getRandomVector(-1.0f, 1.0f) * s.explosionSpeed;
    float timeBias = rng.getRandom(0, s.particleTimeBias);
    vec3 pos = s.explosionCentre + (vel * (s.timeElapsed + timeBias));
    glPoint3fv(&pos);
  }
  glEnd();
}

Затем вы просто увеличиваете s.timeElapsed на каждой итерации цикла обновления.

Он также полностью поддается реализации на GPU, освобождая ваш процессор от необходимости выполнять какую-либо работу. Реализация gpu может выглядеть так:

void drawExplosion(ExplosionParameters& s)
{
    //bind Vertex Shader If Not Already Bound();
    ...
    // bindVertexBuffer of Zeroes If Not AlreadyBound();
    glVertexPointer(...)
    //uploadShaderUniformsForExplosion(s);
    glUniform3f(...)
    ...
    glDrawArrays(GL_POINTS, 0, s.numParticles);
} 

Вершинный шейдер GPU затем восстанавливал бы положение частицы с помощью уравнения физики и передавал ему униформы / константы - так же, как это делала версия CPU.

Чтобы добавить некоторую дисперсию, вы можете использовать больше одновременных взрывов с немного отличающимися параметрами, анимируя цвета / альфа, выбирая разные начальные позиции. и т.п.


Кроме того, вы можете использовать предсказуемость псевдослучайных чисел для генерации всех начальных векторов частиц, создавая сотни частиц на основе данных с несколькими int. Использование графического процессора для создания четырехугольников - действительно хорошая идея для простых частиц.
Skizz

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

7

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

Эффект ДЕЙСТВИТЕЛЬНО классный (посмотрите видео о любой войне с геометрией, чтобы увидеть его), и ДЕЙСТВИТЕЛЬНО быстрый. Выбить дерьмо из четырехугольников (особенно потому, что из-за четырехугольников мне нужно вычислить двойное количество вершин)

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


2
+1 за объяснение того, что вы в итоге сделали, хотя мне было бы интересно узнать больше подробностей о ваших тестах. =)
Леандер

Кстати: все это было в непосредственном режиме (это единственное, что я знаю, как кодировать, и я узнал имя вчера ...)
спидер

6

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

Если вы используете предварительно умноженную альфу в искусстве, вы можете легко поддерживать свет, огонь, дым и многое другое, кроме всего прочего, с помощью одного типа операции смешивания.


Хум ... точки не быстрее текстур?
спидер

2
Графическое оборудование специально оптимизировано для растеризации текстур в буфер кадров. Если очки быстрее, они, вероятно, будут незначительными, и вы потеряете все возможности, которые вы получаете с текстурированием.
Kylotan

Как что? Имейте в виду, я не делаю полнофункциональную систему частиц, это всего лишь специфический эффект (небольшие взрывы, в основном из-за обратной связи геймплея, когда вы что-то поражаете)
спидер

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

4

В OpenGL ES 2.0, ES 1.X с расширением и OpenGL => 2.1 вы можете использовать GL_POINT_SPRITES. GL_POINT_SPRITES - это как четверка всегда перед камерой.

Во фрагментных шейдерах вы можете:

  • определить размеры спрайта с помощью gl_PointSize в вершинном шейдере
  • использовать gl_PointCoord (UV-координаты) во фрагментном шейдере

Вы можете использовать текстуру с альфа-каналом для рисования спрайтов шаров ...

Учебник для точечных спрайтов


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

1

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


1
Правда, но он стремится к стилю Vectrex, там он будет работать хуже.
Кай

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

1

Для удобного небольшого способа обработки появления / удаления / обновления частиц, при условии, что у вас есть простой массив частиц - Particles [MAX_PARTICLES]:

Отслеживать активные частицы (начиная с NumActiveParticles = 0)

Новые частицы всегда добавляются в конец массива:

pNewParticle = &Particles[NumActiveParticles++];

Умный бит - При удалении «мертвой» частицы - меняйте ее на последнюю активную частицу и уменьшайте NumActiveParticles:

if ( DeadParticle < NumActiveParticles-1 )
{
  Particles[ DeadParticle ] = Particles[ NumActiveParticles-1 ];
}
NumActiveParticles--;

Это позволяет избежать любого поиска «неиспользованных частиц» при порождении и избежать сканирования через массив MAX_PARTICLES, если ни один из них не используется.

Обратите внимание, что это работает только в том случае, если порядок обновления / рендеринга не важен (как в случае со многими эффектами частиц, которые используют аддитивное смешивание) - так как этот метод удаления частиц переупорядочивает массив


-1

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.