Моделиране на експлозии със система от частици

Преводни и оригинални статии в областта на разработката на игри.
gemicha
Site Admin
Site Admin
Мнения: 2930
Регистриран: 20 ное 2003 22:20
Местоположение: USA

Моделиране на експлозии със система от частици

Мнение от gemicha » 07 авг 2004 15:49

Моделиране на експлозии със система от частици
Автор: Tom Hammersley
E-mail на автора: tomh@globalnet.co.uk
Превод от английски: Мордет
Материалът е публикуван с разрешението на DevMaster

Въведение

Системите от частици са техника за моделиране на неща, които не могат бъдат добре пресъздадени по друг начин. Експлозиите попадат точно в тази категория, и този текст се занимава с моделирането им чрез използване на системи от частици.

Основите

Системите от частици представляват група от независими обекти, наречени частици, които са анимирани чрез набор от правила, с цел да се пресъздаде някакъв ефект. Начинът, по който се изобразяват, движат и взаимодействат частиците, се определя от тяхното приложение.

Частиците представляват анимирани точки в пространството на които са дадени някакви характеристики. Често давани характеристики са:

• Позиция
• Скорост
• Енергия
• Посока

По време на анимация тези характеристики се използват, променят и актуализират. Примерно при time = 0 дадена частица може да притежава много високи скорост и енергия. С течение на времето скоростта и енергията ще намалеят и пътя на частицата ще се промени.

Общият алгоритъм за частица е:

Код: Избери всички

Set up particle

While Animation In Progress
    If Particle Not Dead Then
        Add Particle Direction * Speed To Particle Position
        Add Particle Acceleration To Particle Speed
        Modify Particles Speed
        Modify Particles Energy

        If Particles Energy < Threshold Then
            Mark Particle As Dead
        End If

	If Particle Hits Object Then
	    Modify Particles Position, Direction, Speed and Energy
	End If

	Display Particle
    End If
End While
За изобразяване на частиците съществуват множество различни начини. Можем да изобразим частицата като единствен пиксел или да я мащабираме според разстоянието й от гледната точка. Можем да накараме частицата да отразява околната среда или дори да ползваме спрайтове и тримерни модели като частици.

Аз предпочитам да добвя цвета на всяка частица към цвета на фона , да огранича получения цвят в определени граници и накрая да замъгля получения резултат с околните точки. Този метод позволява близките частици да осветят част от изображението, както и да се намали пикселизирането. Замъгляването създава и лека визуална "опашка" на частиците.

Експлозии

Експлозиите са едни от най-лесните и впечатляващи неща, които могат за бъдат пресъздадени чрез системи от частици. За да създадем експлозия определяме началните точки на всяка една частица. Те могат да представляват една обща начална точка или всяка частица да притежава своя начална точка, произволно разположена в сфера. На всяка частица определяме посоката и скоростта, с която ще бъде “изстреляна”, и задаваме високо ниво на енергия. След това привеждаме системата в действие...

Съществуват два вида експлозии, които можем да моделирами по този начин – въздушни и експлозии в някаква точка на удар. Двата вида експлозии имат доста различно поведение една от друга. При въздушните експлозии посоките на частиците ще бъдат насочени в сфера, центрирана в точката на експлозията. Частиците на експлозиите породени от удар ще притежават посоки разпределени в полусфера, получена при разрязването на сферата от равнината, в която е възникнала експлозията (земя, стена или равнина на модел). Частиците ще се движат в посока на нормалните вектори на равнините, но ще бъдат произволно разпръснати.

Въздушни експлозии

При тези експлозии началните точки на частиците могат за бъдат една обща точка, представляваща точката на експлозията или всяка частица да има начални точки, които са произволно разположени в сфера. Произволно разпределяме посоките на частиците в сфера и ги нормализираме. За скорост избираме случайно число.

Следващият псевдо код показва как се създава частица в двумерното пространство. Използвам двумерно пространство за опростяване на примера.

Код: Избери всички

randomvec.x = random(distribution) - distribution / 2
randomvec.y = random(distribution) - distribution / 2
Normalize(randomvec)
dist = random(distribution)

particle.x = explosion-x + randomvec.x * dist
particle.y = explosion-y + randomvec.y * dist

dir.x = random(width) - width / 2
dir.y = random(height) - height / 2
Normalize(dir)
dist = random(size)

particle.dir.x = dir.x
particle.dir.y = dir.y;
particle.speed = dist + 1
particle.energy = 1.0
Това е адаптация на кода, който аз използвам. Тук distribution е стойност, която се използва за разпределение на началните точки около центъра на експлозията. Width и Height се използват за промяна на формата на експлозиите. Ако Width = Height тогава се създава сферична експлозия, в противен случай експлозията е елипсовидна. По мое мнение елипсовидните експлозии са по-добри, защото изглеждат по-естествени и случайни.

