Mtg 23/26: Tue-01-Apr-2025

Outline for Today

Textures

Administration

Today

For Next Meeting

Wiki

Link to the UR Courses wiki page for this meeting

Media

Transcript

Audio Transcript

  • So we have meeting 23 today, of 26
  • April 1. Doesn't feel like it. I
  • Okay, so we're going to talk about textures a bit more detail
  • today. So you
  • so maybe we'll Watch more videos too.
  • Okay, I
  • It's actually interesting. I'm creating a tackle box for 458,
  • class. So I ended up using three different textures. I created
  • one that was just the standard shader for Maya. One was the one
  • of their presets for metal, and then the third one was a preset
  • metal one with PBR, and the difference between them is
  • astronomical, like just the difference between the three
  • different ones having the three different textures on this one
  • identical object under the same lighting. It's crazy how
  • different it is and how more realistic the PBR stuff is
  • versus the other stuff.
  • So are you combining the three textures? I'm not going to
  • combine. I can't combine
  • them, but I applied the same the three different textures
  • identical color to all through to three different texture
  • objects, and then attach the texture object to the object
  • itself, and just the difference in coloring and the look of them
  • is just crazy. Oh,
  • so standard models like fun shading, even though it gives
  • some realistic looking effects, it's not physically based, so It
  • doesn't it's limited in What it can produce. I
  • Okay, I guess I just have to switch this. I
  • so let's look at our quiz before reading 23
  • can the texture sound made change from pixel
  • to pixel, yes, I
  • only heard three yess, yes.
  • Thank you. Thank
  • so can we talk a little bit of why it is? I
  • because we might have the same texture, but it's projected on,
  • projected differently onto scene geometry, for example. Does that
  • make sense?
  • Well, I mean, it may be the same texture, but in this pixel, it
  • could be getting more light, and then in another pixel it gets a
  • different light. So it's not necessarily going to look
  • exactly the same way in each pixel anyway. So we need to make
  • sure that our sampling rate accounts for that difference.
  • Yeah, but the sampling rate isn't about the lighting, okay.
  • So what if our sampling rate is let
  • me
  • ask another different question, similar question, but it's
  • definitely different.
  • So what Is the Nyquist limit.
  • Yeah, so that's a phrase. It's often in the textbook, I think,
  • to talk about the limit of the Nyquist limit. What are some
  • other ways you've used Nyquist name in vain, not taken His name
  • In vain. But I
  • talking about the micro strait. I
  • That's twice the rate of this smallest thing is that? Right?
  • We dissemble twice the highest frequency We want to
  • reconstruct. So I
  • So a good example is CD Quality, audio. Everyone knows what a CD
  • is.
  • So we set up a 44.1 kilohertz, so we can reconstruct 22
  • kiloHertz, which is The range of most what most people can hear.
  • So so then in recording, we don't want to record frequencies
  • that are higher than that, because we won't be able to
  • reconstruct them. Going to filter out the higher
  • frequencies higher than that?
  • Does that make sense?
  • So if we're not able to set so in images, we we can't often get
  • the functions we're sampling aren't band limited, so there's
  • no equivalent to the 44.1 kilohertz, which is the limit we
  • can set and we could be happy with being able to reconstruct,
  • then 22 kiloHertz suffragette CS up to 22 kilohertz.
  • So for sampling, at a rate. So how can we think of the Nyquist
  • rate As a limit? If that question makes sense, I
  • so if we were sampling a certain rate, then We can only
  • reconstruct the rate divided by Two and
  • so Rate is limit so
  • I'm sorry, some days I just seem to be intent on writing more,
  • more smallly than others. So I'm maybe a secretly trying to get
  • you to sit in the front row, but I'll take when I take pictures
  • of the board, then they'll be legible.
  • So we're we're limiting the frequency.
  • So we're limited by the Nyquist limit, because we don't want
  • aliasing in our images, so we we have that as an upper bound on
  • the frequency that we can include so that affects how we
  • sample the textures. Does that make sense? I
  • it. This is clear when I wrote it, but I tried to give you some
  • pointers to what I was looking for. I
  • so there are a few different ways to do a 2d mapping of the
  • texture. In fact, there are four different ways listed. Anyone
  • like to offer one? Yeah, planner,
  • selectical. Do and
  • the last way can't remember. I there's two letters of the
  • alphabet,
  • because sometimes we just have a natural parameterization of the
  • surface, so we can map the UV parameterized coordinates into
  • the texture coordinates
  • blue depending on your object, you might need to have your
  • texture map into all of those different
  • ways. What's an example of that?
  • Well, you could you do planar combined with UV for, like, if
  • you have, like, a table with side pieces. So we would be in
  • the UV spectrum on some sides, but you'd be on planar on
  • other parts. Yeah, so you talked about in the book, they talked
  • about different ways depending on the normal so one, if it was
  • pointing up, you would get an image, one image, and if it's
  • pointing to the side, you'd get a do. Different image. So that
  • would be like the front cover of the magazine and the spine,
  • or even the back back. You can have a different one too. Yes,
  • yeah. So there are different variations like that.
  • Well, I mean, using a magazine, example, if you roll up a
  • magazine, it's going to have a different, different texture
  • mapping than if it's laid out flat.
  • Yes, it's not cylindrical and flat at the same time,
  • though, no, but you would need to account for that Depending on
  • what you're doing.
  • Okay, would You See The
  • so here's spherical mapping makes sense. So just in this
  • case, we just have the texture in B we just have the texture on
  • the surface of the sphere, we can define the texture that's
  • three dimensions. And so we could, in that way, we could cut
  • into the sphere and see the texture on the inside as well.
  • And
  • anyone familiar with these coffee pots?
  • They say a kettle. I don't know. I
  • think that would be like a percolator.
  • Yeah, put water in the bottom, and then you have coffee grounds
  • in the middle, and then as the water boils, it's forced through
  • the coffee grounds into the kettle on top. You to make
  • espresso. I remember once I had a big, very big one, not not
  • huge, but it's maybe this big that would get me going in the
  • morning. But my wife and kids didn't like the smell in the
  • kitchen, so I gave it up
  • anyway. So that's a cylindrical mapping. I It's not quite
  • cylindrical, but it's an approximation of a cylinder. And
  • then we can map on to that scratch texture supplied using
  • the cylindrical texture mapping and
  • any other questions or comments about that,
  • although we're looking For like the function side of the
  • progress, I'm
  • just I'm sorry. I was just confused on the way that you'd
  • asked the questions. What?
  • Oh, well, not
  • pretty much. But now understand what you meant. Okay.
  • I last question was,
  • image, texture store, Q, D, arrays of point, sound, values
  • of a texture function, which are used to reconstruct a continuous
  • image that can be evaluated at arbitrary position. What are
  • these samples called texels? Everyone agree?
  • Yes, I
  • so called texels. So why does that sound familiar? It's
  • the texture version of pixels i
  • So pixels Are picture elements and
  • texture textiles or texture elements and
  • What if we had volume elements, pixels, foxes,
  • Fox. I probably
  • Fox, yeah, it's the term is voxel. So it's just, I
  • so we look at participating media or I or contents of
  • chapter 11, then we're In the realm of voxels that we're
  • dealing with for
  • so I've had a cold the past few days, but I seem to be maybe on
  • the road to recovery, because I, my daughter claims that I gave
  • it to her, so she said, this morning, you mean you got me
  • sick? And I thought, Well,
  • I'm sorry about that, but if that means that I'm going to get
  • better, that's
  • when you reply to them and say, Well, my mother always taught me
  • to share. Yes,
  • I anyway,
  • any questions about that?
  • So I picked this procedural noise video because it was from
  • the same series that we looked at the micro facet videos from a
  • little while ago.
  • But this one doesn't have as much doesn't have any theory in
  • front of it, but I thought it might be interesting to watch.
  • And then the Perlin noise video is from somebody who I the
  • author of the book called The nature of code, which I enjoyed
  • reading. But I'm not sure about his presentation, but he seems a
  • little bit off the wall, so maybe that would be interesting
  • to watch. Let's watch as well. These aren't paper fools jokes.
  • Anyway, we'll see. Does
  • that seem like a good plan?
  • Watch this before drinking plant based milks, oat milk, latte
  • protein, you know, it's excellent. Oh,
  • called pause, back to pause the first step.
  • Hello everybody. Welcome to shaders. Mansfield Today we talk
  • about procedural noise. In particular, we will learn how to
  • generate value noise that you see on the left and color
  • gradient noise that is shown on the right. Furthermore, we will
  • see that we can add multiple layers of noise with different
  • frequencies and amplitudes to generate noise with more
  • details. This approach is often called Fractal Noise. On the
  • left you see fractal value noise, and on the right, fractal
  • gradient noise to implement the procedural noise functions in
  • GLSL. I use the GS and composer at GSN minus lip.org as a shader
  • editor, but you can use any other shader editor as well, we
  • are writing pure open GLSL code, which you can use everywhere.
  • Links to examples that execute the same shader code using CS or
  • Java can be found in the video description. Our implementation
  • starts with our example from episode number five, in which we
  • have applied a two detection to a triangle, click project and
  • type in the project name, shaders, monthly, 05, and click
  • open existing, then open the graph texture triangle and press
  • play in the time control panel, let's replace the triangle with
  • The chord. Click Create and navigate to 3d compute, generate
  • play. Then we connect the mesh data node to the mesh input slot
  • of the shader node. Perfect. We are rendering a quad set exactly
  • fits the size of the frame buffer. The currently applied
  • texture is this image here? Let's have a look at the shader
  • code. We select the shader node and click the Edit Code button.
  • This dialog is a shader editor of the GSM composer. In the top
  • section we can define the vertex shader and in the bottom section
  • the fragment shader. Here we have the uniform variable
  • sampler, 2d my texture that represents the pixel based input
  • texture in the fragment shader, we use texture function to get a
  • color value from the texture. The first parameter is the
  • sample to D variable, and the second parameter is the current
  • texture coordinate. The next line writes a texture color to
  • the frame of a pixel uniform sample to D, my texture can be
  • removed. We replace texture, my texture, with the function
  • value, noise, and define the function VEC for value noise,
  • the texture coordinates are passed via a VEC two that we
  • call POS. VEC two, POS, we first simply return the texture
  • coordinates in the red and green channels. We turn back four post
  • dot x, post dot y, 0.0, 1.0 we see at the shader output that
  • the texture coordinates are in the interval from zero to one in
  • both dimensions, a texture coordinate of 00, is at the
  • bottom left corner, one, zero at the bottom right corner, 01, at
  • the top left corner, and one, one at the top right corner.
  • First of all, we need a function that generates some pseudo
  • random numbers. It is called pseudo random because the
  • numbers appear to be generated statistically by a real random
  • process, but in fact, are generated by a deterministic
  • function. Because it is a deterministic function, it
  • produces the same numbers for the same input parameters. To
  • select a good pseudo random number generator, I would like
  • to refer to a paper called hash functions for GPU random by Mark
  • jacinski and Mark boleno, published in the Journal of
  • Computer Graphics techniques in 2020 the authors compare
  • different random number generators for quality and
  • speed. I paste the code of a random number generator that
  • they recommend into our shader, we see that this function is
  • expecting a U VEC three as input, which is a vector of
  • three unsigned integers. The output is a VEC three, a vector
  • of three floating point values. This means that we get three
  • random numbers from one function call these output numbers have a
  • uniform distribution in the interval from zero to one. Our
  • first goal is to output a random color for each pixel of the
  • output frame buffer. As we have learned in previous episodes of
  • shaders monthly, the fragment shader is called for every pixel
  • of the output frame buffer. To convert the texture coordinates
  • to pixels, we add the function t to p. Now the current pixel in x
  • direction can be computed by float p x equals t to P plus dot
  • x comma with and the current pixel in y direction by a float
  • p y equals t 2p plus dot y, comma height. Furthermore, we
  • need to define uniform int width and uniform int height to get
  • the width and height of the frame buffer. Now we can use p x
  • and p y as seeds for the random number generator VEC three
  • random equals random, underscore, PC, G, 3d, u, v, x,
  • v, p, x, p, y, zero. Return VEC for random 1.0 we return random
  • as the R, G, B value and 1.0 SC, alpha value. Okay, this looks
  • good. For every pixel, we get a different random color as
  • output. Now, when we change the seat here, for example, when we
  • put one instead of zero, we get different random values, two,
  • three, every time we get different values, let's animate
  • this value. We add a uniform variable, uniform int, graph,
  • time, apply code and close the input. Texture can be deleted.
  • We create the node input, compute time, and it's a time
  • Control dialog, which we can reach via this button, we set
  • the end parameter to a larger number, for example, 20,000
  • Furthermore, we increase the rendering speed and set the
  • parameter milliseconds per tick to 20 milliseconds. Next, we
  • connect the data output of the time node to the input slot
  • graph time of our shader. We open the shader Editor again and
  • put graph time as the third seed of the random number generator.
  • Perfect. Now we get new random values for every rendered frame
  • buffer image for many applications, this noise output
  • is too chaotic. There is no correlation between neighboring
  • values. These are just random numbers from a uniform random
  • number generator. To change this, we are now implementing
  • value noise. The idea is that we're not generating a random
  • value for each pixel. Instead, we generate a random value for
  • points on a coarser grid. To this end, we subdivide the
  • complete domain of texture coordinates into an eight by
  • eight grid. We compute a grid position, cons, float. Grid size
  • equals 8.0 vector grid POS equals POS times grid size if
  • POS is in the interval from zero to one, grid POS is in the
  • interval from zero to eight. To get the integer part of grid
  • POS, we cast to a U VEC two, which is a vector of two
  • unsigned integers, u VEC two, I equals u VEC two. Grid POS. With
  • this operation, we round downwards to the nearest
  • integer, which gives us the digits before the decimal point.
  • We also need the fractional part of the grid position VEC to f
  • equals frag grid pause, which gives us the digits after the
  • decimal point. Consequently, the values of f are again in the
  • interval from zero to one, let's output F, return back 4f, dot x,
  • f, dot y, 0.0, 1.0, as you see here, we get an eight by eight
  • grid, and inside each cell, the variable f goes from zero to one
  • in both dimensions. This is a grid size of 16 by 16, four by
  • four, and back to a grid size of eight by eight.
  • Now if we use the integer value of each grid cell as seeds for
  • the random function, we get the same random value per grid cell,
  • although each grid cell consists of many output pixels, UX,
  • three, I dot x, I dot y, zero apply. Okay. Let's use the graph
  • time variable to translate the grid cells over time. Vector,
  • pos equals interpolated text coordinate plus 0.002, times
  • load graph, time value, noise, POS, well, this looks nice. It
  • is a never ending stream of random colors that only repeat
  • when graph time repeats. The value of graph time repeats when
  • it reaches the end of our animation, time which we have
  • set to 20,000 let's stop the animation. To generate value
  • nodes, we need a smooth interpolation between the grid
  • colors. One interpolation technique that we already have
  • learned in episode number six is the bilinear interpolation.
  • The bilinear interpolation is computed from four neighboring
  • values, which are the random colors in our example, the dash
  • lines represent the core script of our random variables to
  • compute the interpolated value at the location of the blue
  • point, we first interpolate in x direction using the x position
  • of the blue point within its neighbors. This is done two
  • times for the two neighbors at the bottom residing in a linear
  • interpolated value at this new point and for the two neighbors
  • at the top, which gives us a result for this new point. Once
  • this is done, we perform linear interpolation in the y direction
  • using the y position of the blue point within the two new points,
  • the same setup is now illustrated in the ly figure.
  • The grid is the ground plane, and the color values are
  • represented as these red bars that point upwards. The length
  • of the red bars corresponds to the stored random values. Now we
  • first compute the value at location q1 by linear
  • interpolation. And here's the equation to perform this
  • operation. You see that we use the values at x1 y1 and x2 y1 to
  • perform this operation. Next, we compute the value at location q2
  • by linear interpolation. The value at x1 y2 x2 y2 are used.
  • And finally, the linear interpolation in the y
  • direction, where the values at q1 and q2 are used. To implement
  • this linear interpolation in our shader, we need the four
  • neighboring random values, f1, one, i, x, I y, vec, one, two, I
  • x plus one, I y, f2 one, I x, I y plus one, f2 two, I x plus
  • one, I y plus one. To perform the linear interpolation. GLSL
  • has a built in mix function. The first two parameters are the
  • values that are interpolated, and the third argument is the
  • interpolation weight. To compute q1 we interpolate f1 one and f1
  • two in x direction, VEC 3q, one equals mix f1, one, f1, two. VEC
  • 3f dot x, return. VEC for q1, 1.0, apply code, send for q2 VEC
  • 3q two makes f2 one, f2, two. VEC 3f dot x, and then
  • interpolate in y direction, VEC 3p equals mix q1, q2, VEC 3f,
  • dot y, we turn back 4p, 1.0 good. This is the correct
  • interpolation result, but it looks a bit blocky. We can fix
  • this by using the built in GLSL smooth step function. The smooth
  • step function is shown on the slide. It implements a non
  • linear smooth transition from zero to one. The first parameter
  • defines where the transition starts and the second parameter
  • where it ends. We needed to map the complete fractional part so
  • we have f equals smooth, step 0.0, 1.0 F, excellent. This
  • looks better. Let's turn on the animation.
  • We refactor the code, VEC three, value, noise, VEC two, POS,
  • flow, grid size, return P, and we define a new function, VEC
  • three, fractal. Value, noise, VEC two, POS, VEC 3n, equals VEC
  • three, 0.0 n plus equal value, noise, pause, 8.0 return n and
  • call it in the main function. VEC three, text, color equals
  • fractal value, noise, POS, how color equals back for text,
  • color 1.0 ok. This should not change. Anything apply. We
  • compute, no change. The idea of fractal noise is that we sum up
  • noise with different frequencies, which means here
  • different values for the grid size parameter. A common
  • approach is to double the frequency and take half the
  • amplitude for every layer. So let's try n plus equal 0.5 times
  • value. Noise plus four apply. We add the next layer n plus equal
  • 0.25 times value, noise POS 8.0
  • and another layer n plus equal 0.125 times value, noise POS
  • 16.0 the layers are also called octaves, same as in music, the
  • frequency doubles for every octave. But you don't have to
  • follow this rule, and can freely play around with these values to
  • produce the noise characteristics that you need
  • for your application. Obviously, the computation effort increases
  • with every layer that we add. Here,
  • let's output the pure value. Noise again, we comment this
  • line and type Vex, V, text, color equals value. Noise, POS,
  • 4.0 we
  • applied and closed. We named the shader value noise. Now the
  • second type of noise that we introduce today is gradient
  • noise. Gradient noise was introduced by Ken Perlin in a
  • SIGGRAPH paper in 1985 we copy the value noise shader and
  • reconnect the inputs. We call this shader gradient noise.
  • We open the shader editor for this new node. We rename the
  • functions to gradient noise and fractal gradient noise.
  • The idea of gradient noise is shown in this slide. Instead of
  • interpolating random values. We interpolate between gradients at
  • each grid point, we create a gradient vector in a random
  • direction of random length. The interpolation part stays exactly
  • the same. How can we compute the gradient vectors influence at
  • each position within the grid? Let's look at a single gradient.
  • For simplicity, this gradient vector that we have selected has
  • unit length, the value of the gradients influenced at each
  • position can be computed with a dot product. The red arrow
  • represents the random gradient vector, and the blue arrow is a
  • vector to the current interpolation point. If we take
  • the dot product of these two vectors, we get a value of zero.
  • If the two vectors are perpendicular, a negative value
  • from zero to minus one is a point in opposite directions,
  • and a positive value from zero to one is a point in the same
  • direction. Overall, within this unit circle, we get a linear
  • gradient from minus one to one. There are different options for
  • the generation of the gradient vectors. The approach that I
  • present here creates a random vector by randomly picking a
  • point within the unit circle, given an angle phi and a radius
  • r, the X and Y position of a point within the unit circle can
  • be computed by x equals r times cosine phi, and y equals r times
  • sine phi. We start from two uniformly distributed values, u
  • and v in the interval zero to one. Let's first try to assign u
  • to the radius and phi equals two pi times v, we then don't get a
  • uniform distribution over the area of the circle. The sampling
  • points are concentrated at the center. What we want is a
  • constant sample density over the complete area, but the area of
  • the circle increases quadratically with the radius.
  • You can concentrate for this by assigning the square root of u
  • to the radius. This gives us a uniform sampling. Let's do that
  • again. Oh. Now that we have discussed the theory, the
  • implementation is not complicated. We copied this code
  • block and comment out these lines. We changed the last
  • parameter from zero to one because we want different random
  • values for our gradient vectors. We replace random PCG 3d with a
  • new function that we call random gradient. The output of this
  • function is a VEC two, and we call the variables, VEC 2g one,
  • one, VEC 2g one, two, VEC 2g two, one, VEC 2g two, two, next.
  • We define the random gradient function. Define M, pi, 3.14,
  • and so on. VEC two, random gradient, U, VEC 3p, VEC three,
  • UV equals random PCG, three, DP, float r equals square root. UV,
  • zero. Float five equals two times m, pi times u, v1 return
  • back to r times cosine phi, r times sine phi. Next, we compute
  • the influence of the gradient at the current interpolation value
  • F with the dot product, as discussed in the slides. Float
  • d1, one equals dot g1, 1f float d1, two equals dot g1, 2f, for
  • d1, two, we should not use F directly, but use the offset
  • relative to the next grid position to the right, which is
  • minus back to 1.0 0.0, then for the grid position above, float
  • d2 one equals dot g2 1f minus VEC two 0.0, 1.0 and lastly,
  • float d2 two equals dot g2 2f, minus VEC two, 1.0 1.0 use the
  • same interpolation code As before, we have to cast the
  • float values to a VEC three. VEC 3f one, one equals back 3d. One,
  • one. VEC 3f one, two equals back, 3d. One, two. VEC 3f two,
  • one equals VEC 3d two, one. VEC 3f two, two equals back, 3d.
  • Two, two. Apply. Code, Okay, this looks good, but we might
  • get negative values, which we can prevent by adding 0.25
  • gradient noise done, but the output is not very colorful. To
  • add colors, we can combine value in gradient noise. We comment
  • out these lines and uncomment the code that we have used for
  • the value noise. There are different ways to combine both
  • approaches. Let's simply multiply our random values and
  • the gradient before the interpolation. Remove plus 0.5
  • here and add times d1 one plus one, times d1 two plus one times
  • d2 one plus one times d2 two plus one apply excellent if you
  • compare both approaches. The gradient noise looks more
  • natural and less regular for the value noise, the underlying grid
  • structure is more obvious. Let's enable the Fractal Noise variant
  • for the gradient noise looks
  • also good. Today we have learned how to generate value in
  • gradient noise. This is an important building block for
  • future episodes of shaders monthly. We are going to use
  • procedural noise functions to create things like water, waves,
  • clouds, fire and so on. If you have questions, use the comments
  • or get in contact with me. See you at the next Episode of
  • shaders monthly. You
  • so procedural textures number seven seems like it would be
  • maybe interesting as well.
  • Oh, add a link to it. Let's stick with Perlin noise and the
  • many hours that
  • I had i i mentioned before i
  • Okay, here we are again. We are at a very exciting moment. We
  • are so close, so close to finishing with this introductory
  • section, where I feel like I'm not really in control, and maybe
  • I'm screwing this all up. But soon we're going to be getting
  • to vectors. The vectors are the place where I think we'll feel
  • comfortable, and we'll sort of be on a directed path, knowing
  • where we're going to create these Ridge motion simulations
  • and processing. But before we do that, there's an important topic
  • that I think is actually probably the most important of
  • all of these kind of beginning, introductory topics about random
  • numbers, and that is Perlin noise. Perlin noise is going to
  • allow us to create a randomness in our code that is smooth, that
  • has a more organic feel to it, that's going to allow us to do a
  • lot of lot of create a lot of things across, things like that,
  • that feel a bit more natural, or that's really interesting to
  • say, trying to come up with the right words, I should stop and
  • restart, but I'm going to keep going. Okay, so Perlin noise?
  • What is Perlin noise? First of all, Perlin noise is named for
  • Ken Perlin, who, if we just broke through this wall and kept
  • going and broke through another wall and went into the next
  • building, we would find Ken Colin is a professor here at NYU
  • in the computer science department, and he developed
  • Perlin noise, I believe, while working on the film Tron,
  • somebody correct me and write nasty letters. I'm getting this
  • all wrong in the agency. In fact, he won a an Academy Award
  • for his work computer graphics. And so prolinois was originally
  • developed to create procedural textures for 3d models in
  • computer graphics, meaning, okay, if we want to have a vase
  • that has a marble like texture to it, would you have a vase
  • with a marble like texture? I'm not sure. Do we need to hand
  • create that with with handmade techniques, or can we create an
  • algorithm that will make that texture procedural? Now, how
  • does it do this? And what is what are we really talking about
  • here? Well, first, let's think about this moment of time for a
  • second. This moment, this idea of time. Let's think about time
  • and random numbers. Let's say this line represents time and
  • time is moving along. This is the beginning of time. This is
  • the end of time. We're somewhere in the middle there. I suppose
  • Time is moving along. And let's say we take a random number at
  • any moment in time. Okay, I'm not going to be able to do this,
  • because I'm a human being and I'm just destined for pattern.
  • But you could imagine it's going to have it's going to be
  • something like this. It's going to be this graph that makes no
  • sense at all, that just looks like a lot of squiggly
  • randomness all over the place. Any random number we pick at any
  • moment in time has no relationship to the previous
  • random number that we picked or the next random number we
  • picked. There's no smoothness here. So what does Perlin noise
  • look like? Well, if you think of Perlin noise over time might
  • look something more like this. Isn't that smooth, soothing and
  • relaxing and blowing a nice little graph there? I know, I
  • don't know if I how well I drew this, but this is randomness,
  • and that it's random. You can't predict it's gonna go up, it's
  • gonna go down, it's gonna go up lot, that a little bit, but yet,
  • there's a smoothness to it. There is this idea that occur a
  • random number over here is related to the previous and
  • related to the next one random numbers change slightly over
  • time. This is a very powerful concept. If we can pick random
  • numbers in this fashion, then we could have something organically
  • grow and shrink randomly, but in a nice kind of almost breathing
  • organic, like web. You see the word organic way too much, but
  • you can see what I really tried driving at. This has a more
  • natural quality than this. And per the noise is something that
  • you know, in a way I was saying earlier, that randomness is this
  • crutch. I'm gonna let them know. What's that? How to make all my
  • variables this, make them all randomness my crutch, my
  • personal crush is right, is I just make everything with Perlin
  • noise. It's random, but it'll be smooth, so people will like it.
  • So we need to be careful here. We want to use these different
  • algorithms in the appropriate time for whatever it is, what
  • behavior or what sort of expressive quality we're trying
  • to achieve in our animations, in our program. But this is another
  • tool in our bag of tricks that we can use. So the question is,
  • how do we use Perlin noise, and what do the results look like?
  • Well, again, let's take let's take a scenario this pen. By the
  • way, we need a new one at the moment. Let's take a scenario
  • where what we want here is our processing window, and what we
  • want is to be able to this way. I should also be talking about
  • this in the middle of the middle of the video, OK, what we want
  • is to put a circle on the screen. And every frame, we're
  • going to give it a random location. So we're going to say,
  • hey, float X equals random between zero and width, and we
  • are going to draw a circle at that at that location, and we're
  • gonna see what that looks like. Let's do that together,
  • actually. Let's press this button and come over here so I
  • should have pre populated this would set up a draw. That's
  • okay. I can type fast, so I'm a background, zero, fill 255, I'm
  • gonna draw a circle.
  • So anyone familiar with processing or p5 JS
  • processing, it's used in C tech tool
  • for Yeah, I just heard, if you were familiar with it,
  • circle, and it's going to be at an X location in the middle
  • screen. And it's going to be a nice size circle, and x is going
  • to be a random value between zero and width, and random
  • noise. Random noise thing. Okay, so let's run this and see what
  • we get. You can see here, if I just slide all this over, I'm
  • going to get used to doing this eventually. You can see here,
  • this is randomness every frame. It's at a new random location.
  • And in fact, we could maybe see this a bit more easily if I just
  • slow the frame rate down to something like 10 frames per
  • second and run it again, you can see there's no relationship. We
  • just have this dot moving anywhere because it's random in
  • every frame. So what do we want to do is we want to start
  • looking at code for doing this with Perlin noise. We want to
  • say float X equals noise something. So this is an
  • interesting question. Now, I'm really botching this. OK, this
  • is an interesting question now, because with random was very
  • clear, what the arguments to the random function are, minimum and
  • maximum range of randomness. What are the arguments to the
  • noise function? It would be nice if I could just say zero comma
  • width, and if you type that in there, it actually would accept
  • that and run, but it wouldn't work the way that you want it
  • to. The thing about noise is, no matter what this noise function
  • is going to give us a value between zero and one, Perlin
  • noise. The noise, Perlin noise function in processing will
  • always, no matter what you do, give you a value between zero
  • and one. You cannot affect the range of what comes out of that
  • function. We're going to be able to affect it quite easily in a
  • moment, using the map function in processing to map it to a
  • different range. But right now, we're only ever going to get a
  • zero between zero and one out of that function. So what goes in
  • there? Well, remember how we had this idea of time? Well, with
  • randomness, you know, there is sort of this idea of timing.
  • There's a pseudo random number generator that's giving us a
  • random set of random numbers in sequence. The timing really play
  • a part in our thinking about it. With Perlin noise, we've
  • actually created a deterministic sort of time, space, continuum,
  • which Star Trek, land that makes no sense. We need to give time
  • as this argument. Now, time, what is it for? I like to sort
  • of think of it as a time in terms of this graph, like, do we
  • want this random number at this moment in time? Or, do we want
  • this random number at this moment in time? What does that?
  • What does that mean? Well, what are we doing here? Well, in
  • fact, we just need to create a variable, and so let's kind of
  • get rid of this stuff over here. Let's call it T and we could
  • say, hey, let's ask for Perlin noise at time equals zero. So
  • let's go ahead and see what happens if we add this now to
  • our code. We know that we want, if this is the beginning of
  • time, we want Perlin noise value at time equals zero, and let's
  • see what that gives us. I'm here. I'm back. Ok. So we are
  • now going to switch this to say x equals noise. And we said, at
  • some moment in time, and we create a global variable called
  • T, and we're going to run this and where's our circle? Well,
  • first of all, our circle is at zero, right? Because Perlin
  • noise only ever gives us a value between zero and one. We can't
  • get any other value but a value between zero and one. So we want
  • to use this function processing called the map function. Boy, I
  • would love to just do a whole video just about the map
  • function. And you know what? I'm definitely going to do that. But
  • right now, I'm going to kind of assume that that exists and
  • you've watched it, and kind of just add the map function kind
  • of quickly. So what I want to do is remap the value of x and map
  • the value of x, which we know goes between zero and one. And
  • actually, yeah, that's fine between zero and one, and I want
  • to map that between zero and width. I'm going to run this
  • now. I lost my pen. Okay, so, ah, so look, the circle is still
  • over there, but we got, let's run it again. It's over there.
  • Now you can see we're going to get a random value. Ah, there it
  • is, right? Perlin noise space is seated the beginning of
  • Processing sketch. Noise value at time equals zero, but it's
  • not moving. It's never changing, because the noise value at time
  • equals zero never changes. It's the same, always in forever more
  • for that, for this instance of the sketch running. So what does
  • that mean we need to do? What we need to do is move through time.
  • We want in our sketches, say, give me the throwin noise value,
  • here, then here, then here, then here, then here, then here. We
  • want all those values in sequence, so we get a sequence
  • of these smooth values. And how far along we move through time?
  • Do we move to here, to here, to here? That's going to really be
  • awful. So when we just regular redness, or do we move very,
  • very tiny, okay, very slowly. We need to say, t equals t plus
  • something, some value to increment. Should we go 0.00001
  • or should we go 0.5 whatever? We could just try that and see what
  • happens. So let's take a look over here and see if we add
  • that. OK, so we want to say, let's move through time. Let's
  • try T equals T plus one. That makes sense, right? Well, that's
  • sort of more just like randomness, and I had that frame
  • rate. Let's take that, let's, let's let it run fast, 60 frames
  • per second. You can see that's pretty much just like
  • randomness, that T equals T plus one is moving really big steps
  • through time, and really big steps through time, we lose the
  • fact that this, there's this nice kind of curve going on
  • there. And so if I come back over here, let's do something
  • much more reasonable, and say, t equals t plus 0.05 and look at
  • this. I want it to appear. I need to, like, redo my way. We
  • can see, look, it's actually kind of moving almost more
  • smoothly. Now maybe that's too big, so it's also running very
  • quickly at 60 frames per second, which so you can see now we're
  • getting this nice, sort of smooth motion because we're
  • seeing this sequence of random numbers. It also looks like it's
  • moving with some type of rules, almost some type of physics to
  • it. We've just sort of accidentally created this
  • physics, this random walker, so to speak, with Perlin noise. And
  • so this would be kind of my exercise to you, if you want to
  • try, to try to take this and kind of like link it to
  • everything we doing. So far, there's so many places in all
  • the examples where you'll be able to add Perlin noise in, but
  • right now, it's in you go to that random walker and try to
  • make a Perlin noise random walker. And I'll include, at
  • some point, I'll watch these videos and see all the things I
  • say, and then I'll put these links on the video page, or
  • whatever it is, to examples. But you should be able to actually,
  • you can definitely find, if you go to the nature of code book,
  • GitHub repo, you can find several examples of the random
  • walker with Perlin noise. So there's more to Perlin noise.
  • One thing I just want to allude to very quickly that you could
  • also do as an exercise, is that, right, we have time here in one
  • dimension. And really, this idea of time I just used as a sort of
  • way of us describing how Perlin noise works. But this is really
  • just one dimensional space, right? There's a value, there's
  • a sort of a string, and on the string are written lots of
  • numbers in one dimension. But if we took that string and made it
  • into a piece of paper, and the number here is related to all
  • these other numbers that are near it, so instead of a number
  • here just having some neighbor to the left and right, there's
  • neighbors all around it in two dimensional space. So what if
  • you could map noise values in two dimensional space to height
  • values in it in some sort of top to top top topology, or for
  • pixel values in some type of texture for an image, right?
  • You'll get this is where you can start to get procedural textures
  • for for three dimensional objects. So that's looking at
  • two dimensional noise, and how that can work is kind of an
  • exciting possibility as well, and we'll see later on in the
  • video series, when we look at flow field for objects who are
  • dropped into space and moving almost as if there's these
  • currents and rivers pushing them along, where you create that
  • flow field with two dimensional, permanent noise. So yeah, I list
  • here, and I would like to make a two day permanence video, which
  • we will do at some point as well. Okay, so this video is
  • done. You're gonna have lots of questions and confusing things
  • and whatever. We'll re make this video or add some links and all
  • this. Everything will be okay. Everything's gonna be okay,
  • right? Okay,
  • goodbye, good girl, he's good. We don't touch that. But for
  • everything else, there's sensory, whether you're a mobile
  • back end, front end or any end. Developer will show you
  • what'd you think of that video.
  • Different. He had too much espresso, perhaps. And put it
  • politely,
  • anyway, I'll put a couple more links on the page for today's
  • meeting. If you can have a look at chapter 11.
  • I think it's fairly fairly short, and we'll talk about that
  • on Thursday, and then we'll touch on chapter 12 on Tuesday
  • next week, and then we have our last meeting on Thursday.
  • Where's the final exam
  • for those classes
  • in here, here at 2pm on on April 17, yes, I Remember
  • today. Yes.
  • Thank you for today. Any questions
  • yes.
  • yes.

Responses

No Responses