Making a PARTICLE SYSTEM in ONE HOUR! (NO ENGINES)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I've heard that a lot of you guys have been missing my intro so I thought that I'd bring it back hey we love guys my name is the churner welcome to another video so today we're going to be doing another one of these kind of one hour challenge things last time I did this I made a game in an hour check out that video if you haven't already basically what I did is this guy called Danny made a game in an hour using unity and I thought I would try and recreate that same exact game but using my engine inside hazal which is a very difficult task because hazel is like barely an engines barely capable of doing well anything but nevertheless I ended up making like exactly the same game and it took me around two hours or so and one of the hardest things to do in that challenge was all of the particles because hazel doesn't have a particle system in fact doesn't have like the rendering technology we typically use to render particles and so because of that I have to ride a particle system from scratch within that time limit and I know that a lot of you were interested in how exactly I managed to pull that off and honestly speaking I don't think particle systems are that difficult especially like the one that was needed for this game where it was just a bunch of colored squares it wasn't like some kind of photo realistic textured you know blending like smoke or something like that it was a lot easier than that it was just a bunch of colored squares with like a lifetime and all of that stuff not that difficult to do so what I thought I would do in today's video is basically set up another timer and see if I could write a particle system from scratch within an hour and I'm actually not gonna use hazel at all for this video I'm just going to use my OpenGL base library if you guys don't know what I'm talking about check out that video there basically I just made like an OpenGL kind of core based library that would easily let me just write OpenGL card on top of an already existing project so that's the plan for today we're gonna see if we can write a part of the system from scratch within an hour but first I want to thank surf shark for sponsoring this video surf shark is a fantastic VPN service that makes online privacy protection easy and attainable it encrypts all Internet traffic sent to and from all of your devices and keeps your IP address hidden so the no one can see what you're doing online and speaking of devices Surf Shack has no limit to how many devices you can use it on simultaneously which is great these days we spend a lot of time online almost as much as we do sleeping and because of that the internet knows a lot about us but by using surf shark all of your data is sent through a secure VPN tunnel so that no one can see it without your permission surf shop is more than just a VPN though it's more of like a fully fledged security toolset and because of that has a lot of other great features for example Surf Shack also blocks ads which is great because I tend to travel quite a lot and not have that much mobile data and by blocking ads I save a bunch of mobile data and also my browsing experience is just faster and speaking of ads have you ever been spooked by how an ad just seems to know exactly what you've been talking about that's because your data is out there but not with surf shop surf shark have been amazing enough to give you guys 83% off and one free month all you have to do is sign up using the link in the description below and use the code Cherno go ahead and sign up now using my code and make sure that you put on all of your devices so that you're completely protected all right let's write this particle system so for this video instead of just showing you guys like a time-lapse of me working on this thing and then later adding some voiceover which let's be honest can be faked anyway I thought that I would instead just take you through the completed code and explain a little bit more about how it actually works I don't want to spend too long going through all this over there something that I've missed that you guys want to know just leave comment below and I'll try and just reply to that comment or make another video or something like that and without further ado let's get into this so we have this class called particle system and that's kind of it you know there's just this simple sauce file this header file that basically makes up the entire particle system the only additional file that is necessary for this particle system or additional class I should say is this random class and this is exactly the same random class as the one that appeared in that one hour game that I made in hazel and it's it's super simple again something that you would definitely expect to be part of the engine it's just using this kind of C++ standard library random like distribution function and random number generation algorithm here and we're just setting up a static instance of that and then there's just like this helper function here called static float float and and that basically just returns a number between 0 and 1 so it just samples this random distribution here and then divides it by the highest possible number that will result from this function here so basically it gives us a number between 0 and 1 and that's great because it just makes it super easy I love doing stuff like this because it makes it super easy to generate any random number I want for example if I want something that's between like I don't know 0 and 10 I can just call you know this random float function and then multiply it by 10 and then obviously I'll get something between 0 and 10 if I want something between 1 and 0 obviously I don't need to multiply it with anything if I want something between 1 and a thousand you guys get the point it's really easy to just kind of whack that on and I to be honest I kind of prefer that to functions with parameters where it's like okay specify your range or something like that all right that's the random class now if I spend too much time here because it's super simple and should make sense particle system is the meat of everything so again you can see it's very simple we have an on update function we have a render function and we have this emit function so emit will actually emit a particle just one particle and the settings that it uses to actually emit this or rather I should say the parameters that it uses are these particle props which stands for particle properties so the reason that I've made this struct in the first place is because I don't want to have you know one two three four five six seven eight nine parameters all over here inside these function parameters that's just way too much it's gonna be really hard to set and also it means that by taking in a struct like this I can not only have defaults such as this like 1.0 F obviously you can do that with function arguments as well but it's a little bit more complicated just because like you there have to be at the end of the function whereas here I could you know set a default position or whatever I want but also it's really useful because I can reuse these same particle props to emit particles that are that should be pretty much the same so when I'm when I'm emitting smoke it's nice to have a little template and maybe only the position changes but everything else stays is saying maybe the velocity will change as well that's what I did in that 1 hour game because obviously the ship the ship's Direction kind of controlled the velocity of the actual particles in which direction they would move in but other than that just by having this particle props here is really cool because I can just kind of create an instance of this struct somewhere inside my client code and then I can just change only the parameter I'm interested in changing and just keep passing that into that this emit function to emit more and more particles as you'll see in a minute alright so other than that we have this struct called particle this is what a particle currently is this is what makes up a particle so a particle at any given frame will have a position of velocity a begin and end color a rotation a beginning end size lifetime life remaining and whether or not it's active because this ties in and this active boolean really ties in with this particle pool because what we want to do is create a pool of particles it what you don't want to do is every time you need a new particle create a new particle because by doing that it's just gonna dramatically slow down everything that's going on what we want to do is basically pre-allocate this pool of particles and then continually reuse that array that way there's no memory allocation everything's kind of contiguous in memory and I mean it's just gonna perform a lot faster we have this pool index which is basically the index of the currently active particle now or rather the next the next active particle so the next particle I should say that will be active once we actually emit it so what we do interesting lis here as we start at the maximum size if I go over it as if to the C++ code you'll see here that the particle pool has a size of 1000 particles so obviously because this is like you know running in our it's hot card it to be 9 and 9 here because that's the last possible index and the reason we start at index 9 and 9 and all 0 is just because when we render this we should be rendering it in reverse order so that everything can blend together properly especially when we start dropping those alpha values if you don't do it that way then it's just you'll get artifacting we're basically weren't blended correctly with anything because it doesn't know how to alright anyway so and then we just have some basic stuff here to actually render the particles so because I'm not using any kind of engine here I'm just using this OpenGL library that I've made we have to do all of the OpenGL rendering ourselves which is fine and there's not that much to do but we basically need to have these things here ok cool let's dive into this obviously an update is a function that will be called every frame as will on render so on render just takes in a camera whereas on update is what does the actual I guess particle simulation and that's why it takes in a time step ok into the C++ code so again in the beginning we just resize this particle pool to be 1000 particles so this is not like reserved or anything it's resize it will actually instantiate 1000 particles which is really nice because again we already have done that there's no nothing that needs to be done when a particle gets emitted it's all kind of pre allocated pre pre instantiated and then in the on update particle actually let's look at an image first probably because I think that'll make more sense and I've got some weird like errors here I don't know if I accidentally press something I don't think I did I mean I did that but no I don't know it's probably just it's probably just nothing yeah it is nothing it's just Visual Studio so what does it mid-to well em it's job is to actually create a particle but the particle already exists it just needs to basically reuse or recycle an existing particle in memory so what it does is it queries basically be the active pool index which is where are we up to in this particle pool what is the next index we can use and then inside that particle pool using that particle index it retrieves a reference to a particle so this is now basically a blob of memory that represents this new particle we're emitting step one is to make it active so that it will get rendered and updated and then we can basically fill out the rest based on the particle properties that get specified so again really simple stuff position obviously just sets to position rotation is kind of hard coded here you can't customize it through particle props this was basically the same as that one our game as I mentioned and I did not care about rotation I just wanted it to rotate I didn't care about the rate I could just hard code that you can see this is an example of using that random float function then we have the velocity which again is just completely random here the velocity variation controls how big we we can vary our velocity so you can see we kind of start with a base velocity and then we add on to that and number that kind of by default will be a number between negative 0.5 and positive 0.5 and then that will get multiplied with whatever the variation here so in other words if we say that the variation is 2 meaning we can kind of go within 2 within 2 units or 1 unit either side of 0 right we can add that on here then that's what it will do so in other words if I actually specify a horizontal velocity variation of 2 and then an initial velocity of 1 what that means is that since I'm going to add that on I'm gonna get a final velocity somewhere between 0 and 2 because it's going to add on 1 or subtract 1 else any number between that range from that kind of base velocity and you can do that kind of separately on each axis which is really nice because you can use it to simulate gravity so in other words if I have a velocity variation I can I can make that velocity Y be always negative because it has to be negative potentially because I always want the particles to go down maybe just a different rates color begin color and super simple this is just the color over life this is the lifetime we also have to keep track of life remaining because according to the life remaining that's what we actually well life time is the total lifetime but we also keep track of life remaining so that we can actually figure out the percentage of life that has passed and we need that so that we can properly figure out you know any kind of looping I guess functionality so anything that needs to linearly be interpolated over the over life such as the color or like the Alpha as well all the size anything that has a beginning end we need this so that we can figure out at what kind of stage of its life that particle is at size begin size end again with the variation thing super simple again and then we have pool index so we decrement this and then we mod it by the size so that it wraps around $2.99 again if it needs to and this will basically the the purpose of this I guess is just to set up the pool index for the next particles that when we omit the next particle we know the index in memory where we can actually write particle data to okay cool super simple on update this goes through the entire particle pool if it's not active it continues now it could potentially be safe to just break at a certain point the reason being that we know that if a particle is not active if it suddenly hears something that's not active it's likely that the all the further ones will also be inactive however this requires you to know the particle this starting particle index because if you picture the particle pool as like a little window in memory that keeps moving and in fact as I'm saying this I'm realizing that there's so much to explain here and not much time so maybe I'll make another video with like diagrams and stuff but let me know if you want to see that in the comment section below but basically because of that we need to know the starting index if we want to break so this is just a lot easier obviously to do and a lot safer so if the particle is life is gone it's dead then we can just set active to false and continue to the next particle otherwise very simple what we do an on update we just subtract the life remaining by the time step because the life remaining is in seconds and the life that you specify for a particle is in seconds so if I set the live to 1.0 as it is by default that's one second position and rotation obviously we increment the position by the velocity times the time step and then the rotation as well by a hard-coded 0.01 which is in radians multiplied by the time step all right rendering now this is a really simple hack here I have a little if not M quad VA which basically means if the quad vertex array which is this is that a zero means we haven't created the vertex array yet so we'll go ahead and do all of our initialization code I didn't want to do this here because the particle system is meant to be used as a stack based variable which means they can definitely be initialized before or instantiated before OpenGL has been instantiated which means we can't do all this stuff up in jail been initialized initialized instantiated you guys get the point but so I couldn't put the stuff in the constructor and I really did not want to write an init function so this is just a nice easy way to be like okay well before you ran delicious make sure that you can render I'm not going to go through this stuff it's really basic rendering code this creates a quad that's it it creates a quad and it retrieves uniform locations so uniforms like the view projection the transform and the color that that's it it's super simple nothing to talk about Apple so we use program and this is again uploading the camera matrix to that particle shader which we might look at in a second and then the particle pool so this goes through the particle pool and again what we've done is and this is the cool thing here we've when we emit a particle we go through a backwards like this so we can actually go through everything forwards which is technically better because I don't think I like when we might not be like particles could get emitted quite often per frame but we're definitely not going through the whole pool to emit particles whereas to update and surrender we definitely have to go through that entire particle pool which means that I don't want to go backwards because that wouldn't be very good for the memory access or anything like that so we can still go through everything forwards which is great it's just that they get emitted from the end which again if you don't have a screen full of particles might be a little bit not good because it has to continue past a whole bunch in fact that's another reason why I said you have to know the starting particle if you want to break okay fade away particles so here all we do is we look between the color end and the color begin right so that we figure out what based on the remaining life what the color should be and then we also multiply the Alpha by life so life will be a value between zero and one because we're dividing it by the total lifetime the current lifetime by the total lifetime and then this will basically make it so that it just fades out to zero alpha by the end of its life linearly ok flirt size again loping between size and the size begin based on the life same with no that's it that's a little lapping and then rendering obviously all we do is just create a transformation matrix here with the position the rotation and the scale because obviously size is also something we care about then we upload those uniform matrices and this is what one year for matrix which is the transform and then also the color and the color just avec for and then we render one single particle now obviously this is not efficient because you would want to render all of the particles in one drakul very likely like literally all of them definitely I think and well in this case is only a thousand marks they're definitely all of them in one drakul whereas we're not doing that and again that's just because the one hour kind of time constraint and also because it is based on that one hour game and hazel did not support batching at all there is currently a batch rendering OpenGL series going on on my channel definitely check that out I'll have it linked in the in the top right corner that's gonna that's basically the technique I'm talking about where we actually batch everything together into a single drawer call instead of rendering all these particles separately because that's a lot slower and that will definitely limit just how many particles we can have on the screen at once because if we use up at this entire particle pool that's 1000 particles 1000 drawers which is already kind of getting up there okay that's it I think that's it now the shader the shade is not that interesting it's just a this is just a normal vertex shader nothing special at all and the colleges and the color traders also special surprise I mean not special it's just literally setting the output color to be that uniform color that we specify so super simple stuff and then be really simple I guess sandbox layer that I wrote which is again really simple as you can see all that does is enable blending which is really important because we want to be able to fade the particles out and we need them to blend with each other properly and with the clear color as well this is what I was talking about and how good it is to initialize this kind of particle prop so rather to kind of have this particle prop system because I can just set up all this stuff here and again you know the color the color begin and end of each particle that I generate it's gonna be the same so why would I keep setting that you know all the time I can just kind of store it here and then if I want to actually emit a particle I can just do particle system in it and then yeah just setting this stuff up again you can tweak it however you you can expose it to GUI and play around with it if you like as well this is just me making sure that we can resize if we resize the window jail viewport will be resized as well and then on update clears the color and then if the left mouse button is pressed what we do is we basically so most of this code is not actually most of this code is to figure out the particle position the reason is we have a camera we can move the camera around we can zoom in and out and we can resize the window and so because of all these floating parameters and because we can literally move the camera as well we want and we want to well the example I've gone with is when you click it it emits particles at your mouse cursor because of that I obviously need to have all this code to figure out where in the wind world space I should be emitting the particles um and then that's it and then what I do is I emit five of them at once because why not just make it a little bit more particles and more fun and also because they obviously have velocity variations size variations all that stuff so if you omit five particles they'll all be a little bit different but they will originate at the same position with the same color and all that stuff cool then I just update the particle system once per frame and render it once per frame that's it and I've added some I am GUI controls because why not so we can customize the birth colour death color and the life time and of course feel free to play around with that however you like okay and with all of that said let's launch this and take a look at what I was able to do in under an hour okay so here we have this kind of OpenGL sandbox thing here if I click and drag my mouse it will emit particles and I can zoom out I can move the camera as well so you can see I'm moving the camera here yeah that's pretty much it pretty cool right so we have all of these particles being emitted from my mouse cursor and then if I I'll try and kind of fullscreen this so I'll resize it to be the full screen that obviously works and we can kind of have a little that stuff here so let's play with the lifetime for fun so you can turn this way up so like this will be like you know 13 seconds which as you can see is quite a lot before it kind of fades out and also I don't think I'm glocks the controls but you can also make it really short so like 0.3 seconds which is kind of cool as well so that's kind of customizing in a lifetime I'll just take it back to like two or something and then we have birth color and death color so like I said the birth college like Wyatt the death color to black or something like that and now you can see they kind of fade out to black or I could make them fade out to like pink or something like that whatever you're into or we could even do something more fun maybe by making it kind of go maybe red to blue and that way would kind of become purple before it goes blue that's pretty cool so there you go that's the particle system one our really simple stuff and then you also have like all the size variation and stuff going on and obviously you can add so much more to this but this was just kind of a simple I guess example and yeah looks pretty cool so that is the particle system in one hour and of course I'll have a download link for all of this code in the description below let me quickly see if I can just draw like a little Chennai lager hey there it is pretty cool honestly that was not all that difficult and it took me 57 minutes and I mean I added a whole bunch of stuff in the end just because I had extra time now obviously we are dealing with a rather simple particle system with plenty of limitations but the point is something like a particle system is super easy to just smash together like I just did and it can just massively improve the visual quality the visual fidelity of your games or any kind of graphics that you're working on not to mention they're extremely fun like I'm just gonna probably keep tinkering with this for a while just cuz it's fun now I mentioned several times that this is not like an optimal way to write a particle system and that's due to a number of reasons in fact I might make a little bit of a particle kind of miniseries let me know if you want to see that in the comment section below just explaining how this kind of all works and how to build it maybe step-by-step and how to improve it over time but one of the reasons there's no optimal is because everything is rendered as a separate drakul which is terrible I'm currently doing a series on batch rendering check that out if you haven't already that's basically where we take all of these squares and we've put them into one draw call that massively improves the number of particles we can actually have on the screen at once because if I push this too far it's just gonna start it's just gonna take too much time and we're gonna start losing frames the other reason is just with how we process data and the kind of for loops and just the layout basically in memory it's not optimal for CPU keishon or anything like that we might talk about that later as well but the point is it works and I want that to be like a takeaway for a lot of people people just tend to overcomplicate software engineering for no apparent reason maybe just to look cool or something like that the simplest solution is like always the best if you can write something and it works and is really simple them the more simple it is the better because apart from other people having to deal with it and also you being able to move on with your life instead of spending your whole life redesigning this particle system to make it the most complicated best thing ever which probably won't be anyway it'll be nice and simple and easy everyone will understand it you'll be able to move on and it will work so in other words what I'm saying is that yes this is simple and it does a lot of naive kind of what other people would say are stupid things but it works it works well it looks great and it performs adequately so there's no reason to over complicate things for nothing anyway let me know what you guys thought of this video if you have any other kind of one-hour challenges or maybe even 24 hour challenges if that's something a little bit more complicated let me know in the comment section below because I really love doing stuff like this it's a ton of fun don't forget to check out surf shark there's a link in the description below that'll save you eighty-three percent and also give you one month for free make sure you use the code chatter make sure you guys stay safe online and I will see you guys next time goodbye [Music]
Info
Channel: The Cherno
Views: 58,604
Rating: undefined out of 5
Keywords: thecherno, thechernoproject, cherno, c++, programming, gamedev, game development, learn c++, c++ tutorial, game engine, how to make a game engine, game engine series, particle system, Making a PARTICLE SYSTEM in ONE HOUR! (NO ENGINES), one hour challenge, particle system in one hour, making a particle system in one hour
Id: GK0jHlv3e3w
Channel Id: undefined
Length: 26min 20sec (1580 seconds)
Published: Wed Feb 05 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.