Войти
Станислав КычановСтатьи

Реализация системы частиц для shader model 1

В статье рассказывается о реализации системы частиц на платформе sm1 с использованием только статических буферов и вершнинных шейдеров vs.1.1
8<-------

Введение
Техническое задание
Исходные данные
Функция состояния системы
Подготовка данных
Редеринг частиц
Вершинный шейдер
Заключение

Введение

Любой программист, занимающийся разработкой графической части движка, непременно сталкивался с реализацией системы частиц. В своё время, мне также пришлось с этим столкнуться, и я, как любой разработчик, занимающийся движками не один год, начал с поисков адекватной реализации, подходящей под мои требования. Признаться, я был сильно удивлён, обнаружив, что все системы частиц были реализованы по одному шаблону и не подходили мне по целому ряду причин. Все реализации, которые мне попались, были сделаны простым расчётом данных частиц на CPU с последующей записью результата в вершинный буфер GPU. Никакие преимущества современного железа типа шейдеров и рендеринга в текстуру не использовались. Хотя, мне попадалась пара статей по реализации системы частиц с помощью рендер-таргетов и вершинных текстур, но работает это, к сожалению, лишь на sm3.0. Нормальная техника для sm1-2 мне так и не попалась, пришлось изобретать своё. Начну с поставленного мне ТЗ, т.е. с самого начала.

Техническое задание

Итак, мне нужны были частицы, удовлетворяющие следующим требованиям:
  • CPU-независимые – расчёт жизни частиц должен быть переложен на плечи GPU;
  • все данные в статические буферах – никакой записи в буферы с геометрией;
  • минимальный DIP cost – в идеале 1 dip на каждый эмиттер;
  • поддержка изменения размеров, цвета и других параметров каждой частицы со временем;
  • действие на частицы различных сил;
  • должно работать на sm1.

Исходные данные

Как обычно начнём решать задачу с определения исходных данных. У нас есть некоторый эмиттер, испускающий частицы. Характеризуется эмиттер следующими параметрами:
  • emission rate – количество частиц, испускаемое эмиттером в единицу времени;
  • position – положение эмиттера в мировой системе координат;
  • rotation – ориентация эмиттера в мировой системе координат;
  • particle linear velocity – линейная скорость испускаемых частиц;
  • particle linear velocity variation – вариация линейной скорости частиц;
  • particle angular velocity – угловая скорость испускаемых частиц;
  • particle angular velocity variation – вариация угловой скорости частиц;
  • particle start size – начальный размер частиц;
  • particle end size – конечный размер частиц;
  • particle start color – начальный цвет частиц;
  • particle end color – конечный цвет частиц;
  • particle mass – масса каждой частицы;
  • particle life time – время жизни каждой частицы.

Внимательно проанализировав эти параметры можно заметить, что нам точно известно сколько частиц будет в каждый момент времени, а также период через который происходит рождение новых частиц:

numParticles = uint32(particleLifeTime * emissionRate);
respawnPeriod = 1.0f / emissionRate;

Теперь рассмотрим какие параметры характеризуют каждую частицу:
  • position – положение частицы в мировой системе координат;
  • rotation – ориентация частицы в мировой системе координат;
  • linear velocity – абсолютная линейная скорость частицы;
  • angular velocity – абсолютная угловая скорость частицы;
  • linear acceleration – абсолютное линейное ускорение частицы;
  • angular acceleration – абсолютное угловое ускорение частицы;
  • color – цвет частицы;
  • size – размер частицы;
  • time – время, прошедшее с момента рождения частицы;
  • mass – масса частицы.

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

Функция состояния системы

Рассмотрим состояние системы в каждый момент времени. На эмиттер действует суммарная сила, которую он передаёт каждой из частиц. Состояние частицы описывается следующими уравнениями:

position = emitter.position + startVelocity*time + acceleration* time^2
acceleration = totalForce/mass = totalForce*invMass
color = lerp ( startColor, endColor, time/lifeTime )
size = lerp ( startSize, endSize, time/lifetime )

Здесь startVelocity – скорость, с которой частица была выпущена эмиттером, totalForce – суммарная сила, действующая на частицу, invMass- инвертированная масса частицы (invMass = 1.0f / mass), lerp – функция линейной интерполяции. Теперь самая важная задача – выделить из уравнений динамические величины. Как видим только time – время жизни частицы – является динамическим параметром, все остальные либо статические, либо постоянны для данного эмиттера.

Страницы: 1 2 3 Следующая »

28 сентября 2006 (Обновление: 17 ноя. 2006)