Експлозии в точка на удар

Ще огранича тази дискусия само до експлозиите възникващи при удар със земя, защото произволните експлозии ще усложнят нещата.

Експлозиите възникнали вследствие на удар работят по същя начин като въдушните, с тази разлика, че са ограничени в полупространство породено от равнина. В този случай това полупространство ще бъде над земята. Кодът е почти същия като този на въздушните експлозии, с изключение на dir.y, която ще бъде ограничена до една посока – положителната. Така всички частици ще бъдат накарани да се движат нагоре от равнината, въпреки че точната посока ще варира.

Код: Избери всички

randomvec.x = random(distribution) - distribution / 2
randomvec.y = random(distribution)
Normalize(randomvec)
dist = random(distribution)

particle.x = explosion-x + randomvec.x * dist
particle.y = explosion-y + randomvec.y * dist

dir.x = random(width) - width / 2
dir.y = random(height)
Normalize(dir)
dist = random(size)

particle.dir.x = dir.x
particle.dir.y = dir.y;
particle.speed = dist + 1
particle.energy = 1.0
Забележете, че не вадим height / 2 или distribution / 2 от Y компонентата не векторите.

Привеждане на системата в действие

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

Движение

В повечето случаи една базова система за движение е всичко от което се нуждаем. Трябва да имаме предвид следните ефекти:

• Движение породено от собствената сила на частиците
• Движение породено от гравитацията
• Движение породено от сблъсък с други обекти

Пренебрегваме движението породено от сблъсък на една частица с друга за да остане кода бърз и опростен. Пък и това не би добавило особено много към реалистичността на симулацията.

Движението причинено от собствената сила на частиците се симулира лесно. Просто добавяме посоката на частицата, умножена със скоростта й, към позицията на частицата. Можете да намалявате скоростта на частицата с всеки кадър, но трябва да бъдете внимателни, защото ако я намалявате прекалено бързо частицата ще спре и падне на пода. Кодът за това не е нищо особено:

Код: Избери всички

Particle.x = Particle.x + Particle.Speed * Particle.Direction.x
Particle.y = Particle.y + Particle.Speed * Particle.Direction.y
Движението породено от гравитацията е най-лесно за симулиране. Само трябва да накарате частицата да се ускорява към пода. Ускорението е 9,8 метра в секунда на квадрат. Запомнете, че става дума за ускорение, а не за постоянна скорост. Лесно можете да видите какво е ускорение. Просто пуснете предмет от някаква височина. Предметът не остава във въздуха, а пада. По време на падането скоростта нараства, но това е трудно забележимо с просто око, ако предметът пада от малка височина.

Движението, вследствие на сбълсък с други обект,и също не е трудно за симулиране. Ако частица се удари в някакъв обект, примерно под, трябва да отразите посоката й спрямо нормалния вектор на обекта и да намалите скоростта й. Формулата за отразяване на вектор е R = 2.0 * (N * L) * N – L, където N е нормалния вектор, а L е посоката на частицата преди сблъсъка. В случаи на сблъсък със стена или под, само едната компонента на посоката ще бъде различна от нула. Примерно при сблъсък с под, само Y компонентата е различна от нула и можете да промените посоката като просто смените знака на Y. Не забравяйте да намалите енергията на частицата. Логично е част от енергията да бъде абсорбирана от обекта, в който се е блъснала частицата. Ако изплозвате замъгляване ще забележите странен пламък над пода, където отскачат многобройни близко разположени частици. Това изглежда доста ефектно.

Визуализиране на системата от частици

Нуждаем се само от две процедури – една да рисува частиците и една да замъглява екрана. Процедурата за рисуване на частици е елементарна. Взимаме цвета на фона под частицата, добавяме цвета на частицата, ограничаваме във валидни граници (т.е. 0..255), и записваме пиксела обратно на екрана. Това ще освети областта от екрана в зависимост от броя на частиците, които са в нея.

Процедурата за замагляване също не е сложна. Вземете 4 съседни пиксела, намерете средната им стойност и извадете някаква константа. Поради изваждането стойността може да стане отрицателна. В такъв случай я нулирайте. И готово! Създайте частицата, влезте в цикъл, който движи, рисува и замаглява, и имате екплозия! Когато старата експлозия “умре”, създайте нова и това е всичко! Толкова е просто...

http://www.devmaster.net/articles/particle_systems/

Отговори