Placeholder Image

Subtitles section Play video

  • (horn toots)

  • - Hello, welcome to a coding challenge

  • entitled 4D Open Simplex Noise Loop.

  • That's got to be a click bait title

  • if I ever heard one, right?

  • (laughs)

  • Anyway, let me thank somebody.

  • The artist Etienne Jacob, who I've referred to

  • in like the last 307 coding challenge videos that I've made,

  • because I keep doing this topic over and over again,

  • has been really an inspiration for these videos.

  • Makes these amazing noise loop GIFs,

  • and I've talked a little bit about some techniques

  • for doing that using classic Perlin noise,

  • the noise function in processing,

  • which you can also refer to as fractal noise.

  • Recently, through feedback and research,

  • been turned on to this idea of Simplex Noise

  • and Open Simplex Noise and I made an entire video

  • all about that and the differences and a little bit

  • about the history there.

  • I'll refer you to that video if you want to find out more.

  • In this particular video, all I'm going to do

  • is I now have the processing 3D noise example,

  • which you'll see nothing is three-dimensional here.

  • There's really a two-dimensional space

  • of noise and the third dimension

  • is what's creating the animation frame.

  • You can think of that third dimension almost as time.

  • I'm seeing frame by frame by frame.

  • What I want to do with this is take this and make it loop.

  • I want to have this noisy scene,

  • and this is using Open Simplex Noise,

  • which has a different quality and character to it.

  • It has less what are known as directional artifacts

  • that I referred to in the previous video

  • as like this herky jerky feeling of what the noise algorithm

  • can sometimes do if you also stop and turn around.

  • The smoothness of this is quite pleasant

  • and has a visual quality that's,

  • for a lot of scenarios, better.

  • There's more to say about that,

  • you can go watch the other video.

  • What I want to do is make this run just over a few seconds

  • and then render it as a GIFs that loops seamlessly.

  • I took a quick break there just

  • to render out that processing sketch.

  • I rendered out a few seconds, and as you'll see,

  • I rendered it to a GIF and every few seconds,

  • you see this jarring thing happen

  • where it goes back to the beginning.

  • The last frame of this noisy scene

  • doesn't match the first frame.

  • This is something that I talked about

  • in previous coding challenge videos,

  • how to get a sequence of values,

  • a one-dimensional array of random values

  • where the last value matches up with the first.

  • You close that loop.

  • The way that I did that was, I want one dimension of values,

  • let me walk around a circle,

  • a circular path in a 2D noise space.

  • Now what we're doing is

  • I want two-dimensional looping values,

  • so I need to basically walk around to space of a torus.

  • I need all of these values to move around and come on back.

  • First, what I want to do is...

  • Let me just be clear, this is

  • the processing noise 3D example and the only changed

  • is I've added this OpenSimplex Noise code from Kurt Spencer.

  • I will link to where that code and some background

  • about this open source implementation where it comes from

  • in the video's description.

  • Instead of calling Processing's noise function,

  • I'm calling noise.eval from Kurt Spencer's OpenSimplex Noise

  • and that gives me a double,

  • so I have to convert that into a float.

  • It also gives me a range of values between -1 and 1,

  • which is different than the values between 0 and 1.

  • What I would like to do is make this

  • a bit more visually obvious what's going on,

  • so I'm going to change this.

  • I'm going to threshold this

  • to render the color either black or white.

  • One way I can do that

  • is with a nice little ternary expression.

  • I can say brightness equals,

  • like is noise greater than zero?

  • If the noise value that comes out is greater than zero,

  • then I want to see 255,

  • otherwise I want to see 0.

  • If I do that, you'll see we get this.

  • I can play with the increment values,

  • like maybe let me make the increment a little less

  • but make it go through the zSpace faster, I don't know.

  • So, now we can see.

  • So this, this would be...

  • I should've rendered this to a GIF,

  • so you could see it not looping,

  • but this is what I want to have loop.

  • Also, look at the beauty of this particular noise algorithm.

  • It's very smooth, it doesn't feel like it's...

  • It doesn't have that directional art effect.

  • It doesn't feel like it's slowing down to a stop

  • and then going backwards, it just keeps going

  • with this kind of beautiful organic randomness.

  • Now that I have this, let's turn this into a GIF loop.

  • All of these videos are now kind of, this series,

  • everything's depending on each other.

  • I did have a previous coding challenge

  • where I made processing code that just renders out

  • the frames for a GIF loop and at the demonstration

  • is just a rotating square.

  • What I want to do is, I'm going to use that as my basis.

  • Let me grab all the code before set up from here,

  • which is all of this.

  • I'm going to put that into my GIF loop code.

  • Then, I wanted to make the new OpenSimplexNoise object,

  • and I'm going to put that in here.

  • Now, it's complaining to me, it doesn't know

  • what OpenSimplexNoise is, so I do need to make a new tab.

  • I'm going to call it OpenSimplexNoise.java.

  • And... whoops.

  • It needs to be .java because this particular

  • OpenSimplexNoise class is using some features

  • of the Java programming language

  • that don't work super elegantly in processing.

  • I can then just go copy and paste it over.

  • Certainly, there's more streamlined ways

  • of importing a Java class,

  • but just copying it over is one way.

  • Then I'm going to come back to here

  • and what I'm going to do is everything that's in draw()

  • is what should go into

  • this render function.

  • This render function should now

  • have all of the drawing code.

  • Here, now we have this running.

  • It's not looping yet, I've got to figure that out.

  • I also want to give myself more frames probably and...

  • Actually let's make it short,

  • 'cause I really want to make sure it's looping.

  • Let's make it 640 by 360,

  • it's kind of nice to have that aspect ratio.

  • Now, this is what I want to render as a perfect loop.

  • So, what's going on?

  • Here's the thing, the thing that needs to loop

  • is the z-axis, the z-axis instead of moving forward in time

  • should move around in a circular path

  • to create that donut in three-dimensional space.

  • How do I do that exactly?

  • It turns out that the way I can do that

  • is let me actually get rid of this idea of z offset

  • and I want to have...

  • Let's see if I can diagram this.

  • Alright, this is my two-dimensional plane of noise

  • in three-dimensional space and at any given point,

  • what I want to do is kind of walk around in a circle.

  • If this were the flat plane,

  • the circle would come out like this.

  • I don't know if this is really...

  • So, what I need is an angle.

  • I need to rotate around,

  • I need to use that polar coordinate formula,

  • to rotate around a circular path within

  • one plane of three-dimensional space.

  • To do that, I used four-dimensional noise,

  • because what I'm doing here is, I get...

  • Remember, in looping a GIF, I want a percentage

  • from 0 to 100%, so I can not now have an angle

  • which is equal to map that percent

  • which goes between 0 and 1, to between 0 and TWO_PI.

  • Then I can have, I'm going to call this u offset

  • for the third dimension and I'm going to call this

  • a v offset for the fourth dimension.

  • What those are is I'm going to say cosine of the angle

  • and sine of the angle, right?

  • I'm going to use the polar

  • to Cartesian coordinate transformation

  • and map these values,

  • which go between 0 and 1.

  • No, sorry, they go between -1 and 1, to between

  • some noise radius and noise diameter.

  • This is a concept I talked about

  • in the previous looping video,

  • but it's very hard to type and talk at the same time.

  • Sometimes I do a good job, sometimes I'm a mess,

  • and right now I'm a mess.

  • This is very hard to explain.

  • This is exactly the same technique that I did

  • in the first noise loop video,

  • where I just had an x and a y.

  • Now, I have an x and a y, but the looping

  • is happening in the u and the v.

  • That's where the size of this circle is important.

  • I'm not sure whether in the Open Simplex Noise algorithm

  • whether I can have negative values or not,

  • but to be safe, I'm just going to map these between 0 and 2.

  • I'm picking sort of an arbitrary, this I think we called

  • noise diameter or something like that,

  • I'm picking an arbitrary value.

  • Now, down here, change this to u offset, v offset,

  • and let's run this.

  • Did I get everything right?

  • No, no.

  • Oh, I have an extra 0 in here,

  • because I'm going crazy.

  • z offset is not a thing anymore,

  • and here we go.

  • (bell dings)

  • Okay, so one this to note here,

  • (laughs)

  • is that 4D,

  • the implementation for getting 4D noise is quite slow.

  • You can see this frame rate sort of chugging along.

  • The good news is we're here to render out to a loop,

  • so I don't care about the speed, the frame rate,

  • I am just going to turn record to true

  • and I'm going to run this again

  • and I will see you when it finishes rendering.

  • (playful synth music)

  • All right, it finished rendering.

  • The good news, just to reiterate,

  • because 3D noise worked quite smoothly,

  • if you're not rendering out to a loop,

  • you don't need that fourth dimension!

  • You can just use the third dimension

  • and watch your real-time software

  • in your media art installation work beautifully.

  • But, if you're rendering it out, I want to close that loop,

  • I do need that fourth dimension.

  • Okay, I'm going to switch over to my terminal window

  • and I'm in the GIF_loop_4D sketches folder

  • and now I'm going to use ffmpeg

  • to render all those frames into a GIF.

  • So, I'm going to say ffmpeg -for image2,

  • and ffmpeg is a utility

  • you would have to install separately.

  • I'll include a link to how to do that

  • in this video's description.

  • - f image2 -framerate, let's give it 30 frames per second,

  • - i, the file path, which is output/gif...

  • Each file is gif dash and then a number,

  • so %3d.png and then I'll call it noiseloop.gif

  • and I'm going to render that out.

  • I am going to take a look at it, here it is.

  • Let's take a look.

  • By golly, if that doesn't loop, I don't know what loops.

  • This is about four seconds long.

  • Of course, you can see.

  • (laughs)

  • You might be able to detect the loop because it's so short,

  • but if I made I a little longer and if there was a bit more,

  • if I was more artistic and had more creative ideas

  • about how to vary the visual quality,

  • we might be able to create something more like

  • what I showed you in those original Etienne Jacob GIFs.

  • Hi, so this might be the strangest,

  • most nontraditional ending of a coding training video ever,

  • 'cause you probably were just watching me

  • in the studio coding, but I was going to record

  • a new ending to it today in the studio, but it's a snow day.

  • Just buried in snow here, can barely walk.

  • (laughs)

  • Anyway, what you have just seen is a coding challenge

  • where I added Open Simplex Noise.

  • Really, I think what you should take away from this

  • is the quality of Open Simplex Noise

  • rather than classic Perlin noise and think about

  • the kinds of projects you might make that run in real time

  • that don't actually need to loop.

  • But, if you're making a looping GIF,

  • this is sort of an interesting technique.

  • I'm going to show you right now this terrain.

  • This is basically my coding challenge before

  • but with Open Simplex Noise instead of classic Perlin noise.

  • That's a challenge to you.

  • If you can make this looping terrain happen,

  • then try that.

  • I'm going to do that in a video, I'll come back this Wednesday

  • during my regular livestream and I will create this terrain

  • with Open Simplex Noise as a follow up video.

  • I hope you enjoyed this short coding challenge

  • with Open Simplex Noise and looping in four dimensions

  • and all sorts of wackiness like that,

  • and I'll see you next time on the coding train, choo choo!

  • (upbeat pop music)

(horn toots)

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it