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