Writing a Particle System (using Three.js)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we're talking about writing a particle system in 3js specifically we're going to be building out a reasonably flexible system from scratch so that you can build something like this with very little effort or even this since it'll be really flexible and you can do quite a bit with it now honestly 3gs doesn't have the greatest particle support it looks a bit weak at least from the examples if we go over to the 3js site and browse the example section searching for particles yields very little in the way of concrete examples i mean some of these are kind of cool but the code mostly relies on either points material or writing your own shader which is fine it does some basic particles but the problem here is that unless you're planning on the absolute most basic particles that don't animate or do much of anything this isn't going to get you far so let's make one ourselves now just for reference there are some third-party ones that various people have written in various states of support but writing one yourself is easy and if you're here you're probably here to learn what we'll start with is a super basic particle system just getting the bones of one up and running what i'll do is get just a few particles on the screen and nothing else the first thing we'll be doing is using the same setup we did in the video on creating a basic 3d world so i'll just copy that directory right into the new one start by defining a particle system class and you need to do a few things need to create a material need to create a buffer geometry to hold the vertex data a list of points to be rendered and we need to add it to the scene next we'll define some particles we'll make 10 particles to start each with a random position once you've done that we have this update geometry function which just iterates over the list of particles and updates the buffer geometry object with properties from the particles separating this out as a separate function will make much more sense once we're animating parameters every frame lastly we need a shader so we'll start with the bare bone shader here the vertex shader just transforms the position and sets the size of the point and the fragment shader just samples the texture so with all that done we load it up and here we have some particles on the screen first thing you notice that there's some weird issues here when i swing the camera around smaller or further particles seem to be drawing over top the ones that are supposed to be closer to the camera it's because they're drawn in the order we defined them meaning we might draw a close one first followed by a far away one after and since we're not writing out depth values the one that's drawn second will override the first one let's start with just two particles as an example it's pretty obvious from here that one is supposed to be further away than the other depending on where the camera is if we swing the camera around the right way you can clearly see the further one drawing in front of the closer one let's go fix this luckily this is an incredibly easy fix we just sort the particles from furthest to nearest in the comparison function we'll compare the distance from the camera to the particle as a side note you can of course use distance squared it's a minor optimization if you know what you're doing just go for it but we're just going to use distance for simplicity's sake once we do that load check sorting from both angles and you can see that it doesn't really matter which side i view the two particles from they always seem to appear in their correct order now and if we go and put all the particles back let's just bump this number back up and see there's no weirdness from any angle let's move on to some more advanced stuff now and add some parameters that can vary from particle to particle let's say that we want to vary the size of each particle there's a few things you need to do first off we need to go into the shader and add a size attribute and then multiply the gl point size by this after that we need to go into the particle definition and we'll randomize the particle size and then we update the geometry with the size so that the value gets passed into the shader loading this up notice the size variation some of these are really big and some are really small we'll add some color variation next so we need to go back in and it's a simple matter of going back into the particle system defining color as part of the geometry add it to the particle definition here we'll randomize the rgb values then you need to go into update geometry and update the geometry properly from the colors after that you add support in the shader by declaring a color attribute then you declare a varying attribute which is a way for a vertex shader to pass values into the fragment shader in the fragment shader you essentially want to multiply the texture's color by the particle's color and once you load it up the colors are all appearing i can just kind of spin it around a bit but you can see there's a lot of different color variation here now let's make them fade and blend so instead of seeing those black squares we see something a bit more like smoke first thing we want to do is just enable blending and that's a simple matter of changing the blend mode from no blending back to normal blending once we do that we can see that they're partially transparent but keep in mind that all we've done is enabled the texture of transparency we also want to be able to affect how faded each particle is overall so like the other attributes like color we're going to be adding a new attribute same thing we modify the particle definition we modify how the geometry is updated in this case we're just going to pack the alpha value along with the color and change color to be a vector of four floats instead of three same changes to the shader we'll just substitute those vector3 for vectors once we run the resulting code you can make out that some of the particles are a lot more faded out than others this is working out great but what is all this work for well what we've quickly built is a basic particle system and what you can do now is start animating it so i'll show you how to do that next the way we can do that is by going back to the particle definition and the first thing we need to do is define a lifetime for a particle that gives you the ability to animate over the lifetime changing the attributes of the particle however you want for example i could easily decide to animate the alpha of each particle to start at zero build up to one quickly and then slowly fade away to zero again then on top of that i could say decide to start each particle as blue make them red and then green as they fade away so how do i do this easily we can define a spline with multiple points representing what color or how faded the particle should be at that particular point in the particle's life i've written this quick linear spline class here and all it's doing is during the update it's checking what fade or color value should be assigned to the particle at that point in its life and of course you could get a bit more variety by rotating the texture a bit randomly for each particle so let's go do that what we're going to do is declare a rotation here in the particle declaration we'll initialize it to a random value between 0 and 2 radians then we do the usual changes beginning with adding an attribute and then updating that attribute in update geometry now here in the vertex shader we take the angle and compute the cosine and sine and pass it down to the fragment shader here on this line we take the 2d texture coordinates and multiply that by a 2d rotation matrix now look at this the smoke looks a lot more random since we just randomly rotate the texture a bit hell you can even animate this back in the code if we just increment this by a fraction of the frame time they should rotate a little bit loading this up pretty cool there's just that tiny bit of movement that makes the particle system look just a bit better lastly let's make the move a bit so we'll go and add a velocity to the declaration of the particle and then we'll just update the position here each frame adding the velocity times the frame time and we'll also just add some drag here just to slow the particles down a bit this isn't a physically accurate simulation just giving you an idea of what could be done let's add the fading back in as well so i'll uncomment that and this is kind of looking cool but it doesn't really look like fire does it what we need to do is change the blend mode now blend modes are a totally different discussion altogether and 3ds supports quite a few options here but a really basic overview is that there are two ones that are often used alpha blending and additive blending the mode that we've been using up until now normal blending is alpha blending or what you'd use to do something like smoke if you want that glowy fiery look you'll want to switch this to added blending and when we do that this is looking a lot more fiery you can kind of look around this at different angles and it's definitely looking a lot better so i'm going to load a rocket model in now and i'll make a few quick changes to the particle system code we'll animate the size of the flames starting small and getting bigger and i do that by adding a spline for the sizes specifying how big roughly the flame should be at various point in the particle's life then i can sample the size here and update particles and multiply it against the current size i'll make a few other small tweaks here and there but mostly it's the same as we've been working through the big difference is i'm going to make the flame shoot down instead of up and here we go once we do all of that this really helps sell the rocket trail on this rocket if we wanted to go even further we could change the flames to turn into ash and smoke but that also requires us to dynamically switch from additive to alpha blending which is entirely possible with a more advanced understanding of blend modes but not today definitely in a future tutorial hope you enjoyed this make sure to like and subscribe as always leave a comment and especially let me know if there's a subject you want covered and i'll add it to my to-do list like always code is available on github grab it and work through it and i'll see you next time cheers you
Info
Channel: SimonDev
Views: 34,751
Rating: undefined out of 5
Keywords: simondev, game development, programming tutorial, three js, three js tutorial, writing particle system, particle system, webgl, webgl tutorial
Id: OFqENgtqRAY
Channel Id: undefined
Length: 10min 18sec (618 seconds)
Published: Tue Aug 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.