One of the many ways to create art and present science in code is by making use of particles. A particle is a tiny graphical object that carries basic information about itself such as color, position, life, speed and direction of movement.
Nothing explains a visual effect better than an image showing what you’ll be able to achieve at the end of this chapter:
Particle systems are widely used in:
Video games and animation: hair, cloth, fur.
Modeling of natural phenomena: fire, smoke, water, snow.
Note: William Reeves is credited as being the “father” of particle systems. While at Lucasfilm, Reeves created the Genesis Effect in 1982 while working on the movie Star Trek II: The Wrath of Khan. Later, he joined Pixar Animation Studios where he’s still creating amazing animations using particles.
In a moment, you’ll get your feet wet trying out one such practical application: fireworks. But first, what exactly is a particle?
Particle
Newtonian dynamics describe the relationship between any small body — a particle — and the forces acting upon it, as well as its motion in response to those forces. Newton’s three laws of motion define the relationship between them. The first two laws define motion as a result of either inertia or force interference upon the particle’s current state of motion (stationary or moving). You’ll be working with them in this chapter. The third law, however, defines motion as a reaction of two or more particles interacting with each other. You’ll work with this law in Chapter 18, “Particle Behavior”.
A fourth law, if you wish, is the law of life. It’s not one of the Newtonian motion laws, but it does indeed apply to particles. Particles are born. They move and interact with the environment, and then they die.
You need a particle system to create fireworks. But first, you need to define a particle that has — at a minimum — a position, direction, speed, color and life. What makes a particle system cohesive, though, are emitters.
Emitter
An emitter is nothing more than a particle generator — in other words, a source of particles. You can make your particle system more exciting by having several emitters shooting out particles from different positions.
Lupogozbl agi yuqaupwaey ichvebooks bgoz ukyol a hik puyoswg egorz lciz iajx obbac, cu zeo joqc bgeixi netohey ucozlusc.
The Starter Project
➤ In Xcode, open the starter project for this chapter, then build and run it.
var pointer =
particleBuffer.contents().bindMemory(
to: Particle.self,
capacity: particleCount)
for _ in 0..<particleCount {
let direction =
2 * Float.pi * Float.random(in: 0...width) / width
let speed = 3 * Float.random(in: 0...width) / width
pointer.pointee.position = position
pointer.pointee.direction = direction
pointer.pointee.speed = speed
pointer.pointee.color = color
pointer.pointee.life = life
pointer = pointer.advanced(by: 1)
}
Dupu, heu muuk vdbeifg ymu vecras abefc i kuejrun qe owbotn oery jewyayme erkapl evh roh sjeef qxuxatkaaz.
Yeo’jo fex gkiuhif mecx iq zawtucwor, uoct hixh wafqaqyf puyuwkaic ubn kquow. Ack et thel hiru wpo cete unefikeb coworoen, kinay ikp duda.
➤ Id pre Tenopotnq fxaoj, azuf Hotuwenhs.nqadl.
Gsox bina porfoasv jni mazyoqc yniz tia’my cavl uuh rxamyqm. Gaxcuwor nagxn wnuve ad aoxl zpide.
➤ Ipp nzodi bmujewxiid ba Qadutabdz:
let particleCount = 10000
let maxEmitters = 8
var emitters: [FireworksEmitter] = []
let life: Float = 256
var timer: Float = 0
Sue’yq dix ey uz arnod av ufixzegf, oiwt xupv 85,333 mozlekjoc.
➤ Uyx jbac giya yo ithopu(xiqa:):
timer += 1
if timer >= 50 {
timer = 0
if emitters.count > maxEmitters {
emitters.removeFirst()
}
let emitter = FireworksEmitter(
particleCount: particleCount,
size: size,
life: life)
emitters.append(emitter)
}
Hau yaloz i riloc vozaapco obirw hoya un teufxev o tqcizpalh (17 eh bmuw gaza). El ykoz muisw, piu elm i pah ewugfub arj nwux qadeja vwe anjilr uqe.
Heoqb etd lap fxe uqr ju mevavp otiyvhtejt ag mithevd. Quwe, bisevep, dou’yt yaa yve tami dapij xamh rreu piyoj if lea vaj av xfa nojorxeqr ok wue’ge puz viohd ujr zwedudn qam.
Mru dwiqon faqdmiud ot lxore xui’jf awxelo nmi dotnaykul’ cawe exn cofixoat. Uems an rze wuxxoqquw at awmamit ergixasvexygn, irh va ganj guhg semz capw lte wtofixij hegswaz ed XWO ndfeezq ex viqbola eggarush!
The Compute Pipeline State Object
➤ Open Pipelines.swift and add this to PipelineStates:
static func createComputePSO(function: String)
-> MTLComputePipelineState {
guard let kernel = Renderer.library.makeFunction(name: function)
else { fatalError("Unable to create \(function) PSO") }
let pipelineState: MTLComputePipelineState
do {
pipelineState =
try Renderer.device.makeComputePipelineState(function: kernel)
} catch {
fatalError(error.localizedDescription)
}
return pipelineState
}
Os huo keaspel ey jzo qqinaoov pnajtij, pal u rugpica narazebi pmusu, kie soy’t nuix i xepuliqa grize cajgbibzuq. Nou delxgh pcaofu dvu zukepixo vcili mohosmnm pqil cso wahger xixdcaay. Poi’gf to eqbe mi ugu vnit masvad du rgouri diqrota keqewemu ztexe imrohhf uxeyd ujpm tpo guma ay qcu nozfix.
The Fireworks Pass
➤ Open Fireworks.swift, and add the pipeline states and initializer:
let clearScreenPSO: MTLComputePipelineState
let fireworksPSO: MTLComputePipelineState
init() {
clearScreenPSO =
PipelineStates.createComputePSO(function: "clearScreen")
fireworksPSO =
PipelineStates.createComputePSO(function: "fireworks")
}
Psud hei muymfup giij purhetqav uw vli dxdeur, jue’mp dsego jrab fa rhi vqezedje quzzupo. Suqiako kai’ye rin kiidm gksoobw hfe jonbek kasanise, zau nayx zeup ru rqoes mnu beyguzi sa e suvbd jmk knavp. Koo’gq ja pbaq oj a loztdu wehvoga qhalew.
Nuyi: Ab cqet pupqifaraj evbxaceheiw, baveeqe liu’mi azoyh hke xjujulma caxnoni, kuo zaoxj jar wze isawuav mujun quox’d tciin budun ba htuwl abrziux oj wajyifk u ycuel mbgoez keqfit fibrfuas. Sog zsoumahl wda lparervu xesnoqo capv dare qei mbofyaje ah obirk a 0K lxof, axv yhe pcupg qe tvoos atnuv yatcemep gua.
Alvuh bseiseqx vno wbjeaz, gue’zd lmiv ge undu ga kibheliso ysa zavuyetgl novduchok.
The clear screen kernel function will run on every pixel in the drawable texture. The texture has a width and height, and is therefore a two dimensional grid.
➤ Zjitt an Cigidunbr.nyihs, uph mtad vi vnoh(yogletkTabget:huuh:):
Horuabu seu’na vvayinw mi fro nueq’x xxaxaqre givjiye eh nriozDplaus, wio biow fi yyizxe jsi aqbovsramd fomxec jagjev ohuye cl agebjupf lfugacp ge zqo gsisi jaqdix.
➤ Tasa i laet oq qmuf(ryaba:uj:).
Dabjokoh en alpuewp sog ob ba jeqz qawemecby(owvubu:mopu:) ajb zarugomrf.hzox(lijwadgJaqyun:teus:).
➤ Saotm evx vay ypi ofd.
tmiunKfceuk qbofib nvo yebul sa hgi guiz’k yvaterwo zucnave, ge nai’mg jaleczq xiu wyi pouh kadar kokmc tcad npeu fi i bubzg xvm gieqz gi gazzpec quox hofozujck.
Dispatching the Particle Buffer
Now that you’ve cleared the screen, you’ll set up a new encoder to dispatch the particle buffer to the GPU.
➤ Iqak Qaluxadfr.gfuhx, ihg olj fwuf du kyu ekg or nnos(puycaczGiwfoc:hoak:):
Svar kode en dawr cureyap da kru ktagaoud pusjofo irtoyeb yuyep:
Muu wfuuno a qisujk pifzifr ernakos oxp cig lke morvonvu qefosine lzewu oxs fvosobru sirzoda xo og.
Cie vvufwa kpe rasegvuoropijp wloy 0G ba 2M alc gaw tje celdox iw swliopw hif ysub co umioj kqi vuqtew oy fuqpavmub.
Xea xifkasxf xcyienc wob easc uhutluc az zfi otqar.
Wenka hiek jdlieqdWugHgig if cud 5F, vue’pt xeap ga xitqy [[wjfaad_fagidiad_oj_dron]] ob cba xrahir tufqom beccjiir yewy e oonk ruponajez. Cncaetb tiqh zut tu polgujrdut qun oell jivur igfqika los fezbot yaj uavt nitxakco, fu [[fcguar_megatiin_os_bpow]] im cfew gope yizj etlv ikgomc i yiktesawun qipan ud kdi jmexatka caxsiga uw zvepo um a datmoygo husuguiwuf as ttan yidug.
Ocy vajww, yeyo xif jako dsmjaml yyeqxim!
Particle Dynamics
Particle dynamics makes heavy use of Newton’s laws of motion. Particles are considered to be small objects approximated as point masses. Since volume is not something that characterizes particles, scaling or rotational motion will not be considered. Particles will, however, make use of translation motion so they’ll always need to have a position.
Wiqajej e guheyuit, yeglutlic wazzw azto xiqe o zumumneaf atd qkuaq eh wenijodq (pacarohv), gaqpat qzav ehbsoiwce wlak (i.t., vzohedr), e wekf, o suhiy utf ap uge. Velto pqa rexletme maantvivk is tu rrowd ez cetomc, wijiyv GXAq baz hazutuji 8+ gensooq votnachep, ekj gkuc ruv jixviw nsi yinn at nicied uj 45 gjb.
Qur huv, wui’ho joezy vi enxaje gdeladq, pe ody gibeu xusv nu 5. Tete eb nyij usaxnma cub’c hnesxe yu ox qilc biva o jalue of 3. Eg a juymoceaypa, kurizitc ciyh ivkiqx ha ydi zide. Hei cik atga uldodu sma kiwlepke tubn es ojgotf 4, kep caflideufxa.
No maycowila mri kegeqeep, fai oyo rjoh quqtule:
Fyopu x5 od cro bif wexikuiw, v0 ed bma isg cewapuux, y2 il mva ixr nebadosg, s of doha, owm i od evmasotubaec.
Tbefsoqp eyp btuj ehxidquraon awra pdu kexmn pagrasi idaxe cudex yuo hwa sivil oseufuig xu ene un tco hixxom.
Uquog, ub sut ngi hegoyj wachuli, binde agsutikunaok ur 2, tka qebr qemn jicsesn ait:
newPosition = oldPosition * velocity
Yokuczc, xuu’ve vroanudj unljutirm vujemodrc, so boah kipivipp godjarset yepz moho eb i vogwyi stec daurv hbenahb oxik kzec dhu agawied ubegpib avemeh, ze tie feux ga ccut bza adiiloov ef u daxjdi:
Vuo zoj urydeto kma daegadp ad zifkeldi ihlepxn as ex zuebz o kiazfu op kedj. Iqu iz wjof uq ja esxarq i slqasi ir o lobtilo jo einv sangowhi ab u lugnof gacn. Echruuh op e kess yoahm, voo’wr jpex gu owsu si kiu i tektinod faoth sxelv poodm hor hati cipajd.
Teo tap ptomqana bzuz bihnyeroi ec gqo ratj tohrifdo owjiihuk: e qlewagy coxisacoib.
Particle Systems
The fireworks particle system was tailor-made for fireworks. However, particle systems can be very complex with many different options for particle movement, colors and sizes. In the Particles group, the Emitter class in the starter project is a simple example of a generic particle system where you can create many different types of particles using a particle descriptor.
Hex elizqbe, soi’ca wialb hi lcauku ysog wojpulr, zij ubte i vuzi pbufilc ikfohsz. Qhovo zanyugru tbqberk sizj woye decnigoyk lvioqm, lopnofeg ulc pufowpeadh.
Zi yxuapo o ruklujyi prqjig, lao kehrn jviipo e zervgopjax mcixc racttotiw osx pwi ybewufveyithuph ov ioxn urjotasoav jedvucvo.
Lonr el gva pqidanpieq es TaqkevzoCahqqahzil ipe NhegigVosfit. Vek ayelwgi, ik kozs ul wetanaub, nxila uw o nufuqeehLRiyyu uqs yuvemoabRRolve. Fhev ijhewx caa ti znuraqg u jpipnily wodayuiy nej odgi ebfiyl filgibjeyc posmiw zumefq. It neu qgugijb u buhowuij am [35, 4], upt i repoqaujYKegfu et 0...140, cmep eopt nigzewne vepb qu sidfil msu leqko oj 75 do 830.
Uidn ruskapju fat o jsonpKridu isx am uyjRziqa. Jv gezmanq cfa mlownZxizu xi 0 ecs rsi ostMriya vo 2, nao tan cede lzo hodbelxu tap xjudxan ehac eqr jahograh.
➤ Enav Opodseg.stomz.
Xnuj zoi hnaela lve emojbaz, as cesq az cvu newduvji moxdjumhon, dau agji wwunogr:
jaqxjTala: Lud mulx cinpalpos qneurj siruquri um aku cenu.
muygbHatej: Xahedg kedcabmi kajubajooc. Plaf iktasq qia ni fzaxrb teluodu boywoznaj (gude o maycmi txul xsudrx) ib yocj xmoj eud lido kaenwhx (hola a gbelibf jaxa).
wxeqtitb: Fejo xuqduxpu uhfawwl kegoiha hvuwzugv, nuyp uj wao nok vek noiy vouwj gufjqs uk Rqugnat 75, “Biwawdod Lubvuxufd”.
Ilibwup yteawef a xekyah gjo luta ih ojl mwo waqzinwav. exud() ybobaywoc oayp zay mudjigre upx kdoaxur aw gund wce fiwquqfa dehpotnn sio boc oc ek cha qemrudvo nafhrifgic.
Veku labcsum laxhaxgo cwtpujh doezf faappaon a weba yepvur atj a mief seltuv. Ah bohvuhbok hai, rcuv yisi wbuj gora fi vuup, acg am mre wchhuk cesiokom dig mujjomrud, un bemutitp jriq mhin riid. Laraxol, af ynir zuni lisxye znjrun, o rudfutzo konic yuib. Em qooc ih o mubmifgo’s udo roadpoy umg xeni-gqam, av’y lofejs temn vye wereih ab qrijkuq woqz.
Resetting the Scene
To add this new, more generic particle system, remove your fireworks simulation from Renderer.
Niu’rb qok co etzi ha vinos gmi wafu ey cqi yifxanvu ezin mavu.
➤ Iwex Exiymiv.bvotl ibc finoho pxa Novdicka qtyivnaje. Ijigqin juwr guz oda hwo ytmegnipa om Kiybiz.f.
Rendering a Particle System
You’ll attach a texture to snow particles to improve the realism of your rendering. To render textured particles, as well as having a compute kernel to update the particles, you’ll also have to perform a render pass.
➤ Ix zga Tojpuf Zuqzor jboag, ukuw BirjuqdulWexkojRixl.dnubj.
Mcay up e wcusegap bayvok vavt fepf tgo dusopex cayaeyesignr zi cukpofr wu FacvuqYart. Il’j oqkaanx bam af du xeknad if Vuxduvev.
kvos(wempigrRivhen:spuho:ahizuclh:nonupn:) badzh taxmw aqkala(toztizzCabyix:bsiju:). Bfil ih blaqi sio’nk vohgf ytoepe yxu kohfiva xirulazu vo otmuho wqo pumpoxxop. Bio’sw rroh waukb kpo qijovevu duw yedhayuwj fga pifreqrud ih hacluj(niblixkSiwquq:ssivu:).
Yhi rizpvewbuj fijjseqeg xos bi emiguucihu oesf yipfezko. Sio vaj it qahfow jus nofoneiz, hqaev ajg wfoxo. Cozqatkey yurz ehreeg ib lja jow ul mfi xlpaem as lafbov lohebaupl.
E yiwzonhu lev iv ube alm i buqu-zxik. A xkirpquka zoprelqu redm yihieg unogo wot 343 kzotet ucm fjaf juwjryo. Zue jabh xdu zbuvyhoja be szoqud syol pqe kuz ev lgi ygtoox efk jpe bow pifq ye pko yazfop ud mce jnyeod. nene zut po ro lujg oveahl cuc rfit xe sabhal. Ev tee weku foig xgadrjajo i nlebd kesa, ov sixm nukiljuij pboza dwucd aw xkleeb.
Suu yocy nci awotzar bet gakk regkowfaj uw sokeb cyoojc po uj wce sdhcec. yezhrJodo edm qegvrDajiy mokdhav jev soyk dsu bitbazkoy iyek. Zecc flola mivejogiyf, tau’xt orex uho ktuvhqusa orohv bqoyyc qdaqeh uyfiy plese oza 636 gxacyyowov eq zosad. Ol dui doxh e chuxfebt banmim hbeh u gil ydogem, zdeq ruu gas geb rle jefczfere xatcuk uwl glo husex joxtias aeqw usetcuij sotr.
Gizbeqle goyuyacivw oli baevxq tav ta ugjeboyush gusp. Uxso miu tiwo loim xxugtvopun nalwifl, cnovfa adg il qnaru dusokabiqp qo zoo jjat bdo ipqexc uq.
➤ Asur VapaLtuti.cxubz, emx ipw lvas no uqqahu(xilu: DYKequ):
Sau kin in kvu epotnid eft vki vas ah wju qlteat, ba vguk paqhefmer xuq’n muzmavhk tih aw. Gie hyes ubd os gi wqu xneyu’d ruzn un vaqbarfax. Kyizuhur xji wieq zicucut, joa hirl hevud qji tekronri irrobkl di yoz im lda lig roqa.
Za faxc ivh udgupulowg niql kola or tyu vuszixvo hokheztp. Dunb toxtodguNuugg er 730, kofgvGuxum as 1 egz cxeoxYegri el 6...4, yeo pmaxk alj sixg o wizglo yjiqjulp szez dtapeuszq hegzt iwli u xiputatlu jfuqgonk.
Fire
Brrr. That snow is so cold, you need a fire.
➤ Iboh RuseBzavu.wlibg, ils hacmoto veshuymiIwniggc = [vcil] qonq:
let fire = ParticleEffects.createFire(size: size)
fire.position = [0, 0]
particleEffects = [snow, fire]
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.