One thing you can do to vary the flow pattern is to use a Perlin noise with one more dimension than your display(3d on a flat screen, 4d on a 3d space), and vary that value(z for the 2d case, t for 3d) over time. That should create a smooth change in the flow pattern…
Thanks for a really good code along - great pace, I love that you keep on point and give a very clear explanation of a rather elegant way of achieving a flow field. I used your approach in Processing using an ArrayList of PVector particles. Update the x, y position of each particle by adding the cos and sin of the noise angle * velocity. So in the for loop in draw(), particles.get(i).x = particles.get(i).x + cos(angle) * velocity; this updates the position very nicely. Do similar for y. The only comment I would make is that new particles introduced at random anywhere in the field results in a rather imbalanced image with all the interesting stuff tending to veer to the left. So I changed the if(!onScreen) to particles.get(i).x = width; and keep y random, so all new particles appear anywhere on the right of the window. This balances up the image. Thanks!
Thank you! And thanks for heads up for the link, it should be working again now, but honestly my website is very old and out dated hahaha might be time for a refresh!
Could u do a video about diferent flow fields, i saw some cool stuff but im not sure how they do it, like spirals/flowing around a point, my guess is that some 3D noise or function is used
Sounds really interesting, I'd love to see some examples! (might be easiest to share in my discord?) Using 3D noise for flow fields seems like a really interesting idea, might have to explore that! Thanks for the comment!
@@BarneyCodes hey barney, the only examples i found where: th-cam.com/video/PHySrgK7sj0/w-d-xo.htmlfeature=shared And a demo of "generative garden" channel By 3D i meant using time to change the flow fields angles, i saw it on a video about "steering behaviours" of the coding train.
Hello ! Here, when you use the alpha parameter to make tracks behind the dots, there remain permanent dark-grey traces - it's inherent to alpha in blend mode. Do you have a trick to solve this ? I'd like it to come back to real black. Thks !
Yea I've run into this issue in the past and it's really annoying isn't it! The only thing I can really think of would be to add a shader to the output that checks if the pixel is at a certain darkness threshold and if it is, set that pixel to black, but that's a fair bit of faff to fix what seems like such a simple issue! If you come up with a better solution I'd love to hear it!
hi! i'm a beginner to p5.js and currently trying to have the particles shift colors (like a rainbow or gradient) as they move in the flow field--would you have any guide or tips on that?
Hi! So glad to hear you're giving P5 a go, it's a lot of fun! And this is a great question! If you want to do anything with rainbow colours, your best bet is to probably use the HSB colour mode (p5js.org/reference/#/p5/colorMode). You're probably familiar with the RGB colour mode, where you specify how much Red, Green, and Blue you want in a pixel, but that makes it very hard to cycle through the rainbow. HSB stands for Hue, Saturation, and Brightness. Saturation is how much colour is present (no saturation will be greyscale, full saturation will be coloured) and brightness is how dark/light the colour is. The magic happens with the hue value, which dictates which colour you want, so if you increment the hue value you will get all the colours of the rainbow! So once you've got P5 running in HSB colour mode, you'll be able to set the colour of the particle just before it's drawn in the draw() function, just before the point(p.x, p.y) line. Since it's drawn using the point function, you'll want to use the stroke function to set the colour, using a hue, saturation and brightness value. To get started, you could try using the particles x coordinate to set the hue (you might want to look at the map function for an easy way to do this! p5js.org/reference/#/p5/map), but once you've got that figured out, you can use whatever you want to choose the position in the rainbow! I hope that helps, and I hope you have heaps of fun on your P5 journey! If you've got any more questions, please don't hesitate to ask!
I find it interesting that the particles can flow up and down freely, but they only ever move to the left. The cos function implies that the particles aren't restricted from moving right, but they simply never do. Is this because of the way that the noise is generated? I know nothing about perlin noise, so maybe there's a property about them that naturally excludes values in certain ranges.
You're spot on, it's because the noise values aren't very uniform (you can see that in this sketch: editor.p5js.org/BarneyCodes/sketches/xfnID7zDQ ), you can see it's clumped around 0.5, which maps to left with this code. So theoretically they CAN flow to the right, but the noise makes it WAY more likely that they'll go to the left! Not exactly sure what the best way to deal with that is, maybe there's some way to map the values to a more uniform distribution?
Hey ! Thank-you very much for this tutorial ! There is an issue I would like to avoid, but I don't know how : If I go to your sketch & i lower the amount of particles to let's say 50, I get these dark grey trails that persists in time... I don't understand why they dont go back to full black... Do you have any idea how to fix this ??
Hi! Thanks for the comment! I've run into this issue a few times actually! I believe it's because of the way that opacity is handled. The way I get the trail effect in this video is, instead of wiping the screen each frame, I draw a background that is a *nearly* clear black, so in theory it darkens the screen, but when things are nearly black already, for some reason it doesn't darken them any more. You could try to use blend modes to achieve the same effect of darkening the screen, instead of using opacity. So instead of saying "background(0, 10)", you could say: blendMode(MULTIPLY); background(250); blendMode(BLEND); Have a look at this link if you want to learn more about blend modes, and feel free to ask if you have any more questions! p5js.org/reference/#/p5/blendMode
@@BarneyCodes Hey, thx, it works. The only down side of that solution is that the black is not complete black... The more you want your trails to be long (the more you go up to 255 for the background ), the less black its gonna be.
@@maf2525 Hmm that's a shame! I'll keep thinking about it and see if I can come up with a simple solution. The only one's I can think of right now are to either use a custom shader to make sure the screen goes to black (you could use my p5.filterShader library for that github.com/BarneyWhiteman/p5.filterShader I've got a video on my channel about setting that up), or to keep track of the last 10 (or however many) positions for each particle and draw them more faintly the older they are, but then you could make the background black in between (I think I do this in my "Electrical Circuit Pulse Particle" video, but be warned, it's very old!!).
@@BarneyCodes Maybe for each frame, i could set each pixel that is lower than 20 (or whatever works) to 0, using the loadPixels(), an if statement and updatePixels(). Is doing that not "CPU friendly" ? I've never tried it... Kinda like a threshold
@@maf2525 That would probably work too! I just worry that doing so might be quite slow, especially with a larger canvas, but definitely worth trying! My idea with using shaders was essentially the same, if a pixel is nearly black, just make it black! I made it quickly here if you'd like to see: editor.p5js.org/BarneyCodes/sketches/2ksGLeFS7
I love this video - the one thing I've been trying to do with this is record the thing but with the fade implementation, any images or videos i record with CCapture the opacity is static (i.e. I've got a solid, unchanging background and particles) and I can't seem to avoid it. The only thing I've done is take a still of the flow field "manually" by screenshotting it on my computer. I doubt you'd know a way (or a reason why) the opacity isn't picked up on the recording or in the saved images? Otherwise, lovely video and really easily introduces particle systems/flow fields. I'll be moving to make a new more complex version soon hopefully!
Thanks for the kind words, glad you enjoyed the video! For recording, I'm not too sure to be honest. You could try using p5.capture (github.com/tapioca24/p5.capture) and see if that's any different from CCapture, not sure if it will be though. I've always just recorded my screen with OBS (obsproject.com/), which captures exactly what you see on your screen. Hopefully one of those solutions works for you! Good luck!
@@BarneyCodes OBS is a good idea actually! I’ve tried CCapture and p5.capture but gotten the same results. But OBS should definitely work, thanks a bunch. :D
Great question! I think the best way would be to make a particle class so that each particle can have a colour. Then you can use the get() function on a PImage to get the colour of a pixel at a given location, so when you make a new particle, it can be the same colour as the image. I hope that helps, let me know if you have any questions!
@@AntoineReekmans I've quickly made this based on the code from the video: editor.p5js.org/BarneyCodes/sketches/_jE4NUmYd Hopefully that's similar to what you had in mind! You can see at the very bottom I've made a Particle class, which has an x,y location and a colour. I also created a function called getImageColour which will figure out what colour a particle needs to be to match the image. The image is loaded in at the top in the preload function, you can change this to whatever image you like! On lines 33/34 there are two options for how the effect looks so definitely play around with them! Hope that helps, good luck :)
Good catch! Looks like there was a mistake on line 28 in the code I linked. When I was checking if the particles were off the screen for some reason I was only putting them back on the screen if the frameCount was under 1000. I've fixed that now so it just checks if the particle is off the screen. If you go to the link with the code again, the effect should keep going forever. Hope that helps!
@@BarneyCodes will do! I am looking into image manipulation effects with P5. Its much easier to convert image into base64 in P5 tha the default HTML Canvas. But if you could reach there before me then I could learn something new :) Btw, how can I repeatedly change the noiseSeed after a set amount of milliseconds and not on mouse press? Any setInterval kind of method?
Sounds cool! Regarding changing the noiseSeed, P5 has a millis() function - p5js.org/reference/#/p5/millis - that returns how many milliseconds have passed since the sketch started running. You can use that to figure out when you want to change the seed!
Great question! P5js uses the html canvas under the hood, so you can definitely do it without P5js! P5js just makes it a bit easier (in my opinion) to draw things to the screen, and also provides easy access to perlin noise (which you'll have to make for yourself). You can learn more about drawing directly to the html canvas here: developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial And here's a link for making perlin noise in js: joeiddon.github.io/projects/javascript/perlin.html Hope that helps! Let me know if you have any issues!
Is there a way to speed up the Perlin Noise or slow it down by the function keyPressed? I’m trying to make a small project where the colours change and the song being played in the background by keyPressed. I’d just like to slow or speed up the Noise depending on what music is being played. Thx
Great question! The place to add it would be when we add to a particles x and y location, and there are two methods you can use. The simplest one is to multiple the output of the sin() and cos() functions by a speed variable i.e. "p.x += cos(a) * speed;" and do the same thing for the y. The problem with this though is that it will probably slightly alter the path that a particle takes because each update it will skip over some locations since it's now travelling further. The second method would be to instead update the particles multiple times each update, which would make them follow the same path but travel faster. The downside to this method is that it might run slower for lots of particles since you're doing a lot more updates. The way you'd do this is to wrap the lines inside the update for loop after we've drawn it to the screen inside another for loop, the more times you execute the loop the faster the particles will be. Sorry for such a long message! I hope that it makes sense, if you have any questions though feel free to ask! And let me know how your project goes!
@@BarneyCodes Thanks for your reponse! I've tried the variant with the speed variable, this works but exactly as you've said the path isn't that nice to look at anymore. Your second solution sounds a bit hard atm but I'm going to try to code it and see the difference:).
The easiest way is probably to create a very simple Particle class with x, y location and a colour. Just before you draw a particle on the screen you can change the stroke colour to the one for the particle. Someone asked me a similar question about colouring the particles from an image, so I've got an example sketch of that set up here: editor.p5js.org/BarneyCodes/sketches/_jE4NUmYd which shows the Particle class and using the particles colour for drawing. You'll want to set the colours based on a rainbow instead of an image though! To make choosing rainbow colours easier, you should look into the HSB colour mode (second example): p5js.org/reference/#/p5/colorMode I hope that helps! Let me know if you have any other questions!
You can use the strokeWeight function to change the thickness of lines in P5js and pass in the number of pixels you want. It defaults to 1px but if you wanted them to be 10px you would put strokeWeight(10) into the setup function. Hope that helps!
Good pickup! I did a bit of investigation and basically just found that the noise() function is not very uniform, it skews heavily towards the middle values (ie clumped around 0.5) which in my sketch maps to 180 degrees, or left. If you've got any suggestions on how to get a more uniform mapping I'd love to hear it! I created this sketch to figure out what was going on if you'd like to have a look! editor.p5js.org/BarneyCodes/sketches/xfnID7zDQ
@@BarneyCodes Ah, makes sense. I used 2 * TAU and it looks better, but ultimately it may be tricky to convert a non-uniform distribution (impossible?) into a uniform one. Not that it's that important in this case.
Yea I think it'd would be a pretty tricky thing to solve. The 2 * TAU solution definitely improves it! And like you say, for something purely visual like this I think your solution is perfect!
@@BarneyCodes I also commented on reddit about that. The following lines do the trick. p.x += cos(a) * ((i%2) ? 1 : -1); p.y += sin(a) * ((i%2) ? 1 : -1); They +/- 1 factors send the vectors to all four directions, however they are still biased in aligning with the axes. This is not that striking, so it looks beautiful. BTW, converting a non-uniform to a uniform can be achieved for any distribution using the "Probability Integral Transform" theorem, but you need the CDF of the first distribution to make it so, which is not practical (worth doing).
Hey, just saw your reddit comment :) I like your approach, it gives a really nice effect! And thanks for the info on mapping non-uniform distributions to a uniform one, sounds very interesting, I'll have to do some more reading into it. It's been years since I've done any stats!
Thanks for the comment! As far as I know flow fields have been a concept in computer graphics since basically the beginning! The idea behind it is to, in some way, visualise a "noise" field, and flow fields do that by creating particles that get moved based on the noise value at their position. In computer graphics noise refers to some sort of random value, the most basic kind which might have heard of is just "white" noise which is like TV static, but there are countless algorithms that have been developed to produce different kinds of noise. In this video I use a type of noise called "Perlin" noise (developed by Ken Perlin), and it's a "smooth" type of noise, where nearby positions have similar, but still random, values. I'd highly recommend looking at some different noise algorithms if this sort of thing interests you, since they are what make the flow fields work. Some other types of noise are: value noise, simplex noise, voronoi noise. Hope that helps, and don't hesitate to ask any follow up questions!
Hi! P5js will automatically call the "draw" function for you so it acts as the update loop. The "setup" function will only get called once when the program is first run. Hope that helps!
No worries! There are a few ways you could go about it! The simplest would be to change the colour in the for loop where we draw the particles on the screen. You could change their colour based on their x or y location, or by the value of the noise at that location, or something else entirely! But this would mean that a particle would be continually changing colour, which leads to option two: You could make the particles into a class and hold the colour as a member variable which we set in the constructor, which ties a colour to a particle. You can see an example of how this might look in my picture particles video! Let me know if you have any questions :)
The noise() function in P5js is based on Perlin noise, and what it does is gives us values that are locally similar (noise(0) and noise(0.0001) will be pretty close to each other) but still random. This is what I use to calculate the direction a particle is heading in and how it's made to be random!
hey there, thanks a lot for this! Do you know how I could recreate the same sketch on Processing? I am having problems with this line: p.push(createVector(random(width), random(height))) because I believe Processing handles vector differently from p5.js. Any idea how I could rewrite that? In any case, thank you for this tutorial and for this lovely sketch :)
Glad you enjoyed the video! It will slightly depend on whether you're using a normal array (PVector[] particles) or an ArrayList (ArrayList particles) If you're using a normal array you'd have to go something like: particles[i] = new PVector(random(width), random(height)); And for an ArrayList: particles.add(new PVector(random(width), random(height)); Hope that helps!
Is this even possible ? Feels like Processing needs more lines of code to do that, or a totally different approach, like creating a grid first and then create a vector in every cell. Did you succeed ? I am not succeeding.
@@BarneyCodes Hi Barney, thanks very much. Apparently one way is create grid and add a vector in each cell... But feels so complicated compared to your code !! It's so clever !!! Thanks for this video. So smoorh !!
That sounds like you're missing a "let x = ..." somewhere in your code, or you've defined x in a different scope from where it's being used. If you give a bit more detail hopefully I can help you out!
Hey, thanks for the feedback! I do think that single letter variables have a place (for loops, using "x" and "y" for positions, etc), but for the most part you're right. Naming variables is still one of the hardest aspects of coding!
Ayy ur back woo!
One thing you can do to vary the flow pattern is to use a Perlin noise with one more dimension than your display(3d on a flat screen, 4d on a 3d space), and vary that value(z for the 2d case, t for 3d) over time. That should create a smooth change in the flow pattern…
I love this technique, thanks for the comment!
Thanks! Transparent background is unexpected way to do such stuff, and it's great!
It's a really handy trick to know!
Nicely done. I like how you made it uncomplicated compared to other ways of doing it.
Thank you!
I learn't so much from this video, Thank you Barney :)
No worries at all, glad you found it useful!
Thanks for a really good code along - great pace, I love that you keep on point and give a very clear explanation of a rather elegant way of achieving a flow field. I used your approach in Processing using an ArrayList of PVector particles. Update the x, y position of each particle by adding the cos and sin of the noise angle * velocity. So in the for loop in draw(), particles.get(i).x = particles.get(i).x + cos(angle) * velocity; this updates the position very nicely. Do similar for y. The only comment I would make is that new particles introduced at random anywhere in the field results in a rather imbalanced image with all the interesting stuff tending to veer to the left. So I changed the if(!onScreen) to particles.get(i).x = width; and keep y random, so all new particles appear anywhere on the right of the window. This balances up the image. Thanks!
Glad you enjoyed the video, and nice work getting it working with Processing and fixing the imbalance too!
would you maybe like to share your processing code with me? i can not get it to work.
Thanks for doing these - Really loving your work!
Thanks, glad you enjoyed it!
Great approach. Just a heads up that your website link isn't working in the description.
Thank you! And thanks for heads up for the link, it should be working again now, but honestly my website is very old and out dated hahaha might be time for a refresh!
Could u do a video about diferent flow fields, i saw some cool stuff but im not sure how they do it, like spirals/flowing around a point, my guess is that some 3D noise or function is used
Sounds really interesting, I'd love to see some examples! (might be easiest to share in my discord?)
Using 3D noise for flow fields seems like a really interesting idea, might have to explore that!
Thanks for the comment!
@@BarneyCodes hey barney, the only examples i found where:
th-cam.com/video/PHySrgK7sj0/w-d-xo.htmlfeature=shared
And a demo of "generative garden" channel
By 3D i meant using time to change the flow fields angles, i saw it on a video about "steering behaviours" of the coding train.
Hello ! Here, when you use the alpha parameter to make tracks behind the dots, there remain permanent dark-grey traces - it's inherent to alpha in blend mode. Do you have a trick to solve this ? I'd like it to come back to real black.
Thks !
Yea I've run into this issue in the past and it's really annoying isn't it! The only thing I can really think of would be to add a shader to the output that checks if the pixel is at a certain darkness threshold and if it is, set that pixel to black, but that's a fair bit of faff to fix what seems like such a simple issue! If you come up with a better solution I'd love to hear it!
hi! i'm a beginner to p5.js and currently trying to have the particles shift colors (like a rainbow or gradient) as they move in the flow field--would you have any guide or tips on that?
Hi! So glad to hear you're giving P5 a go, it's a lot of fun! And this is a great question!
If you want to do anything with rainbow colours, your best bet is to probably use the HSB colour mode (p5js.org/reference/#/p5/colorMode). You're probably familiar with the RGB colour mode, where you specify how much Red, Green, and Blue you want in a pixel, but that makes it very hard to cycle through the rainbow.
HSB stands for Hue, Saturation, and Brightness. Saturation is how much colour is present (no saturation will be greyscale, full saturation will be coloured) and brightness is how dark/light the colour is. The magic happens with the hue value, which dictates which colour you want, so if you increment the hue value you will get all the colours of the rainbow!
So once you've got P5 running in HSB colour mode, you'll be able to set the colour of the particle just before it's drawn in the draw() function, just before the point(p.x, p.y) line. Since it's drawn using the point function, you'll want to use the stroke function to set the colour, using a hue, saturation and brightness value.
To get started, you could try using the particles x coordinate to set the hue (you might want to look at the map function for an easy way to do this! p5js.org/reference/#/p5/map), but once you've got that figured out, you can use whatever you want to choose the position in the rainbow!
I hope that helps, and I hope you have heaps of fun on your P5 journey! If you've got any more questions, please don't hesitate to ask!
@@BarneyCodes thank you so much for the reply! i'll be sure to check this out!
Good work. Thanks for putting chapters on the vid
No worries, and thanks!
Explanation and the result is perfect thank you so much.
No worries, glad you found it useful!
I find it interesting that the particles can flow up and down freely, but they only ever move to the left. The cos function implies that the particles aren't restricted from moving right, but they simply never do. Is this because of the way that the noise is generated? I know nothing about perlin noise, so maybe there's a property about them that naturally excludes values in certain ranges.
You're spot on, it's because the noise values aren't very uniform (you can see that in this sketch: editor.p5js.org/BarneyCodes/sketches/xfnID7zDQ ), you can see it's clumped around 0.5, which maps to left with this code.
So theoretically they CAN flow to the right, but the noise makes it WAY more likely that they'll go to the left!
Not exactly sure what the best way to deal with that is, maybe there's some way to map the values to a more uniform distribution?
Hey ! Thank-you very much for this tutorial ! There is an issue I would like to avoid, but I don't know how : If I go to your sketch & i lower the amount of particles to let's say 50, I get these dark grey trails that persists in time... I don't understand why they dont go back to full black... Do you have any idea how to fix this ??
Hi! Thanks for the comment! I've run into this issue a few times actually! I believe it's because of the way that opacity is handled.
The way I get the trail effect in this video is, instead of wiping the screen each frame, I draw a background that is a *nearly* clear black, so in theory it darkens the screen, but when things are nearly black already, for some reason it doesn't darken them any more.
You could try to use blend modes to achieve the same effect of darkening the screen, instead of using opacity.
So instead of saying "background(0, 10)", you could say:
blendMode(MULTIPLY);
background(250);
blendMode(BLEND);
Have a look at this link if you want to learn more about blend modes, and feel free to ask if you have any more questions! p5js.org/reference/#/p5/blendMode
@@BarneyCodes Hey, thx, it works. The only down side of that solution is that the black is not complete black... The more you want your trails to be long (the more you go up to 255 for the background ), the less black its gonna be.
@@maf2525 Hmm that's a shame! I'll keep thinking about it and see if I can come up with a simple solution. The only one's I can think of right now are to either use a custom shader to make sure the screen goes to black (you could use my p5.filterShader library for that github.com/BarneyWhiteman/p5.filterShader I've got a video on my channel about setting that up), or to keep track of the last 10 (or however many) positions for each particle and draw them more faintly the older they are, but then you could make the background black in between (I think I do this in my "Electrical Circuit Pulse Particle" video, but be warned, it's very old!!).
@@BarneyCodes Maybe for each frame, i could set each pixel that is lower than 20 (or whatever works) to 0, using the loadPixels(), an if statement and updatePixels(). Is doing that not "CPU friendly" ? I've never tried it... Kinda like a threshold
@@maf2525 That would probably work too! I just worry that doing so might be quite slow, especially with a larger canvas, but definitely worth trying! My idea with using shaders was essentially the same, if a pixel is nearly black, just make it black!
I made it quickly here if you'd like to see: editor.p5js.org/BarneyCodes/sketches/2ksGLeFS7
I love this video - the one thing I've been trying to do with this is record the thing but with the fade implementation, any images or videos i record with CCapture the opacity is static (i.e. I've got a solid, unchanging background and particles) and I can't seem to avoid it. The only thing I've done is take a still of the flow field "manually" by screenshotting it on my computer. I doubt you'd know a way (or a reason why) the opacity isn't picked up on the recording or in the saved images? Otherwise, lovely video and really easily introduces particle systems/flow fields. I'll be moving to make a new more complex version soon hopefully!
Thanks for the kind words, glad you enjoyed the video!
For recording, I'm not too sure to be honest. You could try using p5.capture (github.com/tapioca24/p5.capture) and see if that's any different from CCapture, not sure if it will be though. I've always just recorded my screen with OBS (obsproject.com/), which captures exactly what you see on your screen.
Hopefully one of those solutions works for you! Good luck!
@@BarneyCodes OBS is a good idea actually! I’ve tried CCapture and p5.capture but gotten the same results. But OBS should definitely work, thanks a bunch. :D
@@jacobstone312 Ah yea okay, I thought p5.capture might be the same as CCapture. Fingers crossed for OBS!
cool. perlin noise
is there a way to use Perlin Noise Flow field from one of my image ? where it would move the pixels from my image ?
thanks
Great question! I think the best way would be to make a particle class so that each particle can have a colour. Then you can use the get() function on a PImage to get the colour of a pixel at a given location, so when you make a new particle, it can be the same colour as the image.
I hope that helps, let me know if you have any questions!
@@BarneyCodes Thank you so much for your answer , im pretty newbie , what would the code be then ? Thanks
@@AntoineReekmans I've quickly made this based on the code from the video: editor.p5js.org/BarneyCodes/sketches/_jE4NUmYd
Hopefully that's similar to what you had in mind!
You can see at the very bottom I've made a Particle class, which has an x,y location and a colour. I also created a function called getImageColour which will figure out what colour a particle needs to be to match the image.
The image is loaded in at the top in the preload function, you can change this to whatever image you like!
On lines 33/34 there are two options for how the effect looks so definitely play around with them!
Hope that helps, good luck :)
@@BarneyCodes supercool thank you so much you are the Best
No worries, happy to help!
If i want the particles to not go off screen for the duration of the song how could I do that? eventually they go away
Good catch! Looks like there was a mistake on line 28 in the code I linked. When I was checking if the particles were off the screen for some reason I was only putting them back on the screen if the frameCount was under 1000. I've fixed that now so it just checks if the particle is off the screen.
If you go to the link with the code again, the effect should keep going forever.
Hope that helps!
@@BarneyCodes thank you
@@sgtrat5772 No problem!
Thx Barney. Amazing effect. P5 is surprisingly easy :D
No worries, glad you enjoyed it. Once you've got the basics of P5 down you can do quite a lot with it! Keep me posted with any projects you make!
@@BarneyCodes will do! I am looking into image manipulation effects with P5. Its much easier to convert image into base64 in P5 tha the default HTML Canvas. But if you could reach there before me then I could learn something new :)
Btw, how can I repeatedly change the noiseSeed after a set amount of milliseconds and not on mouse press? Any setInterval kind of method?
Sounds cool!
Regarding changing the noiseSeed, P5 has a millis() function - p5js.org/reference/#/p5/millis - that returns how many milliseconds have passed since the sketch started running. You can use that to figure out when you want to change the seed!
can a flow field like this be made with html, css and javascript in this same manner?
Great question! P5js uses the html canvas under the hood, so you can definitely do it without P5js! P5js just makes it a bit easier (in my opinion) to draw things to the screen, and also provides easy access to perlin noise (which you'll have to make for yourself).
You can learn more about drawing directly to the html canvas here: developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial
And here's a link for making perlin noise in js: joeiddon.github.io/projects/javascript/perlin.html
Hope that helps! Let me know if you have any issues!
@@BarneyCodes thank you!
@@Life_vines No problem!
Is there a way to speed up the Perlin Noise or slow it down by the function keyPressed? I’m trying to make a small project where the colours change and the song being played in the background by keyPressed. I’d just like to slow or speed up the Noise depending on what music is being played. Thx
Great question! The place to add it would be when we add to a particles x and y location, and there are two methods you can use.
The simplest one is to multiple the output of the sin() and cos() functions by a speed variable i.e. "p.x += cos(a) * speed;" and do the same thing for the y. The problem with this though is that it will probably slightly alter the path that a particle takes because each update it will skip over some locations since it's now travelling further.
The second method would be to instead update the particles multiple times each update, which would make them follow the same path but travel faster. The downside to this method is that it might run slower for lots of particles since you're doing a lot more updates. The way you'd do this is to wrap the lines inside the update for loop after we've drawn it to the screen inside another for loop, the more times you execute the loop the faster the particles will be.
Sorry for such a long message! I hope that it makes sense, if you have any questions though feel free to ask! And let me know how your project goes!
@@BarneyCodes Thanks for your reponse!
I've tried the variant with the speed variable, this works but exactly as you've said the path isn't that nice to look at anymore. Your second solution sounds a bit hard atm but I'm going to try to code it and see the difference:).
Good luck! Let me know if you have any questions!
If I wanted to have the particles be rainbow colored, how would I do that?
The easiest way is probably to create a very simple Particle class with x, y location and a colour. Just before you draw a particle on the screen you can change the stroke colour to the one for the particle.
Someone asked me a similar question about colouring the particles from an image, so I've got an example sketch of that set up here: editor.p5js.org/BarneyCodes/sketches/_jE4NUmYd
which shows the Particle class and using the particles colour for drawing. You'll want to set the colours based on a rainbow instead of an image though!
To make choosing rainbow colours easier, you should look into the HSB colour mode (second example): p5js.org/reference/#/p5/colorMode
I hope that helps! Let me know if you have any other questions!
Man, this was lit, like congrats cause you made it look simple af 🥹
Hahaha thank you, glad you enjoyed it!
Awensome work, thanks for guide
No problem!
perfectly explained thank you
No problem, glad you found it useful!
how do i make the particles bigger
You can use the strokeWeight function to change the thickness of lines in P5js and pass in the number of pixels you want. It defaults to 1px but if you wanted them to be 10px you would put strokeWeight(10) into the setup function.
Hope that helps!
Why does it seem that your flow fields are biased to the left side of the screen?
Good pickup! I did a bit of investigation and basically just found that the noise() function is not very uniform, it skews heavily towards the middle values (ie clumped around 0.5) which in my sketch maps to 180 degrees, or left.
If you've got any suggestions on how to get a more uniform mapping I'd love to hear it!
I created this sketch to figure out what was going on if you'd like to have a look!
editor.p5js.org/BarneyCodes/sketches/xfnID7zDQ
@@BarneyCodes Ah, makes sense. I used 2 * TAU and it looks better, but ultimately it may be tricky to convert a non-uniform distribution (impossible?) into a uniform one. Not that it's that important in this case.
Yea I think it'd would be a pretty tricky thing to solve. The 2 * TAU solution definitely improves it! And like you say, for something purely visual like this I think your solution is perfect!
@@BarneyCodes I also commented on reddit about that.
The following lines do the trick.
p.x += cos(a) * ((i%2) ? 1 : -1);
p.y += sin(a) * ((i%2) ? 1 : -1);
They +/- 1 factors send the vectors to all four directions, however they are still biased in aligning with the axes. This is not that striking, so it looks beautiful.
BTW, converting a non-uniform to a uniform can be achieved for any distribution using the "Probability Integral Transform" theorem, but you need the CDF of the first distribution to make it so, which is not practical (worth doing).
Hey, just saw your reddit comment :) I like your approach, it gives a really nice effect!
And thanks for the info on mapping non-uniform distributions to a uniform one, sounds very interesting, I'll have to do some more reading into it. It's been years since I've done any stats!
Best tutorial so easy to understand
Thanks so much, glad you found it easy!
Incredible effect, you explain it very well friend. I suscribe
Thank you very much!
Nice! Did you come up with the flowfield algorithm yourself or is it from somewhere else? Would love to learn about how it works 😁
Thanks for the comment! As far as I know flow fields have been a concept in computer graphics since basically the beginning! The idea behind it is to, in some way, visualise a "noise" field, and flow fields do that by creating particles that get moved based on the noise value at their position.
In computer graphics noise refers to some sort of random value, the most basic kind which might have heard of is just "white" noise which is like TV static, but there are countless algorithms that have been developed to produce different kinds of noise. In this video I use a type of noise called "Perlin" noise (developed by Ken Perlin), and it's a "smooth" type of noise, where nearby positions have similar, but still random, values.
I'd highly recommend looking at some different noise algorithms if this sort of thing interests you, since they are what make the flow fields work. Some other types of noise are: value noise, simplex noise, voronoi noise.
Hope that helps, and don't hesitate to ask any follow up questions!
Hi sir, How did you update to run? Do you have use the initial?
Hi! P5js will automatically call the "draw" function for you so it acts as the update loop. The "setup" function will only get called once when the program is first run.
Hope that helps!
Hey there, thank you for this video! How could we make the particles different colors?
No worries! There are a few ways you could go about it!
The simplest would be to change the colour in the for loop where we draw the particles on the screen. You could change their colour based on their x or y location, or by the value of the noise at that location, or something else entirely! But this would mean that a particle would be continually changing colour, which leads to option two:
You could make the particles into a class and hold the colour as a member variable which we set in the constructor, which ties a colour to a particle. You can see an example of how this might look in my picture particles video!
Let me know if you have any questions :)
how do you make it random?
The noise() function in P5js is based on Perlin noise, and what it does is gives us values that are locally similar (noise(0) and noise(0.0001) will be pretty close to each other) but still random. This is what I use to calculate the direction a particle is heading in and how it's made to be random!
hey there, thanks a lot for this! Do you know how I could recreate the same sketch on Processing? I am having problems with this line: p.push(createVector(random(width), random(height))) because I believe Processing handles vector differently from p5.js. Any idea how I could rewrite that?
In any case, thank you for this tutorial and for this lovely sketch :)
Glad you enjoyed the video!
It will slightly depend on whether you're using a normal array (PVector[] particles) or an ArrayList (ArrayList particles)
If you're using a normal array you'd have to go something like:
particles[i] = new PVector(random(width), random(height));
And for an ArrayList:
particles.add(new PVector(random(width), random(height));
Hope that helps!
Is this even possible ? Feels like Processing needs more lines of code to do that, or a totally different approach, like creating a grid first and then create a vector in every cell. Did you succeed ? I am not succeeding.
I think it should be possible! I might give it a go when I get some time, I'll let you know how it goes!
@@BarneyCodes Hi Barney, thanks very much. Apparently one way is create grid and add a vector in each cell... But feels so complicated compared to your code !! It's so clever !!! Thanks for this video. So smoorh !!
Thanks! I'm glad you like my method!
I've adapted the code to work in Processing if you want to have a look! The code is here:
pastebin.com/RXH8ftaQ
Im getting x undefined error
That sounds like you're missing a "let x = ..." somewhere in your code, or you've defined x in a different scope from where it's being used. If you give a bit more detail hopefully I can help you out!
is this p5 js? lovely vid btw
Yea this is in p5js! Thanks for the comment!
great pedagogue! ^^
Thanks!
Nice work 👏
Thank you!
impressive
Thanks!
Great thanks
Glad you liked it!
hi, try to avoid single letter variable names
Hey, thanks for the feedback! I do think that single letter variables have a place (for loops, using "x" and "y" for positions, etc), but for the most part you're right. Naming variables is still one of the hardest aspects of coding!
Idk, I love my single letter variables for small scope projects. It makes it way easier to type at higher speeds and prevents typos
nice video. need more creative coding video. Could u try coding art like shvembldr ?
Thanks, I'm glad you enjoyed the video. I haven't made much like the art Shvembldr is making but I might be able to give it a go in the future!
guys just try changing the
const noiseScale = 0.001/2;
background(0,20);
let a = TAU/2 * n;
you get your meteor shower xd