#### Discover more from GM Shaders Mini Tuts

# GM Shaders Mini: Noise 2

Hi folks,

Last week we went over 3 common noise algorithms. Today we will continue where we left off and show 3 more! Worley, Voronoi, and fractal noise.

Tutorial Difficulty: **Intermediate**

## Worley Noise

Worley noise functions a bit differently from the other noise algorithms because there is no interpolation involved. The concept is simple, scatter a bunch of points randomly and use the distance to the closest point to determine the output brightness. 0.0 at the point center and 1.0 for cell unit a way.

Let's break this down into simple steps:

**Step 1: Round To Cells**

Like before, round down the input coordinates to cells:

`vec2`

` cell = `

`floor`

`(p);`

And we'll also store our distance value in a float:

`float dist = 9.0;`

I'm using 9 because it's our maximum distance, that we should never exceed (even in higher dimensions).

**Step 2: Sample Point**

Compute the difference from `p`

to a random point in the cell:

`vec2 `

`worley_dif = hash2(cell) + cell - p;`

hash2 gives us a random x and y value between 0 and 1. Then add cell so the point position ranges from `cell `

to `cell+1.0`

and subtract `p`

to find the relative difference.

We can then calculate the distance by using the length of this difference:

`dist = `

`length`

`(worley_dif);`

Doing so gives us the result on the left:

So we now have our random points and we just want it to smoothly blend with the neighboring cells as shown above on the right. You might be able to guess the last step.

**Step 3: Sample Neighbors**

Loop through the 3x3 cell area instead

`for`

`(`

`int `

`x = -1; x<=1; x++)`

`for`

`(`

`int `

`y = -1; y<=1; y++)`

And we'll add this offset before sampling each cell:

`vec2 `

`sample_cell = cell + `

`vec2`

`(x,y);`

So we'll use our `sample_cell `

when computing `worley_dif`

instead:

`vec2 `

`worley_dif = hash2(sample_cell) + sample_cell - p;`

And we'll just use minimum distance across all neighbor cells:

`dist = `

`min`

`(dist, `

`length`

`(worley_dif));`

This gives us the desired cellular pattern we were looking for!

Again, I'll link a ShaderToy example at the end.

## Voronoi Noise

Voronoi noise is a simple variation of Worley noise. Instead of using the distance to nearest point, we'll pick a random value for every point and use the closest points value for the output.

**Step 1: Voronoi Cells**

So use your Worley function as a base, but before the loops, add another vec2:

`vec2 `

`voronoi_cell = cell;`

This will be used store the cell coordinates of the nearest point.

**Step 2: Find Nearest Cell**

Inside the loop, we need more than just the minimum distance to neighbor cells. We'll put our Worley distance value into a new float:

`float `

`new_dist `

`= length`

`(worley_dif);`

And when our new distance value is smaller than our old one:

`if `

`(dist > new_dist)`

Replace our old distance with the new, smaller value:

`dist = new_dist;`

This does the same thing as `min`

, but we'll also store our nearest sample cell:

`voronoi_cell = sample_cell;`

**Step 3: Final Hash**

And finally, once the loop is complete, we can use our hash function on the coordinates of the nearest Voronoi cell:

`return `

`hash1(voronoi_cell);`

This gives you neat honeycomb-like pattern:

## Fractal Noise

Now let's take a look at fractal noise! Fractal noise is when you layer multiple noise "octaves" at different scales and intensities to produce a more natural look. This can be used for clouds, smoke, fire or even terrain generation!

The neat part is that it can be applied to any of the other noise algorithms:

Let's break it down!

**Step 1: Initialize**

The first step is to initialize the variables we need:

`float `

`noise_sum = 0.0;`

//Noise total across octaves

`float `

`weight_sum = 0.0;`

//Weight total across octaves

`float `

`weight = 1.0;`

//Octave weight

`int `

`oct = 6;`

//Number of octaves

`float `

`per = 0.5;`

//Octave persistence (intensity)

**Step 2: Octaves**

A simple loop through octaves will do:

`for(`

`int `

`i = 0; i < oct; i++)`

For each octave, we want to add a weighted layer of noise.

`noise_sum += value_noise(p) * weight;`

And add the current weight to a total for averaging.

`weight_sum += weight;`

Next, we'll multiply our octave weight by the persistence value.

`weight *= per;`

This means with a persistence value of 0.5, each octave has half the intensity of the octave before it. Play around with different values to see how it looks.

And finally, quite importantly we rotate and scale each octave:

`p *= `

`mat2`

`(1.6, 1.2, -1.2, 1.6);`

This matrix scales coordinates by 2 and rotates by about 143 degrees. The rotation helps break up any patterns that might arise from noise octaves overlapping each. `p *= 2.0`

also works, but doesn't look as good.

**Step 3: Weighted Average**

And finally, just return the weighted average:

`return noise_sum / weight_sum;`

In case you didn't know, a weighted average is an average where some values have more of an effect than others. In this case, If you have a persistence value of 0.5, the first octave contributes to half of the average, the second octave: one-quarter, the third: one-eighth, and so on.

It's a great trick to learn and use in any shader where you need to blend multiple values together with different weights!

## Conclusion

That covers it for tonight. Let me know if there are any other noise algorithms you'd like me to go over.

You can take a look at the code I used in my ShaderToy example here!

And you're bored, check out this 3D game I made in 2 weeks using just GameMaker (no 3D modeling/animation software, just shader code!)

Thanks for reading! Enjoy your night!